Skip to content

Commit 1ff8171

Browse files
authored
Merge pull request #260 from AdaWorldAPI/claude/gcc-intrinsic-spec-reference
knowledge: GCC as the intrinsic-spec reference (3-layer drill-down)
2 parents 61b3abc + 790a934 commit 1ff8171

3 files changed

Lines changed: 157 additions & 0 deletions

File tree

.claude/knowledge/agnostic-surface-cpu-matrix.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,40 @@ verifies that no per-CPU regression has crept in vs the historical baseline:
532532
533533
## M. AArch64 ground-truth core enumeration (GCC source)
534534
535+
> **Scope correction (appended 2026-07-27, operator-stated).** The heading and
536+
> the "authoritative" wording below overstate GCC's role. **GCC is the fill-in
537+
> for what we could not execute**; everything reachable was verified by running
538+
> it. Two distinct mechanisms, not to be conflated:
539+
>
540+
> - **Validation (what the lanes compute):** `scripts/neon-parity.sh` cross-builds
541+
> `crates/neon-simd-parity` for `aarch64-unknown-linux-gnu` and runs it under
542+
> `qemu-aarch64-static`, asserting the exercised lanes are bit-identical to
543+
> their scalar reference; `scripts/wasm-parity.sh` is the wasm32+simd128 twin
544+
> under node. **Coverage as of 2026-07-28 (from `selfcheck` in
545+
> `crates/neon-simd-parity/src/main.rs`, not the full export surface):**
546+
> `U32x16` (Add / BitXor / rotate_leftthe ChaCha20/BLAKE ARX triple),
547+
> `F32x16` (splat / roundtrip / add / reduce_sum), `I8x16` (roundtrip / add).
548+
> Exported lanes NOT yet exercised there (e.g. `I16x8`, `U8x16`, `U64x2`) are
549+
> **unverified by this harness**a later SIMD audit must not treat them as
550+
> measured; extending `selfcheck` is the way to promote one. Within its
551+
> coverage these runs are the measurement of record for lane arithmeticand
552+
> they need **no physical silicon**, which is why the aarch64 surface could be
553+
> measured at all.
554+
> - **Runtime detection (what a given CPU admits to having):**
555+
> `sysctl hw.optional.arm.FEAT_*` on Darwin / `getauxval(AT_HWCAP)` on
556+
> Linux/Android (`src/simd_neon_dotprod.rs:29-30`), `__cpuid_count` on x86
557+
> (`src/simd_caps.rs:160-167`).
558+
>
559+
> GCC's role is the third thing neither of those gives you: **which shipping core
560+
> carries which feature.** Emulation proves an instruction works; it cannot tell
561+
> you that `cortex-a76` has DOTPROD and `cortex-a72` does not. Read the table
562+
> below as *GCC's declared per-core feature membership*authoritative for
563+
> untestable parts, corroborating elsewhere.
564+
>
565+
> The URL cited at the end of this section points at mutable `master`; pin a
566+
> commit when re-scraping (see `.claude/knowledge/gcc-intrinsic-spec-reference.md`,
567+
> which also documents the intrinsic-semantics layers of the same source).
568+
535569
The matrix above uses three aarch64 columns (A53 / A72 / A76) that
536570
each cover a *dispatch tier*multiple physical cores share the same
537571
SIMD primitive set. The authoritative per-core feature membership is
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# GCC as the intrinsic-spec reference — the three-layer drill-down
2+
3+
> READ BY: anyone verifying what an intrinsic actually *does* before writing or
4+
> porting a SIMD kernel — `simd-savant`, `arm-neon-specialist`, and any session
5+
> touching `src/simd_*.rs`, the polyfill matryoshka, or a consumer-crate SIMD
6+
> swap.
7+
>
8+
> **Why this file exists:** the reference below was used across the NEON /
9+
> aarch64 / wasm planning work but was never written down. A 2026-07-27 sweep of
10+
> every URL host in every `.md` / `.rs` / `.toml` in this repo found no
11+
> intrinsic or ISA reference of any kind — the only spec-shaped citations were
12+
> four bare "Intel Intrinsics Guide" mentions with no link
13+
> (`vertical-simd-consumer-contract.md`) and one GCC file fetched off mutable
14+
> `master` (`agnostic-surface-cpu-matrix.md` §M). The link existed only in
15+
> session context. Recording it so it survives the session that knew it.
16+
17+
## The source
18+
19+
**`github.com/gcc-mirror/gcc`** — mirror of `gcc.gnu.org`. Pin a commit; never
20+
cite `master` (a spec citation that moves under you is not a citation).
21+
22+
Working pin used for the 2026-07-27 verification:
23+
`8f1698229d33a74cda7ec9f02575172df10b2774`
24+
25+
```
26+
https://raw.githubusercontent.com/gcc-mirror/gcc/<SHA>/<path>
27+
```
28+
29+
## The three layers — each answers a different question
30+
31+
| layer | path | answers |
32+
|---|---|---|
33+
| **1. declarations** | `gcc/config/i386/*intrin.h`<br>`gcc/config/aarch64/arm_neon.h` | *What builtin does this intrinsic map to, and what are its exact C types?* |
34+
| **2. machine description** | `gcc/config/*/*.md` | *What instruction / RTL does that builtin lower to, and what are the bit encodings?* |
35+
| **3. conformance tests** | `gcc/testsuite/gcc.target/{i386,aarch64,arm,...}/` | *What does it compute?***where a runtime test exists**, an executable check with an **inline scalar reference implementation** |
36+
37+
Layer 3 is the one people don't know about and is the most useful **when it
38+
applies** — but qualify the claim: `gcc.target` mixes runtime tests with
39+
compile-only, diagnostic, and codegen (`scan-assembler`) tests, and not every
40+
intrinsic has a runtime test with a scalar reference. The discriminator is the
41+
DejaGnu directive: `dg-do run` (executable) vs `dg-do compile` / `dg-do
42+
assemble` (no semantic validation). Where a `dg-do run` test with a scalar
43+
loop + `abort()`-style comparison exists, it is a per-intrinsic **oracle**,
44+
not prose — directly usable for the byte-parity discipline this workspace
45+
already applies elsewhere (tesseract-rs, stockfish-rs): port a kernel, then
46+
prove it against GCC's own definition of what the instruction computes rather
47+
than a hand-written reference. Where only a compile/scan test exists, layer 3
48+
proves nothing about semantics — fall back to the ISA specification (Intel
49+
SDM / Arm ARM) as the authority, with layers 1-2 still pinning types and
50+
lowering.
51+
52+
## Worked example — the question that motivated this file
53+
54+
`_mm256_mul_epu32` vs `_mm256_mul_epi32`, needed for a `curve25519-dalek`
55+
SIMD swap onto `ndarray::simd`.
56+
57+
**Layer 1** (`gcc/config/i386/avx2intrin.h`):
58+
59+
```c
60+
_mm256_mul_epi32 (__m256i __X, __m256i __Y)
61+
{ return (__m256i) __builtin_ia32_pmuldq256 ((__v8si)__X, (__v8si)__Y); }
62+
63+
_mm256_mul_epu32 (__m256i __A, __m256i __B)
64+
{ return (__m256i) __builtin_ia32_pmuludq256 ((__v8si)__A, (__v8si)__B); }
65+
```
66+
67+
Both take `__v8si` and return `__m256i` — **identical C signatures**. The
68+
signed/unsigned distinction lives entirely in the instruction (VPMULDQ vs
69+
VPMULUDQ), not in the type. So the type system will not catch a mix-up here;
70+
only the semantics will.
71+
72+
**Layer 3** (`gcc/testsuite/gcc.target/i386/avx2-vpmuludq-2.c`) gives the
73+
semantics in one line:
74+
75+
```c
76+
for (i = 0; i < 4; i++)
77+
r[i] = s1[i * 2] * s2[i * 2]; /* unsigned int × unsigned int → unsigned long long */
78+
```
79+
80+
i.e. **even 32-bit lanes only** (equivalently: the low 32 bits of each packed
81+
64-bit element), widening to 4 × u64. The odd lanes are ignored entirely.
82+
`avx2-vpmuldq-2.c` sits beside it as the signed twin — the pair is a ready-made
83+
differential oracle.
84+
85+
## Honest limits
86+
87+
- **Test filenames are not guessable.** `avx2-vpmuludq-2.c` and
88+
`avx2-vpermd-1.c` exist; `avx2-vpsrlvd-1.c` does not (that op is tested under
89+
a different name). Get a real directory listing rather than probing guesses.
90+
- **The GitHub *API* is scoped to session repos**, so `gcc-mirror/gcc` cannot be
91+
listed through it from here; `raw.githubusercontent.com` fetches work fine.
92+
- **GitHub *code search* excludes forks** — it silently returns 0 for files that
93+
demonstrably exist in this org's forked repos. Verified 2026-07-27:
94+
`filename:harvest_network.rs` returned 0 while the file exists at
95+
`AdaWorldAPI/ruff:crates/ruff_cpp_spo/examples/harvest_network.rs`. **Never
96+
treat a code-search miss on a fork as evidence of absence** — clone and grep.
97+
- Layer 3 covers what an intrinsic *computes*. It does not give latency or
98+
throughput; that is a separate question and a separate source.
99+
100+
## Not harvested
101+
102+
There is no baked/harvested copy of this spec set in the workspace. Checked
103+
2026-07-27 by local grep (not code search — see above): `ndarray` (tree +
104+
releases — it has none), `lance-graph` (tree + all 11 releases, which are model
105+
codebooks / corpus / topology data), `ruff` (5 harvest examples, all
106+
Tesseract/Leptonica C++), `curve25519-dalek`. The reference is consulted
107+
directly at a pinned SHA.
108+
109+
Worth noting for anyone who wants one: `ruff_cpp_spo` already walks C++ headers
110+
via libclang and emits SPO manifests, and GCC's `*intrin.h` are plain C headers
111+
of exactly that shape — so a `harvest_intrinsics.rs` producing the full
112+
intrinsic → builtin → instruction table would be an extension of proven
113+
machinery rather than new machinery. Not built; recorded as an option.

.claude/knowledge/vertical-simd-consumer-contract.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,16 @@ The `simd-savant` agent on the `lance-graph` side runs PRE-MERGE against every W
300300
- PR #400 (architectural capture commit) — the canonical reference + tech-debt entries
301301

302302
**External references:**
303+
304+
> **Sourcing note (appended 2026-07-27):** the four intrinsic citations below
305+
> were recorded as bare "Intel Intrinsics Guide" mentions with no link. The
306+
> checkable source for intrinsic *semantics* in this workspace is GCC —
307+
> declarations in `gcc/config/i386/*intrin.h`, plus an executable per-intrinsic
308+
> oracle (scalar reference inline) in `gcc/testsuite/gcc.target/i386/`. See
309+
> `.claude/knowledge/gcc-intrinsic-spec-reference.md` for the three-layer
310+
> drill-down and a pinned SHA. Prefer that, at a pinned commit, over an
311+
> unlinked guide reference. Original lines kept verbatim below.
312+
303313
- Intel Intrinsics Guide — `_mm512_abs_epi8` (VPABSB; does NOT saturate `i8::MIN`)
304314
- Intel Intrinsics Guide — `_mm512_min_epu8` (VPMINUB; unsigned-byte minimum, used to clamp the VPABSB result)
305315
- Intel Intrinsics Guide — `_mm512_popcnt_epi64` (VPOPCNTDQ; AVX-512 feature `avx512vpopcntdq`)

0 commit comments

Comments
 (0)