changeset 59310:37ab496acb09

8244721: CTW: C2 (Shenandoah) compilation fails with "unexpected infinite loop graph shape" Reviewed-by: shade
author roland
date Fri, 15 May 2020 10:24:38 +0200
parents 9f3244962bb3
children da9d92098f44
files src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp test/hotspot/jtreg/gc/shenandoah/compiler/BarrierInInfiniteLoop.java
diffstat 2 files changed, 58 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp	Fri May 15 19:57:37 2020 +0200
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp	Fri May 15 10:24:38 2020 +0200
@@ -2101,17 +2101,7 @@
               mem = call->in(TypeFunc::Memory);
             } else if (in->Opcode() == Op_NeverBranch) {
               Node* head = in->in(0);
-              assert(head->is_Region() && head->req() == 3, "unexpected infinite loop graph shape");
-              assert(_phase->is_dominator(head, head->in(1)) || _phase->is_dominator(head, head->in(2)), "no back branch?");
-              Node* tail = _phase->is_dominator(head, head->in(1)) ? head->in(1) : head->in(2);
-              Node* c = tail;
-              while (c != head) {
-                if (c->is_SafePoint() && !c->is_CallLeaf()) {
-                  mem = c->in(TypeFunc::Memory);
-                }
-                c = _phase->idom(c);
-              }
-              assert(mem != NULL, "should have found safepoint");
+              assert(head->is_Region(), "unexpected infinite loop graph shape");
 
               Node* phi_mem = NULL;
               for (DUIterator_Fast jmax, j = head->fast_outs(jmax); j < jmax; j++) {
@@ -2128,7 +2118,28 @@
                   }
                 }
               }
-              if (phi_mem != NULL) {
+              if (phi_mem == NULL) {
+                for (uint j = 1; j < head->req(); j++) {
+                  Node* tail = head->in(j);
+                  if (!_phase->is_dominator(head, tail)) {
+                    continue;
+                  }
+                  Node* c = tail;
+                  while (c != head) {
+                    if (c->is_SafePoint() && !c->is_CallLeaf()) {
+                      Node* m =c->in(TypeFunc::Memory);
+                      if (m->is_MergeMem()) {
+                        m = m->as_MergeMem()->memory_at(_alias);
+                      }
+                      assert(mem == NULL || mem == m, "several memory states");
+                      mem = m;
+                    }
+                    c = _phase->idom(c);
+                  }
+                  assert(mem != NULL, "should have found safepoint");
+                }
+                assert(mem != NULL, "should have found safepoint");
+              } else {
                 mem = phi_mem;
               }
             }
@@ -2237,7 +2248,7 @@
           assert(m != NULL || (c->is_Loop() && j == LoopNode::LoopBackControl && iteration == 1) || _phase->C->has_irreducible_loop() || has_never_branch(_phase->C->root()), "expect memory state");
           if (m != NULL) {
             if (m == prev_region && ((c->is_Loop() && j == LoopNode::LoopBackControl) || (prev_region->is_Phi() && prev_region->in(0) == c))) {
-              assert(c->is_Loop() && j == LoopNode::LoopBackControl || _phase->C->has_irreducible_loop(), "");
+              assert(c->is_Loop() && j == LoopNode::LoopBackControl || _phase->C->has_irreducible_loop() || has_never_branch(_phase->C->root()), "");
               // continue
             } else if (unique == NULL) {
               unique = m;
--- a/test/hotspot/jtreg/gc/shenandoah/compiler/BarrierInInfiniteLoop.java	Fri May 15 19:57:37 2020 +0200
+++ b/test/hotspot/jtreg/gc/shenandoah/compiler/BarrierInInfiniteLoop.java	Fri May 15 10:24:38 2020 +0200
@@ -23,29 +23,59 @@
 
 /**
  * @test
- * @bug 8237837
+ * @bug 8237837 8244721
  * @summary  Shenandoah: assert(mem == __null) failed: only one safepoint
  * @key gc
  * @requires vm.flavor == "server"
  * @requires vm.gc.Shenandoah & !vm.graal.enabled
  *
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xcomp -XX:CompileOnly=BarrierInInfiniteLoop::test -XX:CompileCommand=quiet BarrierInInfiniteLoop
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xcomp -XX:CompileOnly=BarrierInInfiniteLoop::test1
+ *                   -XX:CompileOnly=BarrierInInfiniteLoop::test2 -XX:CompileOnly=BarrierInInfiniteLoop::test3 -XX:CompileCommand=quiet BarrierInInfiniteLoop
  *
  */
 
 public class BarrierInInfiniteLoop {
     private static Object field1 = new Object();
     private static Object field2 = new Object();
+    private static int field3;
 
     public static void main(String[] args) {
-        test(false);
+        test1(false);
+        test2(false, false);
+        test3(false);
     }
 
-    private static void test(boolean flag) {
+    private static void test1(boolean flag) {
         if (flag) {
             for (;;) {
                 field1 = field2;
             }
         }
     }
+
+    private static void test2(boolean flag1, boolean flag2) {
+        if (flag1) {
+            for (;;) {
+                for (;;) {
+                    if (flag2) {
+                        break;
+                    }
+                    field1 = field2;
+                }
+            }
+        }
+    }
+
+    private static void test3(boolean flag) {
+        if (flag) {
+            for (;;) {
+                for (;;) {
+                    field3 = 42;
+                    if (field1 == field2) {
+                        break;
+                    }
+                }
+            }
+        }
+    }
 }