Skip to content

Commit

Permalink
8321278: C2: Partial peeling fails with assert "last_peel <- first_no…
Browse files Browse the repository at this point in the history
…t_peeled"

Backport-of: af15c68f3ccb72537b0a60d942f12d600f13ebb6
  • Loading branch information
TheRealMDoerr committed Jun 14, 2024
1 parent df03054 commit dba6716
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 1 deletion.
28 changes: 27 additions & 1 deletion src/hotspot/share/opto/domgraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,25 @@ struct NTarjan {
#endif
};

void remove_single_entry_region(NTarjan* t, NTarjan*& tdom, Node*& dom, PhaseIterGVN& igvn) {
// remove phis:
for (DUIterator_Fast jmax, j = dom->fast_outs(jmax); j < jmax; j++) {
Node* use = dom->fast_out(j);
if (use->is_Phi()) {
igvn.replace_node(use, use->in(1));
--j; --jmax;
}
}
// Disconnect region from dominator tree
assert(dom->unique_ctrl_out() == t->_control, "expect a single dominated node");
tdom = tdom->_dom;
t->_dom = tdom;
assert(tdom->_control == dom->in(1), "dominator of region with single input should be that input");
// and remove it
igvn.replace_node(dom, dom->in(1));
dom = tdom->_control;
}

// Compute the dominator tree of the sea of nodes. This version walks all CFG
// nodes (using the is_CFG() call) and places them in a dominator tree. Thus,
// it needs a count of the CFG nodes for the mapping table. This is the
Expand Down Expand Up @@ -486,7 +505,14 @@ void PhaseIdealLoop::Dominators() {
assert(t->_control != nullptr,"Bad DFS walk");
NTarjan *tdom = t->_dom; // Handy access to immediate dominator
if( tdom ) { // Root has no immediate dominator
_idom[t->_control->_idx] = tdom->_control; // Set immediate dominator
Node* dom = tdom->_control;
// The code that removes unreachable loops above could have left a region with a single input. Remove it. Do it
// now that we iterate over cfg nodes for the last time (doing it earlier would have left a dead cfg node behind
// that code that goes over the dfs list would have had to handle).
if (dom != C->root() && dom->is_Region() && dom->req() == 2) {
remove_single_entry_region(t, tdom, dom, _igvn);
}
_idom[t->_control->_idx] = dom; // Set immediate dominator
t->_dom_next = tdom->_dom_child; // Make me a sibling of parent's child
tdom->_dom_child = t; // Make me a child of my parent
} else
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 8321278
* @summary C2: Partial peeling fails with assert "last_peel <- first_not_peeled"
* @run main/othervm -XX:CompileCommand=quiet -XX:CompileCommand=compileonly,TestPartialPeelingAtSingleInputRegion::test
* -XX:-TieredCompilation -Xbatch -XX:PerMethodTrapLimit=0 TestPartialPeelingAtSingleInputRegion
*
*/

public class TestPartialPeelingAtSingleInputRegion {

static void test() {
for (int i = 100; i > 10; --i) {
for (int j = i; j < 10; ++j) {
switch (j) {
case 1:
if (j != 0) {
return;
}
}
}
}
}

public static void main(String[] args) {
for (int i = 0; i < 10_000; ++i) {
test();
}
}
}

1 comment on commit dba6716

@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.