Skip to content

Commit 9ef11ac

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 f999efd commit 9ef11ac

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
@@ -1858,26 +1858,28 @@ void PhaseIdealLoop::clone_loop_handle_data_uses(Node* old, Node_List &old_new,
18581858
}
18591859
}
18601860

1861-
static void clone_outer_loop_helper(Node* n, const IdealLoopTree *loop, const IdealLoopTree* outer_loop,
1862-
const Node_List &old_new, Unique_Node_List& wq, PhaseIdealLoop* phase,
1863-
bool check_old_new) {
1861+
static void collect_nodes_in_outer_loop_not_reachable_from_sfpt(Node* n, const IdealLoopTree *loop, const IdealLoopTree* outer_loop,
1862+
const Node_List &old_new, Unique_Node_List& wq, PhaseIdealLoop* phase,
1863+
bool check_old_new) {
18641864
for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
18651865
Node* u = n->fast_out(j);
18661866
assert(check_old_new || old_new[u->_idx] == NULL, "shouldn't have been cloned");
18671867
if (!u->is_CFG() && (!check_old_new || old_new[u->_idx] == NULL)) {
18681868
Node* c = phase->get_ctrl(u);
18691869
IdealLoopTree* u_loop = phase->get_loop(c);
1870-
assert(!loop->is_member(u_loop), "can be in outer loop or out of both loops only");
1871-
if (outer_loop->is_member(u_loop)) {
1872-
wq.push(u);
1873-
} else {
1874-
// nodes pinned with control in the outer loop but not referenced from the safepoint must be moved out of
1875-
// the outer loop too
1876-
Node* u_c = u->in(0);
1877-
if (u_c != NULL) {
1878-
IdealLoopTree* u_c_loop = phase->get_loop(u_c);
1879-
if (outer_loop->is_member(u_c_loop) && !loop->is_member(u_c_loop)) {
1880-
wq.push(u);
1870+
assert(!loop->is_member(u_loop) || !loop->_body.contains(u), "can be in outer loop or out of both loops only");
1871+
if (!loop->is_member(u_loop)) {
1872+
if (outer_loop->is_member(u_loop)) {
1873+
wq.push(u);
1874+
} else {
1875+
// nodes pinned with control in the outer loop but not referenced from the safepoint must be moved out of
1876+
// the outer loop too
1877+
Node* u_c = u->in(0);
1878+
if (u_c != NULL) {
1879+
IdealLoopTree* u_c_loop = phase->get_loop(u_c);
1880+
if (outer_loop->is_member(u_c_loop) && !loop->is_member(u_c_loop)) {
1881+
wq.push(u);
1882+
}
18811883
}
18821884
}
18831885
}
@@ -1996,12 +1998,17 @@ void PhaseIdealLoop::clone_outer_loop(LoopNode* head, CloneLoopMode mode, IdealL
19961998
Unique_Node_List wq;
19971999
for (uint i = 0; i < extra_data_nodes.size(); i++) {
19982000
Node* old = extra_data_nodes.at(i);
1999-
clone_outer_loop_helper(old, loop, outer_loop, old_new, wq, this, true);
2001+
collect_nodes_in_outer_loop_not_reachable_from_sfpt(old, loop, outer_loop, old_new, wq, this, true);
2002+
}
2003+
2004+
for (uint i = 0; i < loop->_body.size(); i++) {
2005+
Node* old = loop->_body.at(i);
2006+
collect_nodes_in_outer_loop_not_reachable_from_sfpt(old, loop, outer_loop, old_new, wq, this, true);
20002007
}
20012008

20022009
Node* inner_out = sfpt->in(0);
20032010
if (inner_out->outcnt() > 1) {
2004-
clone_outer_loop_helper(inner_out, loop, outer_loop, old_new, wq, this, true);
2011+
collect_nodes_in_outer_loop_not_reachable_from_sfpt(inner_out, loop, outer_loop, old_new, wq, this, true);
20052012
}
20062013

20072014
Node* new_ctrl = cl->outer_loop_exit();
@@ -2012,7 +2019,7 @@ void PhaseIdealLoop::clone_outer_loop(LoopNode* head, CloneLoopMode mode, IdealL
20122019
if (n->in(0) != NULL) {
20132020
_igvn.replace_input_of(n, 0, new_ctrl);
20142021
}
2015-
clone_outer_loop_helper(n, loop, outer_loop, old_new, wq, this, false);
2022+
collect_nodes_in_outer_loop_not_reachable_from_sfpt(n, loop, outer_loop, old_new, wq, this, false);
20162023
}
20172024
} else {
20182025
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)