Skip to content

Commit

Permalink
8295788: C2 compilation hits "assert((mode == ControlAroundStripMined…
Browse files Browse the repository at this point in the history
… && use == sfpt) || !use->is_reachable_from_root()) failed: missed a node"

Backport-of: 761a4f4852cbb40660b6fb9eda4d740464218f75
  • Loading branch information
GoeLin committed Jan 12, 2023
1 parent 520ae87 commit ffecc39
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 17 deletions.
41 changes: 24 additions & 17 deletions src/hotspot/share/opto/loopopts.cpp
Expand Up @@ -2041,26 +2041,28 @@ void PhaseIdealLoop::clone_loop_handle_data_uses(Node* old, Node_List &old_new,
}
}

static void clone_outer_loop_helper(Node* n, const IdealLoopTree *loop, const IdealLoopTree* outer_loop,
const Node_List &old_new, Unique_Node_List& wq, PhaseIdealLoop* phase,
bool check_old_new) {
static void collect_nodes_in_outer_loop_not_reachable_from_sfpt(Node* n, const IdealLoopTree *loop, const IdealLoopTree* outer_loop,
const Node_List &old_new, Unique_Node_List& wq, PhaseIdealLoop* phase,
bool check_old_new) {
for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
Node* u = n->fast_out(j);
assert(check_old_new || old_new[u->_idx] == NULL, "shouldn't have been cloned");
if (!u->is_CFG() && (!check_old_new || old_new[u->_idx] == NULL)) {
Node* c = phase->get_ctrl(u);
IdealLoopTree* u_loop = phase->get_loop(c);
assert(!loop->is_member(u_loop), "can be in outer loop or out of both loops only");
if (outer_loop->is_member(u_loop)) {
wq.push(u);
} else {
// nodes pinned with control in the outer loop but not referenced from the safepoint must be moved out of
// the outer loop too
Node* u_c = u->in(0);
if (u_c != NULL) {
IdealLoopTree* u_c_loop = phase->get_loop(u_c);
if (outer_loop->is_member(u_c_loop) && !loop->is_member(u_c_loop)) {
wq.push(u);
assert(!loop->is_member(u_loop) || !loop->_body.contains(u), "can be in outer loop or out of both loops only");
if (!loop->is_member(u_loop)) {
if (outer_loop->is_member(u_loop)) {
wq.push(u);
} else {
// nodes pinned with control in the outer loop but not referenced from the safepoint must be moved out of
// the outer loop too
Node* u_c = u->in(0);
if (u_c != NULL) {
IdealLoopTree* u_c_loop = phase->get_loop(u_c);
if (outer_loop->is_member(u_c_loop) && !loop->is_member(u_c_loop)) {
wq.push(u);
}
}
}
}
Expand Down Expand Up @@ -2179,12 +2181,17 @@ void PhaseIdealLoop::clone_outer_loop(LoopNode* head, CloneLoopMode mode, IdealL
Unique_Node_List wq;
for (uint i = 0; i < extra_data_nodes.size(); i++) {
Node* old = extra_data_nodes.at(i);
clone_outer_loop_helper(old, loop, outer_loop, old_new, wq, this, true);
collect_nodes_in_outer_loop_not_reachable_from_sfpt(old, loop, outer_loop, old_new, wq, this, true);
}

for (uint i = 0; i < loop->_body.size(); i++) {
Node* old = loop->_body.at(i);
collect_nodes_in_outer_loop_not_reachable_from_sfpt(old, loop, outer_loop, old_new, wq, this, true);
}

Node* inner_out = sfpt->in(0);
if (inner_out->outcnt() > 1) {
clone_outer_loop_helper(inner_out, loop, outer_loop, old_new, wq, this, true);
collect_nodes_in_outer_loop_not_reachable_from_sfpt(inner_out, loop, outer_loop, old_new, wq, this, true);
}

Node* new_ctrl = cl->outer_loop_exit();
Expand All @@ -2195,7 +2202,7 @@ void PhaseIdealLoop::clone_outer_loop(LoopNode* head, CloneLoopMode mode, IdealL
if (n->in(0) != NULL) {
_igvn.replace_input_of(n, 0, new_ctrl);
}
clone_outer_loop_helper(n, loop, outer_loop, old_new, wq, this, false);
collect_nodes_in_outer_loop_not_reachable_from_sfpt(n, loop, outer_loop, old_new, wq, this, false);
}
} else {
Node *newhead = old_new[loop->_head->_idx];
Expand Down
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2022, Red Hat, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/**
* @test
* @bug 8295788
* @summary C2 compilation hits "assert((mode == ControlAroundStripMined && use == sfpt) || !use->is_reachable_from_root()) failed: missed a node"
*
* @run main/othervm -Xcomp -XX:CompileOnly=TestUseFromInnerInOuterUnusedBySfpt TestUseFromInnerInOuterUnusedBySfpt
*
*/

public class TestUseFromInnerInOuterUnusedBySfpt {

public static final int N = 400;

public static void dMeth(long l, int i5, int i6) {

int i7=14, i8=-14, i9=7476, i11=0;
long lArr[]=new long[N];

for (i7 = 3; i7 < 177; i7++) {
lArr[i7 + 1] >>= l;
l -= i8;
i6 = (int)l;
}
for (i9 = 15; i9 < 356; i9 += 3) {
i11 = 14;
do {
i5 |= i6;
} while (--i11 > 0);
}
}

public static void main(String[] strArr) {
TestUseFromInnerInOuterUnusedBySfpt _instance = new TestUseFromInnerInOuterUnusedBySfpt();
for (int i = 0; i < 10; i++) {
_instance.dMeth(-12L, -50242, 20);
}
}
}

1 comment on commit ffecc39

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.