[turbofan] Strip useless sign-extension for store8/store16.
authorbmeurer@chromium.org <bmeurer@chromium.org>
Tue, 4 Nov 2014 07:35:29 +0000 (07:35 +0000)
committerbmeurer@chromium.org <bmeurer@chromium.org>
Tue, 4 Nov 2014 07:35:49 +0000 (07:35 +0000)
TEST=unittests
R=svenpanne@chromium.org

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

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

src/compiler/machine-operator-reducer.cc
src/compiler/machine-operator-reducer.h
test/unittests/compiler/machine-operator-reducer-unittest.cc

index 836ddd1..f51125a 100644 (file)
@@ -534,22 +534,8 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
       if (m.IsChangeFloat32ToFloat64()) return Replace(m.node()->InputAt(0));
       break;
     }
-    case IrOpcode::kStore: {
-      Node* const value = node->InputAt(2);
-      // TODO(turbofan): Extend to 64-bit?
-      if (value->opcode() == IrOpcode::kWord32And) {
-        MachineType const rep = static_cast<MachineType>(
-            StoreRepresentationOf(node->op()).machine_type() & kRepMask);
-        Uint32BinopMatcher m(value);
-        if (m.right().HasValue() &&
-            ((rep == kRepWord8 && (m.right().Value() & 0xff) == 0xff) ||
-             (rep == kRepWord16 && (m.right().Value() & 0xffff) == 0xffff))) {
-          node->ReplaceInput(2, m.left().node());
-          return Changed(node);
-        }
-      }
-      break;
-    }
+    case IrOpcode::kStore:
+      return ReduceStore(node);
     default:
       break;
   }
@@ -712,6 +698,41 @@ Reduction MachineOperatorReducer::ReduceUint32Mod(Node* node) {
 }
 
 
+Reduction MachineOperatorReducer::ReduceStore(Node* node) {
+  MachineType const rep =
+      RepresentationOf(StoreRepresentationOf(node->op()).machine_type());
+  Node* const value = node->InputAt(2);
+  switch (value->opcode()) {
+    case IrOpcode::kWord32And: {
+      Uint32BinopMatcher m(value);
+      if (m.right().HasValue() &&
+          ((rep == kRepWord8 && (m.right().Value() & 0xff) == 0xff) ||
+           (rep == kRepWord16 && (m.right().Value() & 0xffff) == 0xffff))) {
+        node->ReplaceInput(2, m.left().node());
+        return Changed(node);
+      }
+      break;
+    }
+    case IrOpcode::kWord32Sar: {
+      Int32BinopMatcher m(value);
+      if (m.left().IsWord32Shl() &&
+          ((rep == kRepWord8 && m.right().IsInRange(1, 24)) ||
+           (rep == kRepWord16 && m.right().IsInRange(1, 16)))) {
+        Int32BinopMatcher mleft(m.left().node());
+        if (mleft.right().Is(m.right().Value())) {
+          node->ReplaceInput(2, mleft.left().node());
+          return Changed(node);
+        }
+      }
+      break;
+    }
+    default:
+      break;
+  }
+  return NoChange();
+}
+
+
 Reduction MachineOperatorReducer::ReduceProjection(size_t index, Node* node) {
   switch (node->opcode()) {
     case IrOpcode::kInt32AddWithOverflow: {
index f19184b..e8fde22 100644 (file)
@@ -65,6 +65,7 @@ class MachineOperatorReducer FINAL : public Reducer {
   Reduction ReduceUint32Div(Node* node);
   Reduction ReduceInt32Mod(Node* node);
   Reduction ReduceUint32Mod(Node* node);
+  Reduction ReduceStore(Node* node);
   Reduction ReduceProjection(size_t index, Node* node);
 
   Graph* graph() const;
index 5169716..268afc4 100644 (file)
@@ -1132,6 +1132,30 @@ TEST_F(MachineOperatorReducerTest, StoreRepWord8WithWord32And) {
 }
 
 
+TEST_F(MachineOperatorReducerTest, StoreRepWord8WithWord32SarAndWord32Shl) {
+  const StoreRepresentation rep(kRepWord8, kNoWriteBarrier);
+  Node* const base = Parameter(0);
+  Node* const index = Parameter(1);
+  Node* const value = Parameter(2);
+  Node* const effect = graph()->start();
+  Node* const control = graph()->start();
+  TRACED_FORRANGE(int32_t, x, 1, 24) {
+    Node* const node = graph()->NewNode(
+        machine()->Store(rep), base, index,
+        graph()->NewNode(
+            machine()->Word32Sar(),
+            graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(x)),
+            Int32Constant(x)),
+        effect, control);
+
+    Reduction r = Reduce(node);
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsStore(rep, base, index, value, effect, control));
+  }
+}
+
+
 TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32And) {
   const StoreRepresentation rep(kRepWord16, kNoWriteBarrier);
   Node* const base = Parameter(0);
@@ -1153,6 +1177,30 @@ TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32And) {
   }
 }
 
+
+TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32SarAndWord32Shl) {
+  const StoreRepresentation rep(kRepWord16, kNoWriteBarrier);
+  Node* const base = Parameter(0);
+  Node* const index = Parameter(1);
+  Node* const value = Parameter(2);
+  Node* const effect = graph()->start();
+  Node* const control = graph()->start();
+  TRACED_FORRANGE(int32_t, x, 1, 16) {
+    Node* const node = graph()->NewNode(
+        machine()->Store(rep), base, index,
+        graph()->NewNode(
+            machine()->Word32Sar(),
+            graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(x)),
+            Int32Constant(x)),
+        effect, control);
+
+    Reduction r = Reduce(node);
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsStore(rep, base, index, value, effect, control));
+  }
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8