Bug 272346
| Summary: | [WASM] BBQ JIT wrongly optimizes I32RemU when rhs is -1 | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | Marcus Plutowski <marcus_plutowski> |
| Component: | WebAssembly | Assignee: | Nobody <webkit-unassigned> |
| Status: | RESOLVED FIXED | ||
| Severity: | Normal | Keywords: | InRadar |
| Priority: | P2 | ||
| Version: | WebKit Nightly Build | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
Marcus Plutowski
When JITing the `I32RemU` bytecode, BBQ performs a wrong optimization when rhs is -1: to wit, it zeroes out the result. This would be correct for I32RemS, but -1 interpreted as an unsigned int is UINT_MAX.
PoC:
```
// (module
// (type (func (param i32) (result i32)))
// (func (type 0) (local i32)
// (local.set 1 (i32.rem_u (local.get 0) (i32.wrap_i64 (i64.const -1))))
// (local.get 1)
// )
// (export "poc" (func 0))
// )
const wasm_code = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 6, 1, 96, 1, 127, 1, 127, 3, 2, 1, 0, 7, 7, 1, 3, 112, 111, 99, 0, 0, 10, 16, 1, 14, 1, 1, 127, 32, 0, 66, 127, 167, 112, 33, 1, 32, 1, 11]);
try {
const wasm_mod = new WebAssembly.Module(wasm_code);
const wasm_instance = new WebAssembly.Instance(wasm_mod);
let ret = undefined;
for (let i = 0; i < 10000; i++) {
ret = wasm_instance.exports.poc(1234.0, -1);
}
print(ret);
}
catch (e) {
print(e);
}
```
```BBQ
[ 0x3] GetLocal
<104> 0x10f8e4108: ldur w0, [fp, #-4]
[ 0x5] I64Const
[ 0x7] I32WrapI64
[ 0x8] I32RemU
<108> 0x10f8e410c: eor w0, w0, w0 <--- [0]
[ 0x9] SetLocal
<112> 0x10f8e4110: stur w0, [fp, #-8]
```
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
Marcus Plutowski
Pull request: https://github.com/WebKit/WebKit/pull/26984
Marcus Plutowski
rdar://121010056
EWS
Committed 277263@main (3d5ca0a94876): <https://commits.webkit.org/277263@main>
Reviewed commits have been landed. Closing PR #26984 and removing active labels.