aarch64 selector: operand-class confusion — "local.set: expected GP operand, got FP" / "fcompare: expected FP operand, got GP" across the float MVP-core files
Found while ranking the MVP-core blockers for RQ-65-MVPCORE (#1017).
Measured
synth compile <file>.wast -b aarch64 --all-exports, per-function skip reasons of one class — the selector's operand-class tracker disagreeing with the value actually on its stack:
On the v0.63 census path (before #1225 the merge fed the backend i32-only signature tables, which makes this class LOOK larger than it is — reported here as the upper bound):
| reason |
files |
functions |
fbinop: expected FP operand, got GP |
3 |
132 |
fcompare: expected FP operand, got GP |
3 |
64 |
funop: expected FP operand, got GP |
7 |
62 |
trunc: expected FP operand, got GP |
3 |
32 |
local.set: expected GP operand, got FP |
6 |
17 |
copysign / reinterpret / fload variants |
3 + |
~10 |
On the v0.65 path (single-module files carry their real signatures; multi-module files are refused by the merge before reaching the selector), the class that REMAINS is the honest one:
| reason |
files |
functions |
sole blocker of |
local.set: expected GP operand, got FP |
local_set.wast, align.wast, memory_redundancy.wast |
4 |
1 file |
fload: expected GP operand, got FP |
2 |
2 |
– |
fcompare: expected FP operand, got GP |
2 |
5 |
– |
The local.set shape (local_set.wast type-param-f32 / type-mixed: an f32 parameter stored to a local) says the aarch64 home-slot model treats every local as GP-class, so an FP value cannot be homed — consistent with the sibling decline function homes its parameters ... but declares a FLOAT parameter — the aarch64 home-slot model is single-class (4 files, 15 functions, 1 sole).
Why it is filed rather than fixed here
A loud decline, not a wrong answer. It sits behind other blockers in all but one file (sole blocker of 1 file on the v0.65 path), so a fix gains reach only together with the br_table value-carrying gap (2 sole, 13 files, 90 functions — the top aarch64 lowering blocker now that the merge's "declares no globals" refusal, which hid it, is gone). Both need the aarch64 float/locals execution oracles (aarch64_locals_851_differential.py, aarch64_float_completion_851_differential.py) extended to the newly accepted shapes first.
Refs #1017, #851, #1225.
aarch64 selector: operand-class confusion — "local.set: expected GP operand, got FP" / "fcompare: expected FP operand, got GP" across the float MVP-core files
Found while ranking the MVP-core blockers for RQ-65-MVPCORE (#1017).
Measured
synth compile <file>.wast -b aarch64 --all-exports, per-function skip reasons of one class — the selector's operand-class tracker disagreeing with the value actually on its stack:On the v0.63 census path (before #1225 the merge fed the backend i32-only signature tables, which makes this class LOOK larger than it is — reported here as the upper bound):
fbinop: expected FP operand, got GPfcompare: expected FP operand, got GPfunop: expected FP operand, got GPtrunc: expected FP operand, got GPlocal.set: expected GP operand, got FPcopysign/reinterpret/floadvariantsOn the v0.65 path (single-module files carry their real signatures; multi-module files are refused by the merge before reaching the selector), the class that REMAINS is the honest one:
local.set: expected GP operand, got FPlocal_set.wast,align.wast,memory_redundancy.wastfload: expected GP operand, got FPfcompare: expected FP operand, got GPThe
local.setshape (local_set.wasttype-param-f32/type-mixed: an f32 parameter stored to a local) says the aarch64 home-slot model treats every local as GP-class, so an FP value cannot be homed — consistent with the sibling declinefunction homes its parameters ... but declares a FLOAT parameter — the aarch64 home-slot model is single-class(4 files, 15 functions, 1 sole).Why it is filed rather than fixed here
A loud decline, not a wrong answer. It sits behind other blockers in all but one file (sole blocker of 1 file on the v0.65 path), so a fix gains reach only together with the
br_tablevalue-carrying gap (2 sole, 13 files, 90 functions — the top aarch64 lowering blocker now that the merge's "declares no globals" refusal, which hid it, is gone). Both need the aarch64 float/locals execution oracles (aarch64_locals_851_differential.py,aarch64_float_completion_851_differential.py) extended to the newly accepted shapes first.Refs #1017, #851, #1225.