8268017: C2: assert(phi_type->isa_int() || phi_type->isa_ptr() || phi_type->isa_long()) failed: bad phi type

Reviewed-by: vlivanov, chagedorn, whuang
This commit is contained in:
Roland Westrelin 2021-06-09 07:58:17 +00:00
parent 2bfd708e92
commit 4413142eca
5 changed files with 113 additions and 20 deletions

View File

@ -106,6 +106,21 @@ Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t,
cast->set_req(0, c);
return cast;
}
case Op_CastFF: {
Node* cast = new CastFFNode(n, t, carry_dependency);
cast->set_req(0, c);
return cast;
}
case Op_CastDD: {
Node* cast = new CastDDNode(n, t, carry_dependency);
cast->set_req(0, c);
return cast;
}
case Op_CastVV: {
Node* cast = new CastVVNode(n, t, carry_dependency);
cast->set_req(0, c);
return cast;
}
case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, carry_dependency);
default:
fatal("Bad opcode %d", opcode);
@ -557,3 +572,21 @@ Node* CastP2XNode::Identity(PhaseGVN* phase) {
if (in(1)->Opcode() == Op_CastX2P) return in(1)->in(1);
return this;
}
Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type) {
Node* cast= NULL;
if (type->isa_int()) {
cast = make_cast(Op_CastII, c, in, type, true);
} else if (type->isa_long()) {
cast = make_cast(Op_CastLL, c, in, type, true);
} else if (type->isa_float()) {
cast = make_cast(Op_CastFF, c, in, type, true);
} else if (type->isa_double()) {
cast = make_cast(Op_CastDD, c, in, type, true);
} else if (type->isa_vect()) {
cast = make_cast(Op_CastVV, c, in, type, true);
} else if (type->isa_ptr()) {
cast = make_cast(Op_CastPP, c, in, type, true);
}
return cast;
}

View File

@ -62,6 +62,8 @@ class ConstraintCastNode: public TypeNode {
#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const;
#endif
static Node* make_cast_for_type(Node* c, Node* in, const Type* type);
};
//------------------------------CastIINode-------------------------------------

View File

@ -1969,15 +1969,10 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// Wait until after parsing for the type information to propagate from the casts.
assert(can_reshape, "Invalid during parsing");
const Type* phi_type = bottom_type();
assert(phi_type->isa_int() || phi_type->isa_ptr() || phi_type->isa_long(), "bad phi type");
// Add casts to carry the control dependency of the Phi that is
// going away
Node* cast = NULL;
if (phi_type->isa_int()) {
cast = ConstraintCastNode::make_cast(Op_CastII, r, uin, phi_type, true);
} else if (phi_type->isa_long()) {
cast = ConstraintCastNode::make_cast(Op_CastLL, r, uin, phi_type, true);
} else {
if (phi_type->isa_ptr()) {
const Type* uin_type = phase->type(uin);
if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) {
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true);
@ -2008,6 +2003,8 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true);
}
}
} else {
cast = ConstraintCastNode::make_cast_for_type(r, uin, phi_type);
}
assert(cast != NULL, "cast should be set");
cast = phase->transform(cast);

View File

@ -1511,22 +1511,9 @@ void PhaseIdealLoop::try_sink_out_of_loop(Node* n) {
Node* in = x->in(k);
if (in != NULL && n_loop->is_member(get_loop(get_ctrl(in)))) {
const Type* in_t = _igvn.type(in);
if (in_t->isa_int()) {
cast = new CastIINode(in, in_t, true);
} else if (in_t->isa_long()) {
cast = new CastLLNode(in, in_t, true);
} else if (in_t->isa_ptr()) {
cast = new CastPPNode(in, in_t, true);
} else if (in_t->isa_float()) {
cast = new CastFFNode(in, in_t, true);
} else if (in_t->isa_double()) {
cast = new CastDDNode(in, in_t, true);
} else if (in_t->isa_vect()) {
cast = new CastVVNode(in, in_t, true);
}
cast = ConstraintCastNode::make_cast_for_type(x_ctrl, in, in_t);
}
if (cast != NULL) {
cast->set_req(0, x_ctrl);
register_new_node(cast, x_ctrl);
x->replace_edge(in, cast);
break;

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2021, 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 8268017
* @summary C2: assert(phi_type->isa_int() || phi_type->isa_ptr() || phi_type->isa_long()) failed: bad phi type
*
* @run main/othervm -Xcomp -XX:-TieredCompilation -XX:CompileOnly=TestCastFFAtPhi TestCastFFAtPhi
*
*/
public class TestCastFFAtPhi {
static int N = 400;
static double dArrFld[] = new double[N];
static long iMeth_check_sum = 0;
static {
init(dArrFld, 90.71133);
}
float fArrFld[] = new float[N];
public static void main(String[] strArr) {
TestCastFFAtPhi _instance = new TestCastFFAtPhi();
for (int i = 0; i < 10; i++) {
_instance.mainTest();
}
}
void mainTest() {
int i24 = 121110, i28, i30;
float f2 = 2.486F;
for (i28 = 322; i28 > 6; i28--) {
i30 = 1;
do {
i24 = (int) f2;
fArrFld[1] += i30;
switch (((i28 % 4) * 5) + 32) {
case 36:
f2 *= f2;
}
} while (++i30 < 80);
}
System.out.println(i24 + ",");
}
public static void init(double[] a, double seed) {
for (int j = 0; j < a.length; j++) {
a[j] = (j % 2 == 0) ? seed + j : seed - j;
}
}
}