From 37426e0f060447cf059f3846275a157084dfdfe5 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 11 Jan 2021 18:03:25 +0000 Subject: [PATCH] aarch64: Add support for unpacked SVE conditional BIC This patch adds support for unpacked conditional BIC. The type suffix could be taken from the element size or the container size, so the patch continues to use the element size. This is consistent with the existing support for unconditional BIC. gcc/ * config/aarch64/aarch64-sve.md (*cond_bic_2): Extend from SVE_FULL_I to SVE_I. (*cond_bic_any): Likewise. gcc/testsuite/ * g++.target/aarch64/sve/cond_bic_1.C: New test. * g++.target/aarch64/sve/cond_bic_2.C: Likewise. * g++.target/aarch64/sve/cond_bic_3.C: Likewise. * g++.target/aarch64/sve/cond_bic_4.C: Likewise. --- gcc/config/aarch64/aarch64-sve.md | 26 ++++++------ .../g++.target/aarch64/sve/cond_bic_1.C | 40 +++++++++++++++++++ .../g++.target/aarch64/sve/cond_bic_2.C | 31 ++++++++++++++ .../g++.target/aarch64/sve/cond_bic_3.C | 36 +++++++++++++++++ .../g++.target/aarch64/sve/cond_bic_4.C | 36 +++++++++++++++++ 5 files changed, 156 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/g++.target/aarch64/sve/cond_bic_1.C create mode 100644 gcc/testsuite/g++.target/aarch64/sve/cond_bic_2.C create mode 100644 gcc/testsuite/g++.target/aarch64/sve/cond_bic_3.C create mode 100644 gcc/testsuite/g++.target/aarch64/sve/cond_bic_4.C diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index 2e6128e6032..b8259f24b3d 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -4475,13 +4475,13 @@ ;; Predicated integer BIC, merging with the first input. (define_insn "*cond_bic_2" - [(set (match_operand:SVE_FULL_I 0 "register_operand" "=w, ?&w") - (unspec:SVE_FULL_I + [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w") + (unspec:SVE_I [(match_operand: 1 "register_operand" "Upl, Upl") - (and:SVE_FULL_I - (not:SVE_FULL_I - (match_operand:SVE_FULL_I 3 "register_operand" "w, w")) - (match_operand:SVE_FULL_I 2 "register_operand" "0, w")) + (and:SVE_I + (not:SVE_I + (match_operand:SVE_I 3 "register_operand" "w, w")) + (match_operand:SVE_I 2 "register_operand" "0, w")) (match_dup 2)] UNSPEC_SEL))] "TARGET_SVE" @@ -4493,14 +4493,14 @@ ;; Predicated integer BIC, merging with an independent value. (define_insn_and_rewrite "*cond_bic_any" - [(set (match_operand:SVE_FULL_I 0 "register_operand" "=&w, &w, &w, ?&w") - (unspec:SVE_FULL_I + [(set (match_operand:SVE_I 0 "register_operand" "=&w, &w, &w, ?&w") + (unspec:SVE_I [(match_operand: 1 "register_operand" "Upl, Upl, Upl, Upl") - (and:SVE_FULL_I - (not:SVE_FULL_I - (match_operand:SVE_FULL_I 3 "register_operand" "w, w, w, w")) - (match_operand:SVE_FULL_I 2 "register_operand" "0, w, w, w")) - (match_operand:SVE_FULL_I 4 "aarch64_simd_reg_or_zero" "Dz, Dz, 0, w")] + (and:SVE_I + (not:SVE_I + (match_operand:SVE_I 3 "register_operand" "w, w, w, w")) + (match_operand:SVE_I 2 "register_operand" "0, w, w, w")) + (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero" "Dz, Dz, 0, w")] UNSPEC_SEL))] "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])" "@ diff --git a/gcc/testsuite/g++.target/aarch64/sve/cond_bic_1.C b/gcc/testsuite/g++.target/aarch64/sve/cond_bic_1.C new file mode 100644 index 00000000000..9f7cd75fd08 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/sve/cond_bic_1.C @@ -0,0 +1,40 @@ +/* { dg-do assemble { target aarch64_asm_sve_ok } } */ +/* { dg-options "-O -msve-vector-bits=2048 -save-temps" } */ + +#include + +#define TEST_OP(TYPE) \ + TYPE \ + test##_##TYPE##_reg (TYPE a, TYPE b, TYPE c) \ + { \ + return c == 0 ? a & ~b : a; \ + } + +#define TEST_TYPE(TYPE, SIZE) \ + typedef TYPE TYPE##SIZE __attribute__((vector_size(SIZE))); \ + TEST_OP (TYPE##SIZE) + +TEST_TYPE (uint8_t, 32) + +TEST_TYPE (uint8_t, 64) +TEST_TYPE (uint16_t, 64) + +TEST_TYPE (uint8_t, 128) +TEST_TYPE (uint16_t, 128) +TEST_TYPE (uint32_t, 128) + +/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.h, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */ +/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.s, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */ +/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.d, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */ +/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.s, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.h, p[0-7]/m, \1\.h, z[0-9]+\.h\n} } } */ +/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.d, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.h, p[0-7]/m, \1\.h, z[0-9]+\.h\n} } } */ +/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+)\.d, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.s, p[0-7]/m, \1\.s, z[0-9]+\.s\n} } } */ + +/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.h, p[0-7]/z, \[x1\]\n[^L]*\tbic\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, \1\.b\n} } } */ +/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.s, p[0-7]/z, \[x1\]\n[^L]*\tbic\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, \1\.b\n} } } */ +/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.d, p[0-7]/z, \[x1\]\n[^L]*\tbic\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, \1\.b\n} } } */ +/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.s, p[0-7]/z, \[x1\]\n[^L]*\tbic\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, \1\.h\n} } } */ +/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.d, p[0-7]/z, \[x1\]\n[^L]*\tbic\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, \1\.h\n} } } */ +/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+)\.d, p[0-7]/z, \[x1\]\n[^L]*\tbic\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, \1\.s\n} } } */ + +/* { dg-final { scan-assembler-not {\tsel\t} } } */ diff --git a/gcc/testsuite/g++.target/aarch64/sve/cond_bic_2.C b/gcc/testsuite/g++.target/aarch64/sve/cond_bic_2.C new file mode 100644 index 00000000000..9f96b741140 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/sve/cond_bic_2.C @@ -0,0 +1,31 @@ +/* { dg-do assemble { target aarch64_asm_sve_ok } } */ +/* { dg-options "-O -msve-vector-bits=2048 -save-temps" } */ + +#include + +#define TEST_OP(TYPE) \ + TYPE \ + test##_##TYPE##_reg (TYPE a, TYPE b, TYPE c) \ + { \ + return c == 0 ? a & ~b : b; \ + } + +#define TEST_TYPE(TYPE, SIZE) \ + typedef TYPE TYPE##SIZE __attribute__((vector_size(SIZE))); \ + TEST_OP (TYPE##SIZE) + +TEST_TYPE (uint8_t, 32) + +TEST_TYPE (uint8_t, 64) +TEST_TYPE (uint16_t, 64) + +TEST_TYPE (uint8_t, 128) +TEST_TYPE (uint16_t, 128) +TEST_TYPE (uint32_t, 128) + +/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, z[0-9]+\.b\n} 3 } } */ +/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */ + +/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */ +/* { dg-final { scan-assembler-times {\tsel\t} 6 } } */ diff --git a/gcc/testsuite/g++.target/aarch64/sve/cond_bic_3.C b/gcc/testsuite/g++.target/aarch64/sve/cond_bic_3.C new file mode 100644 index 00000000000..f69f61a61a0 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/sve/cond_bic_3.C @@ -0,0 +1,36 @@ +/* { dg-do assemble { target aarch64_asm_sve_ok } } */ +/* { dg-options "-O -msve-vector-bits=2048 -save-temps" } */ + +#include + +#define TEST_OP(TYPE) \ + TYPE \ + test##_##TYPE##_reg (TYPE a, TYPE b, TYPE c) \ + { \ + return c == 0 ? a & ~b : c; \ + } + +#define TEST_TYPE(TYPE, SIZE) \ + typedef TYPE TYPE##SIZE __attribute__((vector_size(SIZE))); \ + TEST_OP (TYPE##SIZE) + +TEST_TYPE (uint8_t, 32) + +TEST_TYPE (uint8_t, 64) +TEST_TYPE (uint16_t, 64) + +TEST_TYPE (uint8_t, 128) +TEST_TYPE (uint16_t, 128) +TEST_TYPE (uint32_t, 128) + +/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.h, p[0-7]/z, \[x2\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */ +/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.s, p[0-7]/z, \[x2\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */ +/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.d, p[0-7]/z, \[x2\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */ +/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.s, p[0-7]/z, \[x2\]\n[^L]*\tbic\t\1\.h, p[0-7]/m, \1\.h, z[0-9]+\.h\n} } } */ +/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.d, p[0-7]/z, \[x2\]\n[^L]*\tbic\t\1\.h, p[0-7]/m, \1\.h, z[0-9]+\.h\n} } } */ +/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+)\.d, p[0-7]/z, \[x2\]\n[^L]*\tbic\t\1\.s, p[0-7]/m, \1\.s, z[0-9]+\.s\n} } } */ + +/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b\n} 3 } } */ +/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 1 } } */ +/* { dg-final { scan-assembler-not {\tsel\t} } } */ diff --git a/gcc/testsuite/g++.target/aarch64/sve/cond_bic_4.C b/gcc/testsuite/g++.target/aarch64/sve/cond_bic_4.C new file mode 100644 index 00000000000..d6eb22b821a --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/sve/cond_bic_4.C @@ -0,0 +1,36 @@ +/* { dg-do assemble { target aarch64_asm_sve_ok } } */ +/* { dg-options "-O -msve-vector-bits=2048 -save-temps" } */ + +#include + +#define TEST_OP(TYPE) \ + TYPE \ + test##_##TYPE##_reg (TYPE a, TYPE b, TYPE c) \ + { \ + return c == 0 ? a & ~b : 0; \ + } + +#define TEST_TYPE(TYPE, SIZE) \ + typedef TYPE TYPE##SIZE __attribute__((vector_size(SIZE))); \ + TEST_OP (TYPE##SIZE) + +TEST_TYPE (uint8_t, 32) + +TEST_TYPE (uint8_t, 64) +TEST_TYPE (uint16_t, 64) + +TEST_TYPE (uint8_t, 128) +TEST_TYPE (uint16_t, 128) +TEST_TYPE (uint32_t, 128) + +/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.h, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */ +/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.s, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */ +/* { dg-final { scan-assembler {\tld1b\t(z[0-9]+)\.d, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.b, p[0-7]/m, \1\.b, z[0-9]+\.b\n} } } */ +/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.s, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.h, p[0-7]/m, \1\.h, z[0-9]+\.h\n} } } */ +/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+)\.d, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.h, p[0-7]/m, \1\.h, z[0-9]+\.h\n} } } */ +/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+)\.d, p[0-7]/z, \[x0\]\n[^L]*\tbic\t\1\.s, p[0-7]/m, \1\.s, z[0-9]+\.s\n} } } */ + +/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.b, p[0-7]/z, z[0-9]+\.b\n} 3 } } */ +/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.h, p[0-7]/z, z[0-9]+\.h\n} 2 } } */ +/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/z, z[0-9]+\.s\n} 1 } } */ +/* { dg-final { scan-assembler-not {\tsel\t} } } */ -- 2.30.2