Closed Bug 1949081 Opened 1 year ago Closed 2 months ago

Implement wide-arithmetic proposal

Categories

(Core :: JavaScript: WebAssembly, task, P3)

task

Tracking

()

RESOLVED FIXED
150 Branch
Tracking Status
firefox150 --- fixed

People

(Reporter: rhunt, Assigned: jseward)

References

(Blocks 1 open bug)

Details

Attachments

(3 files, 4 obsolete files)

The wide-arithmetic proposal is now at phase 3 in the CG. We should experiment with implementing this sometime.

Blocks: wasm-lang
Assignee: nobody → jseward

Implements i64.add128, i64.sub128, i64.mul_wide_u and i64.mul_wide_s,
baseline only, and 64-bit-targets only. (Very) WIP patch.

WIP patch. Works for baseline only; but all targets now.

Attachment #9542678 - Attachment is obsolete: true
Attached file badness260-WideArith.js (obsolete) —

Interim test cases (definitely not the final version)

First functionally complete implementation, for x86_32, x86_64,
arm32, arm64 and riscv64. With a minimal test case.

Attachment #9544151 - Attachment is obsolete: true
Attachment #9544152 - Attachment is obsolete: true

Complete implementation, except for having a guarding pref,
and fairly decent tests, including spec tests.

Attachment #9549789 - Attachment is obsolete: true

This patch implements the wasm wide-arithmetic proposal, that is, i64.add128,
i64.sub128, i64.mul_wide_s and i64.mul_wide_u.

The code generated by baseline and Ion is identical, apart from register
allocation. On 64-bit targets, target-specific instructions are used to
compute the high-halves of results. On 32-bit targets, all work is done by
Instance methods in C++ land.

On 64-bit targets, two new macroassembler methods have been added, along with
corresponding LIR and MIR classes.

On 32-bit targets, for simplicity, argument and result passing to/from the
helper functions is done by placing data in the Instance::baselineScratchWords_
array.

On 64-bit targets, for all 4 wasm instructions, the high 64 bits of results are
computed independently of the low 64 bits. This sidesteps the difficult
problem of extending MIR and/or LIR to have multiple result values/registers,
but does introduce some inefficiency. Ignoring register moves, the sequences
are:

i64.add128:
add (for low half), add-and-set-flags, add-with-carry (for high half)
and similar for i64.sub128

i64.mul_wide_*:
mul (for low half), mul-wide (for high half)

On x64, arm64 and riscv64, the add128/sub128 scheme produces an extra 64-bit
add/sub compared to optimal code.

On x64, the i64.mul_wide_* scheme produces an extra 64-bit multiply compared
to optimal code. Interestingly, on arm64 and riscv64, the code is optimal --
that is, mul + mul_high is as good as it gets.

On 32-bit targets, moving args/results into / out of
Instance::baselineScratchWords_[] is straightforward on baseline. But on Ion,
two new classes have been added to read/write those areas.

Main changes:

  • MIR: 64-bit targets only: new classes MWasmAddSubI128HI64 and
    MWasmMulI64WideHI64, to compute high halves of results.

  • .. and the corresponding LIRs, LIRGenerator and CodeGenerator methods, and
    MacroAssembler methods.

  • MIR: 32-bit targes only: new classes MWasmStoreInstanceScratch2xI32 and
    MWasmLoadInstanceScratch2xI32, to write/read
    Instance::baselineScratchWords_[].

  • .. and the corresponding LIRs, LIRGenerator and CodeGenerator methods, and
    MacroAssembler methods.

  • BaseCompiler::{emitI64AddSub128, emitI64MulWide}: generate inline code on
    64-bit targets and helper callouts on 32-bit targets.

  • FunctionCompiler::{emitI64AddSub128, emitI64MulWide}: generate inline MIR
    on 64-bit targets and helper callouts on 32-bit targets.

  • The I64AddSub128 entities carry a bool isAdd, and the I64MulWide entities
    carry a bool isSigned, indicating what operation they are. Plain signed
    is obviously infeasible anywhere, and plain add doesn't work on riscv64
    since that's the name of one of its assembler methods.

  • The x64 MacroAssembler::wasmMulI64WideHI64 involves a bit of register
    shuffling. All other macroassembler methods are straightforward.

  • new test case wasm/wide-arithmetic.js, with some initial smoke tests,
    followed by tests taken from the proposal document.

This patch adds the pref javascript.options.wasm_wide_arithmetic and relevant
checks. This functionality is currently preffed-off by default.

Status: NEW → RESOLVED
Closed: 2 months ago
Resolution: --- → FIXED
Target Milestone: --- → 150 Branch
Blocks: 2023308
Blocks: 2024119
QA Whiteboard: [qa-triage-done-c151/b150]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: