Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(121)

Unified Diff: src/compiler/typer.cc

Issue 1121573004: Precise shift right result type derivation for all int32 input ranges. Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Split out the shift-right integer result type derivation. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/typer.h ('k') | test/unittests/compiler/typer-unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/typer.cc
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
index dafd3c95a128f317d0033d1d0b6aeb2e0441f0a2..a0af29f6a6ed1277ac38c36326a5647ee1b22f73 100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -984,38 +984,39 @@ Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) {
}
-Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) {
- lhs = NumberToInt32(ToNumber(lhs, t), t);
- rhs = NumberToUint32(ToNumber(rhs, t), t);
- double min = kMinInt;
- double max = kMaxInt;
- if (lhs->Min() >= 0) {
- // Right-shifting a non-negative value cannot make it negative, nor larger.
- min = std::max(min, 0.0);
- max = std::min(max, lhs->Max());
- if (rhs->Min() > 0 && rhs->Max() <= 31) {
- max = static_cast<int>(max) >> static_cast<int>(rhs->Min());
- }
- }
- if (lhs->Max() < 0) {
- // Right-shifting a negative value cannot make it non-negative, nor smaller.
- min = std::max(min, lhs->Min());
- max = std::min(max, -1.0);
- if (rhs->Min() > 0 && rhs->Max() <= 31) {
- min = static_cast<int>(min) >> static_cast<int>(rhs->Min());
+IntType JSShiftRightIntType(IntType lhs, IntType rhs) {
+ // Canonicalize the shift range to 0 to 31.
+ int32_t shift_min = rhs.min;
+ int32_t shift_max = rhs.max;
+ if ((int64_t(shift_max) - int64_t(shift_min)) >= 31) {
+ shift_min = 0;
+ shift_max = 31;
+ } else {
+ shift_min &= 0x1f;
+ shift_max &= 0x1f;
+ if (shift_min > shift_max) {
+ shift_min = 0;
+ shift_max = 31;
}
}
- if (rhs->Min() > 0 && rhs->Max() <= 31) {
- // Right-shifting by a positive value yields a small integer value.
- double shift_min = kMinInt >> static_cast<int>(rhs->Min());
- double shift_max = kMaxInt >> static_cast<int>(rhs->Min());
- min = std::max(min, shift_min);
- max = std::min(max, shift_max);
- }
+ DCHECK(shift_min >= 0 && shift_max <= 31);
+
+ return IntType(lhs.min < 0 ? lhs.min >> shift_min : lhs.min >> shift_max,
+ lhs.max >= 0 ? lhs.max >> shift_min : lhs.max >> shift_max);
+}
+
+
+Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) {
+ lhs = NumberToInt32(ToNumber(lhs, t), t);
+ rhs = NumberToInt32(ToNumber(rhs, t), t);
+ IntType type = JSShiftRightIntType(IntType(lhs->Min(), lhs->Max()),
+ IntType(rhs->Min(), rhs->Max()));
+
// TODO(jarin) Ideally, the following micro-optimization should be performed
// by the type constructor.
- if (max != Type::Signed32()->Max() || min != Type::Signed32()->Min()) {
- return Type::Range(min, max, t->zone());
+ if (type.max != Type::Signed32()->Max() ||
+ type.min != Type::Signed32()->Min()) {
+ return Type::Range(type.min, type.max, t->zone());
}
return Type::Signed32();
}
« no previous file with comments | « src/compiler/typer.h ('k') | test/unittests/compiler/typer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698