From c5c0867881a43c81e88453274ac12e45454685a4 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 5 Jun 2024 15:37:31 +0000 Subject: [PATCH] 8333252: C2: assert(assertion_predicate_has_loop_opaque_node(iff)) failed: must find OpaqueLoop* nodes Reviewed-by: kvn, epeter --- src/hotspot/share/opto/loopPredicate.cpp | 25 +++++-- .../TestTemplateWithoutOpaqueLoopNodes.java | 69 +++++++++++++++++++ 2 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/predicates/assertion/TestTemplateWithoutOpaqueLoopNodes.java diff --git a/src/hotspot/share/opto/loopPredicate.cpp b/src/hotspot/share/opto/loopPredicate.cpp index 8d2cf9dc936..e23da54f765 100644 --- a/src/hotspot/share/opto/loopPredicate.cpp +++ b/src/hotspot/share/opto/loopPredicate.cpp @@ -1212,7 +1212,13 @@ bool PhaseIdealLoop::loop_predication_impl_helper(IdealLoopTree* loop, IfProjNod // Limit is not exact. // Calculate exact limit here. // Note, counted loop's test is '<' or '>'. +#ifdef ASSERT + const bool exact_trip_count = cl->has_exact_trip_count(); + const uint trip_count = cl->trip_count(); loop->compute_trip_count(this); + assert(exact_trip_count == cl->has_exact_trip_count() && trip_count == cl->trip_count(), + "should have computed trip count on Loop Predication entry"); +#endif Node* limit = exact_limit(loop); int stride = cl->stride()->get_int(); @@ -1321,7 +1327,9 @@ IfProjNode* PhaseIdealLoop::add_template_assertion_predicate(IfNode* iff, IdealL max_value = new AddINode(opaque_init, max_value); register_new_node(max_value, new_proj); // init + (current stride - initial stride) is within the loop so narrow its type by leveraging the type of the iv Phi - max_value = new CastIINode(max_value, loop->_head->as_CountedLoop()->phi()->bottom_type()); + const Type* type_iv = loop->_head->as_CountedLoop()->phi()->bottom_type(); + assert(!type_iv->is_int()->is_con(), "constant indicates one loop iteration for which we bailed out earlier"); + max_value = new CastIINode(max_value, type_iv); register_new_node(max_value, parse_predicate_proj); bol = rc_predicate(new_proj, scale, offset, max_value, limit, stride, rng, (stride > 0) != (scale > 0), @@ -1350,12 +1358,21 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree* loop) { CountedLoopNode *cl = nullptr; if (head->is_valid_counted_loop(T_INT)) { cl = head->as_CountedLoop(); - // do nothing for iteration-splitted loops - if (!cl->is_normal_loop()) return false; + if (!cl->is_normal_loop()) { + // Do nothing for iteration-splitted loops + return false; + } + loop->compute_trip_count(this); + if (cl->trip_count() == 1) { + // Not worth to hoist checks out of a loop that is only run for one iteration since the checks are only going to + // be executed once anyway. + return false; + } // Avoid RCE if Counted loop's test is '!='. BoolTest::mask bt = cl->loopexit()->test_trip(); - if (bt != BoolTest::lt && bt != BoolTest::gt) + if (bt != BoolTest::lt && bt != BoolTest::gt) { cl = nullptr; + } } Node* entry = head->skip_strip_mined()->in(LoopNode::EntryControl); diff --git a/test/hotspot/jtreg/compiler/predicates/assertion/TestTemplateWithoutOpaqueLoopNodes.java b/test/hotspot/jtreg/compiler/predicates/assertion/TestTemplateWithoutOpaqueLoopNodes.java new file mode 100644 index 00000000000..309da03e08c --- /dev/null +++ b/test/hotspot/jtreg/compiler/predicates/assertion/TestTemplateWithoutOpaqueLoopNodes.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024, 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 + * 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 id=Xcomp + * @bug 8333252 + * @summary Test that no Template Assertion Predicate is created in Loop Prediction for one iteration loop. + * @run main/othervm -Xcomp -XX:CompileCommand=compileonly,*TestTemplateWithoutOpaqueLoopNodes::test + * compiler.predicates.assertion.TestTemplateWithoutOpaqueLoopNodes + */ + +/* + * @test id=Xbatch + * @bug 8333252 + * @summary Test that no Template Assertion Predicate is created in Loop Prediction for one iteration loop. + * @run main/othervm -Xbatch -XX:CompileCommand=compileonly,*TestTemplateWithoutOpaqueLoopNodes::test + * compiler.predicates.assertion.TestTemplateWithoutOpaqueLoopNodes + */ + +package compiler.predicates.assertion; + +public class TestTemplateWithoutOpaqueLoopNodes { + static long lFld; + static long lArr[] = new long[10]; + + public static void main(String[] args) { + for (int i = 0; i < 10; i++) { + test(); + } + } + + static void test() { + int i16 = 1, i17, i19, i20 = 1, i22; + for (i17 = 6; i17 < 7; i17++) { + switch ((i16 >> 1) + 38) { + case 38: + for (i19 = 1; i19 < 200000; i19++) { + } + case 1: + for (i22 = 1; i22 < 2; i22 += 2) { + lArr[i22] = i20; + } + break; + case 4: + lFld = 42; + } + } + } +}