[turbofan] Lower NumberModulus to Uint32Mod if both inputs are Unsigned32.
authorbmeurer@chromium.org <bmeurer@chromium.org>
Fri, 31 Oct 2014 07:58:49 +0000 (07:58 +0000)
committerbmeurer@chromium.org <bmeurer@chromium.org>
Fri, 31 Oct 2014 07:59:18 +0000 (07:59 +0000)
TEST=cctest/test-simplified-lowering
R=dcarney@chromium.org

Review URL: https://codereview.chromium.org/685993003

Cr-Commit-Position: refs/heads/master@{#25025}
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25025 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/compiler/simplified-lowering.cc
test/cctest/compiler/test-simplified-lowering.cc

index 8595ee6..ff48d34 100644 (file)
@@ -510,6 +510,10 @@ class RepresentationSelector {
     return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0;
   }
 
+  bool CanObserveNaN(MachineTypeUnion use) {
+    return (use & (kTypeNumber | kTypeAny)) != 0;
+  }
+
   bool CanObserveNonUint32(MachineTypeUnion use) {
     return (use & (kTypeInt32 | kTypeNumber | kTypeAny)) != 0;
   }
@@ -707,7 +711,7 @@ class RepresentationSelector {
           if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
           break;
         }
-        if (CanLowerToUint32Binop(node, use)) {
+        if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) {
           // => unsigned Uint32Mod
           VisitUint32Binop(node);
           if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
index 6e18478..dcbb9c8 100644 (file)
@@ -1010,8 +1010,10 @@ TEST(LowerNumberDivMod_to_float64) {
     TestingGraph t(test_types[i], test_types[i]);
 
     t.CheckLoweringBinop(IrOpcode::kFloat64Div, t.simplified()->NumberDivide());
-    t.CheckLoweringBinop(IrOpcode::kFloat64Mod,
-                         t.simplified()->NumberModulus());
+    if (!test_types[i]->Is(Type::Unsigned32())) {
+      t.CheckLoweringBinop(IrOpcode::kFloat64Mod,
+                           t.simplified()->NumberModulus());
+    }
   }
 }
 
@@ -1936,3 +1938,22 @@ TEST(NumberModulus_Int32) {
     CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode());  // Pesky -0 behavior.
   }
 }
+
+
+TEST(NumberModulus_Uint32) {
+  const double kConstants[] = {2, 100, 1000, 1024, 2048};
+  const MachineType kTypes[] = {kMachInt32, kMachUint32};
+
+  for (auto const type : kTypes) {
+    for (auto const c : kConstants) {
+      TestingGraph t(Type::Unsigned32());
+      Node* k = t.jsgraph.Constant(c);
+      Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
+      Node* use = t.Use(mod, type);
+      t.Return(use);
+      t.Lower();
+
+      CHECK_EQ(IrOpcode::kUint32Mod, use->InputAt(0)->opcode());
+    }
+  }
+}