fix(decoder): SIMD (v128) ops loud-skip — category-level catch, no silent no-op drop (#680) - #691
Merged
Merged
Conversation
…lent no-op drop on non-SIMD targets (#680) On cortex-m3 (no SIMD hardware) WASM SIMD ops silently compiled to zero machine code: i32x4.add returned an operand passthrough (mov r0,r1) and v128.store left memory unwritten — the #554 class, for v128. Root cause: the decoder DOES decode a large v128 subset into WasmOp variants, but the only selector arms for them are gated on a `has_helium` flag that nothing in the production pipeline ever sets (test-only prototype), so selection dropped them without a diagnostic. The GI-FPU-001 (#371) loud-skip only fires for ops that decode to None — the decoded-but-unselectable v128 ops sailed past it (per-op-incomplete honesty, exactly how #680 slipped in). Fix — category-level, no wildcard drop survives: - `is_simd_operator`: macro-generated from wasmparser's own `for_each_operator!` proposal markers (`@simd` / `@relaxed_simd`), so it covers the ENTIRE SIMD operator space of the pinned wasmparser with no hand-kept op list. Any SIMD-proposal operator flags the function into the established loud-skip/honest-bail lane (#371 all-exports skip with a named reason, #556 single-function bail). - v128-typed LOCALS and v128 params/results flag too — expressible with zero SIMD operators (`local.get 0` passthrough), lowered as 4-byte moves that silently truncate the 16-byte value (both decode entry points, like the #648 float-global fix). - v128-typed GLOBAL accesses (imported + defined, full index space) flag — same lane as #648's f32/f64 globals: the `v128.const` initializer is never captured and an access moves 4 of the 16 bytes. The reason string says "no SIMD lowering for this target" (not "SIMD invalid") — cortex-m55/MVE can legitimately lift this once the Helium lowering is actually wired to a target. Oracles: red on main (issue reproducers compile rc=0, wrong result under QEMU vs wasmtime) → green (rc=1, diagnostic naming the op + #680); scalar functions in the same module still compile (non-vacuity, mixed-module verified). New decoder tests red on main: SIMD-op flag (both issue reproducers), v128 local + signature flag, v128 global access flag (imported index shift), i32/scalar siblings unflagged. Frozen anchors 10/10 byte-identical; workspace 109 suites green; fmt + chunked clippy -D warnings clean. Refs #554, #665, #648, #371, #556, #369. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #680.
Problem
On
-t cortex-m3(no SIMD hardware) WASM SIMD (v128) ops silently compiled to zero machine code:i32x4.addreturned an operand passthrough (mov r0,r1) andv128.storeleft memory unwritten — wrong result shipped with rc=0. The #554 class (aarch64 f32 drop), here for v128 on the thumb backend.Root cause: the decoder decodes a large v128 subset into
WasmOpvariants, but the only selector arms for them are gated on ahas_heliumflag nothing in the production pipeline sets (test-only MVE prototype) — so selection dropped them without a diagnostic. The GI-FPU-001 loud-skip (#371) only fires for ops that decode toNone; the decoded-but-unselectable v128 ops sailed past it. Per-op-incomplete honesty is exactly how this slipped through (v128.any_truewas loud,i32x4.addsilent).Fix — category-level, no wildcard drop survives
is_simd_operator— macro-generated from wasmparser's ownfor_each_operator!proposal markers (@simd/@relaxed_simd): covers the entire SIMD operator space of the pinned wasmparser, no hand-kept op list to fall out of date. Any SIMD-proposal operator routes the function through the established machinery: fix(#369): unsupported decoder ops loud-skip, never silently drop (GI-FPU-001) #371 all-exports loud-skip with a named reason, fix(aarch64): reject f32 ops honestly instead of silent miscompile (#554) #556 single-function honest bail.local.get 0passthrough), lowered as 4-byte moves that silently truncate the 16-byte value. Both decode entry points, following the fix(decoder): float-typed global accesses loud-skip — the last silent float path (GI-FPU-001, #369) #648 float-global precedent.v128.constinitializer is never captured and an access moves 4 of the 16 bytes.The diagnostic says "no SIMD lowering for this target" (not "SIMD invalid") — cortex-m55/MVE can legitimately lift this once the Helium lowering is actually wired to a target.
Oracles (red → green)
skipping function 'f': ... I32x4Splat: no SIMD lowering for this target — the op would be silently dropped to a no-op (WASM SIMD proposal, #680).vfskipped,sfemitted, ELF produced).frozen_codegen_bytes); workspace 109 test suites green;cargo fmt --check+ chunkedclippy --all-targets -- -D warningsclean across all crates.Lineage: #554 (honest rejection over silent miscompile), #665 (intentionally-ignored class), #648 (typed-global/local precedent), #371/#556 (loud-skip / honest-bail machinery), #369 (GI-FPU-001).
🤖 Generated with Claude Code