1.1 --- a/src/share/vm/opto/subnode.cpp Thu Feb 16 15:14:44 2017 -0800 1.2 +++ b/src/share/vm/opto/subnode.cpp Thu Mar 30 15:28:33 2017 +0200 1.3 @@ -707,6 +707,60 @@ 1.4 return TypeInt::CC; // else use worst case results 1.5 } 1.6 1.7 + 1.8 +// Simplify a CmpUL (compare 2 unsigned longs) node, based on local information. 1.9 +// If both inputs are constants, compare them. 1.10 +const Type* CmpULNode::sub(const Type* t1, const Type* t2) const { 1.11 + assert(!t1->isa_ptr(), "obsolete usage of CmpUL"); 1.12 + 1.13 + // comparing two unsigned longs 1.14 + const TypeLong* r0 = t1->is_long(); // Handy access 1.15 + const TypeLong* r1 = t2->is_long(); 1.16 + 1.17 + // Current installed version 1.18 + // Compare ranges for non-overlap 1.19 + julong lo0 = r0->_lo; 1.20 + julong hi0 = r0->_hi; 1.21 + julong lo1 = r1->_lo; 1.22 + julong hi1 = r1->_hi; 1.23 + 1.24 + // If either one has both negative and positive values, 1.25 + // it therefore contains both 0 and -1, and since [0..-1] is the 1.26 + // full unsigned range, the type must act as an unsigned bottom. 1.27 + bool bot0 = ((jlong)(lo0 ^ hi0) < 0); 1.28 + bool bot1 = ((jlong)(lo1 ^ hi1) < 0); 1.29 + 1.30 + if (bot0 || bot1) { 1.31 + // All unsigned values are LE -1 and GE 0. 1.32 + if (lo0 == 0 && hi0 == 0) { 1.33 + return TypeInt::CC_LE; // 0 <= bot 1.34 + } else if ((jlong)lo0 == -1 && (jlong)hi0 == -1) { 1.35 + return TypeInt::CC_GE; // -1 >= bot 1.36 + } else if (lo1 == 0 && hi1 == 0) { 1.37 + return TypeInt::CC_GE; // bot >= 0 1.38 + } else if ((jlong)lo1 == -1 && (jlong)hi1 == -1) { 1.39 + return TypeInt::CC_LE; // bot <= -1 1.40 + } 1.41 + } else { 1.42 + // We can use ranges of the form [lo..hi] if signs are the same. 1.43 + assert(lo0 <= hi0 && lo1 <= hi1, "unsigned ranges are valid"); 1.44 + // results are reversed, '-' > '+' for unsigned compare 1.45 + if (hi0 < lo1) { 1.46 + return TypeInt::CC_LT; // smaller 1.47 + } else if (lo0 > hi1) { 1.48 + return TypeInt::CC_GT; // greater 1.49 + } else if (hi0 == lo1 && lo0 == hi1) { 1.50 + return TypeInt::CC_EQ; // Equal results 1.51 + } else if (lo0 >= hi1) { 1.52 + return TypeInt::CC_GE; 1.53 + } else if (hi0 <= lo1) { 1.54 + return TypeInt::CC_LE; 1.55 + } 1.56 + } 1.57 + 1.58 + return TypeInt::CC; // else use worst case results 1.59 +} 1.60 + 1.61 //============================================================================= 1.62 //------------------------------sub-------------------------------------------- 1.63 // Simplify an CmpP (compare 2 pointers) node, based on local information.