src/share/vm/opto/addnode.cpp

changeset 10010
824065fb8b18
parent 9610
f43f77de876a
child 10015
eb7ce841ccec
child 10024
b36c3f635d93
     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---------------------------------------

mercurial