< prev index next >

src/share/vm/opto/mulnode.cpp

Print this page
rev 9644 : 8145096: Undefined behaviour in HotSpot
Summary: Fix some integer overflows
Reviewed-by: duke

*** 243,259 **** double c = (double)lo1; int32_t hi1 = r1->_hi; double d = (double)hi1; // Compute all endpoints & check for overflow ! int32_t A = lo0*lo1; if( (double)A != a*c ) return TypeInt::INT; // Overflow? ! int32_t B = lo0*hi1; if( (double)B != a*d ) return TypeInt::INT; // Overflow? ! int32_t C = hi0*lo1; if( (double)C != b*c ) return TypeInt::INT; // Overflow? ! int32_t D = hi0*hi1; if( (double)D != b*d ) return TypeInt::INT; // Overflow? if( A < B ) { lo0 = A; hi0 = B; } // Sort range endpoints else { lo0 = B; hi0 = A; } if( C < D ) { --- 243,259 ---- double c = (double)lo1; int32_t hi1 = r1->_hi; double d = (double)hi1; // Compute all endpoints & check for overflow ! int32_t A = java_multiply(lo0, lo1); if( (double)A != a*c ) return TypeInt::INT; // Overflow? ! int32_t B = java_multiply(lo0, hi1); if( (double)B != a*d ) return TypeInt::INT; // Overflow? ! int32_t C = java_multiply(hi0, lo1); if( (double)C != b*c ) return TypeInt::INT; // Overflow? ! int32_t D = java_multiply(hi0, hi1); if( (double)D != b*d ) return TypeInt::INT; // Overflow? if( A < B ) { lo0 = A; hi0 = B; } // Sort range endpoints else { lo0 = B; hi0 = A; } if( C < D ) {
*** 339,355 **** double c = (double)lo1; jlong hi1 = r1->_hi; double d = (double)hi1; // Compute all endpoints & check for overflow ! jlong A = lo0*lo1; if( (double)A != a*c ) return TypeLong::LONG; // Overflow? ! jlong B = lo0*hi1; if( (double)B != a*d ) return TypeLong::LONG; // Overflow? ! jlong C = hi0*lo1; if( (double)C != b*c ) return TypeLong::LONG; // Overflow? ! jlong D = hi0*hi1; if( (double)D != b*d ) return TypeLong::LONG; // Overflow? if( A < B ) { lo0 = A; hi0 = B; } // Sort range endpoints else { lo0 = B; hi0 = A; } if( C < D ) { --- 339,355 ---- double c = (double)lo1; jlong hi1 = r1->_hi; double d = (double)hi1; // Compute all endpoints & check for overflow ! jlong A = java_multiply(lo0, lo1); if( (double)A != a*c ) return TypeLong::LONG; // Overflow? ! jlong B = java_multiply(lo0, hi1); if( (double)B != a*d ) return TypeLong::LONG; // Overflow? ! jlong C = java_multiply(hi0, lo1); if( (double)C != b*c ) return TypeLong::LONG; // Overflow? ! jlong D = java_multiply(hi0, hi1); if( (double)D != b*d ) return TypeLong::LONG; // Overflow? if( A < B ) { lo0 = A; hi0 = B; } // Sort range endpoints else { lo0 = B; hi0 = A; } if( C < D ) {
*** 572,582 **** if( t2 && t2->is_con() ) { jlong con = t2->get_con(); // Masking off high bits which are always zero is useless. const TypeLong* t1 = phase->type( in(1) )->isa_long(); if (t1 != NULL && t1->_lo >= 0) { ! jlong t1_support = ((jlong)1 << (1 + log2_long(t1->_hi))) - 1; if ((t1_support & con) == t1_support) return usr; } uint lop = usr->Opcode(); // Masking off the high bits of a unsigned-shift-right is not --- 572,582 ---- if( t2 && t2->is_con() ) { jlong con = t2->get_con(); // Masking off high bits which are always zero is useless. const TypeLong* t1 = phase->type( in(1) )->isa_long(); if (t1 != NULL && t1->_lo >= 0) { ! jlong t1_support = java_subtract(((jlong)1 << (1 + log2_long(t1->_hi))), (jlong)1); if ((t1_support & con) == t1_support) return usr; } uint lop = usr->Opcode(); // Masking off the high bits of a unsigned-shift-right is not
*** 800,810 **** } } // Check for ((x & ((CONST64(1)<<(64-c0))-1)) << c0) which ANDs off high bits // before shifting them away. ! const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) - CONST64(1); if( add1_op == Op_AndL && phase->type(add1->in(2)) == TypeLong::make( bits_mask ) ) return new LShiftLNode( add1->in(1), in(2) ); return NULL; --- 800,810 ---- } } // Check for ((x & ((CONST64(1)<<(64-c0))-1)) << c0) which ANDs off high bits // before shifting them away. ! const jlong bits_mask = java_subtract((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con), CONST64(1)); if( add1_op == Op_AndL && phase->type(add1->in(2)) == TypeLong::make( bits_mask ) ) return new LShiftLNode( add1->in(1), in(2) ); return NULL;
*** 1252,1262 **** if( !t2 || !t2->is_con() ) return NULL; // Right input is a constant const int con = t2->get_con() & ( BitsPerLong - 1 ); // Shift count is always masked if ( con == 0 ) return NULL; // let Identity() handle a 0 shift count // note: mask computation below does not work for 0 shift count // We'll be wanting the right-shift amount as a mask of that many bits ! const jlong mask = (((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) -1); // Check for ((x << z) + Y) >>> z. Replace with x + con>>>z // The idiom for rounding to a power of 2 is "(Q+(2^z-1)) >>> z". // If Q is "X << z" the rounding is useless. Look for patterns like // ((X<<Z) + Y) >>> Z and replace with (X + Y>>>Z) & Z-mask. --- 1252,1262 ---- if( !t2 || !t2->is_con() ) return NULL; // Right input is a constant const int con = t2->get_con() & ( BitsPerLong - 1 ); // Shift count is always masked if ( con == 0 ) return NULL; // let Identity() handle a 0 shift count // note: mask computation below does not work for 0 shift count // We'll be wanting the right-shift amount as a mask of that many bits ! const jlong mask = java_subtract(((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)), (jlong)1); // Check for ((x << z) + Y) >>> z. Replace with x + con>>>z // The idiom for rounding to a power of 2 is "(Q+(2^z-1)) >>> z". // If Q is "X << z" the rounding is useless. Look for patterns like // ((X<<Z) + Y) >>> Z and replace with (X + Y>>>Z) & Z-mask.
< prev index next >