From: Soumya AR Date: Wed, 11 Dec 2024 04:02:35 +0000 (+0530) Subject: aarch64: Extend SVE2 bit-select instructions for Neon modes. X-Git-Tag: basepoints/gcc-16~3455 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=65b7c8db9c61bcdfd07a3404047dd2d2beac4bbb;p=thirdparty%2Fgcc.git aarch64: Extend SVE2 bit-select instructions for Neon modes. NBSL, BSL1N, and BSL2N are bit-select intructions on SVE2 with certain operands inverted. These can be extended to work with Neon modes. Since these instructions are unpredicated, duplicate patterns were added with the predicate removed to generate these instructions for Neon modes. The patch was bootstrapped and regtested on aarch64-linux-gnu, no regression. Signed-off-by: Soumya AR gcc/ChangeLog: * config/aarch64/aarch64-sve2.md (*aarch64_sve2_nbsl_unpred): New pattern to match unpredicated form. (*aarch64_sve2_bsl1n_unpred): Likewise. (*aarch64_sve2_bsl2n_unpred): Likewise. gcc/testsuite/ChangeLog: * gcc.target/aarch64/sve/bitsel.c: New test. --- diff --git a/gcc/config/aarch64/aarch64-sve2.md b/gcc/config/aarch64/aarch64-sve2.md index 7e8a505f707c..5f41df7cf6ec 100644 --- a/gcc/config/aarch64/aarch64-sve2.md +++ b/gcc/config/aarch64/aarch64-sve2.md @@ -1732,6 +1732,23 @@ } ) +(define_insn "*aarch64_sve2_nbsl_unpred" + [(set (match_operand:VDQ_I 0 "register_operand") + (not:VDQ_I + (xor:VDQ_I + (and:VDQ_I + (xor:VDQ_I + (match_operand:VDQ_I 1 "register_operand") + (match_operand:VDQ_I 2 "register_operand")) + (match_operand:VDQ_I 3 "register_operand")) + (match_dup BSL_DUP))))] + "TARGET_SVE2" + {@ [ cons: =0 , 1 , 2 , 3 ; attrs: movprfx ] + [ w , , , w ; * ] nbsl\t%Z0.d, %Z0.d, %Z.d, %Z3.d + [ ?&w , w , w , w ; yes ] movprfx\t%Z0, %Z\;nbsl\t%Z0.d, %Z0.d, %Z.d, %Z3.d + } +) + ;; Unpredicated bitwise select with inverted first operand. ;; (op3 ? ~bsl_mov : bsl_dup) == ((~(bsl_mov ^ bsl_dup) & op3) ^ bsl_dup) (define_expand "@aarch64_sve2_bsl1n" @@ -1777,6 +1794,23 @@ } ) +(define_insn "*aarch64_sve2_bsl1n_unpred" + [(set (match_operand:VDQ_I 0 "register_operand") + (xor:VDQ_I + (and:VDQ_I + (not:VDQ_I + (xor:VDQ_I + (match_operand:VDQ_I 1 "register_operand") + (match_operand:VDQ_I 2 "register_operand"))) + (match_operand:VDQ_I 3 "register_operand")) + (match_dup BSL_DUP)))] + "TARGET_SVE2" + {@ [ cons: =0 , 1 , 2 , 3 ; attrs: movprfx ] + [ w , , , w ; * ] bsl1n\t%Z0.d, %Z0.d, %Z.d, %Z3.d + [ ?&w , w , w , w ; yes ] movprfx\t%Z0, %Z\;bsl1n\t%Z0.d, %Z0.d, %Z.d, %Z3.d + } +) + ;; Unpredicated bitwise select with inverted second operand. ;; (bsl_dup ? bsl_mov : ~op3) == ((bsl_dup & bsl_mov) | (~op3 & ~bsl_dup)) (define_expand "@aarch64_sve2_bsl2n" @@ -1851,6 +1885,38 @@ } ) +(define_insn "*aarch64_sve2_bsl2n_unpred" + [(set (match_operand:VDQ_I 0 "register_operand") + (ior:VDQ_I + (and:VDQ_I + (match_operand:VDQ_I 1 "register_operand") + (match_operand:VDQ_I 2 "register_operand")) + (and:VDQ_I + (not:VDQ_I (match_operand:VDQ_I 3 "register_operand")) + (not:VDQ_I (match_dup BSL_DUP)))))] + "TARGET_SVE2" + {@ [ cons: =0 , 1 , 2 , 3 ; attrs: movprfx ] + [ w , , , w ; * ] bsl2n\t%Z0.d, %Z0.d, %Z3.d, %Z.d + [ ?&w , w , w , w ; yes ] movprfx\t%Z0, %Z\;bsl2n\t%Z0.d, %Z0.d, %Z3.d, %Z.d + } +) + +(define_insn "*aarch64_sve2_bsl2n_unpred" + [(set (match_operand:VDQ_I 0 "register_operand") + (ior:VDQ_I + (and:VDQ_I + (match_operand:VDQ_I 1 "register_operand") + (match_operand:VDQ_I 2 "register_operand")) + (and:VDQ_I + (not:VDQ_I (match_dup BSL_DUP)) + (not:VDQ_I (match_operand:VDQ_I 3 "register_operand")))))] + "TARGET_SVE2" + {@ [ cons: =0 , 1 , 2 , 3 ; attrs: movprfx ] + [ w , , , w ; * ] bsl2n\t%Z0.d, %Z0.d, %Z3.d, %Z.d + [ ?&w , w , w , w ; yes ] movprfx\t%Z0, %Z\;bsl2n\t%Z0.d, %Z0.d, %Z3.d, %Z.d + } +) + ;; ------------------------------------------------------------------------- ;; ---- [INT] Shift-and-accumulate operations ;; ------------------------------------------------------------------------- diff --git a/gcc/testsuite/gcc.target/aarch64/sve/bitsel.c b/gcc/testsuite/gcc.target/aarch64/sve/bitsel.c new file mode 100644 index 000000000000..635bfefc17ce --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/bitsel.c @@ -0,0 +1,35 @@ +/* { dg-options "-O2 -mcpu=neoverse-v2 --param aarch64-autovec-preference=asimd-only" } */ + +#include + +#define OPNBSL(x,y,z) (~(((x) & (z)) | ((y) & ~(z)))) +#define OPBSL1N(x,y,z) ((~(x) & (z)) | ((y) & ~(z))) +#define OPBSL2N(x,y,z) (((x) & (z)) | (~(y) & ~(z))) + +#define N 1024 + +#define TYPE(N) int##N##_t + +#define TEST(SIZE, OP, SUFFIX) \ +void __attribute__ ((noinline, noclone)) \ +f_##SIZE##_##SUFFIX \ + (TYPE(SIZE) *restrict a, TYPE(SIZE) *restrict b, \ + TYPE(SIZE) *restrict c, TYPE(SIZE) *restrict d) \ +{ \ + for (int i = 0; i < N; i++) \ + a[i] = OP (b[i], c[i], d[i]); \ +} + +#define TEST_ALL(SIZE) \ + TEST(SIZE, OPNBSL, nbsl) \ + TEST(SIZE, OPBSL1N, bsl1n) \ + TEST(SIZE, OPBSL2N, bsl2n) + +TEST_ALL(8); +TEST_ALL(16); +TEST_ALL(32); +TEST_ALL(64); + +/* { dg-final { scan-assembler-times {\tnbsl\tz[0-9]+\.d, z[0-9]+\.d, z[0-9]+\.d, z[0-9]+\.d\n} 4 } } */ +/* { dg-final { scan-assembler-times {\tbsl1n\tz[0-9]+\.d, z[0-9]+\.d, z[0-9]+\.d, z[0-9]+\.d\n} 4 } } */ +/* { dg-final { scan-assembler-times {\tbsl2n\tz[0-9]+\.d, z[0-9]+\.d, z[0-9]+\.d, z[0-9]+\.d\n} 4 } } */ \ No newline at end of file