Skip to content
Permalink
Browse files
8267988: C2: assert(!addp->is_AddP() || addp->in(AddPNode::Base)->is_…
…top() || addp->in(AddPNode::Base) == n->in(AddPNode::Base)) failed: Base pointers must match (addp 1301)

Reviewed-by: chagedorn, vlivanov, kvn
  • Loading branch information
rwestrel committed Jun 16, 2021
1 parent b18de6c commit 4d545a1f86325140ed268c5437d776ceb8e21077
Showing 8 changed files with 148 additions and 63 deletions.
@@ -1406,7 +1406,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
}
if (addr->Opcode() == Op_AddP) {
Node* orig_base = addr->in(AddPNode::Base);
Node* base = new CheckCastPPNode(ctrl, orig_base, orig_base->bottom_type(), true);
Node* base = new CheckCastPPNode(ctrl, orig_base, orig_base->bottom_type(), ConstraintCastNode::StrongDependency);
phase->register_new_node(base, ctrl);
if (addr->in(AddPNode::Base) == addr->in((AddPNode::Address))) {
// Field access
@@ -39,7 +39,7 @@ Node* ConstraintCastNode::Identity(PhaseGVN* phase) {
if (dom != NULL) {
return dom;
}
if (_carry_dependency) {
if (_dependency != RegularDependency) {
return this;
}
return phase->type(in(1))->higher_equal_speculative(_type) ? in(1) : this;
@@ -82,46 +82,46 @@ Node *ConstraintCastNode::Ideal(PhaseGVN *phase, bool can_reshape) {
}

bool ConstraintCastNode::cmp(const Node &n) const {
return TypeNode::cmp(n) && ((ConstraintCastNode&)n)._carry_dependency == _carry_dependency;
return TypeNode::cmp(n) && ((ConstraintCastNode&)n)._dependency == _dependency;
}

uint ConstraintCastNode::size_of() const {
return sizeof(*this);
}

Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t, bool carry_dependency) {
Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t, DependencyType dependency) {
switch(opcode) {
case Op_CastII: {
Node* cast = new CastIINode(n, t, carry_dependency);
Node* cast = new CastIINode(n, t, dependency);
cast->set_req(0, c);
return cast;
}
case Op_CastLL: {
Node* cast = new CastLLNode(n, t, carry_dependency);
Node* cast = new CastLLNode(n, t, dependency);
cast->set_req(0, c);
return cast;
}
case Op_CastPP: {
Node* cast = new CastPPNode(n, t, carry_dependency);
Node* cast = new CastPPNode(n, t, dependency);
cast->set_req(0, c);
return cast;
}
case Op_CastFF: {
Node* cast = new CastFFNode(n, t, carry_dependency);
Node* cast = new CastFFNode(n, t, dependency);
cast->set_req(0, c);
return cast;
}
case Op_CastDD: {
Node* cast = new CastDDNode(n, t, carry_dependency);
Node* cast = new CastDDNode(n, t, dependency);
cast->set_req(0, c);
return cast;
}
case Op_CastVV: {
Node* cast = new CastVVNode(n, t, carry_dependency);
Node* cast = new CastVVNode(n, t, dependency);
cast->set_req(0, c);
return cast;
}
case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, carry_dependency);
case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, dependency);
default:
fatal("Bad opcode %d", opcode);
}
@@ -131,10 +131,10 @@ Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t,
Node* ConstraintCastNode::make(Node* c, Node *n, const Type *t, BasicType bt) {
switch(bt) {
case T_INT: {
return make_cast(Op_CastII, c, n, t, false);
return make_cast(Op_CastII, c, n, t, RegularDependency);
}
case T_LONG: {
return make_cast(Op_CastLL, c, n, t, false);
return make_cast(Op_CastLL, c, n, t, RegularDependency);
}
default:
fatal("Bad basic type %s", type2name(bt));
@@ -143,6 +143,9 @@ Node* ConstraintCastNode::make(Node* c, Node *n, const Type *t, BasicType bt) {
}

TypeNode* ConstraintCastNode::dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const {
if (_dependency == UnconditionalDependency) {
return NULL;
}
Node* val = in(1);
Node* ctl = in(0);
int opc = Opcode();
@@ -183,8 +186,8 @@ TypeNode* ConstraintCastNode::dominating_cast(PhaseGVN* gvn, PhaseTransform* pt)
#ifndef PRODUCT
void ConstraintCastNode::dump_spec(outputStream *st) const {
TypeNode::dump_spec(st);
if (_carry_dependency) {
st->print(" carry dependency");
if (_dependency != RegularDependency) {
st->print(" %s dependency", _dependency == StrongDependency ? "strong" : "unconditional");
}
}
#endif
@@ -194,7 +197,7 @@ const Type* CastIINode::Value(PhaseGVN* phase) const {

// Try to improve the type of the CastII if we recognize a CmpI/If
// pattern.
if (_carry_dependency) {
if (_dependency != RegularDependency) {
if (in(0) != NULL && in(0)->in(0) != NULL && in(0)->in(0)->is_If()) {
assert(in(0)->is_IfFalse() || in(0)->is_IfTrue(), "should be If proj");
Node* proj = in(0);
@@ -255,8 +258,8 @@ const Type* CastIINode::Value(PhaseGVN* phase) const {
return res;
}

static Node* find_or_make_CastII(PhaseIterGVN* igvn, Node* parent, Node* control, const TypeInt* type, bool carry_dependency) {
Node* n = new CastIINode(parent, type, carry_dependency);
static Node* find_or_make_CastII(PhaseIterGVN* igvn, Node* parent, Node* control, const TypeInt* type, ConstraintCastNode::DependencyType dependency) {
Node* n = new CastIINode(parent, type, dependency);
n->set_req(0, control);
Node* existing = igvn->hash_find_insert(n);
if (existing != NULL) {
@@ -289,8 +292,8 @@ Node *CastIINode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node* x = z->in(1);
Node* y = z->in(2);

Node* cx = find_or_make_CastII(igvn, x, in(0), rx->is_int(), _carry_dependency);
Node* cy = find_or_make_CastII(igvn, y, in(0), ry->is_int(), _carry_dependency);
Node* cx = find_or_make_CastII(igvn, x, in(0), rx->is_int(), _dependency);
Node* cy = find_or_make_CastII(igvn, y, in(0), ry->is_int(), _dependency);
switch (op) {
case Op_AddI: return new AddINode(cx, cy);
case Op_SubI: return new SubINode(cx, cy);
@@ -377,7 +380,7 @@ Node* CheckCastPPNode::Identity(PhaseGVN* phase) {
if (dom != NULL) {
return dom;
}
if (_carry_dependency) {
if (_dependency != RegularDependency) {
return this;
}
const Type* t = phase->type(in(1));
@@ -573,20 +576,20 @@ Node* CastP2XNode::Identity(PhaseGVN* phase) {
return this;
}

Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type) {
Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency) {
Node* cast= NULL;
if (type->isa_int()) {
cast = make_cast(Op_CastII, c, in, type, true);
cast = make_cast(Op_CastII, c, in, type, dependency);
} else if (type->isa_long()) {
cast = make_cast(Op_CastLL, c, in, type, true);
cast = make_cast(Op_CastLL, c, in, type, dependency);
} else if (type->isa_float()) {
cast = make_cast(Op_CastFF, c, in, type, true);
cast = make_cast(Op_CastFF, c, in, type, dependency);
} else if (type->isa_double()) {
cast = make_cast(Op_CastDD, c, in, type, true);
cast = make_cast(Op_CastDD, c, in, type, dependency);
} else if (type->isa_vect()) {
cast = make_cast(Op_CastVV, c, in, type, true);
cast = make_cast(Op_CastVV, c, in, type, dependency);
} else if (type->isa_ptr()) {
cast = make_cast(Op_CastPP, c, in, type, true);
cast = make_cast(Op_CastPP, c, in, type, dependency);
}
return cast;
}
@@ -32,15 +32,21 @@
//------------------------------ConstraintCastNode-----------------------------
// cast to a different range
class ConstraintCastNode: public TypeNode {
public:
enum DependencyType {
RegularDependency, // if cast doesn't improve input type, cast can be removed
StrongDependency, // leave cast in even if _type doesn't improve input type, can be replaced by stricter dominating cast if one exist
UnconditionalDependency // leave cast in unconditionally
};

protected:
// Can this node be removed post CCP or does it carry a required dependency?
const bool _carry_dependency;
const DependencyType _dependency;
virtual bool cmp( const Node &n ) const;
virtual uint size_of() const;

public:
ConstraintCastNode(Node *n, const Type *t, bool carry_dependency)
: TypeNode(t,2), _carry_dependency(carry_dependency) {
ConstraintCastNode(Node *n, const Type *t, DependencyType dependency)
: TypeNode(t,2), _dependency(dependency) {
init_class_id(Class_ConstraintCast);
init_req(1, n);
}
@@ -49,10 +55,10 @@ class ConstraintCastNode: public TypeNode {
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
virtual int Opcode() const;
virtual uint ideal_reg() const = 0;
virtual bool depends_only_on_test() const { return !_carry_dependency; }
bool carry_dependency() const { return _carry_dependency; }
virtual bool depends_only_on_test() const { return _dependency == RegularDependency; }
bool carry_dependency() const { return _dependency != RegularDependency; }
TypeNode* dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const;
static Node* make_cast(int opcode, Node* c, Node *n, const Type *t, bool carry_dependency);
static Node* make_cast(int opcode, Node* c, Node *n, const Type *t, DependencyType dependency);
static Node* make(Node* c, Node *n, const Type *t, BasicType bt);
virtual bool operates_on(BasicType bt, bool signed_int) const {
assert(bt == T_INT || bt == T_LONG, "unsupported");
@@ -63,7 +69,7 @@ class ConstraintCastNode: public TypeNode {
virtual void dump_spec(outputStream *st) const;
#endif

static Node* make_cast_for_type(Node* c, Node* in, const Type* type);
static Node* make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency);
};

//------------------------------CastIINode-------------------------------------
@@ -76,12 +82,12 @@ class CastIINode: public ConstraintCastNode {
virtual uint size_of() const;

public:
CastIINode(Node* n, const Type* t, bool carry_dependency = false, bool range_check_dependency = false)
: ConstraintCastNode(n, t, carry_dependency), _range_check_dependency(range_check_dependency) {
CastIINode(Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false)
: ConstraintCastNode(n, t, dependency), _range_check_dependency(range_check_dependency) {
init_class_id(Class_CastII);
}
CastIINode(Node* ctrl, Node* n, const Type* t, bool carry_dependency = false, bool range_check_dependency = false)
: ConstraintCastNode(n, t, carry_dependency), _range_check_dependency(range_check_dependency) {
CastIINode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false)
: ConstraintCastNode(n, t, dependency), _range_check_dependency(range_check_dependency) {
init_class_id(Class_CastII);
init_req(0, ctrl);
}
@@ -110,13 +116,13 @@ class CastIINode: public ConstraintCastNode {

class CastLLNode: public ConstraintCastNode {
public:
CastLLNode(Node* ctrl, Node* n, const Type* t, bool carry_dependency = false)
: ConstraintCastNode(n, t, carry_dependency) {
CastLLNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency)
: ConstraintCastNode(n, t, dependency) {
init_class_id(Class_CastLL);
init_req(0, ctrl);
}
CastLLNode(Node* n, const Type* t, bool carry_dependency = false)
: ConstraintCastNode(n, t, carry_dependency){
CastLLNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
: ConstraintCastNode(n, t, dependency){
init_class_id(Class_CastLL);
}
virtual bool operates_on(BasicType bt, bool signed_int) const {
@@ -129,8 +135,8 @@ class CastLLNode: public ConstraintCastNode {

class CastFFNode: public ConstraintCastNode {
public:
CastFFNode(Node* n, const Type* t, bool carry_dependency = false)
: ConstraintCastNode(n, t, carry_dependency){
CastFFNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
: ConstraintCastNode(n, t, dependency){
init_class_id(Class_CastFF);
}
virtual int Opcode() const;
@@ -139,8 +145,8 @@ class CastFFNode: public ConstraintCastNode {

class CastDDNode: public ConstraintCastNode {
public:
CastDDNode(Node* n, const Type* t, bool carry_dependency = false)
: ConstraintCastNode(n, t, carry_dependency){
CastDDNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
: ConstraintCastNode(n, t, dependency){
init_class_id(Class_CastDD);
}
virtual int Opcode() const;
@@ -149,8 +155,8 @@ class CastDDNode: public ConstraintCastNode {

class CastVVNode: public ConstraintCastNode {
public:
CastVVNode(Node* n, const Type* t, bool carry_dependency = false)
: ConstraintCastNode(n, t, carry_dependency){
CastVVNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
: ConstraintCastNode(n, t, dependency){
init_class_id(Class_CastVV);
}
virtual int Opcode() const;
@@ -162,8 +168,8 @@ class CastVVNode: public ConstraintCastNode {
// cast pointer to pointer (different type)
class CastPPNode: public ConstraintCastNode {
public:
CastPPNode (Node *n, const Type *t, bool carry_dependency = false)
: ConstraintCastNode(n, t, carry_dependency) {
CastPPNode (Node *n, const Type *t, DependencyType dependency = RegularDependency)
: ConstraintCastNode(n, t, dependency) {
}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegP; }
@@ -173,8 +179,8 @@ class CastPPNode: public ConstraintCastNode {
// for _checkcast, cast pointer to pointer (different type), without JOIN,
class CheckCastPPNode: public ConstraintCastNode {
public:
CheckCastPPNode(Node *c, Node *n, const Type *t, bool carry_dependency = false)
: ConstraintCastNode(n, t, carry_dependency) {
CheckCastPPNode(Node *c, Node *n, const Type *t, DependencyType dependency = RegularDependency)
: ConstraintCastNode(n, t, dependency) {
init_class_id(Class_CheckCastPP);
init_req(0, c);
}
@@ -1975,7 +1975,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
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);
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency);
} else {
// Use a CastPP for a cast to not null and a CheckCastPP for
// a cast to a new klass (and both if both null-ness and
@@ -1985,7 +1985,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// null, uin's type must be casted to not null
if (phi_type->join(TypePtr::NOTNULL) == phi_type->remove_speculative() &&
uin_type->join(TypePtr::NOTNULL) != uin_type->remove_speculative()) {
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL, true);
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL, ConstraintCastNode::StrongDependency);
}

// If the type of phi and uin, both casted to not null,
@@ -1997,14 +1997,14 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
cast = phase->transform(cast);
n = cast;
}
cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, true);
cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, ConstraintCastNode::StrongDependency);
}
if (cast == NULL) {
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true);
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency);
}
}
} else {
cast = ConstraintCastNode::make_cast_for_type(r, uin, phi_type);
cast = ConstraintCastNode::make_cast_for_type(r, uin, phi_type, ConstraintCastNode::StrongDependency);
}
assert(cast != NULL, "cast should be set");
cast = phase->transform(cast);
@@ -4135,7 +4135,7 @@ Node* Compile::conv_I2X_index(PhaseGVN* phase, Node* idx, const TypeInt* sizetyp
Node* Compile::constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt* itype, Node* ctrl, bool carry_dependency) {
if (ctrl != NULL) {
// Express control dependency by a CastII node with a narrow type.
value = new CastIINode(value, itype, carry_dependency, true /* range check dependency */);
value = new CastIINode(value, itype, carry_dependency ? ConstraintCastNode::StrongDependency : ConstraintCastNode::RegularDependency, true /* range check dependency */);
// Make the CastII node dependent on the control input to prevent the narrowed ConvI2L
// node from floating above the range check during loop optimizations. Otherwise, the
// ConvI2L node may be eliminated independently of the range check, causing the data path
@@ -1193,7 +1193,7 @@ Node *PhaseIdealLoop::clone_up_backedge_goo(Node *back_ctrl, Node *preheader_ctr
}

Node* PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop) {
Node* castii = new CastIINode(incr, TypeInt::INT, true);
Node* castii = new CastIINode(incr, TypeInt::INT, ConstraintCastNode::StrongDependency);
castii->set_req(0, ctrl);
register_new_node(castii, ctrl);
for (DUIterator_Fast imax, i = incr->fast_outs(imax); i < imax; i++) {

0 comments on commit 4d545a1

Please sign in to comment.