Skip to content

Commit 7c05f32

Browse files
TobiHartmannslowhog
authored andcommitted
8244924: Additional fix for JDK-8241119
Reviewed-by: kvn, vlivanov, rhalade, ahgross
1 parent 62a03bd commit 7c05f32

File tree

1 file changed

+26
-12
lines changed

1 file changed

+26
-12
lines changed

src/hotspot/share/opto/addnode.cpp

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,14 @@ const Type *MaxINode::add_ring( const Type *t0, const Type *t1 ) const {
10041004
return TypeInt::make( MAX2(r0->_lo,r1->_lo), MAX2(r0->_hi,r1->_hi), MAX2(r0->_widen,r1->_widen) );
10051005
}
10061006

1007+
// Check if addition of an integer with type 't' and a constant 'c' can overflow
1008+
static bool can_overflow(const TypeInt* t, jint c) {
1009+
jint t_lo = t->_lo;
1010+
jint t_hi = t->_hi;
1011+
return ((c < 0 && (java_add(t_lo, c) > t_lo)) ||
1012+
(c > 0 && (java_add(t_hi, c) < t_hi)));
1013+
}
1014+
10071015
//=============================================================================
10081016
//------------------------------Idealize---------------------------------------
10091017
// MINs show up in range-check loop limit calculations. Look for
@@ -1026,7 +1034,7 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
10261034

10271035
// Get left input & constant
10281036
Node *x = l;
1029-
int x_off = 0;
1037+
jint x_off = 0;
10301038
if( x->Opcode() == Op_AddI && // Check for "x+c0" and collect constant
10311039
x->in(2)->is_Con() ) {
10321040
const Type *t = x->in(2)->bottom_type();
@@ -1037,7 +1045,7 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
10371045

10381046
// Scan a right-spline-tree for MINs
10391047
Node *y = r;
1040-
int y_off = 0;
1048+
jint y_off = 0;
10411049
// Check final part of MIN tree
10421050
if( y->Opcode() == Op_AddI && // Check for "y+c1" and collect constant
10431051
y->in(2)->is_Con() ) {
@@ -1051,6 +1059,7 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
10511059
return this;
10521060
}
10531061

1062+
const TypeInt* tx = phase->type(x)->isa_int();
10541063

10551064
if( r->Opcode() == Op_MinI ) {
10561065
assert( r != r->in(2), "dead loop in MinINode::Ideal" );
@@ -1067,18 +1076,23 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
10671076
if( x->_idx > y->_idx )
10681077
return new MinINode(r->in(1),phase->transform(new MinINode(l,r->in(2))));
10691078

1070-
// See if covers: MIN2(x+c0,MIN2(y+c1,z))
1071-
if( !phase->eqv(x,y) ) return NULL;
1072-
// If (y == x) transform MIN2(x+c0, MIN2(x+c1,z)) into
1073-
// MIN2(x+c0 or x+c1 which less, z).
1074-
return new MinINode(phase->transform(new AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2));
1079+
// Transform MIN2(x + c0, MIN2(x + c1, z)) into MIN2(x + MIN2(c0, c1), z)
1080+
// if x == y and the additions can't overflow.
1081+
if (phase->eqv(x,y) &&
1082+
!can_overflow(tx, x_off) &&
1083+
!can_overflow(tx, y_off)) {
1084+
return new MinINode(phase->transform(new AddINode(x, phase->intcon(MIN2(x_off, y_off)))), r->in(2));
1085+
}
10751086
} else {
1076-
// See if covers: MIN2(x+c0,y+c1)
1077-
if( !phase->eqv(x,y) ) return NULL;
1078-
// If (y == x) transform MIN2(x+c0,x+c1) into x+c0 or x+c1 which less.
1079-
return new AddINode(x,phase->intcon(MIN2(x_off,y_off)));
1087+
// Transform MIN2(x + c0, y + c1) into x + MIN2(c0, c1)
1088+
// if x == y and the additions can't overflow.
1089+
if (phase->eqv(x,y) &&
1090+
!can_overflow(tx, x_off) &&
1091+
!can_overflow(tx, y_off)) {
1092+
return new AddINode(x,phase->intcon(MIN2(x_off,y_off)));
1093+
}
10801094
}
1081-
1095+
return NULL;
10821096
}
10831097

10841098
//------------------------------add_ring---------------------------------------

0 commit comments

Comments
 (0)