commit ab22f181a2f5f330406c5451c46d5fbfea842651
parent 11b4c69ef331696376eaecba6b00b3625d13d4a5
Author: André Bargull <andre.bargull@gmail.com>
Date: Mon, 27 Oct 2025 08:59:59 +0000
Bug 1996344 - Part 1: Support lea instruction when constant is left-hand side operand. r=spidermonkey-reviewers,iain
```js
function f(x) {
var a = (x+1)|0;
var b = (x+2)|0;
return (a+b)|0;
}
```
generates:
```asm
leal 0x1(%rcx), %eax
addl $2, %ecx
addl %ecx, %eax
```
whereas:
```js
function f(x) {
var a = (1+x)|0;
var b = (2+x)|0;
return (a+b)|0;
}
```
generates:
```asm
movl %eax, %ecx
addl $1, %ecx
addl $2, %eax
addl %eax, %ecx
```
Change lowering to support generating `lea` even the constant is the left-hand
side operand, so that the second script will also be compiled to:
```asm
leal 0x1(%rcx), %eax
addl $2, %ecx
addl %ecx, %eax
```
And simplify the code generator to test when `lea` can be emitted.
Differential Revision: https://phabricator.services.mozilla.com/D270018
Diffstat:
2 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp b/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
@@ -662,20 +662,21 @@ void CodeGeneratorX86Shared::emitUndoALUOperationOOL(LInstruction* ins) {
}
void CodeGenerator::visitAddI(LAddI* ins) {
- if (ins->rhs()->isConstant()) {
- if (MOZ_UNLIKELY(ins->numDefs() == 1 &&
- ins->getDef(0)->policy() !=
- LDefinition::MUST_REUSE_INPUT &&
- ToRegister(ins->lhs()) != ToRegister(ins->output()))) {
+ Register lhs = ToRegister(ins->lhs());
+ const LAllocation* rhs = ins->rhs();
+ Register out = ToRegister(ins->output());
+
+ if (rhs->isConstant()) {
+ if (lhs != out) {
MOZ_ASSERT(!ins->snapshot());
// Special case to lower the add to LEA instruction.
- masm.add32(Imm32(ToInt32(ins->rhs())), ToRegister(ins->lhs()),
- ToRegister(ins->output()));
+ masm.add32(Imm32(ToInt32(rhs)), lhs, out);
} else {
- masm.addl(Imm32(ToInt32(ins->rhs())), ToOperand(ins->lhs()));
+ masm.addl(Imm32(ToInt32(rhs)), lhs);
}
} else {
- masm.addl(ToOperand(ins->rhs()), ToRegister(ins->lhs()));
+ MOZ_ASSERT(out == lhs);
+ masm.addl(ToOperand(rhs), lhs);
}
if (ins->snapshot()) {
diff --git a/js/src/jit/x86-shared/Lowering-x86-shared.cpp b/js/src/jit/x86-shared/Lowering-x86-shared.cpp
@@ -135,19 +135,21 @@ void LIRGeneratorX86Shared::lowerForALU(LInstructionHelper<1, 1, 0>* ins,
void LIRGeneratorX86Shared::lowerForALU(LInstructionHelper<1, 2, 0>* ins,
MDefinition* mir, MDefinition* lhs,
MDefinition* rhs) {
- ins->setOperand(0, useRegisterAtStart(lhs));
- ins->setOperand(1, willHaveDifferentLIRNodes(lhs, rhs)
- ? useOrConstant(rhs)
- : useOrConstantAtStart(rhs));
if (MOZ_UNLIKELY(mir->isAdd() && mir->type() == MIRType::Int32 &&
- mir->getOperand(1)->isConstant() &&
- !mir->toAdd()->fallible())) {
+ rhs->isConstant() && !mir->toAdd()->fallible())) {
// Special case instruction that is widely used in Wasm during address
// calculation. And x86 platform has LEA instruction for it.
// See CodeGenerator::visitAddI for codegen.
+ ins->setOperand(0, useRegisterAtStart(lhs));
+ ins->setOperand(1, useOrConstantAtStart(rhs));
define(ins, mir);
return;
}
+
+ ins->setOperand(0, useRegisterAtStart(lhs));
+ ins->setOperand(1, willHaveDifferentLIRNodes(lhs, rhs)
+ ? useOrConstant(rhs)
+ : useOrConstantAtStart(rhs));
defineReuseInput(ins, mir, 0);
}