CI: Build and test the SVE backend

No CI job compiles the SVE backend. The aarch64 jobs are NEON, and the SME jobs take the NEON headers by design, so Eigen/src/Core/arch/SVE/* is never built — and .rules:libeigen:affected-tests:sve-sme fired SME jobs on SVE changes, so editing SVE ran jobs that never touched it. That is how the backend came to vectorize three of the fourteen scalar types NEON does without anything going red.

Adds EIGEN_TEST_SVE and EIGEN_TEST_SVE_VL, since the backend needs a compile-time vector length: EIGEN_ARM64_SVE_VL comes from __ARM_FEATURE_SVE_BITS, which only -msve-vector-bits sets. The -march stays the caller's responsibility, as it is for SME.

Builds and runs the suite under QEMU at 128, 256 and 512 bits — the three vector lengths SVE hardware implements: Neoverse V2 and Grace at 128, Neoverse V1 and Graviton3 at 256, A64FX at 512. The sweep is the point: the packet code has VL-dependent fold counts and transpose networks that one length cannot exercise, and a packet size of eight — where the GEBP column-group guard goes wrong — is reached by float at 256 and by double at 512. Lengths above 512 are architecturally legal but unimplemented; compile-only coverage of them runs nothing, so they are not built. The shared affected-tests rule is split so an SVE change triggers SVE jobs.

sve_vector_length guards the rest. A binary built for one vector length and run at another makes every packet type a lie and lets the suite pass vacuously; qemu is the easy way in, because above 512 bits it keeps its default 512-bit task vector length unless sve-default-vector-length is given. The check reads RDVL through inline asm — svcntb() folds to the compile-time constant under -msve-vector-bits, which would make it a tautology. Verified it fails when the lengths disagree, not just that it passes when they match.

The -march is armv8.2-a+sve, which is all the backend needs. Do not raise it to +sve2: GCC 13 through 15 then emit whilewr p0.b, wzr, wzr for the autovectorizer's alias checks — 32-bit W registers where the instruction takes X — and the assembler rejects it, at every vector length from 256 up. That is a GCC bug, not an Eigen one; clang is unaffected.

What the coverage finds

This is CI configuration only — no Eigen/ change — so the new jobs do not trigger on this MR's own diff: .rules:libeigen:affected-tests:sve keys on changes: of arch/SVE/** or ConfigureVectorization.h, or on an all-platforms label. Adding that label here runs the ten SVE jobs — four cross-builds and six test jobs — and the 256- and 512-bit test jobs go red, because turning this coverage on finds four pre-existing bugs on master:

Job Bug
test:linux:sve256:gcc-13 and sve512 170 of 2816 tests fail with malloc(): corrupted top size, double free, and SIGSEGV. gebp_kernel gates a four-column group on a sub-packet size compared against nr, which is 8 on this backend, so the group runs through an eight-lane sub-packet — wrong results and out-of-bounds writes whenever rows % 8 >= 4 and cols % 8 >= 4. Reachable on shipping hardware: a packet size of eight is float at 256 and double at 512, and the failures split exactly that way — the 256-bit jobs fail float tests, the 512-bit jobs double ones. sve128, where no type has a packet size of eight, is green.

Two further bugs — an EIGEN_STACK_ALLOCATION_LIMIT too small for the blocked kernels' stack panel, and loadQuadToDoublePacket having no overload above 16 real lanes — only bite above 512 bits. They were found while this MR still built at 1024 and 2048, and are fixed even though no hardware reaches those widths, so that the backend already compiles when one does.

All four are fixed in !2938 (merged), stacked directly on this branch so these same jobs run against the fixes there and in !2934 (merged). Merge this first, then !2938 (merged), then !2934 (merged).

Verification

On a Neoverse V2 machine: the full suite compiles at VL=128 and VL=512, and the Official suite passes at VL=128 natively. Two caveats — eigensolver_complex_4 is flaky independently of this (66/120 seeds on SVE, 40/120 on NEON, unchanged by anything here), and I have no GCC 14 to hand, which is what these jobs pin; 13.3 and 15.2 both behave identically on the flag that matters.

test:linux:aarch64:clang-14:default is unrelated and pre-existing — it is red on !2910 (merged) and !2926 (merged) too; here it is a single redux_4 that passes on retry. The other non-SVE reds are infrastructure, not code: the four Windows builds landed on a runner with no build tool (CMake was unable to find a build program corresponding to "Ninja", CMAKE_CXX_COMPILER not set), and the three avx512dq jobs landed on a machine without AVX-512, so essentially every test dies on SIGILL before running.

Edited by Rasmus Munk Larsen

Merge request reports

Loading
Loading