tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit fb96cba7f3ea28abac1fb671fa23c0452285e70a
parent c6f2c7e54a4ab1229d9c37801c473610becc33ea
Author: André Bargull <andre.bargull@gmail.com>
Date:   Fri, 24 Oct 2025 14:58:55 +0000

Bug 1996085 - Part 3: Call lowerForFPU for Neg{D,F}. r=spidermonkey-reviewers,jandem

Lowering for `MWasmNeg` now no longer needs to be duplicated for each architecture.

This also saves a move instruction on all architectures except x86-shared.

```js
function f(x) {
  return -x + x;
}
```

Was compiled to (ARM64):
```asm
[Codegen]                                 # LIR=Double
[Codegen] [e] 000028 1e7e1001        fmov    d1, #0xf0 (-1,0000)
[Codegen]                                 # LIR=MoveGroup
[Codegen] [e] 00002c 1e604001        fmov    d1, d0
[Codegen]                                 # LIR=NegD
[Codegen] [e] 000030 1e614021        fneg    d1, d1
[Codegen]                                 # LIR=MathD:Add
[Codegen] [e] 000034 1e602820        fadd    d0, d1, d0
```

And is now:
```asm
[Codegen]                                 # LIR=Double
[Codegen] [e] 000028 1e7e1001        fmov    d1, #0xf0 (-1,0000)
[Codegen]                                 # LIR=NegD
[Codegen] [e] 00002c 1e614001        fneg    d1, d0
[Codegen]                                 # LIR=MathD:Add
[Codegen] [e] 000030 1e602820        fadd    d0, d1, d0
```

(The unnecessary `fmov` is tracked in bug 1986976.)

Differential Revision: https://phabricator.services.mozilla.com/D269842

Diffstat:
Mjs/src/jit/LIROps.yaml | 2++
Mjs/src/jit/Lowering.cpp | 20++++++++++++++++++--
Mjs/src/jit/arm/Lowering-arm.cpp | 11-----------
Mjs/src/jit/arm64/Lowering-arm64.cpp | 16----------------
Mjs/src/jit/loong64/Lowering-loong64.cpp | 11-----------
Mjs/src/jit/mips-shared/Lowering-mips-shared.cpp | 11-----------
Mjs/src/jit/riscv64/Lowering-riscv64.cpp | 11-----------
Mjs/src/jit/x86-shared/Lowering-x86-shared.cpp | 24++++++------------------
Mjs/src/jit/x86-shared/Lowering-x86-shared.h | 3+++
9 files changed, 29 insertions(+), 80 deletions(-)

diff --git a/js/src/jit/LIROps.yaml b/js/src/jit/LIROps.yaml @@ -1126,12 +1126,14 @@ result_type: WordSized operands: input: WordSized + defer_init: true # Negative of float32 - name: NegF result_type: WordSized operands: input: WordSized + defer_init: true # Absolute value of an integer. - name: AbsI diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp @@ -2405,7 +2405,7 @@ void LIRGenerator::visitMul(MMul* ins) { // If our RHS is a constant -1.0, we can optimize to an LNegD. if (!ins->mustPreserveNaN() && rhs->isConstant() && rhs->toConstant()->toDouble() == -1.0) { - defineReuseInput(new (alloc()) LNegD(useRegisterAtStart(lhs)), ins, 0); + lowerForFPU(new (alloc()) LNegD, ins, lhs); return; } @@ -2420,7 +2420,7 @@ void LIRGenerator::visitMul(MMul* ins) { // We apply the same optimizations as for doubles if (!ins->mustPreserveNaN() && rhs->isConstant() && rhs->toConstant()->toFloat32() == -1.0f) { - defineReuseInput(new (alloc()) LNegF(useRegisterAtStart(lhs)), ins, 0); + lowerForFPU(new (alloc()) LNegF, ins, lhs); return; } @@ -2431,6 +2431,22 @@ void LIRGenerator::visitMul(MMul* ins) { MOZ_CRASH("Unhandled number specialization"); } +void LIRGenerator::visitWasmNeg(MWasmNeg* ins) { + switch (ins->type()) { + case MIRType::Int32: + lowerForALU(new (alloc()) LNegI, ins, ins->input()); + break; + case MIRType::Float32: + lowerForFPU(new (alloc()) LNegF, ins, ins->input()); + break; + case MIRType::Double: + lowerForFPU(new (alloc()) LNegD, ins, ins->input()); + break; + default: + MOZ_CRASH(); + } +} + void LIRGenerator::visitDiv(MDiv* ins) { MDefinition* lhs = ins->lhs(); MDefinition* rhs = ins->rhs(); diff --git a/js/src/jit/arm/Lowering-arm.cpp b/js/src/jit/arm/Lowering-arm.cpp @@ -575,17 +575,6 @@ void LIRGeneratorARM::lowerBigIntPtrMod(MBigIntPtrMod* ins) { } } -void LIRGenerator::visitWasmNeg(MWasmNeg* ins) { - if (ins->type() == MIRType::Int32) { - lowerForALU(new (alloc()) LNegI, ins, ins->input()); - } else if (ins->type() == MIRType::Float32) { - define(new (alloc()) LNegF(useRegisterAtStart(ins->input())), ins); - } else { - MOZ_ASSERT(ins->type() == MIRType::Double); - define(new (alloc()) LNegD(useRegisterAtStart(ins->input())), ins); - } -} - void LIRGeneratorARM::lowerUDiv(MDiv* div) { MDefinition* lhs = div->getOperand(0); MDefinition* rhs = div->getOperand(1); diff --git a/js/src/jit/arm64/Lowering-arm64.cpp b/js/src/jit/arm64/Lowering-arm64.cpp @@ -507,22 +507,6 @@ bool LIRGeneratorARM64::canEmitWasmReduceSimd128AtUses( #endif -void LIRGenerator::visitWasmNeg(MWasmNeg* ins) { - switch (ins->type()) { - case MIRType::Int32: - lowerForALU(new (alloc()) LNegI, ins, ins->input()); - break; - case MIRType::Float32: - define(new (alloc()) LNegF(useRegisterAtStart(ins->input())), ins); - break; - case MIRType::Double: - define(new (alloc()) LNegD(useRegisterAtStart(ins->input())), ins); - break; - default: - MOZ_CRASH("unexpected type"); - } -} - void LIRGeneratorARM64::lowerUDiv(MDiv* div) { LAllocation lhs = useRegister(div->lhs()); if (div->rhs()->isConstant()) { diff --git a/js/src/jit/loong64/Lowering-loong64.cpp b/js/src/jit/loong64/Lowering-loong64.cpp @@ -823,17 +823,6 @@ void LIRGenerator::visitWasmStore(MWasmStore* ins) { add(lir, ins); } -void LIRGenerator::visitWasmNeg(MWasmNeg* ins) { - if (ins->type() == MIRType::Int32) { - lowerForALU(new (alloc()) LNegI, ins, ins->input()); - } else if (ins->type() == MIRType::Float32) { - define(new (alloc()) LNegF(useRegisterAtStart(ins->input())), ins); - } else { - MOZ_ASSERT(ins->type() == MIRType::Double); - define(new (alloc()) LNegD(useRegisterAtStart(ins->input())), ins); - } -} - void LIRGenerator::visitWasmTruncateToInt64(MWasmTruncateToInt64* ins) { MDefinition* opd = ins->input(); MOZ_ASSERT(opd->type() == MIRType::Double || opd->type() == MIRType::Float32); diff --git a/js/src/jit/mips-shared/Lowering-mips-shared.cpp b/js/src/jit/mips-shared/Lowering-mips-shared.cpp @@ -308,17 +308,6 @@ void LIRGeneratorMIPSShared::lowerBigIntPtrMod(MBigIntPtrMod* ins) { define(lir, ins); } -void LIRGenerator::visitWasmNeg(MWasmNeg* ins) { - if (ins->type() == MIRType::Int32) { - lowerForALU(new (alloc()) LNegI, ins, ins->input()); - } else if (ins->type() == MIRType::Float32) { - define(new (alloc()) LNegF(useRegisterAtStart(ins->input())), ins); - } else { - MOZ_ASSERT(ins->type() == MIRType::Double); - define(new (alloc()) LNegD(useRegisterAtStart(ins->input())), ins); - } -} - void LIRGenerator::visitWasmLoad(MWasmLoad* ins) { MDefinition* base = ins->base(); // 'base' is a GPR but may be of either type. If it is 32-bit, it is diff --git a/js/src/jit/riscv64/Lowering-riscv64.cpp b/js/src/jit/riscv64/Lowering-riscv64.cpp @@ -824,17 +824,6 @@ void LIRGenerator::visitWasmStore(MWasmStore* ins) { add(lir, ins); } -void LIRGenerator::visitWasmNeg(MWasmNeg* ins) { - if (ins->type() == MIRType::Int32) { - lowerForALU(new (alloc()) LNegI, ins, ins->input()); - } else if (ins->type() == MIRType::Float32) { - define(new (alloc()) LNegF(useRegisterAtStart(ins->input())), ins); - } else { - MOZ_ASSERT(ins->type() == MIRType::Double); - define(new (alloc()) LNegD(useRegisterAtStart(ins->input())), ins); - } -} - void LIRGenerator::visitWasmTruncateToInt64(MWasmTruncateToInt64* ins) { MDefinition* opd = ins->input(); MOZ_ASSERT(opd->type() == MIRType::Double || opd->type() == MIRType::Float32); diff --git a/js/src/jit/x86-shared/Lowering-x86-shared.cpp b/js/src/jit/x86-shared/Lowering-x86-shared.cpp @@ -151,6 +151,12 @@ void LIRGeneratorX86Shared::lowerForALU(LInstructionHelper<1, 2, 0>* ins, defineReuseInput(ins, mir, 0); } +void LIRGeneratorX86Shared::lowerForFPU(LInstructionHelper<1, 1, 0>* ins, + MDefinition* mir, MDefinition* input) { + ins->setOperand(0, useRegisterAtStart(input)); + defineReuseInput(ins, mir, 0); +} + void LIRGeneratorX86Shared::lowerForFPU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir, MDefinition* lhs, MDefinition* rhs) { @@ -281,24 +287,6 @@ void LIRGeneratorX86Shared::lowerModI(MMod* mod) { defineFixed(lir, mod, LAllocation(AnyRegister(edx))); } -void LIRGenerator::visitWasmNeg(MWasmNeg* ins) { - switch (ins->type()) { - case MIRType::Int32: - lowerForALU(new (alloc()) LNegI, ins, ins->input()); - break; - case MIRType::Float32: - defineReuseInput(new (alloc()) LNegF(useRegisterAtStart(ins->input())), - ins, 0); - break; - case MIRType::Double: - defineReuseInput(new (alloc()) LNegD(useRegisterAtStart(ins->input())), - ins, 0); - break; - default: - MOZ_CRASH(); - } -} - void LIRGeneratorX86Shared::lowerWasmSelectI(MWasmSelect* select) { auto* lir = new (alloc()) LWasmSelect(useRegisterAtStart(select->trueExpr()), diff --git a/js/src/jit/x86-shared/Lowering-x86-shared.h b/js/src/jit/x86-shared/Lowering-x86-shared.h @@ -36,8 +36,11 @@ class LIRGeneratorX86Shared : public LIRGeneratorShared { void lowerForShiftInt64(LInstr* ins, MDefinition* mir, MDefinition* lhs, MDefinition* rhs); + void lowerForFPU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir, + MDefinition* input); void lowerForFPU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir, MDefinition* lhs, MDefinition* rhs); + void lowerMulI(MMul* mul, MDefinition* lhs, MDefinition* rhs); void lowerDivI(MDiv* div); void lowerModI(MMod* mod);