Index: src/compiler/operation-typer.cc |
diff --git a/src/compiler/operation-typer.cc b/src/compiler/operation-typer.cc |
index c422f0986be6e314296588f66956b5c1dc65804e..dfd4c4b60477cad6b154fcbaeb123d472cc85235 100644 |
--- a/src/compiler/operation-typer.cc |
+++ b/src/compiler/operation-typer.cc |
@@ -864,12 +864,29 @@ Type* OperationTyper::NumberShiftRightLogical(Type* lhs, Type* rhs) { |
DCHECK(lhs->Is(Type::Number())); |
DCHECK(rhs->Is(Type::Number())); |
- if (!lhs->IsInhabited()) return Type::None(); |
+ if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None(); |
lhs = NumberToUint32(lhs); |
+ rhs = NumberToUint32(rhs); |
+ |
+ uint32_t min_lhs = lhs->Min(); |
+ uint32_t max_lhs = lhs->Max(); |
+ uint32_t min_rhs = rhs->Min(); |
+ uint32_t max_rhs = rhs->Max(); |
+ if (max_rhs > 31) { |
+ // rhs can be larger than the bitmask |
+ max_rhs = 31; |
+ min_rhs = 0; |
+ } |
+ |
+ double min = min_lhs >> max_rhs; |
+ double max = max_lhs >> min_rhs; |
+ DCHECK_LE(0, min); |
+ DCHECK_LE(max, kMaxUInt32); |
- // Logical right-shifting any value cannot make it larger. |
- return Type::Range(0.0, lhs->Max(), zone()); |
+ if (min == 0 && max == kMaxInt) return Type::Unsigned31(); |
+ if (min == 0 && max == kMaxUInt32) return Type::Unsigned32(); |
+ return Type::Range(min, max, zone()); |
} |
Type* OperationTyper::NumberAtan2(Type* lhs, Type* rhs) { |