aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfyang <unknown>2019-10-28 13:29:09 +0800
committerbell-sw <liberica@bell-sw.com>2020-01-19 09:12:34 +0300
commit284f15d9206338440de8e8375f6f5a1952b164ad (patch)
tree0aec6c0776d0b1715fdf00ac9fa038e369a2e921
parenta3b1f31fa0feb92d1d22695b6d6e012587563e65 (diff)
downloadjdk8u_hotspot-284f15d9206338440de8e8375f6f5a1952b164ad.tar.gz
8231988: Unexpected test result caused by C2 IdealLoopTree::do_remove_empty_loop
Summary: Duplicate cmp node in empty loop if it has other users Reviewed-by: neliasso, thartmann Contributed-by: wanghuang3@huawei.com, xietuo@huawei.com
-rw-r--r--src/share/vm/opto/loopTransform.cpp9
-rw-r--r--test/compiler/loopopts/TestRemoveEmptyLoop.java53
2 files changed, 61 insertions, 1 deletions
diff --git a/src/share/vm/opto/loopTransform.cpp b/src/share/vm/opto/loopTransform.cpp
index 7ef67c155..e3637b652 100644
--- a/src/share/vm/opto/loopTransform.cpp
+++ b/src/share/vm/opto/loopTransform.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2231,6 +2231,13 @@ bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) {
// We also need to replace the original limit to collapse loop exit.
Node* cmp = cl->loopexit()->cmp_node();
assert(cl->limit() == cmp->in(2), "sanity");
+ // Duplicate cmp node if it has other users
+ if (cmp->outcnt() > 1) {
+ cmp = cmp->clone();
+ cmp = phase->_igvn.register_new_node_with_optimizer(cmp);
+ BoolNode *bol = cl->loopexit()->in(CountedLoopEndNode::TestValue)->as_Bool();
+ phase->_igvn.replace_input_of(bol, 1, cmp); // put bol on worklist
+ }
phase->_igvn._worklist.push(cmp->in(2)); // put limit on worklist
phase->_igvn.replace_input_of(cmp, 2, exact_limit); // put cmp on worklist
}
diff --git a/test/compiler/loopopts/TestRemoveEmptyLoop.java b/test/compiler/loopopts/TestRemoveEmptyLoop.java
new file mode 100644
index 000000000..d9828e56f
--- /dev/null
+++ b/test/compiler/loopopts/TestRemoveEmptyLoop.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019, Huawei Technologies Co. Ltd. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8231988
+ * @summary Unexpected test result caused by C2 IdealLoopTree::do_remove_empty_loop
+ *
+ * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation
+ * TestRemoveEmptyLoop
+ */
+
+public class TestRemoveEmptyLoop {
+
+ public void test() {
+ int i = 34;
+ for (; i > 0; i -= 11);
+ if (i < 0) {
+ // do nothing
+ } else {
+ throw new RuntimeException("Test failed.");
+ }
+ }
+
+ public static void main(String[] args) {
+ TestRemoveEmptyLoop _instance = new TestRemoveEmptyLoop();
+ for (int i = 0; i < 50000; i++) {
+ _instance.test();
+ }
+ System.out.println("Test passed.");
+ }
+
+}