[arm64][turbofan] Fix add+shr for big shift values.
Arm64 compiles "x +_64 (y >> shift)" into a single instruction if "shift" is a constant. The code generator expects that "shift" is a 32 bit constant. however, TurboFan can also pass in a 64 bit constant, which caused a crash in the code generator. With this CL we cast the constant of TurboFan to an int in the instruction selector and thereby satisfy the assumption of the code generator. This should be correct since the code generator anyways cast the "shift" to an int5 or int6 eventually. R=v8-arm-ports@googlegroups.com BUG=v8:5923 Review-Url: https://codereview.chromium.org/2669203005 Cr-Commit-Position: refs/heads/master@{#43036}
This commit is contained in:
parent
a1bba7fe3b
commit
ed6e28d2ad
@ -436,14 +436,18 @@ void VisitBinop(InstructionSelector* selector, Node* node,
|
||||
Matcher m_shift(right_node);
|
||||
inputs[input_count++] = g.UseRegisterOrImmediateZero(left_node);
|
||||
inputs[input_count++] = g.UseRegister(m_shift.left().node());
|
||||
inputs[input_count++] = g.UseImmediate(m_shift.right().node());
|
||||
// We only need at most the last 6 bits of the shift.
|
||||
inputs[input_count++] =
|
||||
g.UseImmediate(static_cast<int>(m_shift.right().Value() & 0x3F));
|
||||
} else if (can_commute && TryMatchAnyShift(selector, node, left_node, &opcode,
|
||||
!is_add_sub)) {
|
||||
if (must_commute_cond) cont->Commute();
|
||||
Matcher m_shift(left_node);
|
||||
inputs[input_count++] = g.UseRegisterOrImmediateZero(right_node);
|
||||
inputs[input_count++] = g.UseRegister(m_shift.left().node());
|
||||
inputs[input_count++] = g.UseImmediate(m_shift.right().node());
|
||||
// We only need at most the last 6 bits of the shift.
|
||||
inputs[input_count++] =
|
||||
g.UseImmediate(static_cast<int>(m_shift.right().Value() & 0x3F));
|
||||
} else {
|
||||
inputs[input_count++] = g.UseRegisterOrImmediateZero(left_node);
|
||||
inputs[input_count++] = g.UseRegister(right_node);
|
||||
|
@ -6709,6 +6709,29 @@ TEST(ParentFramePointer) {
|
||||
CHECK_EQ(1, r.Call(1));
|
||||
}
|
||||
|
||||
#if V8_TARGET_ARCH_64_BIT
|
||||
|
||||
TEST(Regression5923) {
|
||||
{
|
||||
BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Int64());
|
||||
m.Return(m.Int64Add(
|
||||
m.Word64Shr(m.Parameter(0), m.Int64Constant(4611686018427387888)),
|
||||
m.Parameter(0)));
|
||||
int64_t input = 16;
|
||||
m.Call(input);
|
||||
}
|
||||
{
|
||||
BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Int64());
|
||||
m.Return(m.Int64Add(
|
||||
m.Parameter(0),
|
||||
m.Word64Shr(m.Parameter(0), m.Int64Constant(4611686018427387888))));
|
||||
int64_t input = 16;
|
||||
m.Call(input);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // V8_TARGET_ARCH_64_BIT
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -745,7 +745,7 @@ TEST_F(InstructionSelectorTest, SubZeroOnLeftWithShift) {
|
||||
EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate());
|
||||
EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0)));
|
||||
EXPECT_EQ(shift.mode, s[0]->addressing_mode());
|
||||
EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(0x3f & imm, 0x3f & s.ToInt32(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(1U, s[0]->OutputCount());
|
||||
}
|
||||
}
|
||||
@ -771,7 +771,7 @@ TEST_F(InstructionSelectorTest, SubZeroOnLeftWithShift) {
|
||||
EXPECT_TRUE(s[0]->InputAt(0)->IsImmediate());
|
||||
EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(0)));
|
||||
EXPECT_EQ(shift.mode, s[0]->addressing_mode());
|
||||
EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(0x3f & imm, 0x3f & s.ToInt32(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(1U, s[0]->OutputCount());
|
||||
}
|
||||
}
|
||||
@ -835,7 +835,7 @@ TEST_F(InstructionSelectorTest, AddShiftByImmediateOnLeft) {
|
||||
EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
|
||||
EXPECT_EQ(shift.mode, s[0]->addressing_mode());
|
||||
EXPECT_EQ(3U, s[0]->InputCount());
|
||||
EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(0x3f & imm, 0x3f & s.ToInt64(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(1U, s[0]->OutputCount());
|
||||
}
|
||||
}
|
||||
@ -859,7 +859,7 @@ TEST_F(InstructionSelectorTest, AddShiftByImmediateOnLeft) {
|
||||
EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
|
||||
EXPECT_EQ(shift.mode, s[0]->addressing_mode());
|
||||
EXPECT_EQ(3U, s[0]->InputCount());
|
||||
EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(0x3f & imm, 0x3f & s.ToInt64(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(1U, s[0]->OutputCount());
|
||||
}
|
||||
}
|
||||
@ -2924,7 +2924,7 @@ TEST_F(InstructionSelectorTest, Word32EqualWithWord32Shift) {
|
||||
ASSERT_EQ(3U, 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(imm, s.ToInt32(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(0x3f & imm, 0x3f & s.ToInt32(s[0]->InputAt(2)));
|
||||
ASSERT_EQ(1U, s[0]->OutputCount());
|
||||
}
|
||||
TRACED_FORRANGE(int32_t, imm, -32, 63) {
|
||||
@ -2941,7 +2941,7 @@ TEST_F(InstructionSelectorTest, Word32EqualWithWord32Shift) {
|
||||
ASSERT_EQ(3U, 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(imm, s.ToInt32(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(0x3f & imm, 0x3f & s.ToInt32(s[0]->InputAt(2)));
|
||||
ASSERT_EQ(1U, s[0]->OutputCount());
|
||||
}
|
||||
}
|
||||
@ -3203,7 +3203,7 @@ TEST_F(InstructionSelectorTest, Word32CompareNegateWithWord32Shift) {
|
||||
EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode());
|
||||
EXPECT_EQ(3U, s[0]->InputCount());
|
||||
EXPECT_EQ(shift.mode, s[0]->addressing_mode());
|
||||
EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(0x3f & imm, 0x3f & s.ToInt32(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(1U, s[0]->OutputCount());
|
||||
EXPECT_EQ(kFlags_set, s[0]->flags_mode());
|
||||
EXPECT_EQ(cmp.cond, s[0]->flags_condition());
|
||||
@ -3311,7 +3311,7 @@ TEST_F(InstructionSelectorTest, CmpShiftByImmediateOnLeft) {
|
||||
EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
|
||||
EXPECT_EQ(shift.mode, s[0]->addressing_mode());
|
||||
EXPECT_EQ(3U, s[0]->InputCount());
|
||||
EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(0x3f & imm, 0x3f & s.ToInt64(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(1U, s[0]->OutputCount());
|
||||
EXPECT_EQ(kFlags_set, s[0]->flags_mode());
|
||||
EXPECT_EQ(cmp.commuted_cond, s[0]->flags_condition());
|
||||
@ -3345,7 +3345,7 @@ TEST_F(InstructionSelectorTest, CmnShiftByImmediateOnLeft) {
|
||||
EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode());
|
||||
EXPECT_EQ(shift.mode, s[0]->addressing_mode());
|
||||
EXPECT_EQ(3U, s[0]->InputCount());
|
||||
EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(0x3f & imm, 0x3f & s.ToInt64(s[0]->InputAt(2)));
|
||||
EXPECT_EQ(1U, s[0]->OutputCount());
|
||||
EXPECT_EQ(kFlags_set, s[0]->flags_mode());
|
||||
EXPECT_EQ(cmp.cond, s[0]->flags_condition());
|
||||
|
Loading…
Reference in New Issue
Block a user