Thanks for the big float-completion push (v0.41–v0.45) — the synthetic differentials (156/156 f32, 126/126 f64) are great. But verifying against the real shipped falcon core (relay invited this on jess#144) shows #369 is not complete for falcon yet. Filing precisely, evidence-first.
Real-build measurement
- Input:
falcon-flight-v1.123.wasm (relay release asset, sha e4622a12…) → meld v0.41.1 fuse --reproducible → the fused Core module.
- Compiler:
synth v0.45.1, compile -t cortex-m7dp --relocatable --native-pointer-abi --shadow-stack-size 4096.
- Result: 26 of 156 functions skipped. (Plain
--relocatable without --native-pointer-abi: 24/183.) Identical on the pre-loom fused module, so it is not a loom/meld artifact.
Breakdown of the 26
| count |
class |
note |
| 12 |
GI-FPU-002: an integer operation popped an f32 (VFP) stack value — invalid wasm or an unlowered float op reached the integer path |
includes run-stabilization (the flight-control step). See caveat below. |
| 3 |
GI-FPU-001: unsupported operator |
i32.trunc_sat_f32_s, i32.trunc_sat_f64_s, f64.reinterpret_i64 |
| 3 |
GI-FPU-002: VFP register file exhausted (S0–S15 / D0–D7 all live, no VFP spilling) |
deep f32/f64 expressions |
| 2 |
#503 (i64/f64 stack arg) |
|
| 2 |
#518 (i64/f64 param in a frame-backing fn) |
|
| 2 |
#345 (LdrSym literal pool out of range, imm12 > 4095 for __synth_globals) |
|
| 2 |
i64 spill-slot pool / no free callee-saved |
|
Confirmed minimal repro (GI-FPU-001, trunc_sat)
(module
(func (export "ts32") (param f32) (result i32) (i32.trunc_sat_f32_s (local.get 0)))
(func (export "ts64") (param f64) (result i32) (i32.trunc_sat_f64_s (local.get 0))))
synth compile ts.wasm -t cortex-m7dp --relocatable
→ skipping 'ts32': unsupported operator (I32TruncSatF32S) … (GI-FPU-001, #369)
→ skipping 'ts64': unsupported operator (I32TruncSatF64S) … (GI-FPU-001, #369)
The trapping trunc_f32_s variants lower, but the saturating trunc_sat_* variants don't. Rust emits trunc_sat for as casts (default since the saturating-float-to-int stabilization), so falcon hits these (8 occurrences in v1.123: 7× i32.trunc_sat_f64_s, 1× i32.trunc_sat_f32_s). On VFP this is a direct VCVT (Arm VCVT.S32.F32 already saturates), so it should be cheap to add.
Honest caveat on the dominant class
I could not minimize the 12× "integer popped f32" yet: the obvious candidate (i32.reinterpret_f32, 97 uses in the module) lowers fine in isolation:
(func (export "f2i") (param f32) (result i32) (i32.add (i32.reinterpret_f32 (local.get 0)) (i32.const 1))) ;; compiles OK
So it's pattern/register-pressure dependent, not one operator. Happy to bisect with you against the fused module — tell me the most useful next probe (e.g. a --dump of the offending function's op stream).
jess impact
run-stabilization is the falcon flight-control step; while it doesn't lower, falcon cannot reach the M7 on-target (REQ-PIX-001 / DD-018 --relocatable+TCB-link path). Not urgent to you if it's fast to close, but it's the gate for our on-target bring-up. #369 is currently marked closed — this is the real-fused-core residual against it.
Repro is fully deterministic (public falcon asset + meld). Glad to help minimize or test a fix.
Thanks for the big float-completion push (v0.41–v0.45) — the synthetic differentials (156/156 f32, 126/126 f64) are great. But verifying against the real shipped falcon core (relay invited this on jess#144) shows #369 is not complete for falcon yet. Filing precisely, evidence-first.
Real-build measurement
falcon-flight-v1.123.wasm(relay release asset, shae4622a12…) →meld v0.41.1 fuse --reproducible→ the fused Core module.synth v0.45.1,compile -t cortex-m7dp --relocatable --native-pointer-abi --shadow-stack-size 4096.--relocatablewithout--native-pointer-abi: 24/183.) Identical on the pre-loom fused module, so it is not a loom/meld artifact.Breakdown of the 26
GI-FPU-002: an integer operation popped an f32 (VFP) stack value — invalid wasm or an unlowered float op reached the integer pathrun-stabilization(the flight-control step). See caveat below.GI-FPU-001: unsupported operatori32.trunc_sat_f32_s,i32.trunc_sat_f64_s,f64.reinterpret_i64GI-FPU-002: VFP register file exhausted(S0–S15 / D0–D7 all live, no VFP spilling)#503(i64/f64 stack arg)#518(i64/f64 param in a frame-backing fn)#345(LdrSymliteral pool out of range, imm12 > 4095 for__synth_globals)Confirmed minimal repro (GI-FPU-001,
trunc_sat)The trapping
trunc_f32_svariants lower, but the saturatingtrunc_sat_*variants don't. Rust emitstrunc_satforascasts (default since thesaturating-float-to-intstabilization), so falcon hits these (8 occurrences in v1.123: 7×i32.trunc_sat_f64_s, 1×i32.trunc_sat_f32_s). On VFP this is a directVCVT(ArmVCVT.S32.F32already saturates), so it should be cheap to add.Honest caveat on the dominant class
I could not minimize the 12× "integer popped f32" yet: the obvious candidate (
i32.reinterpret_f32, 97 uses in the module) lowers fine in isolation:So it's pattern/register-pressure dependent, not one operator. Happy to bisect with you against the fused module — tell me the most useful next probe (e.g. a
--dumpof the offending function's op stream).jess impact
run-stabilizationis the falcon flight-control step; while it doesn't lower, falcon cannot reach the M7 on-target (REQ-PIX-001 / DD-018--relocatable+TCB-link path). Not urgent to you if it's fast to close, but it's the gate for our on-target bring-up. #369 is currently marked closed — this is the real-fused-core residual against it.Repro is fully deterministic (public falcon asset + meld). Glad to help minimize or test a fix.