commit bfc5055cb73637fbae68ea69cd8d61edf26115c6
parent 897281b10610d7f70362971d8e1ddeb658e5ae9a
Author: André Bargull <andre.bargull@gmail.com>
Date: Mon, 27 Oct 2025 15:22:14 +0000
Bug 1996346 - Part 2: Relax register constraints for UrshD on x86-shared. r=spidermonkey-reviewers,iain
We don't need `tempCopy(lhs)` when BMI2 is available. This can save an
unnecessary move.
For example:
```js
// Call with x=-1 and y=0.
function f(x, y) {
return x >>> y;
}
```
was compiled to:
```asm
[Codegen] # LIR=MoveGroup
[Codegen] movl %eax, %edx
[Codegen] # LIR=UrshD
[Codegen] shrxl %edx, %ecx, %edx
[Codegen] xorpd %xmm0, %xmm0
[Codegen] cvtsi2sd %rdx, %xmm0
```
And is now compiled to:
```asm
[Codegen] # LIR=UrshD
[Codegen] shrxl %eax, %edx, %ecx
[Codegen] xorpd %xmm0, %xmm0
[Codegen] cvtsi2sd %rcx, %xmm0
```
Differential Revision: https://phabricator.services.mozilla.com/D270026
Diffstat:
2 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp b/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
@@ -1645,22 +1645,29 @@ void CodeGenerator::visitShiftI64(LShiftI64* lir) {
void CodeGenerator::visitUrshD(LUrshD* ins) {
Register lhs = ToRegister(ins->lhs());
- MOZ_ASSERT(ToRegister(ins->temp0()) == lhs);
-
const LAllocation* rhs = ins->rhs();
FloatRegister out = ToFloatRegister(ins->output());
+ Register temp = ToRegister(ins->temp0());
if (rhs->isConstant()) {
+ MOZ_ASSERT(temp == lhs);
+
int32_t shift = ToInt32(rhs) & 0x1F;
if (shift) {
masm.shrl(Imm32(shift), lhs);
}
} else {
+ MOZ_ASSERT_IF(temp != lhs, Assembler::HasBMI2());
+
Register shift = ToRegister(rhs);
- masm.rshift32(shift, lhs);
+ if (temp != lhs) {
+ masm.shrxl(lhs, shift, temp);
+ } else {
+ masm.rshift32(shift, lhs);
+ }
}
- masm.convertUInt32ToDouble(lhs, out);
+ masm.convertUInt32ToDouble(temp, out);
}
Operand CodeGeneratorX86Shared::ToOperand(const LAllocation& a) {
diff --git a/js/src/jit/x86-shared/Lowering-x86-shared.cpp b/js/src/jit/x86-shared/Lowering-x86-shared.cpp
@@ -478,19 +478,21 @@ void LIRGeneratorX86Shared::lowerUrshD(MUrsh* mir) {
MOZ_ASSERT(rhs->type() == MIRType::Int32);
MOZ_ASSERT(mir->type() == MIRType::Double);
-#ifdef JS_CODEGEN_X64
- static_assert(ecx == rcx);
-#endif
-
LUse lhsUse = useRegisterAtStart(lhs);
LAllocation rhsAlloc;
+ LDefinition tempDef;
if (rhs->isConstant()) {
rhsAlloc = useOrConstant(rhs);
+ tempDef = tempCopy(lhs, 0);
+ } else if (Assembler::HasBMI2()) {
+ rhsAlloc = useRegisterAtStart(rhs);
+ tempDef = temp();
} else {
rhsAlloc = useShiftRegister(rhs);
+ tempDef = tempCopy(lhs, 0);
}
- LUrshD* lir = new (alloc()) LUrshD(lhsUse, rhsAlloc, tempCopy(lhs, 0));
+ auto* lir = new (alloc()) LUrshD(lhsUse, rhsAlloc, tempDef);
define(lir, mir);
}