Commit 7374e6dc authored by martyn.capewell's avatar martyn.capewell Committed by Commit bot

[turbofan] Move MulHigh asr onto add on ARM64

Move the arithmetic shift from Int32MulHigh to a following Int32Add on ARM64.
This graph is commonly generated on reduction of signed integer division.

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

Cr-Commit-Position: refs/heads/master@{#29380}
parent 80b3f169
......@@ -841,6 +841,34 @@ void InstructionSelector::VisitWord32Sar(Node* node) {
return;
}
if (m.left().IsInt32Add() && m.right().HasValue() &&
CanCover(node, node->InputAt(0))) {
Node* add_node = m.left().node();
Int32BinopMatcher madd_node(add_node);
if (madd_node.left().IsInt32MulHigh() &&
CanCover(add_node, madd_node.left().node())) {
// Combine the shift that would be generated by Int32MulHigh with the add
// on the left of this Sar operation. We do it here, as the result of the
// add potentially has 33 bits, so we have to ensure the result is
// truncated by being the input to this 32-bit Sar operation.
Arm64OperandGenerator g(this);
Node* mul_node = madd_node.left().node();
InstructionOperand const smull_operand = g.TempRegister();
Emit(kArm64Smull, smull_operand, g.UseRegister(mul_node->InputAt(0)),
g.UseRegister(mul_node->InputAt(1)));
InstructionOperand const add_operand = g.TempRegister();
Emit(kArm64Add | AddressingModeField::encode(kMode_Operand2_R_ASR_I),
add_operand, g.UseRegister(add_node->InputAt(1)), smull_operand,
g.TempImmediate(32));
Emit(kArm64Asr32, g.DefineAsRegister(node), add_operand,
g.UseImmediate(node->InputAt(1)));
return;
}
}
VisitRRO(this, kArm64Asr32, node, kShift32Imm);
}
......
......@@ -2603,6 +2603,38 @@ TEST_F(InstructionSelectorTest, Int32MulHighWithSar) {
}
TEST_F(InstructionSelectorTest, Int32MulHighWithAdd) {
StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
Node* const p0 = m.Parameter(0);
Node* const p1 = m.Parameter(1);
Node* const a = m.Int32Add(m.Int32MulHigh(p0, p1), p0);
// Test only one shift constant here, as we're only interested in it being a
// 32-bit operation; the shift amount is irrelevant.
Node* const n = m.Word32Sar(a, m.Int32Constant(1));
m.Return(n);
Stream s = m.Build();
ASSERT_EQ(3U, s.size());
EXPECT_EQ(kArm64Smull, 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)));
ASSERT_EQ(1U, s[0]->OutputCount());
EXPECT_EQ(kArm64Add, s[1]->arch_opcode());
EXPECT_EQ(kMode_Operand2_R_ASR_I, s[1]->addressing_mode());
ASSERT_EQ(3U, s[1]->InputCount());
EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[1]->InputAt(0)));
EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(1)));
EXPECT_EQ(32, s.ToInt64(s[1]->InputAt(2)));
ASSERT_EQ(1U, s[1]->OutputCount());
EXPECT_EQ(kArm64Asr32, s[2]->arch_opcode());
ASSERT_EQ(2U, s[2]->InputCount());
EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(0)));
EXPECT_EQ(1, s.ToInt64(s[2]->InputAt(1)));
ASSERT_EQ(1U, s[2]->OutputCount());
EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[2]->Output()));
}
TEST_F(InstructionSelectorTest, Uint32MulHighWithShr) {
TRACED_FORRANGE(int32_t, shift, -32, 63) {
StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
......
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