8343380: C2: assert(iff->in(1)->is_OpaqueNotNull()) failed: must be OpaqueNotNull

Reviewed-by: thartmann, kvn
This commit is contained in:
Christian Hagedorn 2024-11-01 06:51:34 +00:00
parent cbda758010
commit 6f6cfe643b
2 changed files with 109 additions and 3 deletions

View File

@ -574,14 +574,13 @@ bool ConnectionGraph::can_reduce_check_users(Node* n, uint nesting) const {
// CmpP/N used by the If controlling the cast.
if (use->in(0)->is_IfTrue() || use->in(0)->is_IfFalse()) {
Node* iff = use->in(0)->in(0);
// We may have an OpaqueNotNull node between If and Bool nodes. Bail out in such case.
// We may have an OpaqueNotNull node between If and Bool nodes. But we could also have a sub class of IfNode,
// for example, an OuterStripMinedLoopEnd or a Parse Predicate. Bail out in all these cases.
bool can_reduce = (iff->Opcode() == Op_If) && iff->in(1)->is_Bool() && iff->in(1)->in(1)->is_Cmp();
if (can_reduce) {
Node* iff_cmp = iff->in(1)->in(1);
int opc = iff_cmp->Opcode();
can_reduce = (opc == Op_CmpP || opc == Op_CmpN) && can_reduce_cmp(n, iff_cmp);
} else {
assert(iff->in(1)->is_OpaqueNotNull(), "must be OpaqueNotNull");
}
if (!can_reduce) {
#ifndef PRODUCT

View File

@ -0,0 +1,107 @@
/*
* 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.
*
* 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 8343380
* @summary Test that can_reduce_check_users() can handle different If nodes and that we bail out properly if it's not
* an actual IfNode.
* @run main/othervm -XX:CompileCommand=compileonly,compiler.escapeAnalysis.TestCanReduceCheckUsersDifferentIfs::test*
* -Xcomp compiler.escapeAnalysis.TestCanReduceCheckUsersDifferentIfs
*/
package compiler.escapeAnalysis;
public class TestCanReduceCheckUsersDifferentIfs {
static int iFld, iFld2;
static boolean flag;
public static void main(String[] args) {
// Make sure classes are loaded.
new B();
new C();
testParsePredicate();
testOuterStripMinedLoopEnd();
}
static void testOuterStripMinedLoopEnd() {
// (1) phi1 for a: phi(CheckCastPP(B), CheckCastPP(c)) with type A:NotNull
A a = flag ? new B() : new C();
// (4) Loop removed in PhaseIdealLoop before EA and we know that x == 77.
int x = 77;
int y = 0;
do {
x--;
y++;
} while (x > 0);
// (L)
for (int i = 0; i < 100; i++) {
iFld += 34;
}
// (6) CastPP(phi1) ends up at IfFalse of OuterStripMinedLoopEnd of loop (L).
// (7) EA tries to reduce phi1(CheckCastPP(B), CheckCastPP(c)) and looks at
// OuterStripMinedLoopEnd and asserts that if it's not an IfNode that it has
// an OpaqueNotNull which obviously is not the case and the assert fails.
// (5) Found to be false after PhaseIdealLoop before EA and is folded away.
if (y == 76) {
a = (B) a; // (2) a = CheckCastPP(phi1)
}
// (3) phi2 for a: phi(if, else) = phi(CheckCastPP(phi1), phi1)
// phi(CheckCastPP(phi1), phi1) is replaced in PhiNode::Ideal with a CastPP:
// a = CastPP(phi1) with type A:NotNull
iFld2 = a.iFld;
}
// Same as testOuterStripMinedLoopEnd() but we find in (7) a ParsePredicate from the
// removed loop (L) which also does not have an OpaqueNotNull and the assert fails.
static void testParsePredicate() {
A a = flag ? new B() : new C();
int x = 77;
int y = 0;
// (L)
do {
x--;
y++;
} while (x > 0);
if (y == 76) {
a = (B) a;
}
iFld2 = a.iFld;
}
}
class A {
int iFld;
}
class B extends A {
}
class C extends A {
}