Revision: 25162
Author:   [email protected]
Date:     Wed Nov  5 14:56:46 2014 UTC
Log:      [turbofan] Compute tighter ranges for modulus in Typer.

[email protected]
BUG=

Review URL: https://codereview.chromium.org/689133003
https://code.google.com/p/v8/source/detail?r=25162

Modified:
 /branches/bleeding_edge/src/compiler/typer.cc
 /branches/bleeding_edge/test/cctest/compiler/test-typer.cc

=======================================
--- /branches/bleeding_edge/src/compiler/typer.cc Mon Nov 3 13:58:39 2014 UTC +++ /branches/bleeding_edge/src/compiler/typer.cc Wed Nov 5 14:56:46 2014 UTC
@@ -232,6 +232,7 @@
static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*); static Type* JSMultiplyRanger(Type::RangeType*, Type::RangeType*, Typer*);
   static Type* JSDivideRanger(Type::RangeType*, Type::RangeType*, Typer*);
+  static Type* JSModulusRanger(Type::RangeType*, Type::RangeType*, Typer*);

   static Type* JSCompareTyper(Type*, Type*, Typer*);

@@ -982,19 +983,59 @@
        (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
   return maybe_nan ? Type::Number() : Type::OrderedNumber();
 }
+
+
+Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs,
+                                      Type::RangeType* rhs, Typer* t) {
+  double lmin = lhs->Min()->Number();
+  double lmax = lhs->Max()->Number();
+  double rmin = rhs->Min()->Number();
+  double rmax = rhs->Max()->Number();
+
+  double labs = std::max(std::abs(lmin), std::abs(lmax));
+  double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1;
+  double abs = std::min(labs, rabs);
+  bool maybe_minus_zero = false;
+  double omin = 0;
+  double omax = 0;
+  if (lmin >= 0) {  // {lhs} positive.
+    omin = 0;
+    omax = abs;
+  } else if (lmax <= 0) {  // {lhs} negative.
+    omin = 0 - abs;
+    omax = 0;
+    maybe_minus_zero = lmin <= omin;
+  } else {
+    omin = 0 - abs;
+    omax = abs;
+    maybe_minus_zero = lmin <= omin;
+  }
+
+  Factory* f = t->isolate()->factory();
+ Type* result = Type::Range(f->NewNumber(omin), f->NewNumber(omax), t->zone());
+  if (maybe_minus_zero)
+    result = Type::Union(result, Type::MinusZero(), t->zone());
+  return result;
+}


 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
   lhs = ToNumber(lhs, t);
   rhs = ToNumber(rhs, t);
   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
-  // Division is tricky, so all we do is try ruling out nan.
-  // TODO(neis): try ruling out -0 as well?
-  bool maybe_nan =
-      lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) ||
-      ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
-       (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
-  return maybe_nan ? Type::Number() : Type::OrderedNumber();
+
+  if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) ||
+      lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) {
+    // Result maybe NaN.
+    return Type::Number();
+  }
+
+  lhs = Rangify(lhs, t);
+  rhs = Rangify(rhs, t);
+  if (lhs->IsRange() && rhs->IsRange()) {
+    return JSModulusRanger(lhs->AsRange(), rhs->AsRange(), t);
+  }
+  return Type::OrderedNumber();
 }


=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-typer.cc Thu Oct 23 14:40:43 2014 UTC +++ /branches/bleeding_edge/test/cctest/compiler/test-typer.cc Wed Nov 5 14:56:46 2014 UTC
@@ -4,6 +4,7 @@

 #include <functional>

+#include "src/codegen.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/compiler/typer.h"
 #include "test/cctest/cctest.h"
@@ -214,6 +215,12 @@
   TyperTester t;
   t.TestBinaryArithOp(t.javascript_.Divide(), std::divides<double>());
 }
+
+
+TEST(TypeJSModulus) {
+  TyperTester t;
+  t.TestBinaryArithOp(t.javascript_.Modulus(), modulo);
+}


 TEST(TypeJSBitwiseOr) {

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to