Skip to content

Commit ffecc39

Browse files
committed
8295788: C2 compilation hits "assert((mode == ControlAroundStripMined && use == sfpt) || !use->is_reachable_from_root()) failed: missed a node"
Backport-of: 761a4f4852cbb40660b6fb9eda4d740464218f75
1 parent 520ae87 commit ffecc39

File tree

2 files changed

+85
-17
lines changed

2 files changed

+85
-17
lines changed

src/hotspot/share/opto/loopopts.cpp

+24-17
Original file line numberDiff line numberDiff line change
@@ -2041,26 +2041,28 @@ void PhaseIdealLoop::clone_loop_handle_data_uses(Node* old, Node_List &old_new,
20412041
}
20422042
}
20432043

2044-
static void clone_outer_loop_helper(Node* n, const IdealLoopTree *loop, const IdealLoopTree* outer_loop,
2045-
const Node_List &old_new, Unique_Node_List& wq, PhaseIdealLoop* phase,
2046-
bool check_old_new) {
2044+
static void collect_nodes_in_outer_loop_not_reachable_from_sfpt(Node* n, const IdealLoopTree *loop, const IdealLoopTree* outer_loop,
2045+
const Node_List &old_new, Unique_Node_List& wq, PhaseIdealLoop* phase,
2046+
bool check_old_new) {
20472047
for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
20482048
Node* u = n->fast_out(j);
20492049
assert(check_old_new || old_new[u->_idx] == NULL, "shouldn't have been cloned");
20502050
if (!u->is_CFG() && (!check_old_new || old_new[u->_idx] == NULL)) {
20512051
Node* c = phase->get_ctrl(u);
20522052
IdealLoopTree* u_loop = phase->get_loop(c);
2053-
assert(!loop->is_member(u_loop), "can be in outer loop or out of both loops only");
2054-
if (outer_loop->is_member(u_loop)) {
2055-
wq.push(u);
2056-
} else {
2057-
// nodes pinned with control in the outer loop but not referenced from the safepoint must be moved out of
2058-
// the outer loop too
2059-
Node* u_c = u->in(0);
2060-
if (u_c != NULL) {
2061-
IdealLoopTree* u_c_loop = phase->get_loop(u_c);
2062-
if (outer_loop->is_member(u_c_loop) && !loop->is_member(u_c_loop)) {
2063-
wq.push(u);
2053+
assert(!loop->is_member(u_loop) || !loop->_body.contains(u), "can be in outer loop or out of both loops only");
2054+
if (!loop->is_member(u_loop)) {
2055+
if (outer_loop->is_member(u_loop)) {
2056+
wq.push(u);
2057+
} else {
2058+
// nodes pinned with control in the outer loop but not referenced from the safepoint must be moved out of
2059+
// the outer loop too
2060+
Node* u_c = u->in(0);
2061+
if (u_c != NULL) {
2062+
IdealLoopTree* u_c_loop = phase->get_loop(u_c);
2063+
if (outer_loop->is_member(u_c_loop) && !loop->is_member(u_c_loop)) {
2064+
wq.push(u);
2065+
}
20642066
}
20652067
}
20662068
}
@@ -2179,12 +2181,17 @@ void PhaseIdealLoop::clone_outer_loop(LoopNode* head, CloneLoopMode mode, IdealL
21792181
Unique_Node_List wq;
21802182
for (uint i = 0; i < extra_data_nodes.size(); i++) {
21812183
Node* old = extra_data_nodes.at(i);
2182-
clone_outer_loop_helper(old, loop, outer_loop, old_new, wq, this, true);
2184+
collect_nodes_in_outer_loop_not_reachable_from_sfpt(old, loop, outer_loop, old_new, wq, this, true);
2185+
}
2186+
2187+
for (uint i = 0; i < loop->_body.size(); i++) {
2188+
Node* old = loop->_body.at(i);
2189+
collect_nodes_in_outer_loop_not_reachable_from_sfpt(old, loop, outer_loop, old_new, wq, this, true);
21832190
}
21842191

21852192
Node* inner_out = sfpt->in(0);
21862193
if (inner_out->outcnt() > 1) {
2187-
clone_outer_loop_helper(inner_out, loop, outer_loop, old_new, wq, this, true);
2194+
collect_nodes_in_outer_loop_not_reachable_from_sfpt(inner_out, loop, outer_loop, old_new, wq, this, true);
21882195
}
21892196

21902197
Node* new_ctrl = cl->outer_loop_exit();
@@ -2195,7 +2202,7 @@ void PhaseIdealLoop::clone_outer_loop(LoopNode* head, CloneLoopMode mode, IdealL
21952202
if (n->in(0) != NULL) {
21962203
_igvn.replace_input_of(n, 0, new_ctrl);
21972204
}
2198-
clone_outer_loop_helper(n, loop, outer_loop, old_new, wq, this, false);
2205+
collect_nodes_in_outer_loop_not_reachable_from_sfpt(n, loop, outer_loop, old_new, wq, this, false);
21992206
}
22002207
} else {
22012208
Node *newhead = old_new[loop->_head->_idx];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright (c) 2022, 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 8295788
27+
* @summary C2 compilation hits "assert((mode == ControlAroundStripMined && use == sfpt) || !use->is_reachable_from_root()) failed: missed a node"
28+
*
29+
* @run main/othervm -Xcomp -XX:CompileOnly=TestUseFromInnerInOuterUnusedBySfpt TestUseFromInnerInOuterUnusedBySfpt
30+
*
31+
*/
32+
33+
public class TestUseFromInnerInOuterUnusedBySfpt {
34+
35+
public static final int N = 400;
36+
37+
public static void dMeth(long l, int i5, int i6) {
38+
39+
int i7=14, i8=-14, i9=7476, i11=0;
40+
long lArr[]=new long[N];
41+
42+
for (i7 = 3; i7 < 177; i7++) {
43+
lArr[i7 + 1] >>= l;
44+
l -= i8;
45+
i6 = (int)l;
46+
}
47+
for (i9 = 15; i9 < 356; i9 += 3) {
48+
i11 = 14;
49+
do {
50+
i5 |= i6;
51+
} while (--i11 > 0);
52+
}
53+
}
54+
55+
public static void main(String[] strArr) {
56+
TestUseFromInnerInOuterUnusedBySfpt _instance = new TestUseFromInnerInOuterUnusedBySfpt();
57+
for (int i = 0; i < 10; i++) {
58+
_instance.dMeth(-12L, -50242, 20);
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)