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

Unified Diff: src/compiler/typer.cc

Issue 986073003: [TurboFan] Calculate precise ranges for bitwise-or with positive input ranges. Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 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 | « no previous file | no next file » | 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 c638535727f1c9593c001fb90e9333d2481dd1fa..00692d9581c7cb59efea7ff3b594258d62f07dfc 100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -874,22 +874,96 @@ Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) {
double rmin = rhs->Min();
double lmax = lhs->Max();
double rmax = rhs->Max();
- // Or-ing any two values results in a value no smaller than their minimum.
- // Even no smaller than their maximum if both values are non-negative.
- double min =
- lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin);
- double max = Type::Signed32()->Max();
titzer 2015/03/10 07:47:13 Please add unit tests for the typer and mjsunit te
- // Or-ing with 0 is essentially a conversion to int32.
- if (rmin == 0 && rmax == 0) {
- min = lmin;
- max = lmax;
+ // Or-ing with 0 is essentially a conversion to int32, and or-ing
+ // with -1 returns -1.
+ if (rmin == rmax) {
+ if (rmin == 0) {
+ return Type::Range(lmin, lmax, t->zone());
+ }
+ if (rmin == -1) {
+ return Type::Range(rmin, rmax, t->zone());
+ }
+ }
+ if (lmin == lmax) {
+ if (lmin == 0) {
+ return Type::Range(rmin, rmax, t->zone());
+ }
+ if (lmin == -1) {
+ return Type::Range(lmin, lmax, t->zone());
+ }
}
- if (lmin == 0 && lmax == 0) {
- min = rmin;
- max = rmax;
+
+ if (lmin >= 0 && rmin >= 0) {
+ // Precise calculation of the result range for positive ranges.
+ double min, max;
+ int32_t lmin2, lmax2, rmin2, rmax2, bit, mask;
+
+ // Calculate the result minimum.
+ lmin2 = lmin, lmax2 = lmax, rmin2 = rmin, rmax2 = rmax;
+ bit = 0x40000000, mask = 0x3fffffff;
+ for (; lmin2 != lmax2 || rmin2 != rmax2; bit >>= 1, mask >>= 1) {
+ int32_t lminb = lmin2 & bit;
+ int32_t lmaxb = lmax2 & bit;
+ int32_t rminb = rmin2 & bit;
+ int32_t rmaxb = rmax2 & bit;
+ if (lminb != lmaxb || rminb != rmaxb) {
+ if (lminb == lmaxb) {
+ if (lminb) {
+ rmin2 = (rmin2 & ~mask) | bit;
+ } else {
+ rmax2 = (rmax2 & ~bit) | mask;
+ }
+ } else if (rminb == rmaxb) {
+ if (rminb) {
+ lmin2 = (lmin2 & ~mask) | bit;
+ } else {
+ lmax2 = (lmax2 & ~bit) | mask;
+ }
+ } else {
+ lmax2 = (lmax2 & ~bit) | mask;
+ rmax2 = (rmax2 & ~bit) | mask;
+ }
+ }
+ }
+ min = lmin2 | rmin2;
+
+ // Calculate the result maximum.
+ lmin2 = lmin, lmax2 = lmax, rmin2 = rmin, rmax2 = rmax;
+ bit = 0x40000000, mask = 0x3fffffff;
+ for (; lmin2 != lmax2 || rmin2 != rmax2; bit >>= 1, mask >>= 1) {
+ int32_t lminb = lmin2 & bit;
+ int32_t lmaxb = lmax2 & bit;
+ int32_t rminb = rmin2 & bit;
+ int32_t rmaxb = rmax2 & bit;
+ if (lminb != lmaxb || rminb != rmaxb) {
+ if (lminb == lmaxb) {
+ if (lminb) {
+ rmax2 = (rmax2 & ~bit) | mask;
+ } else {
+ rmin2 = (rmin2 & ~mask) | bit;
+ }
+ } else if (rminb == rmaxb) {
+ if (rminb) {
+ lmax2 = (lmax2 & ~bit) | mask;
+ } else {
+ lmin2 = (lmin2 & ~mask) | bit;
+ }
+ } else {
+ lmax2 = lmax2 | mask;
+ break;
+ }
+ }
+ }
+ max = lmax2 | rmax2;
+
+ return Type::Range(min, max, t->zone());
}
+ // Or-ing any two values results in a value no smaller than their minimum.
+ double min = std::min(lmin, rmin);
+ double max = Type::Signed32()->Max();
+
if (lmax < 0 || rmax < 0) {
// Or-ing two values of which at least one is negative results in a negative
// value.
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698