From 9bf532350f1f2f55a215a998114cd97fe7d7b190 Mon Sep 17 00:00:00 2001 From: "martyn.capewell" Date: Fri, 31 Jul 2015 05:46:01 -0700 Subject: [PATCH] [turbofan] Merge dependent Word32Equal on ARM64 Improve code generated for flag materialization. Review URL: https://codereview.chromium.org/1260733003 Cr-Commit-Position: refs/heads/master@{#29954} --- .../arm64/instruction-selector-arm64.cc | 8 +++++ .../instruction-selector-arm64-unittest.cc | 34 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc index 03dfd73a73..f025bf2f42 100644 --- a/src/compiler/arm64/instruction-selector-arm64.cc +++ b/src/compiler/arm64/instruction-selector-arm64.cc @@ -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; } diff --git a/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc b/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc index 7e67b31616..71c2d44d2f 100644 --- a/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc +++ b/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc @@ -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