Chromium Code Reviews| Index: src/hydrogen-instructions.cc |
| diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
| index 3b18dab308b220f92fc33713f24249353ab75ef2..94b900227cf7cf5a33e7db48ca9cbdd681666233 100644 |
| --- a/src/hydrogen-instructions.cc |
| +++ b/src/hydrogen-instructions.cc |
| @@ -2310,7 +2310,42 @@ void HMathMinMax::InferRepresentation(HInferRepresentation* h_infer) { |
| Range* HBitwise::InferRange(Zone* zone) { |
| - if (op() == Token::BIT_XOR) return HValue::InferRange(zone); |
| + if (op() == Token::BIT_XOR) { |
| + if (left()->range() != NULL && right()->range() != NULL) { |
|
Sven Panne
2013/06/04 12:15:27
We traditionally use HasRange() for stuff like thi
|
| + // The maximum value has the high bit, and all bits below, set: |
| + // (1 << high) - 1. |
| + // If the range can be negative, the minimum int is a negative number with |
| + // the high bit, and all bits below, unset: |
| + // -(1 << high). |
| + // If it cannot be negative, conservatively choose 0 as minimum int. |
| + int64_t left_upper = left()->range()->upper(); |
| + int64_t left_lower = left()->range()->lower(); |
| + int64_t right_upper = right()->range()->upper(); |
| + int64_t right_lower = right()->range()->lower(); |
| + |
| + // With the same number of bits, 1 lower value can be represented on the |
| + // negative side. Lower the number of required negative bits of log2 |
| + // values by removing this value. |
| + if (left_upper < 0) left_upper = llabs(left_upper + 1); |
| + if (left_lower < 0) left_lower = llabs(left_lower + 1); |
| + if (right_upper < 0) right_upper = llabs(right_upper + 1); |
| + if (right_lower < 0) right_lower = llabs(right_lower + 1); |
| + |
| + // Find the highest used bit. |
| + int high = static_cast<int>(log2(left_upper)); |
| + high = Max(high, static_cast<int>(log2(left_lower))); |
| + high = Max(high, static_cast<int>(log2(right_upper))); |
| + high = Max(high, static_cast<int>(log2(right_lower))); |
| + |
| + int64_t limit = 1; |
| + limit <<= high + 1; |
| + int32_t min = (left()->range()->CanBeNegative() || |
| + right()->range()->CanBeNegative()) |
| + ? static_cast<int32_t>(-limit) : 0; |
| + return new(zone) Range(min, static_cast<int32_t>(limit - 1)); |
| + } |
| + return HValue::InferRange(zone); |
| + } |
| const int32_t kDefaultMask = static_cast<int32_t>(0xffffffff); |
| int32_t left_mask = (left()->range() != NULL) |
| ? left()->range()->Mask() |