]> git.ipfire.org Git - thirdparty/gcc.git/commit
aarch64: Use SVE2 NBSL for vector NOR and NAND for Advanced SIMD modes
authorKyrylo Tkachov <ktkachov@nvidia.com>
Fri, 11 Jul 2025 09:50:32 +0000 (02:50 -0700)
committerKyrylo Tkachov <ktkachov@nvidia.com>
Wed, 16 Jul 2025 07:26:51 +0000 (09:26 +0200)
commitc02fa90cb32132c42c801c70144ceb76168248a2
tree37569df874742d9494340100c496ff0da9d2f85b
parent82e912344d28cf1a69e5f8e047203ea7eb625302
aarch64: Use SVE2 NBSL for vector NOR and NAND for Advanced SIMD modes

We already have patterns to use the NBSL instruction to implement vector
NOR and NAND operations for SVE types and modes.  It is straightforward to
have similar patterns for the fixed-width Advanced SIMD modes as well, though
it requires combine patterns without the predicate operand and an explicit 'Z'
output modifier.  This patch does so.

So now for example we generate for:

uint64x2_t nand_q(uint64x2_t a, uint64x2_t b) { return NAND(a, b); }
uint64x2_t nor_q(uint64x2_t a, uint64x2_t b) { return NOR(a, b); }

nand_q:
        nbsl    z0.d, z0.d, z1.d, z1.d
        ret

nor_q:
        nbsl    z0.d, z0.d, z1.d, z0.d
        ret

instead of the previous:
nand_q:
        and     v0.16b, v0.16b, v1.16b
        not     v0.16b, v0.16b
        ret

nor_q:
        orr     v0.16b, v0.16b, v1.16b
        not     v0.16b, v0.16b
        ret

The tied operand requirements for NBSL mean that we can generate the MOVPRFX
when the operands fall that way, but I guess having a 2-insn MOVPRFX form is
not worse than the current 2-insn codegen at least, and the MOVPRFX can be
fused by many cores.

Bootstrapped and tested on aarch64-none-linux-gnu.

Signed-off-by: Kyrylo Tkachov <ktkachov@nvidia.com>
gcc/

* config/aarch64/aarch64-sve2.md (*aarch64_sve2_unpred_nor<mode>):
New define_insn.
(*aarch64_sve2_nand_unpred<mode>): Likewise.

gcc/testsuite/

* gcc.target/aarch64/sve2/nbsl_nor_nand_neon.c: New test.
gcc/config/aarch64/aarch64-sve2.md
gcc/testsuite/gcc.target/aarch64/sve2/nbsl_nor_nand_neon.c [new file with mode: 0644]