[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,
|
void TurboAssembler::Alsl_d(Register rd, Register rj, Register rk, uint8_t sa,
|
||||||
Register scratch) {
|
Register scratch) {
|
||||||
DCHECK(sa >= 1 && sa <= 31);
|
DCHECK(sa >= 1 && sa <= 63);
|
||||||
if (sa <= 4) {
|
if (sa <= 4) {
|
||||||
alsl_d(rd, rj, rk, sa);
|
alsl_d(rd, rj, rk, sa);
|
||||||
} else {
|
} 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,
|
void TurboAssembler::Dlsa(Register rd, Register rt, Register rs, uint8_t sa,
|
||||||
Register scratch) {
|
Register scratch) {
|
||||||
DCHECK(sa >= 1 && sa <= 31);
|
DCHECK(sa >= 1 && sa <= 63);
|
||||||
if (kArchVariant == kMips64r6 && sa <= 4) {
|
if (kArchVariant == kMips64r6 && sa <= 4) {
|
||||||
dlsa(rd, rt, rs, sa - 1);
|
dlsa(rd, rt, rs, sa - 1);
|
||||||
} else {
|
} else {
|
||||||
Register tmp = rd == rt ? scratch : rd;
|
Register tmp = rd == rt ? scratch : rd;
|
||||||
DCHECK(tmp != rt);
|
DCHECK(tmp != rt);
|
||||||
|
if (sa <= 31)
|
||||||
dsll(tmp, rs, sa);
|
dsll(tmp, rs, sa);
|
||||||
|
else
|
||||||
|
dsll32(tmp, rs, sa - 32);
|
||||||
Daddu(rd, rt, tmp);
|
Daddu(rd, rt, tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1086,15 +1086,14 @@ void InstructionSelector::VisitInt64Mul(Node* node) {
|
|||||||
Loong64OperandGenerator g(this);
|
Loong64OperandGenerator g(this);
|
||||||
Int64BinopMatcher m(node);
|
Int64BinopMatcher m(node);
|
||||||
if (m.right().HasResolvedValue() && m.right().ResolvedValue() > 0) {
|
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)) {
|
if (base::bits::IsPowerOfTwo(value)) {
|
||||||
Emit(kLoong64Sll_d | AddressingModeField::encode(kMode_None),
|
Emit(kLoong64Sll_d | AddressingModeField::encode(kMode_None),
|
||||||
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
|
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
|
||||||
g.TempImmediate(base::bits::WhichPowerOfTwo(value)));
|
g.TempImmediate(base::bits::WhichPowerOfTwo(value)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (base::bits::IsPowerOfTwo(value - 1) && value - 1 > 0 &&
|
if (base::bits::IsPowerOfTwo(value - 1) && value - 1 > 0) {
|
||||||
value - 1 <= 31) {
|
|
||||||
// Alsl_d macro will handle the shifting value out of bound cases.
|
// Alsl_d macro will handle the shifting value out of bound cases.
|
||||||
Emit(kLoong64Alsl_d, g.DefineAsRegister(node),
|
Emit(kLoong64Alsl_d, g.DefineAsRegister(node),
|
||||||
g.UseRegister(m.left().node()), g.UseRegister(m.left().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) {
|
void InstructionSelector::VisitInt64Mul(Node* node) {
|
||||||
Mips64OperandGenerator g(this);
|
Mips64OperandGenerator g(this);
|
||||||
Int64BinopMatcher m(node);
|
Int64BinopMatcher m(node);
|
||||||
// TODO(dusmil): Add optimization for shifts larger than 32.
|
|
||||||
if (m.right().HasResolvedValue() && m.right().ResolvedValue() > 0) {
|
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)) {
|
if (base::bits::IsPowerOfTwo(value)) {
|
||||||
Emit(kMips64Dshl | AddressingModeField::encode(kMode_None),
|
Emit(kMips64Dshl | AddressingModeField::encode(kMode_None),
|
||||||
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
|
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
|
||||||
g.TempImmediate(base::bits::WhichPowerOfTwo(value)));
|
g.TempImmediate(base::bits::WhichPowerOfTwo(value)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (base::bits::IsPowerOfTwo(value - 1) && kArchVariant == kMips64r6 &&
|
if (base::bits::IsPowerOfTwo(value - 1) && value - 1 > 0) {
|
||||||
value - 1 > 0 && value - 1 <= 31) {
|
|
||||||
// Dlsa macro will handle the shifting value out of bound cases.
|
// Dlsa macro will handle the shifting value out of bound cases.
|
||||||
Emit(kMips64Dlsa, g.DefineAsRegister(node),
|
Emit(kMips64Dlsa, g.DefineAsRegister(node),
|
||||||
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
|
g.UseRegister(m.left().node()), g.UseRegister(m.left().node()),
|
||||||
|
@ -7308,6 +7308,20 @@ TEST(Regression12330) {
|
|||||||
m.Return(ovf);
|
m.Return(ovf);
|
||||||
m.GenerateCode();
|
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
|
#endif // V8_TARGET_ARCH_64_BIT
|
||||||
|
|
||||||
} // namespace compiler
|
} // namespace compiler
|
||||||
|
Loading…
Reference in New Issue
Block a user