1.1 --- a/src/share/vm/opto/addnode.cpp Wed Sep 23 16:26:20 2020 +0300 1.2 +++ b/src/share/vm/opto/addnode.cpp Wed May 13 15:59:17 2020 +0200 1.3 @@ -844,6 +844,14 @@ 1.4 return TypeInt::make( MAX2(r0->_lo,r1->_lo), MAX2(r0->_hi,r1->_hi), MAX2(r0->_widen,r1->_widen) ); 1.5 } 1.6 1.7 +// Check if addition of an integer with type 't' and a constant 'c' can overflow 1.8 +static bool can_overflow(const TypeInt* t, jint c) { 1.9 + jint t_lo = t->_lo; 1.10 + jint t_hi = t->_hi; 1.11 + return ((c < 0 && (java_add(t_lo, c) > t_lo)) || 1.12 + (c > 0 && (java_add(t_hi, c) < t_hi))); 1.13 +} 1.14 + 1.15 //============================================================================= 1.16 //------------------------------Idealize--------------------------------------- 1.17 // MINs show up in range-check loop limit calculations. Look for 1.18 @@ -866,7 +874,7 @@ 1.19 1.20 // Get left input & constant 1.21 Node *x = l; 1.22 - int x_off = 0; 1.23 + jint x_off = 0; 1.24 if( x->Opcode() == Op_AddI && // Check for "x+c0" and collect constant 1.25 x->in(2)->is_Con() ) { 1.26 const Type *t = x->in(2)->bottom_type(); 1.27 @@ -877,7 +885,7 @@ 1.28 1.29 // Scan a right-spline-tree for MINs 1.30 Node *y = r; 1.31 - int y_off = 0; 1.32 + jint y_off = 0; 1.33 // Check final part of MIN tree 1.34 if( y->Opcode() == Op_AddI && // Check for "y+c1" and collect constant 1.35 y->in(2)->is_Con() ) { 1.36 @@ -891,6 +899,7 @@ 1.37 return this; 1.38 } 1.39 1.40 + const TypeInt* tx = phase->type(x)->isa_int(); 1.41 1.42 if( r->Opcode() == Op_MinI ) { 1.43 assert( r != r->in(2), "dead loop in MinINode::Ideal" ); 1.44 @@ -907,18 +916,23 @@ 1.45 if( x->_idx > y->_idx ) 1.46 return new (phase->C) MinINode(r->in(1),phase->transform(new (phase->C) MinINode(l,r->in(2)))); 1.47 1.48 - // See if covers: MIN2(x+c0,MIN2(y+c1,z)) 1.49 - if( !phase->eqv(x,y) ) return NULL; 1.50 - // If (y == x) transform MIN2(x+c0, MIN2(x+c1,z)) into 1.51 - // MIN2(x+c0 or x+c1 which less, z). 1.52 - return new (phase->C) MinINode(phase->transform(new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2)); 1.53 + // Transform MIN2(x + c0, MIN2(x + c1, z)) into MIN2(x + MIN2(c0, c1), z) 1.54 + // if x == y and the additions can't overflow. 1.55 + if (phase->eqv(x,y) && 1.56 + !can_overflow(tx, x_off) && 1.57 + !can_overflow(tx, y_off)) { 1.58 + return new (phase->C) MinINode(phase->transform(new (phase->C) AddINode(x, phase->intcon(MIN2(x_off, y_off)))), r->in(2)); 1.59 + } 1.60 } else { 1.61 - // See if covers: MIN2(x+c0,y+c1) 1.62 - if( !phase->eqv(x,y) ) return NULL; 1.63 - // If (y == x) transform MIN2(x+c0,x+c1) into x+c0 or x+c1 which less. 1.64 - return new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off))); 1.65 + // Transform MIN2(x + c0, y + c1) into x + MIN2(c0, c1) 1.66 + // if x == y and the additions can't overflow. 1.67 + if (phase->eqv(x,y) && 1.68 + !can_overflow(tx, x_off) && 1.69 + !can_overflow(tx, y_off)) { 1.70 + return new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off))); 1.71 + } 1.72 } 1.73 - 1.74 + return NULL; 1.75 } 1.76 1.77 //------------------------------add_ring---------------------------------------