Filed by the PulseEngine challenge harness (synth v0.29.0). Found by executing synth's Cortex-M thumb output under qemu-system-arm and differencing vs wasmtime.
Defect: i64.rotl / i64.rotr / i64.div_u / i64.rem_u silently compile to code that returns 0
These four i64 ops compile without error and produce 0 for every input — a silent miscompile. i64.and/or/xor/shl/add are correct (same harness), so this is not a harness/ABI issue. The generated code is self-contained (no external helper call, no relocations — ruled out a missing __aeabi_uldivmod), so the wrong result is synth's, not a link artifact.
Executed on Cortex-M3 (qemu lm3s6965evb, semihosting); i64 param in r0:r1; result via i32.wrap_i64. Oracle = wasmtime.
op (i64 param -> i32 result) input synth wasmtime
i64.rotl by 8 1 0 256 DIVERGE
i64.rotl by 0 (identity!) 123 0 123 DIVERGE
i64.rotr by 8 256 0 1 DIVERGE
i64.div_u by 7 100 0 14 DIVERGE
i64.div_u by 7 700 0 100 DIVERGE
i64.rem_u by 7 100 0 2 DIVERGE
-- controls (CORRECT) --
i64.and / or / xor ... == == OK
i64.shl by 4 / i64.add +1 ... == == OK
i64.rotl by 0 is the clearest tell: it is the identity (must return the operand) yet returns 0, and rotate needs no runtime helper — so this is a genuine lowering bug, not "unimplemented, needs a libcall."
Repro
(module (func (export "f") (param i64) (result i32)
(i32.wrap_i64 (i64.rotl (local.get 0) (i64.const 8)))))
synth compile f.wat -t cortex-m3 -n f --relocatable -o f.o # self-contained, no undefined symbols
# link f (as synth_f) with a semihosting runner calling synth_f(low, high); run under
# qemu-system-arm -M lm3s6965evb -nographic -semihosting -> prints 0 for any input
# wasmtime --invoke f (arg=(high<<32)|low) prints the correct rotate/quotient.
Expected
Either implement these i64 ops correctly, or — following the #554 precedent (dropped-at-decode ops now raise an explicit error rather than emit a silent miscompile) — honestly reject them. Silently returning 0 for a 64-bit rotate/divide on a shipping target is the worst outcome. (The i64 op-class work in the closed #587/#242 was about regalloc skipping functions; these ops are not skipped — they compile and return 0.)
Note
Found with the thumb-execution differential probe (harness/synth_thumb_exec_probe.sh); these i64 ops are now tracked there.
Filed by the PulseEngine challenge harness (synth v0.29.0). Found by executing synth's Cortex-M thumb output under qemu-system-arm and differencing vs wasmtime.
Defect:
i64.rotl/i64.rotr/i64.div_u/i64.rem_usilently compile to code that returns 0These four i64 ops compile without error and produce 0 for every input — a silent miscompile.
i64.and/or/xor/shl/addare correct (same harness), so this is not a harness/ABI issue. The generated code is self-contained (no external helper call, no relocations — ruled out a missing__aeabi_uldivmod), so the wrong result is synth's, not a link artifact.Executed on Cortex-M3 (qemu
lm3s6965evb, semihosting); i64 param in r0:r1; result viai32.wrap_i64. Oracle = wasmtime.i64.rotl by 0is the clearest tell: it is the identity (must return the operand) yet returns 0, and rotate needs no runtime helper — so this is a genuine lowering bug, not "unimplemented, needs a libcall."Repro
Expected
Either implement these i64 ops correctly, or — following the #554 precedent (dropped-at-decode ops now raise an explicit error rather than emit a silent miscompile) — honestly reject them. Silently returning 0 for a 64-bit rotate/divide on a shipping target is the worst outcome. (The i64 op-class work in the closed #587/#242 was about regalloc skipping functions; these ops are not skipped — they compile and return 0.)
Note
Found with the thumb-execution differential probe (
harness/synth_thumb_exec_probe.sh); these i64 ops are now tracked there.