Closed Bug 1710403 Opened 3 years ago Closed 3 years ago

Constant fold 0-n (for integer type n) as negate

Categories

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

enhancement

Tracking

()

RESOLVED FIXED
91 Branch
Tracking Status
firefox91 --- fixed

People

(Reporter: lth, Assigned: lth)

References

(Blocks 2 open bugs)

Details

Attachments

(1 file)

The idiom for -n where n is an integer is 0-n, there is no wasm instruction for this. Emscripten generates 0-n for example. We should constant-fold this to "negate n" cross-platform to generate tighter code and use fewer registers.

ARM64 output at present (from bug 1710087):

0x1e381ef2b084  52800001  mov     w1, #0x0
0x1e381ef2b088  4b000020  sub     w0, w1, w0

x64 output at present:

00000014  33 c0                     xor %eax, %eax
00000016  2b c7                     sub %edi, %eax

Obvious test case:

wasmDis(new WebAssembly.Module(wasmTextToBinary(`
(module
  (func $f1 (param $p i32) (result i32)
    (i32.sub (i32.const 0) (local.get $p))))
`)))
Depends on: 1710024
Depends on: 1712692
No longer depends on: 1712692

This can't be done mechanically during constant folding for reasons having to do with 0 vs -0 for fp numbers (there's an explicit guard against the folding in MWasmBinaryArith::foldsTo) so we're going to do it in common lowering code for integer types only. This is fine for wasm: the wasm instruction set has dedicated instructions for negating floating point values.

Blocks: 1712291

For 0-n with integer n, add specialization in shared lowering code to
lower as LNegI and LNegI64 (a new node type).

For n*-1 with int64 n, add a specialization in shared lowering code to
lower as LNegI64. The case for int32 was already handled. (The
specialization for n*-1 that's performed in codegen on some platforms
is now redundant, but that will be cleaned up with bug 1712298.)

These optimizations benefit wasm, as there is no integer negate
operation in the wasm instruction set, one of these cliches will be
used instead.

The lowering for 64-bit is a little easier than for 32-bit since
64-bit subtract/multiply are not fallible.

There's some platform-dependent codegen here because we want to allow
the src and dest registers to differ on arm64 and arm, but to reuse
the input on x86 and x64. mips64 follows x64, for simplicity.

Drive-by change: The 'reused input index' argument to lowerNegI has no
function and is removed. (Its value must always be zero because it's
the index of the reused input in the LIR node, not an index in the MIR
node.)

Pushed by lhansen@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/0108d03e2910
Lower 0-n and n*-1 as -n for int types. r=nbp
Status: ASSIGNED → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → 91 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: