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;
}
}
+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