mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-13 20:05:31 +00:00
8244924: Additional fix for JDK-8241119
Reviewed-by: kvn, vlivanov, rhalade, ahgross
This commit is contained in:
parent
62a03bd387
commit
7c05f32bc9
@ -1004,6 +1004,14 @@ const Type *MaxINode::add_ring( const Type *t0, const Type *t1 ) const {
|
||||
return TypeInt::make( MAX2(r0->_lo,r1->_lo), MAX2(r0->_hi,r1->_hi), MAX2(r0->_widen,r1->_widen) );
|
||||
}
|
||||
|
||||
// Check if addition of an integer with type 't' and a constant 'c' can overflow
|
||||
static bool can_overflow(const TypeInt* t, jint c) {
|
||||
jint t_lo = t->_lo;
|
||||
jint t_hi = t->_hi;
|
||||
return ((c < 0 && (java_add(t_lo, c) > t_lo)) ||
|
||||
(c > 0 && (java_add(t_hi, c) < t_hi)));
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//------------------------------Idealize---------------------------------------
|
||||
// MINs show up in range-check loop limit calculations. Look for
|
||||
@ -1026,7 +1034,7 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
|
||||
// Get left input & constant
|
||||
Node *x = l;
|
||||
int x_off = 0;
|
||||
jint x_off = 0;
|
||||
if( x->Opcode() == Op_AddI && // Check for "x+c0" and collect constant
|
||||
x->in(2)->is_Con() ) {
|
||||
const Type *t = x->in(2)->bottom_type();
|
||||
@ -1037,7 +1045,7 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
|
||||
// Scan a right-spline-tree for MINs
|
||||
Node *y = r;
|
||||
int y_off = 0;
|
||||
jint y_off = 0;
|
||||
// Check final part of MIN tree
|
||||
if( y->Opcode() == Op_AddI && // Check for "y+c1" and collect constant
|
||||
y->in(2)->is_Con() ) {
|
||||
@ -1051,6 +1059,7 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const TypeInt* tx = phase->type(x)->isa_int();
|
||||
|
||||
if( r->Opcode() == Op_MinI ) {
|
||||
assert( r != r->in(2), "dead loop in MinINode::Ideal" );
|
||||
@ -1067,18 +1076,23 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
if( x->_idx > y->_idx )
|
||||
return new MinINode(r->in(1),phase->transform(new MinINode(l,r->in(2))));
|
||||
|
||||
// See if covers: MIN2(x+c0,MIN2(y+c1,z))
|
||||
if( !phase->eqv(x,y) ) return NULL;
|
||||
// If (y == x) transform MIN2(x+c0, MIN2(x+c1,z)) into
|
||||
// MIN2(x+c0 or x+c1 which less, z).
|
||||
return new MinINode(phase->transform(new AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2));
|
||||
// Transform MIN2(x + c0, MIN2(x + c1, z)) into MIN2(x + MIN2(c0, c1), z)
|
||||
// if x == y and the additions can't overflow.
|
||||
if (phase->eqv(x,y) &&
|
||||
!can_overflow(tx, x_off) &&
|
||||
!can_overflow(tx, y_off)) {
|
||||
return new MinINode(phase->transform(new AddINode(x, phase->intcon(MIN2(x_off, y_off)))), r->in(2));
|
||||
}
|
||||
} else {
|
||||
// See if covers: MIN2(x+c0,y+c1)
|
||||
if( !phase->eqv(x,y) ) return NULL;
|
||||
// If (y == x) transform MIN2(x+c0,x+c1) into x+c0 or x+c1 which less.
|
||||
return new AddINode(x,phase->intcon(MIN2(x_off,y_off)));
|
||||
// Transform MIN2(x + c0, y + c1) into x + MIN2(c0, c1)
|
||||
// if x == y and the additions can't overflow.
|
||||
if (phase->eqv(x,y) &&
|
||||
!can_overflow(tx, x_off) &&
|
||||
!can_overflow(tx, y_off)) {
|
||||
return new AddINode(x,phase->intcon(MIN2(x_off,y_off)));
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//------------------------------add_ring---------------------------------------
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user