Skip to content

x86/gfni: fix AltiVec paths on big-endian POWER#1418

Draft
fo40225 wants to merge 2 commits into
simd-everywhere:masterfrom
fo40225:fix_GFNI
Draft

x86/gfni: fix AltiVec paths on big-endian POWER#1418
fo40225 wants to merge 2 commits into
simd-everywhere:masterfrom
fo40225:fix_GFNI

Conversation

@fo40225

@fo40225 fo40225 commented Jul 18, 2026

Copy link
Copy Markdown

Problem

The POWER AltiVec (P6 and P8) implementations of simde_x_mm_gf2p8matrix_multiply_epi64_epi8 the helper used by the gf2p8affine / gf2p8affineinv family return wrong results on big-endian POWER. The code was correct only for little-endian.

Root cause

Three endianness assumptions baked into vector constants and element indices:

  1. P8, vec_perm index tables (byte_interleave, byte_deinterleave): vec_perm byte indices are subject to the compiler's little-endian adjustment, so the same table selects different bytes on big-endian.
    The BE variants are the reversed index vectors.
    bit_select is not affected: it feeds vec_bperm, whose bit numbering is big-endian on both targets, so it stays shared.

  2. P8, vec_bperm result position: the gathered bits land in bits 48:63 of the vector unsigned-short element 4 in little-endian element numbering, but element 3 in big-endian.
    The vec_splat index must follow.

  3. P6, byte_select table: vec_sum2s leaves the 8-bit gather in the low byte of words 1 and 3, i.e. byte offset 4/12 on little-endian but 7/15 on big-endian.

Changes

simde/x86/gfni.h only: the three constants/indices above become endianness-specific via SIMDE_ENDIAN_ORDER.

No change on little-endian; no functional change to any other backend.

Testing

Existing gfni munit tests exercise these paths; verified on ppc64 (big-endian) and ppc64le.

The POWER AltiVec implementations of
simde_x_mm_gf2p8matrix_multiply_epi64_epi8 (the helper behind the
gf2p8affine family) produce wrong results on big-endian targets:

* P8: byte_interleave / byte_deinterleave are vec_perm byte-index
  tables. The compiler applies a little-endian adjustment to vec_perm,
  so the same index vector selects different bytes on big-endian;
  provide the reversed tables for BE. bit_select feeds vec_bperm,
  whose bit numbering is big-endian on both targets, so it remains
  shared.

* P8: vec_bperm leaves its gather in bits 48:63, which is
  unsigned-short element 4 in little-endian element numbering but
  element 3 in big-endian; splat the correct element per endianness.

* P6: vec_sum2s leaves the 8-bit gather in the low byte of words 1
  and 3 -- byte offset 4/12 on little-endian but 7/15 on big-endian;
  use the endianness-correct byte_select table.
@fo40225
fo40225 marked this pull request as draft July 19, 2026 02:47
The AltiVec paths of the GFNI matrix-multiply helper were fixed for
big-endian POWER in the previous commit (ef81068), but CI has no
big-endian POWER coverage: the only POWER target in the gcc-qemu
matrix is little-endian (powerpc64le/ppc64el), and the only big-endian
target is s390x, which takes the ZVECTOR paths and never exercises
AltiVec.

Add a power9be entry to the gcc-qemu matrix, cross-compiling with the
Ubuntu 24.04 gcc-14 powerpc64-linux-gnu toolchain and running the
tests under qemu-ppc64-static -cpu power9. The new cross file mirrors
power9-gcc-14-ccache.cross with the big-endian triple, qemu binary,
sysroot and endian=big; -mcpu=power9 is kept, so the P8 AltiVec paths
are compiled and now run in their big-endian variants.
@rosbif

rosbif commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

Good catch, congratulations for finding and correcting the problem.
I am Christopher Moore (aka rosbif) the principal author of gfni.h.
When testing my code I use the big-endian s390x to check for endian issues but (retrospectively) it is obvious that it cannot test for them in code paths for other platforms.
There are potentially problems with ARM too which theoretically is (or used to be ?) bi-endian.
However the only big-endian ARM system I have encountered is the venerable Intel IXP420 in the Linksys NSLU2 (aka slug).
I haven't heard of any big-endian ARM system with NEON.
Does anyone know of one ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants