Commit 5db2af48 authored by whesse@chromium.org's avatar whesse@chromium.org

Fix error in static type information computation for bitwise shift.

Review URL: http://codereview.chromium.org/1756007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4471 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 49d68568
...@@ -1180,16 +1180,23 @@ static TypeInfo CalculateTypeInfo(TypeInfo operands_type, ...@@ -1180,16 +1180,23 @@ static TypeInfo CalculateTypeInfo(TypeInfo operands_type,
case Token::SAR: case Token::SAR:
if (left.is_smi()) return TypeInfo::Smi(); if (left.is_smi()) return TypeInfo::Smi();
// Result is a smi if we shift by a constant >= 1, otherwise an integer32. // Result is a smi if we shift by a constant >= 1, otherwise an integer32.
// Shift amount is masked with 0x1F (ECMA standard 11.7.2).
return (right.is_constant() && right.handle()->IsSmi() return (right.is_constant() && right.handle()->IsSmi()
&& Smi::cast(*right.handle())->value() >= 1) && (Smi::cast(*right.handle())->value() & 0x1F) >= 1)
? TypeInfo::Smi() ? TypeInfo::Smi()
: TypeInfo::Integer32(); : TypeInfo::Integer32();
case Token::SHR: case Token::SHR:
// Result is a smi if we shift by a constant >= 2, otherwise an integer32. // Result is a smi if we shift by a constant >= 2, an integer32 if
return (right.is_constant() && right.handle()->IsSmi() // we shift by 1, and an unsigned 32-bit integer if we shift by 0.
&& Smi::cast(*right.handle())->value() >= 2) if (right.is_constant() && right.handle()->IsSmi()) {
? TypeInfo::Smi() int shift_amount = Smi::cast(*right.handle())->value() & 0x1F;
: TypeInfo::Integer32(); if (shift_amount > 1) {
return TypeInfo::Smi();
} else if (shift_amount > 0) {
return TypeInfo::Integer32();
}
}
return TypeInfo::Number();
case Token::ADD: case Token::ADD:
if (operands_type.IsSmi()) { if (operands_type.IsSmi()) {
// The Integer32 range is big enough to take the sum of any two Smis. // The Integer32 range is big enough to take the sum of any two Smis.
......
...@@ -5840,9 +5840,9 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op, ...@@ -5840,9 +5840,9 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
result_type = TypeInfo::Smi(); result_type = TypeInfo::Smi();
break; break;
case Token::SHR: case Token::SHR:
// Result of x >>> y is always a smi if y >= 1, otherwise a number. // Result of x >>> y is always a smi if masked y >= 1, otherwise a number.
result_type = (right.is_constant() && right.handle()->IsSmi() result_type = (right.is_constant() && right.handle()->IsSmi()
&& Smi::cast(*right.handle())->value() >= 1) && (Smi::cast(*right.handle())->value() & 0x1F) >= 1)
? TypeInfo::Smi() ? TypeInfo::Smi()
: TypeInfo::Number(); : TypeInfo::Number();
break; break;
......
...@@ -669,3 +669,12 @@ intConversion(); ...@@ -669,3 +669,12 @@ intConversion();
function shiftByZero(n) { return n << 0; } function shiftByZero(n) { return n << 0; }
assertEquals(3, shiftByZero(3.1415)); assertEquals(3, shiftByZero(3.1415));
// Verify that the static type information of x >>> 32 is computed correctly.
function LogicalShiftRightByMultipleOf32(x) {
x = x >>> 32;
return x + x;
}
assertEquals(4589934592, LogicalShiftRightByMultipleOf32(-2000000000));
assertEquals(4589934592, LogicalShiftRightByMultipleOf32(-2000000000));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment