Skip to content

#369 marked closed, but the real falcon-flight-v1.123 fused core still skips 26/156 on --relocatable cortex-m7dp (incl. run-stabilization); trunc_sat unsupported + a pressure-dependent 'integer popped f32' class #782

Description

@avrabe

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions