Repository navigation
feat(aarch64): milestone 3 — scalar floating point (#538) - #787
Merged
Merged
Conversation
Add the A64 scalar-float instruction encodings (V/D/S register file): FADD/FSUB/FMUL/FDIV, FABS/FNEG/FSQRT (S+D), FCMP + the NaN-correct Mi condition, the FMOV GP<->FP bridges, FCVT S<->D, and SCVTF/UCVTF int->float. Every base is clang-cross-verified (fp_* tests). The trapping float->int truncations (FCVTZS/FCVTZU) are deliberately absent — A64 saturates where WASM traps (#709 class), so they stay loud-declined at the selector. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…APCS64 (#538) Lower the high-value scalar-float ops: f32/f64 const, add/sub/mul/div, abs/neg/sqrt, the full compare family (NaN-correct conds), f32<->f64 promote/demote, i32->float convert (SCVTF/UCVTF), and the f32<->i32 reinterprets (FMOV). The value stack now tags each entry with its register FILE (GP vs FP); float params resolve to their AAPCS64 V registers via an independent counter (select_typed threads the f32/f64 param masks). A GP op fed an FP operand ERRORS (type-confusion guard), never reads the wrong file. Trapping float->int truncations (FCVTZS/FCVTZU saturate, #709) and min/max/copysign/rounding stay loud-declined. 36 backend tests green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
aarch64_m3_floats_538_differential.py runs each emitted float function two ways — under unicorn (UC_ARCH_ARM64, FPEN enabled) AND natively on the arm64 host (MAP_JIT mmap + CFUNCTYPE) — and diffs BOTH bit-exactly against wasmtime, including NaN / +-0 / +-inf inputs (compare NaN-ordering) and mixed int/float AAPCS64 param assignment. 513/513 cases matched (native + unicorn). The trapping float->int truncations are absent by design (loud-declined, #709); their decline is asserted in the backend unit tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…upports The m2 decline-matrix oracle + the #554 loudskip test asserted f32.add/f64.mul LOUD-DECLINE, but m3 (#787) implemented them → CI RED (correctly). Move both gates to floats that DELIBERATELY stay declined: i32.trunc_f32_s (A64 FCVTZS saturates where WASM traps — #709 soundness) + f32.min (NaN-propagation differs). The honesty gate stays meaningful; the now-supported floats are exercised by the m3 differential. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AArch64 backend milestone 3 — scalar floating point (#538)
v0.46 Wave-2 Lane 4. Extends the host-native A64 backend (
crates/synth-backend-aarch64) from the integer-only m2 subset to scalar floating point — the separate V/D/S register file.Float op coverage: 0 → 35
m2 loud-declined every float op. m3 lands the high-value, total (non-trapping) scalar-float surface:
addsubmuldivabsnegeqneltlegtgef32.const(materialize + FMOV)addsubmuldivabsnegsqrteqneltlegtgef64.constf64.promote_f32f32.demote_f64f32/f64.convert_i32_sf32/f64.convert_i32_uf32.reinterpret_i32i32.reinterpret_f32Register-file separation
A64 floats live in V0–V31, an ABI counter independent of the GP arg registers. The value stack now tags each entry with its file (
Gp/Fp);select_typedthreads the per-paramf32/f64masks so(param i32 f32 i32)correctly resolves tow0, s0, w1. A GP op fed an FP operand errors (type-confusion guard) — never reads the wrong file.Soundness — honest decline matrix
Still loud-declined (no symbol emitted, honest error — never silent-wrong):
i32.trunc_f32_s/_u,i32.trunc_f64_s/_u): A64FCVTZS/FCVTZUsaturate where WASM traps on out-of-range/NaN — the thumb-2 f32: i32.trunc_f32_s/u silently saturate instead of trapping on NaN/Inf/out-of-range (bare VCVT, no guard) — WASM Core §4.3.3 soundness bug #709 "more-total-than-WASM" class. Verified declined end-to-end.min/max/copysign/rounding (ceil/floor/trunc/nearest) and i64↔float conversions — a later increment.f32.sqrtis decode-dropped upstream (_ => None); the selector arm exists but isn't reached (kept out of the count).Verification
mi/ls/gt/geconds, the FMOV GP↔FP bridges, FCVT S↔D, SCVTF/UCVTF) checked againstclang -target aarch64-linux-gnuground truth (fp_*encoder tests).aarch64_m3_floats_538_differential.py): each function runs under unicorn (UC_ARCH_ARM64, FPEN on) AND natively on the arm64 host (MAP_JIT), diffed bit-exactly vs wasmtime — 513/513 cases, including NaN/±0/±inf inputs and mixed int/float param assignment.Cover targets only. References #538 (milestone 3). Do not merge.
🤖 Generated with Claude Code
https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L