Skip to content

Commit 8f2b23b

Browse files
committedOct 21, 2024
8341407: C2: assert(main_limit == cl->limit() || get_ctrl(main_limit) == new_limit_ctrl) failed: wrong control for added limit
Reviewed-by: chagedorn, thartmann
1 parent 21682bc commit 8f2b23b

File tree

2 files changed

+72
-8
lines changed

2 files changed

+72
-8
lines changed
 

‎src/hotspot/share/opto/loopTransform.cpp

+11-8
Original file line numberDiff line numberDiff line change
@@ -2894,7 +2894,7 @@ void PhaseIdealLoop::do_range_check(IdealLoopTree *loop, Node_List &old_new) {
28942894
limit_ctrl = ensure_node_and_inputs_are_above_pre_end(pre_end, limit);
28952895

28962896
// offset and limit could have control below new_limit_ctrl if they are not loop invariant in the pre loop.
2897-
new_limit_ctrl = dominated_node(new_limit_ctrl, offset_ctrl, limit_ctrl);
2897+
Node* next_limit_ctrl = dominated_node(new_limit_ctrl, offset_ctrl, limit_ctrl);
28982898

28992899
#ifdef ASSERT
29002900
if (TraceRangeLimitCheck) {
@@ -2915,16 +2915,16 @@ void PhaseIdealLoop::do_range_check(IdealLoopTree *loop, Node_List &old_new) {
29152915
jlong lscale_con = scale_con;
29162916
Node* int_offset = offset;
29172917
offset = new ConvI2LNode(offset);
2918-
register_new_node(offset, new_limit_ctrl);
2918+
register_new_node(offset, next_limit_ctrl);
29192919
Node* int_limit = limit;
29202920
limit = new ConvI2LNode(limit);
2921-
register_new_node(limit, new_limit_ctrl);
2921+
register_new_node(limit, next_limit_ctrl);
29222922

29232923
// Adjust pre and main loop limits to guard the correct iteration set
29242924
if (cmp->Opcode() == Op_CmpU) { // Unsigned compare is really 2 tests
29252925
if (b_test._test == BoolTest::lt) { // Range checks always use lt
29262926
// The underflow and overflow limits: 0 <= scale*I+offset < limit
2927-
add_constraint(stride_con, lscale_con, offset, zero, limit, new_limit_ctrl, &pre_limit, &main_limit);
2927+
add_constraint(stride_con, lscale_con, offset, zero, limit, next_limit_ctrl, &pre_limit, &main_limit);
29282928
Node* init = cl->init_trip();
29292929
Node* opaque_init = new OpaqueLoopInitNode(C, init);
29302930
register_new_node(opaque_init, loop_entry);
@@ -2977,22 +2977,22 @@ void PhaseIdealLoop::do_range_check(IdealLoopTree *loop, Node_List &old_new) {
29772977
// Convert (I*scale+offset) >= Limit to (I*(-scale)+(-offset)) <= -Limit
29782978
lscale_con = -lscale_con;
29792979
offset = new SubLNode(zero, offset);
2980-
register_new_node(offset, new_limit_ctrl);
2980+
register_new_node(offset, next_limit_ctrl);
29812981
limit = new SubLNode(zero, limit);
2982-
register_new_node(limit, new_limit_ctrl);
2982+
register_new_node(limit, next_limit_ctrl);
29832983
// Fall into LE case
29842984
case BoolTest::le:
29852985
if (b_test._test != BoolTest::gt) {
29862986
// Convert X <= Y to X < Y+1
29872987
limit = new AddLNode(limit, one);
2988-
register_new_node(limit, new_limit_ctrl);
2988+
register_new_node(limit, next_limit_ctrl);
29892989
}
29902990
// Fall into LT case
29912991
case BoolTest::lt:
29922992
// The underflow and overflow limits: MIN_INT <= scale*I+offset < limit
29932993
// Note: (MIN_INT+1 == -MAX_INT) is used instead of MIN_INT here
29942994
// to avoid problem with scale == -1: MIN_INT/(-1) == MIN_INT.
2995-
add_constraint(stride_con, lscale_con, offset, mini, limit, new_limit_ctrl, &pre_limit, &main_limit);
2995+
add_constraint(stride_con, lscale_con, offset, mini, limit, next_limit_ctrl, &pre_limit, &main_limit);
29962996
break;
29972997
default:
29982998
if (PrintOpto) {
@@ -3001,6 +3001,9 @@ void PhaseIdealLoop::do_range_check(IdealLoopTree *loop, Node_List &old_new) {
30013001
continue; // Unhandled case
30023002
}
30033003
}
3004+
// Only update variable tracking control for new nodes if it's indeed a range check that can be eliminated (and
3005+
// limits are updated)
3006+
new_limit_ctrl = next_limit_ctrl;
30043007

30053008
// Kill the eliminated test
30063009
C->set_major_progress();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright (c) 2024, Red Hat, Inc. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/**
25+
* @test
26+
* @bug 8341407
27+
* @summary C2: assert(main_limit == cl->limit() || get_ctrl(main_limit) == new_limit_ctrl) failed: wrong control for added limit
28+
*
29+
* @run main/othervm -XX:CompileCommand=compileonly,TestLimitControlWhenNoRCEliminated::* -Xcomp TestLimitControlWhenNoRCEliminated
30+
*
31+
*/
32+
33+
public class TestLimitControlWhenNoRCEliminated {
34+
static long[] lArr;
35+
static int iFld;
36+
37+
public static void main(String[] strArr) {
38+
try {
39+
test();
40+
} catch (NullPointerException npe) {}
41+
}
42+
43+
static void test() {
44+
int x = iFld;
45+
int i = 1;
46+
do {
47+
lArr[i - 1] = 9;
48+
x += 1;
49+
iFld += x;
50+
if (x != 0) {
51+
A.foo();
52+
}
53+
} while (++i < 23);
54+
}
55+
}
56+
57+
class A {
58+
static void foo() {
59+
}
60+
}
61+

1 commit comments

Comments
 (1)

openjdk-notifier[bot] commented on Oct 21, 2024

@openjdk-notifier[bot]
Please sign in to comment.