RFR(S): 8146792: Predicate moved after partial peel may lead to broken graph

Roland Westrelin roland.westrelin at oracle.com
Tue Jan 12 10:17:16 UTC 2016


> With the test case, it would be safe to move the StoreF above the predicates I think. But in the general case, I don’t see how we can be sure that we don’t have:
> 
> - null check/range check for the StoreF moved out of loops as predicates
> - partial peel that causes the StoreF to be pinned below the predicates
> - loop predication that moves some data node that depends on the StoreF above it

Actually, I can reproduce this scenario with the patch below: some changes to the test and making range check smearing a little big more aggressive so a range check is replaced by a dominating predicate range check.

Roland.

diff --git a/src/share/vm/opto/ifnode.cpp b/src/share/vm/opto/ifnode.cpp
--- a/src/share/vm/opto/ifnode.cpp
+++ b/src/share/vm/opto/ifnode.cpp
@@ -514,7 +514,7 @@
   // along the OOB path.  Otherwise, it's possible that the user wrote
   // something which optimized to look like a range check but behaves
   // in some other way.
-  if (iftrap->is_uncommon_trap_proj(Deoptimization::Reason_range_check) == NULL) {
+  if (iftrap->is_uncommon_trap_proj(Deoptimization::Reason_none) == NULL) {
     return 0;
   }
 
diff --git a/test/compiler/loopopts/BadPredicateAfterPartialPeel.java b/test/compiler/loopopts/BadPredicateAfterPartialPeel.java
--- a/test/compiler/loopopts/BadPredicateAfterPartialPeel.java
+++ b/test/compiler/loopopts/BadPredicateAfterPartialPeel.java
@@ -30,6 +30,8 @@
  *
  */
 
+import java.util.Objects;
+
 public class BadPredicateAfterPartialPeel {
 
     static void not_inlined1() {}
@@ -45,13 +47,13 @@
     boolean flag;
     int j;
 
-    static void m(BadPredicateAfterPartialPeel o1, BadPredicateAfterPartialPeel o2, BadPredicateAfterPartialPeel o, int i4) {
+    static void m(BadPredicateAfterPartialPeel o1, BadPredicateAfterPartialPeel o2, BadPredicateAfterPartialPeel o, int i4) throws Exception {
         int i1 = 1;
 
         // To delay partial peeling to the loop opts pass right before CCP
-        int i2 = 0;
-        for (; i2 < 10; i2 += i1);
-        i2 = i2 / 10;
+        int i2 = 1;
+        // for (; i2 < 10; i2 += i1);
+        // i2 = i2 / 10;
         
         // Simplified during CCP:
         int i3 = 2;
@@ -63,11 +65,12 @@
 
         not_inlined1();
 
-        array[0] = -1;
         do {
             // peeled section starts here
             o.flag = false;
             o.j = 0;
+            
+            Objects.checkIndex(0, array.length, null);
 
             if (b) {
                 // The following store will be pinned between
@@ -300,7 +303,7 @@
         not_inlined4();
     }
 
-    static public void main(String[] args) {
+    static public void main(String[] args) throws Exception {
         BadPredicateAfterPartialPeel o1 = new BadPredicateAfterPartialPeel();
         BadPredicateAfterPartialPeel o2 = new BadPredicateAfterPartialPeel();
         for (int i = 0; i < 20000; i++) {




More information about the hotspot-compiler-dev mailing list