Home | History | Annotate | Download | only in compiler
      1 // Copyright 2016 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/compiler/operation-typer.h"
      6 
      7 #include "src/compiler/common-operator.h"
      8 #include "src/compiler/type-cache.h"
      9 #include "src/compiler/types.h"
     10 #include "src/factory.h"
     11 #include "src/isolate.h"
     12 
     13 #include "src/objects-inl.h"
     14 
     15 namespace v8 {
     16 namespace internal {
     17 namespace compiler {
     18 
     19 OperationTyper::OperationTyper(Isolate* isolate, Zone* zone)
     20     : zone_(zone), cache_(TypeCache::Get()) {
     21   Factory* factory = isolate->factory();
     22   infinity_ = Type::NewConstant(factory->infinity_value(), zone);
     23   minus_infinity_ = Type::NewConstant(factory->minus_infinity_value(), zone);
     24   Type* truncating_to_zero = Type::MinusZeroOrNaN();
     25   DCHECK(!truncating_to_zero->Maybe(Type::Integral32()));
     26 
     27   singleton_false_ = Type::HeapConstant(factory->false_value(), zone);
     28   singleton_true_ = Type::HeapConstant(factory->true_value(), zone);
     29   singleton_the_hole_ = Type::HeapConstant(factory->the_hole_value(), zone);
     30   signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone);
     31   unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone);
     32 }
     33 
     34 Type* OperationTyper::Merge(Type* left, Type* right) {
     35   return Type::Union(left, right, zone());
     36 }
     37 
     38 Type* OperationTyper::WeakenRange(Type* previous_range, Type* current_range) {
     39   static const double kWeakenMinLimits[] = {0.0,
     40                                             -1073741824.0,
     41                                             -2147483648.0,
     42                                             -4294967296.0,
     43                                             -8589934592.0,
     44                                             -17179869184.0,
     45                                             -34359738368.0,
     46                                             -68719476736.0,
     47                                             -137438953472.0,
     48                                             -274877906944.0,
     49                                             -549755813888.0,
     50                                             -1099511627776.0,
     51                                             -2199023255552.0,
     52                                             -4398046511104.0,
     53                                             -8796093022208.0,
     54                                             -17592186044416.0,
     55                                             -35184372088832.0,
     56                                             -70368744177664.0,
     57                                             -140737488355328.0,
     58                                             -281474976710656.0,
     59                                             -562949953421312.0};
     60   static const double kWeakenMaxLimits[] = {0.0,
     61                                             1073741823.0,
     62                                             2147483647.0,
     63                                             4294967295.0,
     64                                             8589934591.0,
     65                                             17179869183.0,
     66                                             34359738367.0,
     67                                             68719476735.0,
     68                                             137438953471.0,
     69                                             274877906943.0,
     70                                             549755813887.0,
     71                                             1099511627775.0,
     72                                             2199023255551.0,
     73                                             4398046511103.0,
     74                                             8796093022207.0,
     75                                             17592186044415.0,
     76                                             35184372088831.0,
     77                                             70368744177663.0,
     78                                             140737488355327.0,
     79                                             281474976710655.0,
     80                                             562949953421311.0};
     81   STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits));
     82 
     83   double current_min = current_range->Min();
     84   double new_min = current_min;
     85   // Find the closest lower entry in the list of allowed
     86   // minima (or negative infinity if there is no such entry).
     87   if (current_min != previous_range->Min()) {
     88     new_min = -V8_INFINITY;
     89     for (double const min : kWeakenMinLimits) {
     90       if (min <= current_min) {
     91         new_min = min;
     92         break;
     93       }
     94     }
     95   }
     96 
     97   double current_max = current_range->Max();
     98   double new_max = current_max;
     99   // Find the closest greater entry in the list of allowed
    100   // maxima (or infinity if there is no such entry).
    101   if (current_max != previous_range->Max()) {
    102     new_max = V8_INFINITY;
    103     for (double const max : kWeakenMaxLimits) {
    104       if (max >= current_max) {
    105         new_max = max;
    106         break;
    107       }
    108     }
    109   }
    110 
    111   return Type::Range(new_min, new_max, zone());
    112 }
    113 
    114 Type* OperationTyper::Rangify(Type* type) {
    115   if (type->IsRange()) return type;  // Shortcut.
    116   if (!type->Is(cache_.kInteger)) {
    117     return type;  // Give up on non-integer types.
    118   }
    119   double min = type->Min();
    120   double max = type->Max();
    121   // Handle the degenerate case of empty bitset types (such as
    122   // OtherUnsigned31 and OtherSigned32 on 64-bit architectures).
    123   if (std::isnan(min)) {
    124     DCHECK(std::isnan(max));
    125     return type;
    126   }
    127   return Type::Range(min, max, zone());
    128 }
    129 
    130 namespace {
    131 
    132 // Returns the array's least element, ignoring NaN.
    133 // There must be at least one non-NaN element.
    134 // Any -0 is converted to 0.
    135 double array_min(double a[], size_t n) {
    136   DCHECK(n != 0);
    137   double x = +V8_INFINITY;
    138   for (size_t i = 0; i < n; ++i) {
    139     if (!std::isnan(a[i])) {
    140       x = std::min(a[i], x);
    141     }
    142   }
    143   DCHECK(!std::isnan(x));
    144   return x == 0 ? 0 : x;  // -0 -> 0
    145 }
    146 
    147 // Returns the array's greatest element, ignoring NaN.
    148 // There must be at least one non-NaN element.
    149 // Any -0 is converted to 0.
    150 double array_max(double a[], size_t n) {
    151   DCHECK(n != 0);
    152   double x = -V8_INFINITY;
    153   for (size_t i = 0; i < n; ++i) {
    154     if (!std::isnan(a[i])) {
    155       x = std::max(a[i], x);
    156     }
    157   }
    158   DCHECK(!std::isnan(x));
    159   return x == 0 ? 0 : x;  // -0 -> 0
    160 }
    161 
    162 }  // namespace
    163 
    164 Type* OperationTyper::AddRanger(double lhs_min, double lhs_max, double rhs_min,
    165                                 double rhs_max) {
    166   double results[4];
    167   results[0] = lhs_min + rhs_min;
    168   results[1] = lhs_min + rhs_max;
    169   results[2] = lhs_max + rhs_min;
    170   results[3] = lhs_max + rhs_max;
    171   // Since none of the inputs can be -0, the result cannot be -0 either.
    172   // However, it can be nan (the sum of two infinities of opposite sign).
    173   // On the other hand, if none of the "results" above is nan, then the
    174   // actual result cannot be nan either.
    175   int nans = 0;
    176   for (int i = 0; i < 4; ++i) {
    177     if (std::isnan(results[i])) ++nans;
    178   }
    179   if (nans == 4) return Type::NaN();
    180   Type* type =
    181       Type::Range(array_min(results, 4), array_max(results, 4), zone());
    182   if (nans > 0) type = Type::Union(type, Type::NaN(), zone());
    183   // Examples:
    184   //   [-inf, -inf] + [+inf, +inf] = NaN
    185   //   [-inf, -inf] + [n, +inf] = [-inf, -inf] \/ NaN
    186   //   [-inf, +inf] + [n, +inf] = [-inf, +inf] \/ NaN
    187   //   [-inf, m] + [n, +inf] = [-inf, +inf] \/ NaN
    188   return type;
    189 }
    190 
    191 Type* OperationTyper::SubtractRanger(double lhs_min, double lhs_max,
    192                                      double rhs_min, double rhs_max) {
    193   double results[4];
    194   results[0] = lhs_min - rhs_min;
    195   results[1] = lhs_min - rhs_max;
    196   results[2] = lhs_max - rhs_min;
    197   results[3] = lhs_max - rhs_max;
    198   // Since none of the inputs can be -0, the result cannot be -0.
    199   // However, it can be nan (the subtraction of two infinities of same sign).
    200   // On the other hand, if none of the "results" above is nan, then the actual
    201   // result cannot be nan either.
    202   int nans = 0;
    203   for (int i = 0; i < 4; ++i) {
    204     if (std::isnan(results[i])) ++nans;
    205   }
    206   if (nans == 4) return Type::NaN();  // [inf..inf] - [inf..inf] (all same sign)
    207   Type* type =
    208       Type::Range(array_min(results, 4), array_max(results, 4), zone());
    209   return nans == 0 ? type : Type::Union(type, Type::NaN(), zone());
    210   // Examples:
    211   //   [-inf, +inf] - [-inf, +inf] = [-inf, +inf] \/ NaN
    212   //   [-inf, -inf] - [-inf, -inf] = NaN
    213   //   [-inf, -inf] - [n, +inf] = [-inf, -inf] \/ NaN
    214   //   [m, +inf] - [-inf, n] = [-inf, +inf] \/ NaN
    215 }
    216 
    217 Type* OperationTyper::MultiplyRanger(Type* lhs, Type* rhs) {
    218   double results[4];
    219   double lmin = lhs->AsRange()->Min();
    220   double lmax = lhs->AsRange()->Max();
    221   double rmin = rhs->AsRange()->Min();
    222   double rmax = rhs->AsRange()->Max();
    223   results[0] = lmin * rmin;
    224   results[1] = lmin * rmax;
    225   results[2] = lmax * rmin;
    226   results[3] = lmax * rmax;
    227   // If the result may be nan, we give up on calculating a precise type, because
    228   // the discontinuity makes it too complicated.  Note that even if none of the
    229   // "results" above is nan, the actual result may still be, so we have to do a
    230   // different check:
    231   bool maybe_nan = (lhs->Maybe(cache_.kSingletonZero) &&
    232                     (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) ||
    233                    (rhs->Maybe(cache_.kSingletonZero) &&
    234                     (lmin == -V8_INFINITY || lmax == +V8_INFINITY));
    235   if (maybe_nan) return cache_.kIntegerOrMinusZeroOrNaN;  // Giving up.
    236   bool maybe_minuszero = (lhs->Maybe(cache_.kSingletonZero) && rmin < 0) ||
    237                          (rhs->Maybe(cache_.kSingletonZero) && lmin < 0);
    238   Type* range =
    239       Type::Range(array_min(results, 4), array_max(results, 4), zone());
    240   return maybe_minuszero ? Type::Union(range, Type::MinusZero(), zone())
    241                          : range;
    242 }
    243 
    244 Type* OperationTyper::ToNumber(Type* type) {
    245   if (type->Is(Type::Number())) return type;
    246   if (type->Is(Type::NullOrUndefined())) {
    247     if (type->Is(Type::Null())) return cache_.kSingletonZero;
    248     if (type->Is(Type::Undefined())) return Type::NaN();
    249     return Type::Union(Type::NaN(), cache_.kSingletonZero, zone());
    250   }
    251   if (type->Is(Type::Boolean())) {
    252     if (type->Is(singleton_false_)) return cache_.kSingletonZero;
    253     if (type->Is(singleton_true_)) return cache_.kSingletonOne;
    254     return cache_.kZeroOrOne;
    255   }
    256   if (type->Is(Type::NumberOrOddball())) {
    257     if (type->Is(Type::NumberOrUndefined())) {
    258       type = Type::Union(type, Type::NaN(), zone());
    259     } else if (type->Is(Type::NullOrNumber())) {
    260       type = Type::Union(type, cache_.kSingletonZero, zone());
    261     } else if (type->Is(Type::BooleanOrNullOrNumber())) {
    262       type = Type::Union(type, cache_.kZeroOrOne, zone());
    263     } else {
    264       type = Type::Union(type, cache_.kZeroOrOneOrNaN, zone());
    265     }
    266     return Type::Intersect(type, Type::Number(), zone());
    267   }
    268   return Type::Number();
    269 }
    270 
    271 Type* OperationTyper::NumberAbs(Type* type) {
    272   DCHECK(type->Is(Type::Number()));
    273 
    274   if (!type->IsInhabited()) {
    275     return Type::None();
    276   }
    277 
    278   bool const maybe_nan = type->Maybe(Type::NaN());
    279   bool const maybe_minuszero = type->Maybe(Type::MinusZero());
    280   type = Type::Intersect(type, Type::PlainNumber(), zone());
    281   double const max = type->Max();
    282   double const min = type->Min();
    283   if (min < 0) {
    284     if (type->Is(cache_.kInteger)) {
    285       type = Type::Range(0.0, std::max(std::fabs(min), std::fabs(max)), zone());
    286     } else {
    287       type = Type::PlainNumber();
    288     }
    289   }
    290   if (maybe_minuszero) {
    291     type = Type::Union(type, cache_.kSingletonZero, zone());
    292   }
    293   if (maybe_nan) {
    294     type = Type::Union(type, Type::NaN(), zone());
    295   }
    296   return type;
    297 }
    298 
    299 Type* OperationTyper::NumberAcos(Type* type) {
    300   DCHECK(type->Is(Type::Number()));
    301   return Type::Number();
    302 }
    303 
    304 Type* OperationTyper::NumberAcosh(Type* type) {
    305   DCHECK(type->Is(Type::Number()));
    306   return Type::Number();
    307 }
    308 
    309 Type* OperationTyper::NumberAsin(Type* type) {
    310   DCHECK(type->Is(Type::Number()));
    311   return Type::Number();
    312 }
    313 
    314 Type* OperationTyper::NumberAsinh(Type* type) {
    315   DCHECK(type->Is(Type::Number()));
    316   return Type::Number();
    317 }
    318 
    319 Type* OperationTyper::NumberAtan(Type* type) {
    320   DCHECK(type->Is(Type::Number()));
    321   return Type::Number();
    322 }
    323 
    324 Type* OperationTyper::NumberAtanh(Type* type) {
    325   DCHECK(type->Is(Type::Number()));
    326   return Type::Number();
    327 }
    328 
    329 Type* OperationTyper::NumberCbrt(Type* type) {
    330   DCHECK(type->Is(Type::Number()));
    331   return Type::Number();
    332 }
    333 
    334 Type* OperationTyper::NumberCeil(Type* type) {
    335   DCHECK(type->Is(Type::Number()));
    336   if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type;
    337   // TODO(bmeurer): We could infer a more precise type here.
    338   return cache_.kIntegerOrMinusZeroOrNaN;
    339 }
    340 
    341 Type* OperationTyper::NumberClz32(Type* type) {
    342   DCHECK(type->Is(Type::Number()));
    343   return cache_.kZeroToThirtyTwo;
    344 }
    345 
    346 Type* OperationTyper::NumberCos(Type* type) {
    347   DCHECK(type->Is(Type::Number()));
    348   return Type::Number();
    349 }
    350 
    351 Type* OperationTyper::NumberCosh(Type* type) {
    352   DCHECK(type->Is(Type::Number()));
    353   return Type::Number();
    354 }
    355 
    356 Type* OperationTyper::NumberExp(Type* type) {
    357   DCHECK(type->Is(Type::Number()));
    358   return Type::Union(Type::PlainNumber(), Type::NaN(), zone());
    359 }
    360 
    361 Type* OperationTyper::NumberExpm1(Type* type) {
    362   DCHECK(type->Is(Type::Number()));
    363   return Type::Union(Type::PlainNumber(), Type::NaN(), zone());
    364 }
    365 
    366 Type* OperationTyper::NumberFloor(Type* type) {
    367   DCHECK(type->Is(Type::Number()));
    368   if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type;
    369   // TODO(bmeurer): We could infer a more precise type here.
    370   return cache_.kIntegerOrMinusZeroOrNaN;
    371 }
    372 
    373 Type* OperationTyper::NumberFround(Type* type) {
    374   DCHECK(type->Is(Type::Number()));
    375   return Type::Number();
    376 }
    377 
    378 Type* OperationTyper::NumberLog(Type* type) {
    379   DCHECK(type->Is(Type::Number()));
    380   return Type::Number();
    381 }
    382 
    383 Type* OperationTyper::NumberLog1p(Type* type) {
    384   DCHECK(type->Is(Type::Number()));
    385   return Type::Number();
    386 }
    387 
    388 Type* OperationTyper::NumberLog2(Type* type) {
    389   DCHECK(type->Is(Type::Number()));
    390   return Type::Number();
    391 }
    392 
    393 Type* OperationTyper::NumberLog10(Type* type) {
    394   DCHECK(type->Is(Type::Number()));
    395   return Type::Number();
    396 }
    397 
    398 Type* OperationTyper::NumberRound(Type* type) {
    399   DCHECK(type->Is(Type::Number()));
    400   if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type;
    401   // TODO(bmeurer): We could infer a more precise type here.
    402   return cache_.kIntegerOrMinusZeroOrNaN;
    403 }
    404 
    405 Type* OperationTyper::NumberSign(Type* type) {
    406   DCHECK(type->Is(Type::Number()));
    407   if (type->Is(cache_.kZeroish)) return type;
    408   bool maybe_minuszero = type->Maybe(Type::MinusZero());
    409   bool maybe_nan = type->Maybe(Type::NaN());
    410   type = Type::Intersect(type, Type::PlainNumber(), zone());
    411   if (type->Max() < 0.0) {
    412     type = cache_.kSingletonMinusOne;
    413   } else if (type->Max() <= 0.0) {
    414     type = cache_.kMinusOneOrZero;
    415   } else if (type->Min() > 0.0) {
    416     type = cache_.kSingletonOne;
    417   } else if (type->Min() >= 0.0) {
    418     type = cache_.kZeroOrOne;
    419   } else {
    420     type = Type::Range(-1.0, 1.0, zone());
    421   }
    422   if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone());
    423   if (maybe_nan) type = Type::Union(type, Type::NaN(), zone());
    424   return type;
    425 }
    426 
    427 Type* OperationTyper::NumberSin(Type* type) {
    428   DCHECK(type->Is(Type::Number()));
    429   return Type::Number();
    430 }
    431 
    432 Type* OperationTyper::NumberSinh(Type* type) {
    433   DCHECK(type->Is(Type::Number()));
    434   return Type::Number();
    435 }
    436 
    437 Type* OperationTyper::NumberSqrt(Type* type) {
    438   DCHECK(type->Is(Type::Number()));
    439   return Type::Number();
    440 }
    441 
    442 Type* OperationTyper::NumberTan(Type* type) {
    443   DCHECK(type->Is(Type::Number()));
    444   return Type::Number();
    445 }
    446 
    447 Type* OperationTyper::NumberTanh(Type* type) {
    448   DCHECK(type->Is(Type::Number()));
    449   return Type::Number();
    450 }
    451 
    452 Type* OperationTyper::NumberTrunc(Type* type) {
    453   DCHECK(type->Is(Type::Number()));
    454   if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type;
    455   // TODO(bmeurer): We could infer a more precise type here.
    456   return cache_.kIntegerOrMinusZeroOrNaN;
    457 }
    458 
    459 Type* OperationTyper::NumberToBoolean(Type* type) {
    460   DCHECK(type->Is(Type::Number()));
    461   if (!type->IsInhabited()) return Type::None();
    462   if (type->Is(cache_.kZeroish)) return singleton_false_;
    463   if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) {
    464     return singleton_true_;  // Ruled out nan, -0 and +0.
    465   }
    466   return Type::Boolean();
    467 }
    468 
    469 Type* OperationTyper::NumberToInt32(Type* type) {
    470   DCHECK(type->Is(Type::Number()));
    471 
    472   if (type->Is(Type::Signed32())) return type;
    473   if (type->Is(cache_.kZeroish)) return cache_.kSingletonZero;
    474   if (type->Is(signed32ish_)) {
    475     return Type::Intersect(Type::Union(type, cache_.kSingletonZero, zone()),
    476                            Type::Signed32(), zone());
    477   }
    478   return Type::Signed32();
    479 }
    480 
    481 Type* OperationTyper::NumberToUint32(Type* type) {
    482   DCHECK(type->Is(Type::Number()));
    483 
    484   if (type->Is(Type::Unsigned32())) return type;
    485   if (type->Is(cache_.kZeroish)) return cache_.kSingletonZero;
    486   if (type->Is(unsigned32ish_)) {
    487     return Type::Intersect(Type::Union(type, cache_.kSingletonZero, zone()),
    488                            Type::Unsigned32(), zone());
    489   }
    490   return Type::Unsigned32();
    491 }
    492 
    493 Type* OperationTyper::NumberToUint8Clamped(Type* type) {
    494   DCHECK(type->Is(Type::Number()));
    495 
    496   if (type->Is(cache_.kUint8)) return type;
    497   return cache_.kUint8;
    498 }
    499 
    500 Type* OperationTyper::NumberSilenceNaN(Type* type) {
    501   DCHECK(type->Is(Type::Number()));
    502   // TODO(jarin): This is a terrible hack; we definitely need a dedicated type
    503   // for the hole (tagged and/or double). Otherwise if the input is the hole
    504   // NaN constant, we'd just eliminate this node in JSTypedLowering.
    505   if (type->Maybe(Type::NaN())) return Type::Number();
    506   return type;
    507 }
    508 
    509 Type* OperationTyper::NumberAdd(Type* lhs, Type* rhs) {
    510   DCHECK(lhs->Is(Type::Number()));
    511   DCHECK(rhs->Is(Type::Number()));
    512 
    513   if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
    514     return Type::None();
    515   }
    516 
    517   // Addition can return NaN if either input can be NaN or we try to compute
    518   // the sum of two infinities of opposite sign.
    519   bool maybe_nan = lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN());
    520 
    521   // Addition can yield minus zero only if both inputs can be minus zero.
    522   bool maybe_minuszero = true;
    523   if (lhs->Maybe(Type::MinusZero())) {
    524     lhs = Type::Union(lhs, cache_.kSingletonZero, zone());
    525   } else {
    526     maybe_minuszero = false;
    527   }
    528   if (rhs->Maybe(Type::MinusZero())) {
    529     rhs = Type::Union(rhs, cache_.kSingletonZero, zone());
    530   } else {
    531     maybe_minuszero = false;
    532   }
    533 
    534   // We can give more precise types for integers.
    535   Type* type = Type::None();
    536   lhs = Type::Intersect(lhs, Type::PlainNumber(), zone());
    537   rhs = Type::Intersect(rhs, Type::PlainNumber(), zone());
    538   if (lhs->IsInhabited() && rhs->IsInhabited()) {
    539     if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) {
    540       type = AddRanger(lhs->Min(), lhs->Max(), rhs->Min(), rhs->Max());
    541     } else {
    542       if ((lhs->Maybe(minus_infinity_) && rhs->Maybe(infinity_)) ||
    543           (rhs->Maybe(minus_infinity_) && lhs->Maybe(infinity_))) {
    544         maybe_nan = true;
    545       }
    546       type = Type::PlainNumber();
    547     }
    548   }
    549 
    550   // Take into account the -0 and NaN information computed earlier.
    551   if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone());
    552   if (maybe_nan) type = Type::Union(type, Type::NaN(), zone());
    553   return type;
    554 }
    555 
    556 Type* OperationTyper::NumberSubtract(Type* lhs, Type* rhs) {
    557   DCHECK(lhs->Is(Type::Number()));
    558   DCHECK(rhs->Is(Type::Number()));
    559 
    560   if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
    561     return Type::None();
    562   }
    563 
    564   // Subtraction can return NaN if either input can be NaN or we try to
    565   // compute the sum of two infinities of opposite sign.
    566   bool maybe_nan = lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN());
    567 
    568   // Subtraction can yield minus zero if {lhs} can be minus zero and {rhs}
    569   // can be zero.
    570   bool maybe_minuszero = false;
    571   if (lhs->Maybe(Type::MinusZero())) {
    572     lhs = Type::Union(lhs, cache_.kSingletonZero, zone());
    573     maybe_minuszero = rhs->Maybe(cache_.kSingletonZero);
    574   }
    575   if (rhs->Maybe(Type::MinusZero())) {
    576     rhs = Type::Union(rhs, cache_.kSingletonZero, zone());
    577   }
    578 
    579   // We can give more precise types for integers.
    580   Type* type = Type::None();
    581   lhs = Type::Intersect(lhs, Type::PlainNumber(), zone());
    582   rhs = Type::Intersect(rhs, Type::PlainNumber(), zone());
    583   if (lhs->IsInhabited() && rhs->IsInhabited()) {
    584     if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) {
    585       type = SubtractRanger(lhs->Min(), lhs->Max(), rhs->Min(), rhs->Max());
    586     } else {
    587       if ((lhs->Maybe(infinity_) && rhs->Maybe(infinity_)) ||
    588           (rhs->Maybe(minus_infinity_) && lhs->Maybe(minus_infinity_))) {
    589         maybe_nan = true;
    590       }
    591       type = Type::PlainNumber();
    592     }
    593   }
    594 
    595   // Take into account the -0 and NaN information computed earlier.
    596   if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone());
    597   if (maybe_nan) type = Type::Union(type, Type::NaN(), zone());
    598   return type;
    599 }
    600 
    601 Type* OperationTyper::NumberMultiply(Type* lhs, Type* rhs) {
    602   DCHECK(lhs->Is(Type::Number()));
    603   DCHECK(rhs->Is(Type::Number()));
    604 
    605   if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
    606     return Type::None();
    607   }
    608 
    609   lhs = Rangify(lhs);
    610   rhs = Rangify(rhs);
    611   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
    612   if (lhs->IsRange() && rhs->IsRange()) {
    613     return MultiplyRanger(lhs, rhs);
    614   }
    615   return Type::Number();
    616 }
    617 
    618 Type* OperationTyper::NumberDivide(Type* lhs, Type* rhs) {
    619   DCHECK(lhs->Is(Type::Number()));
    620   DCHECK(rhs->Is(Type::Number()));
    621 
    622   if (!lhs->IsInhabited() || !rhs->IsInhabited()) {
    623     return Type::None();
    624   }
    625 
    626   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
    627   // Division is tricky, so all we do is try ruling out nan.
    628   bool maybe_nan =
    629       lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) ||
    630       ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
    631        (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
    632   return maybe_nan ? Type::Number() : Type::OrderedNumber();
    633 }
    634 
    635 Type* OperationTyper::NumberModulus(Type* lhs, Type* rhs) {
    636   DCHECK(lhs->Is(Type::Number()));
    637   DCHECK(rhs->Is(Type::Number()));
    638 
    639   // Modulus can yield NaN if either {lhs} or {rhs} are NaN, or
    640   // {lhs} is not finite, or the {rhs} is a zero value.
    641   bool maybe_nan = lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) ||
    642                    lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY;
    643 
    644   // Deal with -0 inputs, only the signbit of {lhs} matters for the result.
    645   bool maybe_minuszero = false;
    646   if (lhs->Maybe(Type::MinusZero())) {
    647     maybe_minuszero = true;
    648     lhs = Type::Union(lhs, cache_.kSingletonZero, zone());
    649   }
    650   if (rhs->Maybe(Type::MinusZero())) {
    651     rhs = Type::Union(rhs, cache_.kSingletonZero, zone());
    652   }
    653 
    654   // Rule out NaN and -0, and check what we can do with the remaining type info.
    655   Type* type = Type::None();
    656   lhs = Type::Intersect(lhs, Type::PlainNumber(), zone());
    657   rhs = Type::Intersect(rhs, Type::PlainNumber(), zone());
    658 
    659   // We can only derive a meaningful type if both {lhs} and {rhs} are inhabited,
    660   // and the {rhs} is not 0, otherwise the result is NaN independent of {lhs}.
    661   if (lhs->IsInhabited() && !rhs->Is(cache_.kSingletonZero)) {
    662     // Determine the bounds of {lhs} and {rhs}.
    663     double const lmin = lhs->Min();
    664     double const lmax = lhs->Max();
    665     double const rmin = rhs->Min();
    666     double const rmax = rhs->Max();
    667 
    668     // The sign of the result is the sign of the {lhs}.
    669     if (lmin < 0.0) maybe_minuszero = true;
    670 
    671     // For integer inputs {lhs} and {rhs} we can infer a precise type.
    672     if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) {
    673       double labs = std::max(std::abs(lmin), std::abs(lmax));
    674       double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1;
    675       double abs = std::min(labs, rabs);
    676       double min = 0.0, max = 0.0;
    677       if (lmin >= 0.0) {
    678         // {lhs} positive.
    679         min = 0.0;
    680         max = abs;
    681       } else if (lmax <= 0.0) {
    682         // {lhs} negative.
    683         min = 0.0 - abs;
    684         max = 0.0;
    685       } else {
    686         // {lhs} positive or negative.
    687         min = 0.0 - abs;
    688         max = abs;
    689       }
    690       type = Type::Range(min, max, zone());
    691     } else {
    692       type = Type::PlainNumber();
    693     }
    694   }
    695 
    696   // Take into account the -0 and NaN information computed earlier.
    697   if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone());
    698   if (maybe_nan) type = Type::Union(type, Type::NaN(), zone());
    699   return type;
    700 }
    701 
    702 Type* OperationTyper::NumberBitwiseOr(Type* lhs, Type* rhs) {
    703   DCHECK(lhs->Is(Type::Number()));
    704   DCHECK(rhs->Is(Type::Number()));
    705 
    706   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
    707 
    708   lhs = NumberToInt32(lhs);
    709   rhs = NumberToInt32(rhs);
    710 
    711   double lmin = lhs->Min();
    712   double rmin = rhs->Min();
    713   double lmax = lhs->Max();
    714   double rmax = rhs->Max();
    715   // Or-ing any two values results in a value no smaller than their minimum.
    716   // Even no smaller than their maximum if both values are non-negative.
    717   double min =
    718       lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin);
    719   double max = kMaxInt;
    720 
    721   // Or-ing with 0 is essentially a conversion to int32.
    722   if (rmin == 0 && rmax == 0) {
    723     min = lmin;
    724     max = lmax;
    725   }
    726   if (lmin == 0 && lmax == 0) {
    727     min = rmin;
    728     max = rmax;
    729   }
    730 
    731   if (lmax < 0 || rmax < 0) {
    732     // Or-ing two values of which at least one is negative results in a negative
    733     // value.
    734     max = std::min(max, -1.0);
    735   }
    736   return Type::Range(min, max, zone());
    737 }
    738 
    739 Type* OperationTyper::NumberBitwiseAnd(Type* lhs, Type* rhs) {
    740   DCHECK(lhs->Is(Type::Number()));
    741   DCHECK(rhs->Is(Type::Number()));
    742 
    743   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
    744 
    745   lhs = NumberToInt32(lhs);
    746   rhs = NumberToInt32(rhs);
    747 
    748   double lmin = lhs->Min();
    749   double rmin = rhs->Min();
    750   double lmax = lhs->Max();
    751   double rmax = rhs->Max();
    752   double min = kMinInt;
    753   // And-ing any two values results in a value no larger than their maximum.
    754   // Even no larger than their minimum if both values are non-negative.
    755   double max =
    756       lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax);
    757   // And-ing with a non-negative value x causes the result to be between
    758   // zero and x.
    759   if (lmin >= 0) {
    760     min = 0;
    761     max = std::min(max, lmax);
    762   }
    763   if (rmin >= 0) {
    764     min = 0;
    765     max = std::min(max, rmax);
    766   }
    767   return Type::Range(min, max, zone());
    768 }
    769 
    770 Type* OperationTyper::NumberBitwiseXor(Type* lhs, Type* rhs) {
    771   DCHECK(lhs->Is(Type::Number()));
    772   DCHECK(rhs->Is(Type::Number()));
    773 
    774   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
    775 
    776   lhs = NumberToInt32(lhs);
    777   rhs = NumberToInt32(rhs);
    778 
    779   double lmin = lhs->Min();
    780   double rmin = rhs->Min();
    781   double lmax = lhs->Max();
    782   double rmax = rhs->Max();
    783   if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) {
    784     // Xor-ing negative or non-negative values results in a non-negative value.
    785     return Type::Unsigned31();
    786   }
    787   if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) {
    788     // Xor-ing a negative and a non-negative value results in a negative value.
    789     // TODO(jarin) Use a range here.
    790     return Type::Negative32();
    791   }
    792   return Type::Signed32();
    793 }
    794 
    795 Type* OperationTyper::NumberShiftLeft(Type* lhs, Type* rhs) {
    796   DCHECK(lhs->Is(Type::Number()));
    797   DCHECK(rhs->Is(Type::Number()));
    798 
    799   // TODO(turbofan): Infer a better type here.
    800   return Type::Signed32();
    801 }
    802 
    803 Type* OperationTyper::NumberShiftRight(Type* lhs, Type* rhs) {
    804   DCHECK(lhs->Is(Type::Number()));
    805   DCHECK(rhs->Is(Type::Number()));
    806 
    807   if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None();
    808 
    809   lhs = NumberToInt32(lhs);
    810   rhs = NumberToUint32(rhs);
    811 
    812   double min = kMinInt;
    813   double max = kMaxInt;
    814   if (lhs->Min() >= 0) {
    815     // Right-shifting a non-negative value cannot make it negative, nor larger.
    816     min = std::max(min, 0.0);
    817     max = std::min(max, lhs->Max());
    818     if (rhs->Min() > 0 && rhs->Max() <= 31) {
    819       max = static_cast<int>(max) >> static_cast<int>(rhs->Min());
    820     }
    821   }
    822   if (lhs->Max() < 0) {
    823     // Right-shifting a negative value cannot make it non-negative, nor smaller.
    824     min = std::max(min, lhs->Min());
    825     max = std::min(max, -1.0);
    826     if (rhs->Min() > 0 && rhs->Max() <= 31) {
    827       min = static_cast<int>(min) >> static_cast<int>(rhs->Min());
    828     }
    829   }
    830   if (rhs->Min() > 0 && rhs->Max() <= 31) {
    831     // Right-shifting by a positive value yields a small integer value.
    832     double shift_min = kMinInt >> static_cast<int>(rhs->Min());
    833     double shift_max = kMaxInt >> static_cast<int>(rhs->Min());
    834     min = std::max(min, shift_min);
    835     max = std::min(max, shift_max);
    836   }
    837   // TODO(jarin) Ideally, the following micro-optimization should be performed
    838   // by the type constructor.
    839   if (max == kMaxInt && min == kMinInt) return Type::Signed32();
    840   return Type::Range(min, max, zone());
    841 }
    842 
    843 Type* OperationTyper::NumberShiftRightLogical(Type* lhs, Type* rhs) {
    844   DCHECK(lhs->Is(Type::Number()));
    845   DCHECK(rhs->Is(Type::Number()));
    846 
    847   if (!lhs->IsInhabited()) return Type::None();
    848 
    849   lhs = NumberToUint32(lhs);
    850 
    851   // Logical right-shifting any value cannot make it larger.
    852   return Type::Range(0.0, lhs->Max(), zone());
    853 }
    854 
    855 Type* OperationTyper::NumberAtan2(Type* lhs, Type* rhs) {
    856   DCHECK(lhs->Is(Type::Number()));
    857   DCHECK(rhs->Is(Type::Number()));
    858   return Type::Number();
    859 }
    860 
    861 Type* OperationTyper::NumberImul(Type* lhs, Type* rhs) {
    862   DCHECK(lhs->Is(Type::Number()));
    863   DCHECK(rhs->Is(Type::Number()));
    864   // TODO(turbofan): We should be able to do better here.
    865   return Type::Signed32();
    866 }
    867 
    868 Type* OperationTyper::NumberMax(Type* lhs, Type* rhs) {
    869   DCHECK(lhs->Is(Type::Number()));
    870   DCHECK(rhs->Is(Type::Number()));
    871   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) {
    872     return Type::NaN();
    873   }
    874   Type* type = Type::None();
    875   // TODO(turbofan): Improve minus zero handling here.
    876   if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
    877     type = Type::Union(type, Type::NaN(), zone());
    878   }
    879   lhs = Type::Intersect(lhs, Type::OrderedNumber(), zone());
    880   rhs = Type::Intersect(rhs, Type::OrderedNumber(), zone());
    881   if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) {
    882     double max = std::max(lhs->Max(), rhs->Max());
    883     double min = std::max(lhs->Min(), rhs->Min());
    884     type = Type::Union(type, Type::Range(min, max, zone()), zone());
    885   } else {
    886     type = Type::Union(type, Type::Union(lhs, rhs, zone()), zone());
    887   }
    888   return type;
    889 }
    890 
    891 Type* OperationTyper::NumberMin(Type* lhs, Type* rhs) {
    892   DCHECK(lhs->Is(Type::Number()));
    893   DCHECK(rhs->Is(Type::Number()));
    894   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) {
    895     return Type::NaN();
    896   }
    897   Type* type = Type::None();
    898   // TODO(turbofan): Improve minus zero handling here.
    899   if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
    900     type = Type::Union(type, Type::NaN(), zone());
    901   }
    902   lhs = Type::Intersect(lhs, Type::OrderedNumber(), zone());
    903   rhs = Type::Intersect(rhs, Type::OrderedNumber(), zone());
    904   if (lhs->Is(cache_.kInteger) && rhs->Is(cache_.kInteger)) {
    905     double max = std::min(lhs->Max(), rhs->Max());
    906     double min = std::min(lhs->Min(), rhs->Min());
    907     type = Type::Union(type, Type::Range(min, max, zone()), zone());
    908   } else {
    909     type = Type::Union(type, Type::Union(lhs, rhs, zone()), zone());
    910   }
    911   return type;
    912 }
    913 
    914 Type* OperationTyper::NumberPow(Type* lhs, Type* rhs) {
    915   DCHECK(lhs->Is(Type::Number()));
    916   DCHECK(rhs->Is(Type::Number()));
    917   // TODO(turbofan): We should be able to do better here.
    918   return Type::Number();
    919 }
    920 
    921 #define SPECULATIVE_NUMBER_BINOP(Name)                                     \
    922   Type* OperationTyper::Speculative##Name(Type* lhs, Type* rhs) {          \
    923     lhs = ToNumber(Type::Intersect(lhs, Type::NumberOrOddball(), zone())); \
    924     rhs = ToNumber(Type::Intersect(rhs, Type::NumberOrOddball(), zone())); \
    925     return Name(lhs, rhs);                                                 \
    926   }
    927 SPECULATIVE_NUMBER_BINOP(NumberAdd)
    928 SPECULATIVE_NUMBER_BINOP(NumberSubtract)
    929 SPECULATIVE_NUMBER_BINOP(NumberMultiply)
    930 SPECULATIVE_NUMBER_BINOP(NumberDivide)
    931 SPECULATIVE_NUMBER_BINOP(NumberModulus)
    932 SPECULATIVE_NUMBER_BINOP(NumberBitwiseOr)
    933 SPECULATIVE_NUMBER_BINOP(NumberBitwiseAnd)
    934 SPECULATIVE_NUMBER_BINOP(NumberBitwiseXor)
    935 SPECULATIVE_NUMBER_BINOP(NumberShiftLeft)
    936 SPECULATIVE_NUMBER_BINOP(NumberShiftRight)
    937 SPECULATIVE_NUMBER_BINOP(NumberShiftRightLogical)
    938 #undef SPECULATIVE_NUMBER_BINOP
    939 
    940 Type* OperationTyper::ToPrimitive(Type* type) {
    941   if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
    942     return type;
    943   }
    944   return Type::Primitive();
    945 }
    946 
    947 Type* OperationTyper::Invert(Type* type) {
    948   DCHECK(type->Is(Type::Boolean()));
    949   DCHECK(type->IsInhabited());
    950   if (type->Is(singleton_false())) return singleton_true();
    951   if (type->Is(singleton_true())) return singleton_false();
    952   return type;
    953 }
    954 
    955 OperationTyper::ComparisonOutcome OperationTyper::Invert(
    956     ComparisonOutcome outcome) {
    957   ComparisonOutcome result(0);
    958   if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined;
    959   if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse;
    960   if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue;
    961   return result;
    962 }
    963 
    964 Type* OperationTyper::FalsifyUndefined(ComparisonOutcome outcome) {
    965   if ((outcome & kComparisonFalse) != 0 ||
    966       (outcome & kComparisonUndefined) != 0) {
    967     return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
    968                                             : singleton_false();
    969   }
    970   // Type should be non empty, so we know it should be true.
    971   DCHECK((outcome & kComparisonTrue) != 0);
    972   return singleton_true();
    973 }
    974 
    975 Type* OperationTyper::TypeTypeGuard(const Operator* sigma_op, Type* input) {
    976   return Type::Intersect(input, TypeGuardTypeOf(sigma_op), zone());
    977 }
    978 
    979 }  // namespace compiler
    980 }  // namespace internal
    981 }  // namespace v8
    982