Commit 9da7ac6f authored by georgia.kouveli's avatar georgia.kouveli Committed by Commit bot

[arm] Improve generation of flag setting instructions.

Generate a flag-setting instruction for a binary operation when
the result is tested for equality/inequality to zero.

BUG=

Review-Url: https://codereview.chromium.org/2315453002
Cr-Commit-Position: refs/heads/master@{#39183}
parent 494e2493
...@@ -1958,6 +1958,10 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, ...@@ -1958,6 +1958,10 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
break; break;
} }
if (user->opcode() == IrOpcode::kWord32Equal) {
return VisitWordCompare(selector, user, cont);
}
// Continuation could not be combined with a compare, emit compare against 0. // Continuation could not be combined with a compare, emit compare against 0.
ArmOperandGenerator g(selector); ArmOperandGenerator g(selector);
InstructionCode const opcode = InstructionCode const opcode =
......
...@@ -2079,10 +2079,6 @@ TEST_P(InstructionSelectorFlagSettingTest, CmpZeroOnlyUserInBasicBlock) { ...@@ -2079,10 +2079,6 @@ TEST_P(InstructionSelectorFlagSettingTest, CmpZeroOnlyUserInBasicBlock) {
const FlagSettingInst inst = GetParam(); const FlagSettingInst inst = GetParam();
// Binop with additional users, but in a different basic block. // Binop with additional users, but in a different basic block.
TRACED_FOREACH(Comparison, cmp, kBinopCmpZeroRightInstructions) { TRACED_FOREACH(Comparison, cmp, kBinopCmpZeroRightInstructions) {
// We don't optimise this case at the moment.
if (cmp.flags_condition == kEqual || cmp.flags_condition == kNotEqual) {
continue;
}
StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
MachineType::Int32()); MachineType::Int32());
RawMachineLabel a, b; RawMachineLabel a, b;
...@@ -2108,10 +2104,6 @@ TEST_P(InstructionSelectorFlagSettingTest, ShiftedOperand) { ...@@ -2108,10 +2104,6 @@ TEST_P(InstructionSelectorFlagSettingTest, ShiftedOperand) {
const FlagSettingInst inst = GetParam(); const FlagSettingInst inst = GetParam();
// Like the test above, but with a shifted input to the binary operator. // Like the test above, but with a shifted input to the binary operator.
TRACED_FOREACH(Comparison, cmp, kBinopCmpZeroRightInstructions) { TRACED_FOREACH(Comparison, cmp, kBinopCmpZeroRightInstructions) {
// We don't optimise this case at the moment.
if (cmp.flags_condition == kEqual || cmp.flags_condition == kNotEqual) {
continue;
}
StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
MachineType::Int32()); MachineType::Int32());
RawMachineLabel a, b; RawMachineLabel a, b;
...@@ -2158,8 +2150,7 @@ TEST_P(InstructionSelectorFlagSettingTest, UsersInSameBasicBlock) { ...@@ -2158,8 +2150,7 @@ TEST_P(InstructionSelectorFlagSettingTest, UsersInSameBasicBlock) {
EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode()); EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode());
EXPECT_NE(kFlags_branch, s[0]->flags_mode()); EXPECT_NE(kFlags_branch, s[0]->flags_mode());
EXPECT_EQ(kArmMul, s[1]->arch_opcode()); EXPECT_EQ(kArmMul, s[1]->arch_opcode());
EXPECT_EQ(cmp.flags_condition == kEqual ? kArmTst : kArmCmp, EXPECT_EQ(kArmCmp, s[2]->arch_opcode());
s[2]->arch_opcode());
EXPECT_EQ(kFlags_branch, s[2]->flags_mode()); EXPECT_EQ(kFlags_branch, s[2]->flags_mode());
EXPECT_EQ(cmp.flags_condition, s[2]->flags_condition()); EXPECT_EQ(cmp.flags_condition, s[2]->flags_condition());
} }
...@@ -3059,10 +3050,11 @@ TEST_F(InstructionSelectorTest, Word32EqualWithZero) { ...@@ -3059,10 +3050,11 @@ TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0))); m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(1U, s.size()); ASSERT_EQ(1U, s.size());
EXPECT_EQ(kArmTst, s[0]->arch_opcode()); EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode()); EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
ASSERT_EQ(2U, s[0]->InputCount()); ASSERT_EQ(2U, s[0]->InputCount());
EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(0)));
EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
EXPECT_EQ(1U, s[0]->OutputCount()); EXPECT_EQ(1U, s[0]->OutputCount());
EXPECT_EQ(kFlags_set, s[0]->flags_mode()); EXPECT_EQ(kFlags_set, s[0]->flags_mode());
EXPECT_EQ(kEqual, s[0]->flags_condition()); EXPECT_EQ(kEqual, s[0]->flags_condition());
...@@ -3072,10 +3064,11 @@ TEST_F(InstructionSelectorTest, Word32EqualWithZero) { ...@@ -3072,10 +3064,11 @@ TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0))); m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
Stream s = m.Build(); Stream s = m.Build();
ASSERT_EQ(1U, s.size()); ASSERT_EQ(1U, s.size());
EXPECT_EQ(kArmTst, s[0]->arch_opcode()); EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode()); EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
ASSERT_EQ(2U, s[0]->InputCount()); ASSERT_EQ(2U, s[0]->InputCount());
EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1))); EXPECT_EQ(s.ToVreg(m.Parameter(0)), s.ToVreg(s[0]->InputAt(0)));
EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
EXPECT_EQ(1U, s[0]->OutputCount()); EXPECT_EQ(1U, s[0]->OutputCount());
EXPECT_EQ(kFlags_set, s[0]->flags_mode()); EXPECT_EQ(kFlags_set, s[0]->flags_mode());
EXPECT_EQ(kEqual, s[0]->flags_condition()); EXPECT_EQ(kEqual, s[0]->flags_condition());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment