Tool + version: synth v0.11.43 and v0.11.42 (reproduces on both — not a recent regression; first time this primitive went through synth). loom 1.1.13.
What happens: compiling the dissolved gale_k_stack_push_decide (a #[repr(C)] struct-return kernel-primitive decide) for cortex-m4f fails in the ARM backend, and the dependent body is then skipped:
warning: skipping function 'gale_k_stack_push_decide': backend 'arm' failed:
ARM encoding failed: Synthesis failed: ADD immediate too large for single instruction
warning: skipping function 'z_impl_k_stack_push': backend 'arm' failed:
branch-resolve size probe failed: Synthesis failed: ADD immediate too large for single instruction
Error: no functions compiled successfully (2 skipped) — nothing to emit
So nothing is emitted — the object is empty (this bit me: the empty object's zero .data/relocs first looked sem-shaped until I checked the compile actually succeeded).
Scope / attribution (measured):
- Repros on 0.11.42 AND 0.11.43 → pre-existing latent ARM-backend bug, not a v0.11.43 regression.
- Repros with and without
--native-pointer-abi → the flag is not implicated; it's the decide's own codegen.
- The decide fails first ("ADD immediate too large"); the body (
z_impl_k_stack_push) then fails the "branch-resolve size probe" (likely downstream of / same root as the oversized ADD).
Likely root: an ADD rd, rn, #imm where #imm exceeds the Thumb-2 modified-immediate range and isn't being split into ADD+ADD/MOVW+ADD (or SUB of the negation). Candidate sources: the 12-byte sret frame offset, a wasm-linmem base/offset add, or a constant in the inlined push_decide. The fix is to lower an out-of-range ADD immediate to a legal sequence instead of asserting.
Repro (frozen): gale-smart-data/.../wasm-testbed/repro-synth-stack-add-imm/ — stack_push.loom.wasm (5337 B, post-loom-inline) + the shim source + ERROR-v0.11.43.txt. One command:
synth compile stack_push.loom.wasm --target cortex-m4f --all-exports --relocatable -o /tmp/out.o2
Impact: blocks shipping k_stack_push (and likely k_stack_pop / any decide whose codegen emits a large ADD immediate) as a wasm-cross-LTO drop-in. Relevant to the struct-return family generally and to the gale#63 kernel-primitives component world (stack is a primitive in it). u64-shaped primitives (sem give+take, pipe rd+wr, fatal) and mutex_unlock are unaffected — they compile clean.
Kill-criterion: synth compile stack_push.loom.wasm --target cortex-m4f emits both functions (no "ADD immediate too large" skip), object non-empty.
Tool + version: synth v0.11.43 and v0.11.42 (reproduces on both — not a recent regression; first time this primitive went through synth). loom 1.1.13.
What happens: compiling the dissolved
gale_k_stack_push_decide(a#[repr(C)]struct-return kernel-primitive decide) forcortex-m4ffails in the ARM backend, and the dependent body is then skipped:So nothing is emitted — the object is empty (this bit me: the empty object's zero
.data/relocs first looked sem-shaped until I checked the compile actually succeeded).Scope / attribution (measured):
--native-pointer-abi→ the flag is not implicated; it's the decide's own codegen.z_impl_k_stack_push) then fails the "branch-resolve size probe" (likely downstream of / same root as the oversized ADD).Likely root: an
ADD rd, rn, #immwhere#immexceeds the Thumb-2 modified-immediate range and isn't being split intoADD+ADD/MOVW+ADD(orSUBof the negation). Candidate sources: the 12-byte sret frame offset, a wasm-linmem base/offset add, or a constant in the inlinedpush_decide. The fix is to lower an out-of-range ADD immediate to a legal sequence instead of asserting.Repro (frozen):
gale-smart-data/.../wasm-testbed/repro-synth-stack-add-imm/—stack_push.loom.wasm(5337 B, post-loom-inline) + the shim source +ERROR-v0.11.43.txt. One command:Impact: blocks shipping
k_stack_push(and likelyk_stack_pop/ any decide whose codegen emits a large ADD immediate) as a wasm-cross-LTO drop-in. Relevant to the struct-return family generally and to the gale#63 kernel-primitives component world (stack is a primitive in it). u64-shaped primitives (sem give+take, pipe rd+wr, fatal) and mutex_unlock are unaffected — they compile clean.Kill-criterion:
synth compile stack_push.loom.wasm --target cortex-m4femits both functions (no "ADD immediate too large" skip), object non-empty.