Skip to content

Commit acf96c6

Browse files
committed
8290432: C2 compilation fails with assert(node->_last_del == _last) failed: must have deleted the edge just produced
Reviewed-by: kvn, thartmann, chagedorn
1 parent ce89673 commit acf96c6

File tree

2 files changed

+111
-6
lines changed

2 files changed

+111
-6
lines changed

src/hotspot/share/opto/loopnode.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3657,11 +3657,13 @@ bool PhaseIdealLoop::is_deleteable_safept(Node* sfpt) {
36573657
void PhaseIdealLoop::replace_parallel_iv(IdealLoopTree *loop) {
36583658
assert(loop->_head->is_CountedLoop(), "");
36593659
CountedLoopNode *cl = loop->_head->as_CountedLoop();
3660-
if (!cl->is_valid_counted_loop(T_INT))
3660+
if (!cl->is_valid_counted_loop(T_INT)) {
36613661
return; // skip malformed counted loop
3662+
}
36623663
Node *incr = cl->incr();
3663-
if (incr == NULL)
3664+
if (incr == NULL) {
36643665
return; // Dead loop?
3666+
}
36653667
Node *init = cl->init_trip();
36663668
Node *phi = cl->phi();
36673669
int stride_con = cl->stride_con();
@@ -3670,25 +3672,33 @@ void PhaseIdealLoop::replace_parallel_iv(IdealLoopTree *loop) {
36703672
for (DUIterator i = cl->outs(); cl->has_out(i); i++) {
36713673
Node *out = cl->out(i);
36723674
// Look for other phis (secondary IVs). Skip dead ones
3673-
if (!out->is_Phi() || out == phi || !has_node(out))
3675+
if (!out->is_Phi() || out == phi || !has_node(out)) {
36743676
continue;
3677+
}
3678+
36753679
PhiNode* phi2 = out->as_Phi();
3676-
Node *incr2 = phi2->in( LoopNode::LoopBackControl );
3680+
Node* incr2 = phi2->in(LoopNode::LoopBackControl);
36773681
// Look for induction variables of the form: X += constant
36783682
if (phi2->region() != loop->_head ||
36793683
incr2->req() != 3 ||
36803684
incr2->in(1)->uncast() != phi2 ||
36813685
incr2 == incr ||
36823686
incr2->Opcode() != Op_AddI ||
3683-
!incr2->in(2)->is_Con())
3687+
!incr2->in(2)->is_Con()) {
36843688
continue;
3689+
}
36853690

3691+
if (incr2->in(1)->is_ConstraintCast() &&
3692+
!(incr2->in(1)->in(0)->is_IfProj() && incr2->in(1)->in(0)->in(0)->is_RangeCheck())) {
3693+
// Skip AddI->CastII->Phi case if CastII is not controlled by local RangeCheck
3694+
continue;
3695+
}
36863696
// Check for parallel induction variable (parallel to trip counter)
36873697
// via an affine function. In particular, count-down loops with
36883698
// count-up array indices are common. We only RCE references off
36893699
// the trip-counter, so we need to convert all these to trip-counter
36903700
// expressions.
3691-
Node *init2 = phi2->in( LoopNode::EntryControl );
3701+
Node* init2 = phi2->in(LoopNode::EntryControl);
36923702
int stride_con2 = incr2->in(2)->get_int();
36933703

36943704
// The ratio of the two strides cannot be represented as an int
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright (c) 2022, Alibaba Group Holding Limited. 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+
/**
26+
* @test
27+
* @bug 8290432
28+
* @summary Unexpected parallel induction variable pattern was recongized
29+
*
30+
* @run main/othervm -XX:-TieredCompilation -Xcomp
31+
* -XX:CompileCommand=compileonly,compiler.c2.TestUnexpectedParallelIV::test
32+
* -XX:CompileCommand=compileonly,compiler.c2.TestUnexpectedParallelIV::test2
33+
* -XX:CompileCommand=quiet
34+
* -XX:CompileCommand=dontinline,compiler.c2.TestUnexpectedParallelIV::* compiler.c2.TestUnexpectedParallelIV
35+
*/
36+
37+
package compiler.c2;
38+
39+
public class TestUnexpectedParallelIV {
40+
41+
static boolean bFld;
42+
43+
static int dontInline() {
44+
return 0;
45+
}
46+
47+
static int test2(int i1) {
48+
int i2, i3 = 0, i4, i5 = 0, i6;
49+
for (i2 = 0; 4 > i2; ++i2) {
50+
for (i4 = 1; i4 < 5; ++i4) {
51+
i3 -= --i1;
52+
i6 = 1;
53+
while (++i6 < 2) {
54+
dontInline();
55+
if (bFld) {
56+
i1 = 5;
57+
}
58+
}
59+
if (bFld) {
60+
break;
61+
}
62+
}
63+
}
64+
return i3;
65+
}
66+
67+
static long test(int val, boolean b) {
68+
long ret = 0;
69+
long dArr[] = new long[100];
70+
for (int i = 15; 293 > i; ++i) {
71+
ret = val;
72+
int j = 1;
73+
while (++j < 6) {
74+
int k = (val--);
75+
for (long l = i; 1 > l; ) {
76+
if (k != 0) {
77+
ret += dontInline();
78+
}
79+
}
80+
if (b) {
81+
break;
82+
}
83+
}
84+
}
85+
return ret;
86+
}
87+
88+
public static void main(String[] args) {
89+
for (int i = 0; i < 1000; i++) {
90+
test(0, false);
91+
}
92+
93+
test2(5);
94+
}
95+
}

0 commit comments

Comments
 (0)