Commit aa541f1c authored by George Wort's avatar George Wort Committed by V8 LUCI CQ

[turbofan][arm64] Emit Lsl for Int32MulWithOverflow when possible

Int32MulWithOverflow on arm64 uses a cmp to set flags rather than
the multiply instruction itself, thus we can use a left shift when
the multiplication is by a power of two.

This provides 0.15% for Speedometer2 on a Neoverse-N1 machine,
with React being improved by 0.45%.

Change-Id: Ic8db42ecc7cb14cf1ac7bbbeab0e9d8359104351
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3829472
Commit-Queue: George Wort <george.wort@arm.com>
Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82499}
parent 8cfbe0fc
......@@ -1669,8 +1669,15 @@ void EmitInt32MulWithOverflow(InstructionSelector* selector, Node* node,
Int32BinopMatcher m(node);
InstructionOperand result = g.DefineAsRegister(node);
InstructionOperand left = g.UseRegister(m.left().node());
InstructionOperand right = g.UseRegister(m.right().node());
selector->Emit(kArm64Smull, result, left, right);
if (m.right().HasResolvedValue() &&
base::bits::IsPowerOfTwo(m.right().ResolvedValue())) {
int32_t shift = base::bits::WhichPowerOfTwo(m.right().ResolvedValue());
selector->Emit(kArm64Lsl, result, left, g.TempImmediate(shift));
} else {
InstructionOperand right = g.UseRegister(m.right().node());
selector->Emit(kArm64Smull, result, left, right);
}
InstructionCode opcode =
kArm64Cmp | AddressingModeField::encode(kMode_Operand2_R_SXTW);
......
......@@ -1930,6 +1930,23 @@ TEST_F(InstructionSelectorTest, OvfBranchWithImmediateOnLeft) {
}
}
TEST_F(InstructionSelectorTest, OvfValMulImmediateOnRight) {
TRACED_FORRANGE(int32_t, shift, 0, 30) {
StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
m.Return(m.Projection(0, m.Int32MulWithOverflow(m.Int32Constant(1 << shift),
m.Parameter(0))));
Stream s = m.Build();
ASSERT_EQ(2U, s.size());
EXPECT_EQ(kArm64Lsl, s[0]->arch_opcode());
EXPECT_EQ(kArm64Cmp, s[1]->arch_opcode());
ASSERT_EQ(2U, s[0]->InputCount());
EXPECT_EQ(shift, s.ToInt32(s[0]->InputAt(1)));
EXPECT_LE(1U, s[0]->OutputCount());
EXPECT_EQ(kFlags_none, s[0]->flags_mode());
}
}
// -----------------------------------------------------------------------------
// Shift instructions.
......
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