Core: Optimize stride-2 pgather on additional SIMD backends

Describe the feature you would like to be implemented.

Extend the stride-2 pgather optimization in !3108 (merged) to additional SIMD backends, keeping the existing packet API. The complex-component evaluator already uses pgather<Scalar, Packet>(from, 2) across supported backends; this follow-up is about improving the backend implementations.

Candidate backends to evaluate:

  • ARM NEON (ARM32 and AArch64, including half packets).
  • ARM SVE.
  • PowerPC AltiVec/VSX.
  • RISC-V RVV, including its supported packet groupings.
  • LoongArch LSX.
  • Other applicable backends, such as ZVector, MSA, and HVX, as hardware and tooling become available.

Cover float and double where supported. Record backends where the existing implementation is already competitive; a specialized path should be justified by measurements.

Why Would such a feature be useful for other users?

Complex real() and imag() reductions gather every other scalar from interleaved storage. In !3108 (merged), scalar lane insertion or hardware gathers limited performance on x86. Optimizing the existing stride-2 gather with bounded overlapping loads and permutations improved SSE, AVX/AVX2, and AVX-512. Other callers of stride-2 pgather can benefit as well.

NEON currently assembles float packets with individual lane loads, SVE uses indexed gathers, and RVV already has native strided loads. The best approach therefore needs to be determined per backend rather than copying the x86 sequence mechanically.

Any hints on how to implement the requested feature?

For a packet of P scalars, the selected coefficients are from[0], from[2], ..., from[2*(P-1)]. Preserve that memory boundary: do not read before from or beyond from[2*(P-1)]. In particular, a full interleaved load of 2*P scalars can overread when from points to the final packet of imaginary components. Evaluate bounded overlapping loads and permutations, or native strided loads, under the backend's actual ISA requirements.

Acceptance criteria for each port:

  • Preserve the existing pgather API, fallback behavior for other strides, device annotations, and C++14 support. Do not add a complex-component-specific packet operation.
  • Run test/packetmath_gather.cpp and test/complex_components.cpp, including full/half packets, unaligned offsets, exact allocation bounds, literal/runtime stride 2, negative/zero/other strides, and bitwise preservation of NaN payloads, signed zeros, infinities, and subnormals. Use sanitizers or memory checking where supported.
  • Compare benchmarks/Core/bench_pgather.cpp and benchmarks/Core/bench_complex_components.cpp before/after on native hardware. Include small and large inputs, float/double, both components, PropagateFast/PropagateNaN, and other-stride controls. Report compiler/ISA flags, CPU, repeated measurements with variability, and regressions. Emulator correctness runs do not establish native speedups.
  • Inspect generated assembly or collect applicable instruction counters to explain the result. Valgrind support varies by backend; report unavailable coverage explicitly.

Use affected-tests and the relevant backend selection for follow-up MRs; do not add all-platforms by default.

Additional resources

  • Related issue: #3097 (closed).
  • Implementation, benchmark tables, and validation evidence: !3108 (merged), stride-2 optimization commit a40b378293e94de417b9ca42d846985697db683d.
  • The tests and benchmarks named above are introduced by !3108 (merged) and can be reused by backend ports.