[loong64][mips64] Fix a Int64Mul error in instruction selection.
The second parameter of Int64Mul may be a 64-bit immediate value, treating it as a 32-bit value will lose the upper 32 bits. Besides, add a test for this error. Bug: v8:12373 Change-Id: I92e95f7906051c91f9076730e5490b0956416d68 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3272195 Auto-Submit: Liu yu <liuyu@loongson.cn> Commit-Queue: Liu yu <liuyu@loongson.cn> Reviewed-by: Adam Klein <adamk@chromium.org> Cr-Commit-Position: refs/heads/main@{#77833}
This commit is contained in:
parent
27f0d28f65
commit
9a900169f8
@ -865,7 +865,7 @@ void TurboAssembler::Alsl_w(Register rd, Register rj, Register rk, uint8_t sa,
|
||||
|
||||
void TurboAssembler::Alsl_d(Register rd, Register rj, Register rk, uint8_t sa,
|
||||
Register scratch) {
|
||||
DCHECK(sa >= 1 && sa <= 31);
|
||||
DCHECK(sa >= 1 && sa <= 63);
|
||||
if (sa <= 4) {
|
||||
alsl_d(rd, rj, rk, sa);
|
||||
} else {
|
||||
|
@ -1097,13 +1097,16 @@ void TurboAssembler::Lsa(Register rd, Register rt, Register rs, uint8_t sa,
|
||||
|
||||
void TurboAssembler::Dlsa(Register rd, Register rt, Register rs, uint8_t sa,
|
||||
Register scratch) {
|
||||
DCHECK(sa >= 1 && sa <= 31);
|
||||
DCHECK(sa >= 1 && sa <= 63);
|
||||
if (kArchVariant == kMips64r6 && sa <= 4) {
|
||||
dlsa(rd, rt, rs, sa - 1);
|
||||
} else {
|
||||
Register tmp = rd == rt ? scratch : rd;
|
||||
DCHECK(tmp != rt);
|
||||
if (sa <= 31)
|
||||
dsll(tmp, rs, sa);
|
||||
else
|
||||
dsll32(tmp, rs, sa - 32);
|
||||
Daddu(rd, rt, tmp);
|
||||
}
|
||||
}
|
||||
|
@ -1086,15 +1086,14 @@ void InstructionSelector::VisitInt64Mul(Node* node) {
|
||||
Loong64OperandGenerator g(this);
|
||||
Int64BinopMatcher m(node);
|
||||
if (m.right().HasResolvedValue() && m.right().ResolvedValue() > 0) {
|
||||
uint32_t value = static_cast<uint32_t>(m.right().ResolvedValue());
|
||||
uint64_t value = static_cast<uint64_t>(m.right().ResolvedValue());
|
||||
if (base::bits::IsPowerOfTwo(value)) {
|
||||
Emit(kLoong64Sll_d | AddressingModeField::encode(kMode_None),
|
||||
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
|
||||
g.TempImmediate(base::bits::WhichPowerOfTwo(value)));
|
||||
return;
|
||||
}
|
||||
if (base::bits::IsPowerOfTwo(value - 1) && value - 1 > 0 &&
|
||||
value - 1 <= 31) {
|
||||
if (base::bits::IsPowerOfTwo(value - 1) && value - 1 > 0) {
|
||||
// Alsl_d macro will handle the shifting value out of bound cases.
|
||||
Emit(kLoong64Alsl_d, g.DefineAsRegister(node),
|
||||
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
|
||||
|
@ -1125,17 +1125,15 @@ void InstructionSelector::VisitUint32MulHigh(Node* node) {
|
||||
void InstructionSelector::VisitInt64Mul(Node* node) {
|
||||
Mips64OperandGenerator g(this);
|
||||
Int64BinopMatcher m(node);
|
||||
// TODO(dusmil): Add optimization for shifts larger than 32.
|
||||
if (m.right().HasResolvedValue() && m.right().ResolvedValue() > 0) {
|
||||
uint32_t value = static_cast<uint32_t>(m.right().ResolvedValue());
|
||||
uint64_t value = static_cast<uint64_t>(m.right().ResolvedValue());
|
||||
if (base::bits::IsPowerOfTwo(value)) {
|
||||
Emit(kMips64Dshl | AddressingModeField::encode(kMode_None),
|
||||
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
|
||||
g.TempImmediate(base::bits::WhichPowerOfTwo(value)));
|
||||
return;
|
||||
}
|
||||
if (base::bits::IsPowerOfTwo(value - 1) && kArchVariant == kMips64r6 &&
|
||||
value - 1 > 0 && value - 1 <= 31) {
|
||||
if (base::bits::IsPowerOfTwo(value - 1) && value - 1 > 0) {
|
||||
// Dlsa macro will handle the shifting value out of bound cases.
|
||||
Emit(kMips64Dlsa, g.DefineAsRegister(node),
|
||||
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
|
||||
|
@ -7308,6 +7308,20 @@ TEST(Regression12330) {
|
||||
m.Return(ovf);
|
||||
m.GenerateCode();
|
||||
}
|
||||
|
||||
TEST(Regression12373) {
|
||||
FOR_INT64_INPUTS(i) {
|
||||
RawMachineAssemblerTester<int64_t> m(MachineType::Int64(),
|
||||
MachineType::Int64());
|
||||
RawMachineAssemblerTester<int64_t> n(MachineType::Int64());
|
||||
|
||||
Node* mul_rr = m.Int64Mul(m.Parameter(0), m.Parameter(1));
|
||||
Node* mul_ri = n.Int64Mul(n.Parameter(0), n.Int64Constant(i));
|
||||
m.Return(mul_rr);
|
||||
n.Return(mul_ri);
|
||||
FOR_INT64_INPUTS(j) { CHECK_EQ(m.Call(j, i), n.Call(j)); }
|
||||
}
|
||||
}
|
||||
#endif // V8_TARGET_ARCH_64_BIT
|
||||
|
||||
} // namespace compiler
|
||||
|
Loading…
Reference in New Issue
Block a user