[turbofan] Merge dependent Word32Equal on ARM64
authormartyn.capewell <martyn.capewell@arm.com>
Fri, 31 Jul 2015 12:46:01 +0000 (05:46 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 31 Jul 2015 12:46:09 +0000 (12:46 +0000)
Improve code generated for flag materialization.

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

Cr-Commit-Position: refs/heads/master@{#29954}

src/compiler/arm64/instruction-selector-arm64.cc
test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc

index 03dfd73a73a76f1111ad8988901f1a77b397f76c..f025bf2f427f7f8eb2b076a19c10af899cf61fe7 100644 (file)
@@ -1877,6 +1877,14 @@ void InstructionSelector::VisitWord32Equal(Node* const node) {
         case IrOpcode::kWord32And:
           return VisitWordCompare(this, value, kArm64Tst32, &cont, true,
                                   kLogical32Imm);
+        case IrOpcode::kWord32Equal: {
+          // Word32Equal(Word32Equal(x, y), 0) => Word32Compare(x, y, ne).
+          Int32BinopMatcher mequal(value);
+          node->ReplaceInput(0, mequal.left().node());
+          node->ReplaceInput(1, mequal.right().node());
+          cont.Negate();
+          return VisitWord32Compare(this, node, &cont);
+        }
         default:
           break;
       }
index 7e67b31616292c8287e86d7b5ae15dbb87d1ac88..71c2d44d2f51722fe2bf6fec1dd2a5f7390006ec 100644 (file)
@@ -2421,6 +2421,40 @@ TEST_F(InstructionSelectorTest, Word32EqualWithSignedExtendHalfword) {
 }
 
 
+TEST_F(InstructionSelectorTest, Word32EqualZeroWithWord32Equal) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    m.Return(m.Word32Equal(m.Word32Equal(p0, p1), m.Int32Constant(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    m.Return(m.Word32Equal(m.Int32Constant(0), m.Word32Equal(p0, p1)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+}
+
+
 // -----------------------------------------------------------------------------
 // Miscellaneous