Index: test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc |
diff --git a/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc b/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc |
index 998601623066957ed24cf4d89352a63e916b7a67..a50870d3d40994037fee89739706ded891fd2af9 100644 |
--- a/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc |
+++ b/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc |
@@ -1178,7 +1178,6 @@ TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnRight) { |
} |
} |
- |
TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnLeft) { |
TRACED_FORRANGE(int, bit, 0, 31) { |
uint32_t mask = 1 << bit; |
@@ -1261,6 +1260,91 @@ TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnLeft) { |
} |
} |
+TEST_F(InstructionSelectorTest, Word32EqualZeroAndBranchWithOneBitMask) { |
+ TRACED_FORRANGE(int, bit, 0, 31) { |
+ uint32_t mask = 1 << bit; |
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
+ RawMachineLabel a, b; |
+ m.Branch(m.Word32Equal(m.Word32And(m.Int32Constant(mask), m.Parameter(0)), |
+ m.Int32Constant(0)), |
+ &a, &b); |
+ m.Bind(&a); |
+ m.Return(m.Int32Constant(1)); |
+ m.Bind(&b); |
+ m.Return(m.Int32Constant(0)); |
+ Stream s = m.Build(); |
+ ASSERT_EQ(1U, s.size()); |
+ EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); |
+ EXPECT_EQ(kEqual, s[0]->flags_condition()); |
+ EXPECT_EQ(4U, s[0]->InputCount()); |
+ EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
+ EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); |
+ } |
+ |
+ TRACED_FORRANGE(int, bit, 0, 31) { |
+ uint32_t mask = 1 << bit; |
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
+ RawMachineLabel a, b; |
+ m.Branch( |
+ m.Word32NotEqual(m.Word32And(m.Int32Constant(mask), m.Parameter(0)), |
+ m.Int32Constant(0)), |
+ &a, &b); |
+ m.Bind(&a); |
+ m.Return(m.Int32Constant(1)); |
+ m.Bind(&b); |
+ m.Return(m.Int32Constant(0)); |
+ Stream s = m.Build(); |
+ ASSERT_EQ(1U, s.size()); |
+ EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); |
+ EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
+ EXPECT_EQ(4U, s[0]->InputCount()); |
+ EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
+ EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); |
+ } |
+} |
+ |
+TEST_F(InstructionSelectorTest, Word64EqualZeroAndBranchWithOneBitMask) { |
+ TRACED_FORRANGE(int, bit, 0, 63) { |
+ uint64_t mask = V8_UINT64_C(1) << bit; |
+ StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
+ RawMachineLabel a, b; |
+ m.Branch(m.Word64Equal(m.Word64And(m.Int64Constant(mask), m.Parameter(0)), |
+ m.Int64Constant(0)), |
+ &a, &b); |
+ m.Bind(&a); |
+ m.Return(m.Int64Constant(1)); |
+ m.Bind(&b); |
+ m.Return(m.Int64Constant(0)); |
+ Stream s = m.Build(); |
+ ASSERT_EQ(1U, s.size()); |
+ EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode()); |
+ EXPECT_EQ(kEqual, s[0]->flags_condition()); |
+ EXPECT_EQ(4U, s[0]->InputCount()); |
+ EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
+ EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); |
+ } |
+ |
+ TRACED_FORRANGE(int, bit, 0, 63) { |
+ uint64_t mask = V8_UINT64_C(1) << bit; |
+ StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
+ RawMachineLabel a, b; |
+ m.Branch( |
+ m.Word64NotEqual(m.Word64And(m.Int64Constant(mask), m.Parameter(0)), |
+ m.Int64Constant(0)), |
+ &a, &b); |
+ m.Bind(&a); |
+ m.Return(m.Int64Constant(1)); |
+ m.Bind(&b); |
+ m.Return(m.Int64Constant(0)); |
+ Stream s = m.Build(); |
+ ASSERT_EQ(1U, s.size()); |
+ EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode()); |
+ EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
+ EXPECT_EQ(4U, s[0]->InputCount()); |
+ EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
+ EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); |
+ } |
+} |
TEST_F(InstructionSelectorTest, CompareAgainstZeroAndBranch) { |
{ |
@@ -1298,6 +1382,75 @@ TEST_F(InstructionSelectorTest, CompareAgainstZeroAndBranch) { |
} |
} |
+TEST_F(InstructionSelectorTest, EqualZeroAndBranch) { |
+ { |
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
+ RawMachineLabel a, b; |
+ Node* p0 = m.Parameter(0); |
+ m.Branch(m.Word32Equal(p0, m.Int32Constant(0)), &a, &b); |
+ m.Bind(&a); |
+ m.Return(m.Int32Constant(1)); |
+ m.Bind(&b); |
+ m.Return(m.Int32Constant(0)); |
+ Stream s = m.Build(); |
+ ASSERT_EQ(1U, s.size()); |
+ EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode()); |
+ EXPECT_EQ(kEqual, s[0]->flags_condition()); |
+ EXPECT_EQ(3U, s[0]->InputCount()); |
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
+ } |
+ |
+ { |
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
+ RawMachineLabel a, b; |
+ Node* p0 = m.Parameter(0); |
+ m.Branch(m.Word32NotEqual(p0, m.Int32Constant(0)), &a, &b); |
+ m.Bind(&a); |
+ m.Return(m.Int32Constant(1)); |
+ m.Bind(&b); |
+ m.Return(m.Int32Constant(0)); |
+ Stream s = m.Build(); |
+ ASSERT_EQ(1U, s.size()); |
+ EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode()); |
+ EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
+ EXPECT_EQ(3U, s[0]->InputCount()); |
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
+ } |
+ |
+ { |
+ StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
+ RawMachineLabel a, b; |
+ Node* p0 = m.Parameter(0); |
+ m.Branch(m.Word64Equal(p0, m.Int64Constant(0)), &a, &b); |
+ m.Bind(&a); |
+ m.Return(m.Int64Constant(1)); |
+ m.Bind(&b); |
+ m.Return(m.Int64Constant(0)); |
+ Stream s = m.Build(); |
+ ASSERT_EQ(1U, s.size()); |
+ EXPECT_EQ(kArm64CompareAndBranch, s[0]->arch_opcode()); |
+ EXPECT_EQ(kEqual, s[0]->flags_condition()); |
+ EXPECT_EQ(3U, s[0]->InputCount()); |
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
+ } |
+ |
+ { |
+ StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); |
+ RawMachineLabel a, b; |
+ Node* p0 = m.Parameter(0); |
+ m.Branch(m.Word64NotEqual(p0, m.Int64Constant(0)), &a, &b); |
+ m.Bind(&a); |
+ m.Return(m.Int64Constant(1)); |
+ m.Bind(&b); |
+ m.Return(m.Int64Constant(0)); |
+ Stream s = m.Build(); |
+ ASSERT_EQ(1U, s.size()); |
+ EXPECT_EQ(kArm64CompareAndBranch, s[0]->arch_opcode()); |
+ EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
+ EXPECT_EQ(3U, s[0]->InputCount()); |
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
+ } |
+} |
// ----------------------------------------------------------------------------- |
// Add and subtract instructions with overflow. |