Skip to content

Commit 489e5fd

Browse files
committedJul 29, 2021
8268019: C2: assert(no_dead_loop) failed: dead loop detected
Reviewed-by: kvn, thartmann
1 parent 6afcf5f commit 489e5fd

File tree

2 files changed

+83
-5
lines changed

2 files changed

+83
-5
lines changed
 

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

+16-5
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,11 @@ static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) {
114114
if( !t->singleton() ) return NULL;
115115

116116
// No intervening control, like a simple Call
117-
Node *r = iff->in(0);
118-
if( !r->is_Region() ) return NULL;
119-
if (r->is_Loop()) return NULL;
120-
if( phi->region() != r ) return NULL;
117+
Node* r = iff->in(0);
118+
if (!r->is_Region() || r->is_Loop() || phi->region() != r || r->as_Region()->is_copy()) {
119+
return NULL;
120+
}
121+
121122
// No other users of the cmp/bool
122123
if (b->outcnt() != 1 || cmp->outcnt() != 1) {
123124
//tty->print_cr("many users of cmp/bool");
@@ -243,13 +244,23 @@ static Node* split_if(IfNode *iff, PhaseIterGVN *igvn) {
243244
}
244245
Node* proj = PhaseIdealLoop::find_predicate(r->in(ii));
245246
if (proj != NULL) {
247+
// Bail out if splitting through a region with a predicate input (could
248+
// also be a loop header before loop opts creates a LoopNode for it).
246249
return NULL;
247250
}
248251
}
249252

250253
// If all the defs of the phi are the same constant, we already have the desired end state.
251254
// Skip the split that would create empty phi and region nodes.
252-
if((r->req() - req_c) == 1) {
255+
if ((r->req() - req_c) == 1) {
256+
return NULL;
257+
}
258+
259+
// At this point we know that we can apply the split if optimization. If the region is still on the worklist,
260+
// we should wait until it is processed. The region might be removed which makes this optimization redundant.
261+
// This also avoids the creation of dead data loops when rewiring data nodes below when a region is dying.
262+
if (igvn->_worklist.member(r)) {
263+
igvn->_worklist.push(iff); // retry split if later again
253264
return NULL;
254265
}
255266

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. 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+
* @key stress randomness
27+
* @requires vm.compiler2.enabled
28+
* @bug 8268019
29+
* @summary Splitting an If through a dying loop header region that is not a LoopNode, yet, results in a dead data loop.
30+
* @run main/othervm -Xcomp -XX:-TieredCompilation -XX:CompileCommand=compileonly,compiler.c2.TestDeadLoopSplitIfLoop::test -XX:+UnlockDiagnosticVMOptions
31+
* -XX:+StressIGVN -XX:StressSeed=2382674767 -XX:CompileCommand=dontinline,compiler.c2.TestDeadLoopSplitIfLoop::test
32+
* compiler.c2.TestDeadLoopSplitIfLoop
33+
* @run main/othervm -Xcomp -XX:-TieredCompilation -XX:CompileCommand=compileonly,compiler.c2.TestDeadLoopSplitIfLoop::test -XX:+UnlockDiagnosticVMOptions
34+
* -XX:+StressIGVN -XX:CompileCommand=dontinline,compiler.c2.TestDeadLoopSplitIfLoop::test
35+
* compiler.c2.TestDeadLoopSplitIfLoop
36+
*/
37+
package compiler.c2;
38+
39+
public class TestDeadLoopSplitIfLoop {
40+
int a;
41+
int b;
42+
boolean c;
43+
44+
public static void main(String[] g) {
45+
TestDeadLoopSplitIfLoop h = new TestDeadLoopSplitIfLoop();
46+
h.test();
47+
}
48+
49+
void test() {
50+
int e = 4;
51+
long f[] = new long[a];
52+
if (c) {
53+
} else if (c) {
54+
// Dead path is removed after parsing which results in a dead data loop for certain node orderings in IGVN.
55+
switch (126) {
56+
case 126:
57+
do {
58+
f[e] = b;
59+
switch (6) {
60+
case 7:
61+
f = f;
62+
}
63+
} while (e++ < 93);
64+
}
65+
}
66+
}
67+
}

0 commit comments

Comments
 (0)