|
| 1 | +# Plan: x86-64-v2 SSE tier (v1) |
| 2 | + |
| 3 | +Operator decision 2026-10-10: a compile-time SIMD tier for **x86-64-v2** |
| 4 | +builds (SSE2 through SSE4.2, no AVX). Baseline x86-64 builds (no SSE4.2) are |
| 5 | +unchanged: they keep the AVX2 arm and the `cpu_guard` AVX2 startup floor. |
| 6 | +No runtime feature checks in the SIMD code. |
| 7 | + |
| 8 | +## Selection |
| 9 | + |
| 10 | +* Arm predicate: `all(target_arch = "x86_64", target_feature = "sse4.2", |
| 11 | + not(target_feature = "avx"))`, written out at each gate. |
| 12 | +* Reached by `target-cpu=native` on a v2-only CPU (Nehalem/Westmere, Atom |
| 13 | + Silvermont-class, VMs that hide AVX), or the new `.cargo/config-v2.toml` |
| 14 | + (`-Ctarget-cpu=x86-64-v2`). |
| 15 | +* Unchanged: AVX-512, AVX2, AVX-without-AVX2 (`simd_avx.rs`), and baseline. |
| 16 | + |
| 17 | +## Shape: route to the scalar realization, not a new intrinsic file |
| 18 | + |
| 19 | +Every type in `simd_avx2.rs` / `simd_avx512.rs` wraps a 256- or 512-bit |
| 20 | +register (`U8x32(pub __m256i)`, …), so none of them can be the v2 realization: |
| 21 | +unlike the AVX arm, there is no impl-block split that works. `simd.rs` instead |
| 22 | +routes the v2 arm to `simd_scalar.rs` — plain `[T; N]` arrays that LLVM |
| 23 | +vectorizes to SSE. Measured earlier (existing `simd_scalar.rs` compiled at |
| 24 | +x86-64 / v2 / sandybridge / v3): element-wise ops ~2× the AVX2 instruction |
| 25 | +count, SSE2/SSSE3/SSE4.2 produce identical code, reductions stay scalar, and |
| 26 | +`mul_add` becomes a software `fmaf` call on any tier without FMA. |
| 27 | + |
| 28 | +Only the `simd_*` backends import the x86 modules directly; every consumer |
| 29 | +goes through `crate::simd`, so the switch is confined to `simd.rs`. |
| 30 | + |
| 31 | +## Work items |
| 32 | + |
| 33 | +- [ ] P0 TESTS FIRST: `v2-qemu` parity arm (`--config .cargo/config-v2.toml`, |
| 34 | + run under `qemu-x86_64-static -cpu Nehalem`) in `scripts/masking-parity.sh` |
| 35 | + and a `realization/v2` row in `simd-matrix.yaml`, with an objdump witness |
| 36 | + (no AVX instruction at all: no `%ymm`, no VEX `v`-prefixed op). Expect it |
| 37 | + to fail before the arm exists. |
| 38 | +- [ ] P1 `.cargo/config-v2.toml`; `simd.rs` routing; `cpu_guard` floor gated off |
| 39 | + the v2 arm. |
| 40 | +- [ ] P2 close the API gap: compile v2, list every missing item, add each to |
| 41 | + `simd_scalar.rs` (types `U8x32`, `F32Mask16`, `F64Mask8` and the x86-only |
| 42 | + methods). Safe Rust only. |
| 43 | +- [ ] P3 gates: lib tests on v2 under qemu Nehalem; parity on every arm; clippy |
| 44 | + v2/v3/v4/avx/baseline; codegen witness avx2/avx512 unchanged. |
| 45 | +- [ ] P4 docs: CLAUDE.md realization list, blackboard, `simd.rs` dispatch comment. |
0 commit comments