8333644: C2: assert(is_Bool()) failed: invalid node class: Phi

Reviewed-by: thartmann, kvn
This commit is contained in:
Christian Hagedorn 2024-06-06 06:58:05 +00:00
parent 8f0785325d
commit 7ef2831293
2 changed files with 51 additions and 8 deletions

View File

@ -2154,18 +2154,19 @@ void PhaseIdealLoop::clone_loop_handle_data_uses(Node* old, Node_List &old_new,
#endif
if (!loop->is_member(use_loop) && !outer_loop->is_member(use_loop) && (!old->is_CFG() || !use->is_CFG())) {
// If the Data use is an IF, that means we have an IF outside of the
// loop that is switching on a condition that is set inside of the
// If the Data use is an IF, that means we have an IF outside the
// loop that is switching on a condition that is set inside the
// loop. Happens if people set a loop-exit flag; then test the flag
// in the loop to break the loop, then test is again outside of the
// in the loop to break the loop, then test is again outside the
// loop to determine which way the loop exited.
// Loop predicate If node connects to Bool node through Opaque1 node.
//
// If the use is an AllocateArray through its ValidLengthTest input,
// make sure the Bool/Cmp input is cloned down to avoid a Phi between
// the AllocateArray node and its ValidLengthTest input that could cause
// For several uses we need to make sure that there is no phi between,
// the use and the Bool/Cmp. We therefore clone the Bool/Cmp down here
// to avoid such a phi in between.
// For example, it is unexpected that there is a Phi between an
// AllocateArray node and its ValidLengthTest input that could cause
// split if to break.
if (use->is_If() || use->is_CMove() || use->is_Opaque4() ||
if (use->is_If() || use->is_CMove() || use->is_Opaque4() || use->is_OpaqueInitializedAssertionPredicate() ||
(use->Opcode() == Op_AllocateArray && use->in(AllocateNode::ValidLengthTest) == old)) {
// Since this code is highly unlikely, we lazily build the worklist
// of such Nodes to go split.

View File

@ -54,6 +54,17 @@
* @run main compiler.predicates.assertion.TestOpaqueInitializedAssertionPredicateNode
*/
/*
* @test id=clone_loop_handle_data_uses
* @bug 8333644
* @modules java.base/jdk.internal.misc:+open
* @summary Test that using OpaqueInitializedAssertionPredicate for Initialized Assertion Predicates instead of Opaque4
* nodes also works with clone_loop_handle_data_uses() which missed a case before.
* @run main/othervm -Xcomp -XX:CompileCommand=compileonly,*TestOpaqueInitializedAssertionPredicateNode::test*
* -XX:CompileCommand=dontinline,*TestOpaqueInitializedAssertionPredicateNode::dontInline
* compiler.predicates.assertion.TestOpaqueInitializedAssertionPredicateNode
*/
package compiler.predicates.assertion;
import jdk.internal.misc.Unsafe;
@ -63,6 +74,7 @@ public class TestOpaqueInitializedAssertionPredicateNode {
static boolean flag, flag2;
static int iFld;
static long lFld;
static int x;
static int y = 51;
static int iArrLength;
@ -95,6 +107,7 @@ public class TestOpaqueInitializedAssertionPredicateNode {
testPolicyRangeCheck(a);
testUnsafeAccess(a);
testOpaqueOutsideLoop();
testOpaqueOutsideLoop8333644();
testOpaqueInsideIfOutsideLoop();
}
}
@ -350,6 +363,35 @@ public class TestOpaqueInitializedAssertionPredicateNode {
}
}
// Same as testOpaqueOutsideLoop() but we crash later when generating the Mach graph due to wrongly having an If
// with a Phi input instead of: If <- Bool <- CmpU <- [x, Phi]. Found by fuzzing.
static void testOpaqueOutsideLoop8333644() {
int a = 3, b = 7;
boolean bArr[] = new boolean[1];
for (int i = 1; i < 122; i++) {
float f = 1.729F;
while (++a < 7) {
iArr[a] *= lFld;
switch (i) {
case 26:
for (; b < 1; ) {}
case 27:
iArr[1] = 9;
case 28:
break;
case 33:
iArr[1] = a;
break;
case 35:
lFld = b;
break;
default:
;
}
}
}
}
// Similar to testOpaqueOutside loop but Opaque is now also inside loop.
// [If]->OpaqueInitializedAssertionPredicate->Bool->Cmp, []: Inside Loop, other nodes outside.
static void testOpaqueInsideIfOutsideLoop() {