Blame SOURCES/jdk8245714-rh1828845-build_loop_late_crash.patch

07b2a4
# HG changeset patch
07b2a4
# User roland
07b2a4
# Date 1590664914 -7200
07b2a4
#      Thu May 28 13:21:54 2020 +0200
07b2a4
# Node ID 516c889e7582598020e49ed62bcf77871fe315d8
07b2a4
# Parent  b2e6516f67ff98224f14e65beb944ddb04b24548
07b2a4
8245714: "Bad graph detected in build_loop_late" when loads are pinned on loop limit check uncommon branch
07b2a4
Reviewed-by: thartmann
07b2a4
07b2a4
diff --git a/src/hotspot/share/opto/loopPredicate.cpp b/src/hotspot/share/opto/loopPredicate.cpp
07b2a4
--- a/src/hotspot/share/opto/loopPredicate.cpp
07b2a4
+++ b/src/hotspot/share/opto/loopPredicate.cpp
07b2a4
@@ -111,6 +111,9 @@
07b2a4
     CallNode* call = rgn->as_Call();
07b2a4
     IdealLoopTree* loop = get_loop(call);
07b2a4
     rgn = new RegionNode(1);
07b2a4
+    Node* uncommon_proj_orig = uncommon_proj;
07b2a4
+    uncommon_proj = uncommon_proj->clone()->as_Proj();
07b2a4
+    register_control(uncommon_proj, loop, iff);
07b2a4
     rgn->add_req(uncommon_proj);
07b2a4
     register_control(rgn, loop, uncommon_proj);
07b2a4
     _igvn.replace_input_of(call, 0, rgn);
07b2a4
@@ -118,13 +121,9 @@
07b2a4
     if (_idom != NULL) {
07b2a4
       set_idom(call, rgn, dom_depth(rgn));
07b2a4
     }
07b2a4
-    for (DUIterator_Fast imax, i = uncommon_proj->fast_outs(imax); i < imax; i++) {
07b2a4
-      Node* n = uncommon_proj->fast_out(i);
07b2a4
-      if (n->is_Load() || n->is_Store()) {
07b2a4
-        _igvn.replace_input_of(n, 0, rgn);
07b2a4
-        --i; --imax;
07b2a4
-      }
07b2a4
-    }
07b2a4
+    // Move nodes pinned on the projection or whose control is set to
07b2a4
+    // the projection to the region.
07b2a4
+    lazy_replace(uncommon_proj_orig, rgn);
07b2a4
   } else {
07b2a4
     // Find region's edge corresponding to uncommon_proj
07b2a4
     for (; proj_index < rgn->req(); proj_index++)
07b2a4
diff --git a/test/hotspot/jtreg/compiler/loopopts/TestBadControlLoopLimitCheck.java b/test/hotspot/jtreg/compiler/loopopts/TestBadControlLoopLimitCheck.java
07b2a4
new file mode 100644
07b2a4
--- /dev/null
07b2a4
+++ b/test/hotspot/jtreg/compiler/loopopts/TestBadControlLoopLimitCheck.java
07b2a4
@@ -0,0 +1,85 @@
07b2a4
+/*
07b2a4
+ * Copyright (c) 2020, Red Hat, Inc. All rights reserved.
07b2a4
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
07b2a4
+ *
07b2a4
+ * This code is free software; you can redistribute it and/or modify it
07b2a4
+ * under the terms of the GNU General Public License version 2 only, as
07b2a4
+ * published by the Free Software Foundation.
07b2a4
+ *
07b2a4
+ * This code is distributed in the hope that it will be useful, but WITHOUT
07b2a4
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
07b2a4
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
07b2a4
+ * version 2 for more details (a copy is included in the LICENSE file that
07b2a4
+ * accompanied this code).
07b2a4
+ *
07b2a4
+ * You should have received a copy of the GNU General Public License version
07b2a4
+ * 2 along with this work; if not, write to the Free Software Foundation,
07b2a4
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
07b2a4
+ *
07b2a4
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
07b2a4
+ * or visit www.oracle.com if you need additional information or have any
07b2a4
+ * questions.
07b2a4
+ */
07b2a4
+
07b2a4
+/*
07b2a4
+ * @test
07b2a4
+ * @bug 8245714
07b2a4
+ * @requires vm.compiler2.enabled
07b2a4
+ * @summary "Bad graph detected in build_loop_late" when loads are pinned on loop limit check uncommon branch
07b2a4
+ *
07b2a4
+ * @run main/othervm -XX:-BackgroundCompilation -XX:ArrayCopyLoadStoreMaxElem=0 TestBadControlLoopLimitCheck
07b2a4
+ */
07b2a4
+
07b2a4
+public class TestBadControlLoopLimitCheck {
07b2a4
+    public static void main(String[] args) {
07b2a4
+        int[] int_array = {0, 0};
07b2a4
+        A[] obj_array = {new A(), new A()};
07b2a4
+        for (int i = 0; i < 20_000; i++) {
07b2a4
+            test1(int_array, 0, 10, false);
07b2a4
+            test_helper(42);
07b2a4
+            test2(obj_array, 0, 10, false);
07b2a4
+        }
07b2a4
+    }
07b2a4
+
07b2a4
+    private static int test1(int[] a, int start, int stop, boolean flag) {
07b2a4
+        int[] b = new int[2]; // non escaping allocation
07b2a4
+        System.arraycopy(a, 0, b, 0, 2); // optimized out
07b2a4
+        int v = 1;
07b2a4
+        int j = 0;
07b2a4
+        for (; j < 10; j++);
07b2a4
+        int inc = test_helper(j); // delay transformation to counted loop
07b2a4
+        // loop limit check here has loads pinned on unc branch
07b2a4
+        for (int i = start; i < stop; i += inc) {
07b2a4
+            v *= 2;
07b2a4
+        }
07b2a4
+        if (flag) {
07b2a4
+            v += b[0] + b[1];
07b2a4
+        }
07b2a4
+        return v;
07b2a4
+    }
07b2a4
+
07b2a4
+    private static int test2(A[] a, int start, int stop, boolean flag) {
07b2a4
+        A[] b = new A[2]; // non escaping allocation
07b2a4
+        System.arraycopy(a, 0, b, 0, 2); // optimized out
07b2a4
+        int v = 1;
07b2a4
+        int j = 0;
07b2a4
+        for (; j < 10; j++);
07b2a4
+        int inc = test_helper(j); // delay transformation to counted loop
07b2a4
+        // loop limit check here has loads pinned on unc branch
07b2a4
+        for (int i = start; i < stop; i += inc) {
07b2a4
+            v *= 2;
07b2a4
+        }
07b2a4
+        if (flag) {
07b2a4
+            v += b[0].f + b[1].f;
07b2a4
+        }
07b2a4
+        return v;
07b2a4
+    }
07b2a4
+
07b2a4
+    static class A {
07b2a4
+        int f;
07b2a4
+    }
07b2a4
+
07b2a4
+    static int test_helper(int j) {
07b2a4
+        return j == 10 ? 10 : 1;
07b2a4
+    }
07b2a4
+}