Skip to content

Commit d8a1c1d

Browse files
committed
8354282: C2: more crashes in compiled code because of dependency on removed range check CastIIs
Reviewed-by: chagedorn Backport-of: 00068a8
1 parent 6950503 commit d8a1c1d

File tree

13 files changed

+340
-101
lines changed

13 files changed

+340
-101
lines changed

src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1394,7 +1394,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
13941394
}
13951395
if (addr->Opcode() == Op_AddP) {
13961396
Node* orig_base = addr->in(AddPNode::Base);
1397-
Node* base = new CheckCastPPNode(ctrl, orig_base, orig_base->bottom_type(), ConstraintCastNode::StrongDependency);
1397+
Node* base = new CheckCastPPNode(ctrl, orig_base, orig_base->bottom_type(), ConstraintCastNode::DependencyType::NonFloatingNarrowing);
13981398
phase->register_new_node(base, ctrl);
13991399
if (addr->in(AddPNode::Base) == addr->in((AddPNode::Address))) {
14001400
// Field access

src/hotspot/share/opto/castnode.cpp

Lines changed: 88 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
*
2323
*/
2424

25-
#include "castnode.hpp"
2625
#include "opto/addnode.hpp"
2726
#include "opto/callnode.hpp"
2827
#include "opto/castnode.hpp"
@@ -35,12 +34,22 @@
3534
#include "opto/type.hpp"
3635
#include "utilities/checkedCast.hpp"
3736

37+
const ConstraintCastNode::DependencyType ConstraintCastNode::DependencyType::FloatingNarrowing(true, true, "floating narrowing dependency"); // not pinned, narrows type
38+
const ConstraintCastNode::DependencyType ConstraintCastNode::DependencyType::FloatingNonNarrowing(true, false, "floating non-narrowing dependency"); // not pinned, doesn't narrow type
39+
const ConstraintCastNode::DependencyType ConstraintCastNode::DependencyType::NonFloatingNarrowing(false, true, "non-floating narrowing dependency"); // pinned, narrows type
40+
const ConstraintCastNode::DependencyType ConstraintCastNode::DependencyType::NonFloatingNonNarrowing(false, false, "non-floating non-narrowing dependency"); // pinned, doesn't narrow type
41+
3842
//=============================================================================
3943
// If input is already higher or equal to cast type, then this is an identity.
4044
Node* ConstraintCastNode::Identity(PhaseGVN* phase) {
41-
if (_dependency == UnconditionalDependency) {
45+
if (!_dependency.narrows_type()) {
46+
// If this cast doesn't carry a type dependency (i.e. not used for type narrowing), we cannot optimize it.
4247
return this;
4348
}
49+
50+
// This cast node carries a type dependency. We can remove it if:
51+
// - Its input has a narrower type
52+
// - There's a dominating cast with same input but narrower type
4453
Node* dom = dominating_cast(phase, phase);
4554
if (dom != nullptr) {
4655
return dom;
@@ -109,15 +118,15 @@ Node* ConstraintCastNode::Ideal(PhaseGVN* phase, bool can_reshape) {
109118
}
110119

111120
uint ConstraintCastNode::hash() const {
112-
return TypeNode::hash() + (int)_dependency + (_extra_types != nullptr ? _extra_types->hash() : 0);
121+
return TypeNode::hash() + _dependency.hash() + (_extra_types != nullptr ? _extra_types->hash() : 0);
113122
}
114123

115124
bool ConstraintCastNode::cmp(const Node &n) const {
116125
if (!TypeNode::cmp(n)) {
117126
return false;
118127
}
119128
ConstraintCastNode& cast = (ConstraintCastNode&) n;
120-
if (cast._dependency != _dependency) {
129+
if (!cast._dependency.cmp(_dependency)) {
121130
return false;
122131
}
123132
if (_extra_types == nullptr || cast._extra_types == nullptr) {
@@ -130,7 +139,7 @@ uint ConstraintCastNode::size_of() const {
130139
return sizeof(*this);
131140
}
132141

133-
Node* ConstraintCastNode::make_cast_for_basic_type(Node* c, Node* n, const Type* t, DependencyType dependency, BasicType bt) {
142+
Node* ConstraintCastNode::make_cast_for_basic_type(Node* c, Node* n, const Type* t, const DependencyType& dependency, BasicType bt) {
134143
switch(bt) {
135144
case T_INT:
136145
return new CastIINode(c, n, t, dependency);
@@ -143,9 +152,9 @@ Node* ConstraintCastNode::make_cast_for_basic_type(Node* c, Node* n, const Type*
143152
}
144153

145154
TypeNode* ConstraintCastNode::dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const {
146-
if (_dependency == UnconditionalDependency) {
147-
return nullptr;
148-
}
155+
// See discussion at definition of ConstraintCastNode::DependencyType: replacing this cast with a dominating one is
156+
// not safe if _dependency.narrows_type() is not true.
157+
assert(_dependency.narrows_type(), "cast can't be replaced by dominating one");
149158
Node* val = in(1);
150159
Node* ctl = in(0);
151160
int opc = Opcode();
@@ -205,30 +214,21 @@ void ConstraintCastNode::dump_spec(outputStream *st) const {
205214
st->print(" extra types: ");
206215
_extra_types->dump_on(st);
207216
}
208-
if (_dependency != RegularDependency) {
209-
st->print(" %s dependency", _dependency == StrongDependency ? "strong" : "unconditional");
210-
}
217+
st->print(" ");
218+
_dependency.dump_on(st);
211219
}
212220
#endif
213221

214-
const Type* CastIINode::Value(PhaseGVN* phase) const {
215-
const Type *res = ConstraintCastNode::Value(phase);
216-
if (res == Type::TOP) {
217-
return Type::TOP;
218-
}
219-
assert(res->isa_int(), "res must be int");
220-
221-
// Similar to ConvI2LNode::Value() for the same reasons
222-
// see if we can remove type assertion after loop opts
223-
res = widen_type(phase, res, T_INT);
222+
CastIINode* CastIINode::make_with(Node* parent, const TypeInteger* type, const DependencyType& dependency) const {
223+
return new CastIINode(in(0), parent, type, dependency, _range_check_dependency, _extra_types);
224+
}
224225

225-
return res;
226+
CastLLNode* CastLLNode::make_with(Node* parent, const TypeInteger* type, const DependencyType& dependency) const {
227+
return new CastLLNode(in(0), parent, type, dependency, _extra_types);
226228
}
227229

228-
Node* ConstraintCastNode::find_or_make_integer_cast(PhaseIterGVN* igvn, Node* parent, const TypeInteger* type) const {
229-
Node* n = clone();
230-
n->set_req(1, parent);
231-
n->as_ConstraintCast()->set_type(type);
230+
Node* ConstraintCastNode::find_or_make_integer_cast(PhaseIterGVN* igvn, Node* parent, const TypeInteger* type, const DependencyType& dependency) const {
231+
Node* n = make_with(parent, type, dependency);
232232
Node* existing = igvn->hash_find_insert(n);
233233
if (existing != nullptr) {
234234
n->destruct(igvn);
@@ -242,14 +242,13 @@ Node *CastIINode::Ideal(PhaseGVN *phase, bool can_reshape) {
242242
if (progress != nullptr) {
243243
return progress;
244244
}
245-
if (can_reshape && !phase->C->post_loop_opts_phase()) {
246-
// makes sure we run ::Value to potentially remove type assertion after loop opts
245+
if (!phase->C->post_loop_opts_phase()) {
246+
// makes sure we run widen_type() to potentially common type assertions after loop opts
247247
phase->C->record_for_post_loop_opts_igvn(this);
248248
}
249249
if (!_range_check_dependency || phase->C->post_loop_opts_phase()) {
250250
return optimize_integer_cast(phase, T_INT);
251251
}
252-
phase->C->record_for_post_loop_opts_igvn(this);
253252
return nullptr;
254253
}
255254

@@ -279,9 +278,9 @@ void CastIINode::dump_spec(outputStream* st) const {
279278
#endif
280279

281280
CastIINode* CastIINode::pin_array_access_node() const {
282-
assert(_dependency == RegularDependency, "already pinned");
281+
assert(_dependency.is_floating(), "already pinned");
283282
if (has_range_check()) {
284-
return new CastIINode(in(0), in(1), bottom_type(), StrongDependency, has_range_check());
283+
return new CastIINode(in(0), in(1), bottom_type(), _dependency.with_pinned_dependency(), has_range_check());
285284
}
286285
return nullptr;
287286
}
@@ -315,16 +314,6 @@ void CastIINode::remove_range_check_cast(Compile* C) {
315314
}
316315

317316

318-
const Type* CastLLNode::Value(PhaseGVN* phase) const {
319-
const Type* res = ConstraintCastNode::Value(phase);
320-
if (res == Type::TOP) {
321-
return Type::TOP;
322-
}
323-
assert(res->isa_long(), "res must be long");
324-
325-
return widen_type(phase, res, T_LONG);
326-
}
327-
328317
bool CastLLNode::is_inner_loop_backedge(ProjNode* proj) {
329318
if (proj != nullptr) {
330319
Node* ctrl_use = proj->unique_ctrl_out_or_null();
@@ -392,7 +381,7 @@ Node* CastLLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
392381
return progress;
393382
}
394383
if (!phase->C->post_loop_opts_phase()) {
395-
// makes sure we run ::Value to potentially remove type assertion after loop opts
384+
// makes sure we run widen_type() to potentially common type assertions after loop opts
396385
phase->C->record_for_post_loop_opts_igvn(this);
397386
}
398387
// transform (CastLL (ConvI2L ..)) into (ConvI2L (CastII ..)) if the type of the CastLL is narrower than the type of
@@ -543,7 +532,7 @@ Node* CastP2XNode::Identity(PhaseGVN* phase) {
543532
return this;
544533
}
545534

546-
Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency,
535+
Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type, const DependencyType& dependency,
547536
const TypeTuple* types) {
548537
if (type->isa_int()) {
549538
return new CastIINode(c, in, type, dependency, false, types);
@@ -564,7 +553,7 @@ Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type
564553
return nullptr;
565554
}
566555

567-
Node* ConstraintCastNode::optimize_integer_cast(PhaseGVN* phase, BasicType bt) {
556+
Node* ConstraintCastNode::optimize_integer_cast_of_add(PhaseGVN* phase, BasicType bt) {
568557
PhaseIterGVN *igvn = phase->is_IterGVN();
569558
const TypeInteger* this_type = this->type()->isa_integer(bt);
570559
if (this_type == nullptr) {
@@ -586,8 +575,42 @@ Node* ConstraintCastNode::optimize_integer_cast(PhaseGVN* phase, BasicType bt) {
586575
Node* x = z->in(1);
587576
Node* y = z->in(2);
588577

589-
Node* cx = find_or_make_integer_cast(igvn, x, rx);
590-
Node* cy = find_or_make_integer_cast(igvn, y, ry);
578+
const TypeInteger* tx = phase->type(x)->is_integer(bt);
579+
const TypeInteger* ty = phase->type(y)->is_integer(bt);
580+
581+
// (Cast (Add x y) tz) is transformed into (Add (Cast x rx) (Cast y ry))
582+
//
583+
// tz = [tzlo, tzhi]
584+
// rx = [rxlo, rxhi]
585+
// ry = [rylo, ryhi]
586+
// with type of x, tx = [txlo, txhi]
587+
// with type of y, ty = [tylo, tyhi]
588+
//
589+
// From Compile::push_thru_add():
590+
// rxlo = max(tzlo - tyhi, txlo)
591+
// rxhi = min(tzhi - tylo, txhi)
592+
// rylo = max(tzlo - txhi, tylo)
593+
// ryhi = min(tzhi - txlo, tyhi)
594+
//
595+
// If x is a constant, then txlo = txhi
596+
// rxlo = txlo, rxhi = txhi
597+
// The bounds of the type of the Add after transformation then is:
598+
// rxlo + rylo >= txlo + tzlo - txhi >= tzlo
599+
// rxhi + ryhi <= txhi + tzhi - txlo <= tzhi
600+
// The resulting type is not wider than the type of the Cast
601+
// before transformation
602+
//
603+
// If neither x nor y are constant then the type of the resulting
604+
// Add can be wider than the type of the type of the Cast before
605+
// transformation.
606+
// For instance, tx = [0, 10], ty = [0, 10], tz = [0, 10]
607+
// then rx = [0, 10], ry = [0, 10]
608+
// and rx + ry = [0, 20] which is wider than tz
609+
//
610+
// Same reasoning applies to (Cast (Sub x y) tz)
611+
const DependencyType& dependency = (!tx->is_con() && !ty->is_con()) ? _dependency.with_non_narrowing() : _dependency;
612+
Node* cx = find_or_make_integer_cast(igvn, x, rx, dependency);
613+
Node* cy = find_or_make_integer_cast(igvn, y, ry, dependency);
591614
if (op == Op_Add(bt)) {
592615
return AddNode::make(cx, cy, bt);
593616
} else {
@@ -599,11 +622,26 @@ Node* ConstraintCastNode::optimize_integer_cast(PhaseGVN* phase, BasicType bt) {
599622
return nullptr;
600623
}
601624

602-
const Type* ConstraintCastNode::widen_type(const PhaseGVN* phase, const Type* res, BasicType bt) const {
603-
if (!phase->C->post_loop_opts_phase()) {
625+
Node* ConstraintCastNode::optimize_integer_cast(PhaseGVN* phase, BasicType bt) {
626+
Node* res = optimize_integer_cast_of_add(phase, bt);
627+
if (res != nullptr) {
604628
return res;
605629
}
630+
const Type* t = Value(phase);
631+
if (t != Type::TOP && phase->C->post_loop_opts_phase()) {
632+
const Type* bottom_t = bottom_type();
633+
const TypeInteger* wide_t = widen_type(phase, bottom_t, bt);
634+
if (wide_t != bottom_t) {
635+
// Widening the type of the Cast (to allow some commoning) causes the Cast to change how it can be optimized (if
636+
// type of its input is narrower than the Cast's type, we can't remove it to not loose the control dependency).
637+
return make_with(in(1), wide_t, _dependency.with_non_narrowing());
638+
}
639+
}
640+
return nullptr;
641+
}
606642

643+
const TypeInteger* ConstraintCastNode::widen_type(const PhaseGVN* phase, const Type* res, BasicType bt) const {
644+
const TypeInteger* this_type = res->is_integer(bt);
607645
// At VerifyConstraintCasts == 1, we verify the ConstraintCastNodes that are present during code
608646
// emission. This allows us detecting possible mis-scheduling due to these nodes being pinned at
609647
// the wrong control nodes.
@@ -612,10 +650,9 @@ const Type* ConstraintCastNode::widen_type(const PhaseGVN* phase, const Type* re
612650
// mis-transformations that may happen due to these nodes being pinned at the wrong control
613651
// nodes.
614652
if (VerifyConstraintCasts > 1) {
615-
return res;
653+
return this_type;
616654
}
617655

618-
const TypeInteger* this_type = res->is_integer(bt);
619656
const TypeInteger* in_type = phase->type(in(1))->isa_integer(bt);
620657
if (in_type != nullptr &&
621658
(in_type->lo_as_long() != this_type->lo_as_long() ||
@@ -636,5 +673,5 @@ const Type* ConstraintCastNode::widen_type(const PhaseGVN* phase, const Type* re
636673
MIN2(in_type->hi_as_long(), hi1),
637674
MAX2((int)in_type->_widen, w1), bt);
638675
}
639-
return res;
676+
return this_type;
640677
}

0 commit comments

Comments
 (0)