Constant fold 0-n (for integer type n) as negate
Categories
(Core :: JavaScript: WebAssembly, enhancement, P3)
Tracking
()
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))))
`)))
Assignee | ||
Comment 1•3 years ago
|
||
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.
Assignee | ||
Comment 2•3 years ago
|
||
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
Comment 4•3 years ago
|
||
bugherder |
Description
•