Mon, 28 Oct 2019 13:29:09 +0800
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
src/share/vm/opto/loopTransform.cpp | file | annotate | diff | comparison | revisions | |
test/compiler/loopopts/TestRemoveEmptyLoop.java | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/opto/loopTransform.cpp Thu Oct 17 13:48:07 2019 +0100 1.2 +++ b/src/share/vm/opto/loopTransform.cpp Mon Oct 28 13:29:09 2019 +0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -2231,6 +2231,13 @@ 1.11 // We also need to replace the original limit to collapse loop exit. 1.12 Node* cmp = cl->loopexit()->cmp_node(); 1.13 assert(cl->limit() == cmp->in(2), "sanity"); 1.14 + // Duplicate cmp node if it has other users 1.15 + if (cmp->outcnt() > 1) { 1.16 + cmp = cmp->clone(); 1.17 + cmp = phase->_igvn.register_new_node_with_optimizer(cmp); 1.18 + BoolNode *bol = cl->loopexit()->in(CountedLoopEndNode::TestValue)->as_Bool(); 1.19 + phase->_igvn.replace_input_of(bol, 1, cmp); // put bol on worklist 1.20 + } 1.21 phase->_igvn._worklist.push(cmp->in(2)); // put limit on worklist 1.22 phase->_igvn.replace_input_of(cmp, 2, exact_limit); // put cmp on worklist 1.23 }
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/compiler/loopopts/TestRemoveEmptyLoop.java Mon Oct 28 13:29:09 2019 +0800 2.3 @@ -0,0 +1,53 @@ 2.4 +/* 2.5 + * Copyright (c) 2019, Huawei Technologies Co. Ltd. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + */ 2.26 + 2.27 +/** 2.28 + * @test 2.29 + * @bug 8231988 2.30 + * @summary Unexpected test result caused by C2 IdealLoopTree::do_remove_empty_loop 2.31 + * 2.32 + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation 2.33 + * TestRemoveEmptyLoop 2.34 + */ 2.35 + 2.36 +public class TestRemoveEmptyLoop { 2.37 + 2.38 + public void test() { 2.39 + int i = 34; 2.40 + for (; i > 0; i -= 11); 2.41 + if (i < 0) { 2.42 + // do nothing 2.43 + } else { 2.44 + throw new RuntimeException("Test failed."); 2.45 + } 2.46 + } 2.47 + 2.48 + public static void main(String[] args) { 2.49 + TestRemoveEmptyLoop _instance = new TestRemoveEmptyLoop(); 2.50 + for (int i = 0; i < 50000; i++) { 2.51 + _instance.test(); 2.52 + } 2.53 + System.out.println("Test passed."); 2.54 + } 2.55 + 2.56 +}