Skip to content

falcon cascade still declines on cortex-m7dp at v0.66.0 — GI-FPU-002 on the single tick function (21 of 22 lower) #1267

Description

@avrabe

Summary

On synth v0.66.0, the falcon flight cascade compiles almost completely for
--target cortex-m7dp: 21 of 22 functions lower, including 1408- and
1468-byte ones. Exactly one declines — the exported tick — with:

GI-FPU-002: VFP register file exhausted (S0..S15 all live) — f32/f64 register
pressure exceeds the file; the backend retries with VFP spilling (#881) and
this surfaces only if that also fails

#881 is closed, so this is a report that the case it covers still reproduces
on the current release with a real workload.

Reproduce

synth compile falcon_cascade_cm.wasm --target cortex-m7dp --all-exports -o out.elf

The component is the published falcon cascade (pulseengine:falcon-cascade@0.10.0),
a single step export wrapping the whole flight core — IEKF estimator,
geometric SE(3) attitude, ADRC inner loop, mixer with rotor-out FDI, plus the
altitude and position loops. It is float-heavy by construction and the tick is
one large function after inlining.

Target sensitivity (same input, same synth)

target functions skipped of 22
cortex-m7dp 1 (the tick only)
cortex-m4f 3
cortex-m7 3
cortex-m3 (no FPU) 16

What we tried on our side, and why it did not help

Register pressure is arguably ours, so we split the export into a thin
forwarder plus an #[inline(never)] body. The decline simply moved with the
body:

warning: skipping function 'func_1': ... GI-FPU-002 ...
Error: #1102: 1 retained function(s) relocate against function(s) this compile
DECLINED: 'controller@0.10.0#step' -> 'func_1'

So the pressure is inherent to the tick body — where FlightCore::step inlines
the full cascade — and not to the export boundary. Splitting at the seam cannot
fix it; it converts a partial object into an unlinkable one. Reducing it from
our side would mean forcing #[inline(never)] on the flight core's internal
stages, which changes the code we verify and fly, so we would rather ask first.

Question: is per-stage #[inline(never)] in the guest the intended remedy
for GI-FPU-002, or is VFP spilling expected to cover a tick of this size?

Credit where due — two refusals behaved exactly right

Both #952 (partial object) and #1102 (unlinkable object) exited non-zero
with an explicit explanation rather than shipping something a $? gate would
accept. That is the correct behaviour and it is what made this diagnosable in
one pass.

Context

Asked by a colleague evaluating the meld+synth firmware route for a Pixhawk
6X-RT / H7 airframe: "validate a trivial float path through
synth compile --cortex-m → Renode before committing the firmware rewrite to
the schedule."
Trivial float paths lower correctly — verified vmul.f32,
vadd.f32, vdiv.f32, vsqrt.f32 with the hard-float ABI on m7dp — so #369
and #708 are genuinely fixed. This tick is the remaining gate.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions