mirror of
https://github.com/hanzoai/wasm2go.git
synced 2026-10-30 15:06:48 +00:00
* codegen: auto-detect runtime-built f16 tables; fail on stale asserts The f16->f32 table's address had to be asserted from outside (-f16-table): ggml-style engines build the table at runtime, so the static byte-check cannot see it. That external magic number proved a liability twice over — the address moves with any layout shift (source changes, even build-cache state), a stale value silently disables every table-keyed rewrite (the llama-wasm v0.2.1 release shipped ~35% slower decode this way), and the existing staleness warning never ran for multi-package modules because that layout returns before the check. Derive the address from the module's own initialization code instead: an init loop that streams constant-strided stores from a constant base and provably covers the table's whole 256KiB range. Detection is structural over the lowered SSA — a loop-carried pointer phi with constant start and advance, a counter phi with a computable trip count, stores through the pointer — so it does not depend on how the compiler vectorized the conversion arithmetic inside the loop. The scan runs lazily on the first gather-site query. -f16-table remains as an explicit override, now cross-checked: a set address that contradicts a module-verified base FAILS the build, naming the address to adopt; the no-evidence case keeps the old warning, which now also runs on the multi-package path. Verified against the llama engine module: flagless transpile auto-detects the table and produces a byte-identical bundle to the correctly-asserted build (121 FCVT conversions intact); a stale assert aborts with the actionable error. Co-Authored-By: Claude Fable 5 <[email protected]> * codegen: drop the f16-table address input; keep only a boolean opt-out With auto-detection proven equivalent (flagless transpile of the engine module is byte-identical to the previously asserted build), an address-carrying override has no remaining legitimate use — it only reintroduces the stale-value hazard. -f16-table is gone; -no-f16-table disables the table-keyed rewrites outright. The end-of-translation diagnostic is now unconditional: gather sites whose base verified neither statically nor through init-loop coverage are reported, so a detection miss after a module change is loud in every pipeline log. Co-Authored-By: Claude Fable 5 <[email protected]> --------- Co-authored-by: Claude Fable 5 <[email protected]>
31 lines
1.1 KiB
WebAssembly Text Format
31 lines
1.1 KiB
WebAssembly Text Format
;; Runtime f16-table initialization idiom: a loop streaming
|
|
;; constant-strided stores from a constant base, covering the full
|
|
;; 65536-entry x 4-byte range. The value computation is irrelevant to
|
|
;; the detection (real modules vectorize a bit-manipulation convert);
|
|
;; only the pointer/counter recurrences and the store coverage matter.
|
|
(module
|
|
(memory 5)
|
|
(func $init_full
|
|
(local $p i32) (local $q i32)
|
|
(local.set $p (i32.const 4096))
|
|
(local.set $q (i32.const -65536))
|
|
(loop $L
|
|
(f32.store (local.get $p) (f32.const 1))
|
|
(local.set $p (i32.add (local.get $p) (i32.const 4)))
|
|
(local.set $q (i32.add (local.get $q) (i32.const 1)))
|
|
(br_if $L (i32.ne (local.get $q) (i32.const 0)))
|
|
)
|
|
)
|
|
(func $init_half
|
|
(local $p i32) (local $q i32)
|
|
(local.set $p (i32.const 266240))
|
|
(local.set $q (i32.const -32768))
|
|
(loop $L
|
|
(f32.store (local.get $p) (f32.const 1))
|
|
(local.set $p (i32.add (local.get $p) (i32.const 4)))
|
|
(local.set $q (i32.add (local.get $q) (i32.const 1)))
|
|
(br_if $L (i32.ne (local.get $q) (i32.const 0)))
|
|
)
|
|
)
|
|
)
|