From: Ezra Sitorus <[email protected]> Add support for these new pairwise intrinsic operations: svaddqp, svaddsubp and svsubp.
This patch requires the SVE2p3/SME2p3 flags from Richard Ball's SVE2p3/SME2p3 dot product intrinsic patch. Here is one version but there may be a newer version: https://inbox.sourceware.org/gcc-patches/bmm.hj1cfgo5za.gcc.gcc-test.ricbal02.164....@forge-stage.sourceware.org/ gcc/ChangeLog: * config/aarch64/aarch64-sve-builtins-sve2.cc (svsubp, svaddqp, svaddsubp): Define new function base. * config/aarch64/aarch64-sve-builtins-sve2.def (svaddqp, svaddsubp, svsubp): Define new SVE functions. * config/aarch64/aarch64-sve-builtins-sve2.h (svaddqp, svaddsubp, svsubp): Declare new function base. * config/aarch64/aarch64-sve2.md (@aarch64_sve_<sve_int_op><mode>): New. * config/aarch64/iterators.md (UNSPEC_ADDQP): New unspec. (UNSPEC_ADDSUBP): Likewise. (UNSPEC_SUBP): Likewise. (SVE2_INT_BINARY_PAIR): Add UNSPEC_SUBP. (SVE2p3_INT_BINARY_PAIR_UNPRED): New int iterator. (sve_int_op): Add new unspec variants. gcc/testsuite/ChangeLog: * gcc.target/aarch64/sve2/acle/asm/addqp.c: New test. * gcc.target/aarch64/sve2/acle/asm/addsubp.c: Likewise. * gcc.target/aarch64/sve2/acle/asm/subp.c: Likewise. --- .../aarch64/aarch64-sve-builtins-sve2.cc | 3 + .../aarch64/aarch64-sve-builtins-sve2.def | 6 + .../aarch64/aarch64-sve-builtins-sve2.h | 3 + gcc/config/aarch64/aarch64-sve2.md | 15 ++ gcc/config/aarch64/iterators.md | 10 ++ .../gcc.target/aarch64/sve2/acle/asm/addqp.c | 99 +++++++++++++ .../aarch64/sve2/acle/asm/addsubp.c | 99 +++++++++++++ .../gcc.target/aarch64/sve2/acle/asm/subp.c | 132 ++++++++++++++++++ 8 files changed, 367 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/addqp.c create mode 100644 gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/addsubp.c create mode 100644 gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/subp.c diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc b/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc index 91a5660928a8..4c227a71453d 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc @@ -1038,6 +1038,8 @@ FUNCTION (svaddlbt, unspec_based_function, (UNSPEC_SADDLBT, -1, -1)) FUNCTION (svaddlt, unspec_based_function, (UNSPEC_SADDLT, UNSPEC_UADDLT, -1)) FUNCTION (svaddp, unspec_based_pred_function, (UNSPEC_ADDP, UNSPEC_ADDP, UNSPEC_FADDP)) +FUNCTION (svaddqp, unspec_based_function, (UNSPEC_ADDQP, UNSPEC_ADDQP, -1)) +FUNCTION (svaddsubp, unspec_based_function, (UNSPEC_ADDSUBP, UNSPEC_ADDSUBP, -1)) FUNCTION (svaddqv, reduction, (UNSPEC_ADDQV, UNSPEC_ADDQV, UNSPEC_FADDQV)) FUNCTION (svaddwb, unspec_based_function, (UNSPEC_SADDWB, UNSPEC_UADDWB, -1)) FUNCTION (svaddwt, unspec_based_function, (UNSPEC_SADDWT, UNSPEC_UADDWT, -1)) @@ -1288,6 +1290,7 @@ FUNCTION (svsublb, unspec_based_function, (UNSPEC_SSUBLB, UNSPEC_USUBLB, -1)) FUNCTION (svsublbt, unspec_based_function, (UNSPEC_SSUBLBT, -1, -1)) FUNCTION (svsublt, unspec_based_function, (UNSPEC_SSUBLT, UNSPEC_USUBLT, -1)) FUNCTION (svsubltb, unspec_based_function, (UNSPEC_SSUBLTB, -1, -1)) +FUNCTION (svsubp, unspec_based_pred_function, (UNSPEC_SUBP, UNSPEC_SUBP, -1)) FUNCTION (svsubwb, unspec_based_function, (UNSPEC_SSUBWB, UNSPEC_USUBWB, -1)) FUNCTION (svsubwt, unspec_based_function, (UNSPEC_SSUBWT, UNSPEC_USUBWT, -1)) FUNCTION (svtbl2, svtbl2_impl,) diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sve2.def b/gcc/config/aarch64/aarch64-sve-builtins-sve2.def index 964a8314c8d8..659231299c1e 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-sve2.def +++ b/gcc/config/aarch64/aarch64-sve-builtins-sve2.def @@ -288,6 +288,12 @@ DEF_SVE_FUNCTION_GS (svwhilelt, compare_scalar, while_x, x2, none) DEF_SVE_FUNCTION (svwhilelt, compare_scalar_count, while_x_c, none) #undef REQUIRED_EXTENSIONS +#define REQUIRED_EXTENSIONS sve_and_sme (AARCH64_FL_SVE2p3, AARCH64_FL_SME2p3) +DEF_SVE_FUNCTION (svaddqp, binary, all_integer, none) +DEF_SVE_FUNCTION (svaddsubp, binary, all_integer, none) +DEF_SVE_FUNCTION (svsubp, binary, all_integer, mx) +#undef REQUIRED_EXTENSIONS + #define REQUIRED_EXTENSIONS nonstreaming_sve (AARCH64_FL_SVE2p1) DEF_SVE_FUNCTION (svld1q_gather, load_gather64_sv_offset, all_data, implicit) DEF_SVE_FUNCTION (svld1q_gather, load_gather64_sv_index, hsd_data, implicit) diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sve2.h b/gcc/config/aarch64/aarch64-sve-builtins-sve2.h index 168c4b69e336..1a029fc1cff4 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins-sve2.h +++ b/gcc/config/aarch64/aarch64-sve-builtins-sve2.h @@ -37,6 +37,8 @@ namespace aarch64_acle extern const function_base *const svaddlb; extern const function_base *const svaddlbt; extern const function_base *const svaddlt; + extern const function_base *const svaddqp; + extern const function_base *const svaddsubp; extern const function_base *const svaddp; extern const function_base *const svaddqv; extern const function_base *const svaddwb; @@ -237,6 +239,7 @@ namespace aarch64_acle extern const function_base *const svsublbt; extern const function_base *const svsublt; extern const function_base *const svsubltb; + extern const function_base *const svsubp; extern const function_base *const svsubwb; extern const function_base *const svsubwt; extern const function_base *const svtbl2; diff --git a/gcc/config/aarch64/aarch64-sve2.md b/gcc/config/aarch64/aarch64-sve2.md index 6fca1632ee80..09f6d40bd3ad 100644 --- a/gcc/config/aarch64/aarch64-sve2.md +++ b/gcc/config/aarch64/aarch64-sve2.md @@ -3213,8 +3213,11 @@ ;; - ADDP ;; - SMAXP ;; - SMINP +;; - SUBP ;; - UMAXP ;; - UMINP +;; - ADDQP +;; - ADDSUBP ;; ------------------------------------------------------------------------- (define_insn "@aarch64_pred_<sve_int_op><mode>" @@ -3232,6 +3235,18 @@ [(set_attr "sve_type" "sve_int_general")] ) +(define_insn "@aarch64_sve_<sve_int_op><mode>" + [(set (match_operand:SVE_FULL_I 0 "register_operand") + (unspec:SVE_FULL_I + [(match_operand:SVE_FULL_I 1 "register_operand") + (match_operand:SVE_FULL_I 2 "register_operand")] + SVE2p3_INT_BINARY_PAIR_UNPRED))] + "TARGET_SVE2p3_OR_SME2p3" + {@ [ cons: =0 , 1 , 2 ; attrs: movprfx ] + [ w , w , w ; * ] <sve_int_op>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype> + } + [(set_attr "sve_type" "sve_int_general")] +) ;; ------------------------------------------------------------------------- ;; ---- [FP] Pairwise arithmetic ;; ------------------------------------------------------------------------- diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index b7f29199fbc1..c8549ec03d6a 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -1295,7 +1295,9 @@ UNSPEC_PERMUTE_PRED ;; All used in aarch64-sve2.md + UNSPEC_ADDQP UNSPEC_ADDQV + UNSPEC_ADDSUBP UNSPEC_ANDQV UNSPEC_DUPQ UNSPEC_EORQV @@ -1325,6 +1327,7 @@ UNSPEC_ST1_TRUNCQ UNSPEC_ST1Q_SCATTER UNSPEC_STNQ + UNSPEC_SUBP UNSPEC_UMAXQV UNSPEC_UMINQV UNSPEC_UQCVT @@ -4013,9 +4016,13 @@ (define_int_iterator SVE2_INT_BINARY_PAIR [UNSPEC_ADDP UNSPEC_SMAXP UNSPEC_SMINP + (UNSPEC_SUBP "TARGET_SVE2p3_OR_SME2p3") UNSPEC_UMAXP UNSPEC_UMINP]) +(define_int_iterator SVE2p3_INT_BINARY_PAIR_UNPRED [UNSPEC_ADDSUBP + UNSPEC_ADDQP]) + (define_int_iterator SVE2_FP_BINARY_PAIR [UNSPEC_FADDP UNSPEC_FMAXP UNSPEC_FMAXNMP @@ -4877,6 +4884,9 @@ (UNSPEC_ADCLT "adclt") (UNSPEC_ADDHNB "addhnb") (UNSPEC_ADDHNT "addhnt") + (UNSPEC_ADDQP "addqp") + (UNSPEC_ADDSUBP "addsubp") + (UNSPEC_SUBP "subp") (UNSPEC_ADDP "addp") (UNSPEC_ANDV "andv") (UNSPEC_ASHIFTRT_WIDE "asr") diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/addqp.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/addqp.c new file mode 100644 index 000000000000..02c89fa0d6f6 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/addqp.c @@ -0,0 +1,99 @@ +/* { dg-do assemble { target aarch64_asm_sve2p3_ok } } */ +/* { dg-do compile { target { ! aarch64_asm_sve2p3_ok } } } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#pragma GCC target "+sve2p3" +#include "test_sve_acle.h" +#ifdef STREAMING_COMPATIBLE +#pragma GCC target "+sme2p3" +#endif + +/* +** addqp_s8: +** addqp z0\.b, z0\.b, z1\.b +** ret +*/ +TEST_UNIFORM_Z (addqp_s8, svint8_t, + z0 = svaddqp_s8 (z0, z1), + z0 = svaddqp (z0, z1)) + +/* +** addqp_s16: +** addqp z0\.h, z0\.h, z1\.h +** ret +*/ +TEST_UNIFORM_Z (addqp_s16, svint16_t, + z0 = svaddqp_s16 (z0, z1), + z0 = svaddqp (z0, z1)) + +/* +** addqp_s32: +** addqp z0\.s, z0\.s, z1\.s +** ret +*/ +TEST_UNIFORM_Z (addqp_s32, svint32_t, + z0 = svaddqp_s32 (z0, z1), + z0 = svaddqp (z0, z1)) + +/* +** addqp_s64: +** addqp z0\.d, z0\.d, z1\.d +** ret +*/ +TEST_UNIFORM_Z (addqp_s64, svint64_t, + z0 = svaddqp_s64 (z0, z1), + z0 = svaddqp (z0, z1)) + +/* +** addqp_u8: +** addqp z0\.b, z0\.b, z1\.b +** ret +*/ +TEST_UNIFORM_Z (addqp_u8, svuint8_t, + z0 = svaddqp_u8 (z0, z1), + z0 = svaddqp (z0, z1)) + +/* +** addqp_u16: +** addqp z0\.h, z0\.h, z1\.h +** ret +*/ +TEST_UNIFORM_Z (addqp_u16, svuint16_t, + z0 = svaddqp_u16 (z0, z1), + z0 = svaddqp (z0, z1)) + +/* +** addqp_u32: +** addqp z0\.s, z0\.s, z1\.s +** ret +*/ +TEST_UNIFORM_Z (addqp_u32, svuint32_t, + z0 = svaddqp_u32 (z0, z1), + z0 = svaddqp (z0, z1)) + +/* +** addqp_u64: +** addqp z0\.d, z0\.d, z1\.d +** ret +*/ +TEST_UNIFORM_Z (addqp_u64, svuint64_t, + z0 = svaddqp_u64 (z0, z1), + z0 = svaddqp (z0, z1)) + +/* +** addqp_s8_tied2: +** addqp z0\.b, z1\.b, z0\.b +** ret +*/ +TEST_UNIFORM_Z (addqp_s8_tied2, svint8_t, + z0 = svaddqp_s8 (z1, z0), + z0 = svaddqp (z1, z0)) + +/* +** addqp_s8_untied: +** addqp z0\.b, z1\.b, z2\.b +** ret +*/ +TEST_UNIFORM_Z (addqp_s8_untied, svint8_t, + z0 = svaddqp_s8 (z1, z2), + z0 = svaddqp (z1, z2)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/addsubp.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/addsubp.c new file mode 100644 index 000000000000..52e357cae87c --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/addsubp.c @@ -0,0 +1,99 @@ +/* { dg-do assemble { target aarch64_asm_sve2p3_ok } } */ +/* { dg-do compile { target { ! aarch64_asm_sve2p3_ok } } } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#pragma GCC target "+sve2p3" +#include "test_sve_acle.h" +#ifdef STREAMING_COMPATIBLE +#pragma GCC target "+sme2p3" +#endif + +/* +** addsubp_s8: +** addsubp z0\.b, z0\.b, z1\.b +** ret +*/ +TEST_UNIFORM_Z (addsubp_s8, svint8_t, + z0 = svaddsubp_s8 (z0, z1), + z0 = svaddsubp (z0, z1)) + +/* +** addsubp_s16: +** addsubp z0\.h, z0\.h, z1\.h +** ret +*/ +TEST_UNIFORM_Z (addsubp_s16, svint16_t, + z0 = svaddsubp_s16 (z0, z1), + z0 = svaddsubp (z0, z1)) + +/* +** addsubp_s32: +** addsubp z0\.s, z0\.s, z1\.s +** ret +*/ +TEST_UNIFORM_Z (addsubp_s32, svint32_t, + z0 = svaddsubp_s32 (z0, z1), + z0 = svaddsubp (z0, z1)) + +/* +** addsubp_s64: +** addsubp z0\.d, z0\.d, z1\.d +** ret +*/ +TEST_UNIFORM_Z (addsubp_s64, svint64_t, + z0 = svaddsubp_s64 (z0, z1), + z0 = svaddsubp (z0, z1)) + +/* +** addsubp_u8: +** addsubp z0\.b, z0\.b, z1\.b +** ret +*/ +TEST_UNIFORM_Z (addsubp_u8, svuint8_t, + z0 = svaddsubp_u8 (z0, z1), + z0 = svaddsubp (z0, z1)) + +/* +** addsubp_u16: +** addsubp z0\.h, z0\.h, z1\.h +** ret +*/ +TEST_UNIFORM_Z (addsubp_u16, svuint16_t, + z0 = svaddsubp_u16 (z0, z1), + z0 = svaddsubp (z0, z1)) + +/* +** addsubp_u32: +** addsubp z0\.s, z0\.s, z1\.s +** ret +*/ +TEST_UNIFORM_Z (addsubp_u32, svuint32_t, + z0 = svaddsubp_u32 (z0, z1), + z0 = svaddsubp (z0, z1)) + +/* +** addsubp_u64: +** addsubp z0\.d, z0\.d, z1\.d +** ret +*/ +TEST_UNIFORM_Z (addsubp_u64, svuint64_t, + z0 = svaddsubp_u64 (z0, z1), + z0 = svaddsubp (z0, z1)) + +/* +** addsubp_s8_tied2: +** addsubp z0\.b, z1\.b, z0\.b +** ret +*/ +TEST_UNIFORM_Z (addsubp_s8_tied2, svint8_t, + z0 = svaddsubp_s8 (z1, z0), + z0 = svaddsubp (z1, z0)) + +/* +** addsubp_s8_untied: +** addsubp z0\.b, z1\.b, z2\.b +** ret +*/ +TEST_UNIFORM_Z (addsubp_s8_untied, svint8_t, + z0 = svaddsubp_s8 (z1, z2), + z0 = svaddsubp (z1, z2)) diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/subp.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/subp.c new file mode 100644 index 000000000000..40c0fc483a1b --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/subp.c @@ -0,0 +1,132 @@ +/* { dg-do assemble { target aarch64_asm_sve2p3_ok } } */ +/* { dg-do compile { target { ! aarch64_asm_sve2p3_ok } } } */ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ + +#pragma GCC target "+sve2p3" +#include "test_sve_acle.h" +#ifdef STREAMING_COMPATIBLE +#pragma GCC target "+sme2p3" +#endif + +/* +** subp_s8_m_tied1: +** subp z0\.b, p0/m, z0\.b, z1\.b +** ret +*/ +TEST_UNIFORM_Z (subp_s8_m_tied1, svint8_t, + z0 = svsubp_s8_m (p0, z0, z1), + z0 = svsubp_m (p0, z0, z1)) + +/* +** subp_s8_m_tied2: +** mov (z[0-9]+)\.d, z0\.d +** movprfx z0, z1 +** subp z0\.b, p0/m, z0\.b, \1\.b +** ret +*/ +TEST_UNIFORM_Z (subp_s8_m_tied2, svint8_t, + z0 = svsubp_s8_m (p0, z1, z0), + z0 = svsubp_m (p0, z1, z0)) + +/* +** subp_s8_m_untied: +** movprfx z0, z1 +** subp z0\.b, p0/m, z0\.b, z2\.b +** ret +*/ +TEST_UNIFORM_Z (subp_s8_m_untied, svint8_t, + z0 = svsubp_s8_m (p0, z1, z2), + z0 = svsubp_m (p0, z1, z2)) + +/* +** subp_s8_x_tied1: +** subp z0\.b, p0/m, z0\.b, z1\.b +** ret +*/ +TEST_UNIFORM_Z (subp_s8_x_tied1, svint8_t, + z0 = svsubp_s8_x (p0, z0, z1), + z0 = svsubp_x (p0, z0, z1)) + +/* +** subp_s8_x_tied2: +** mov (z[0-9]+)\.d, z0\.d +** movprfx z0, z1 +** subp z0\.b, p0/m, z0\.b, \1\.b +** ret +*/ +TEST_UNIFORM_Z (subp_s8_x_tied2, svint8_t, + z0 = svsubp_s8_x (p0, z1, z0), + z0 = svsubp_x (p0, z1, z0)) + +/* +** subp_s8_x_untied: +** movprfx z0, z1 +** subp z0\.b, p0/m, z0\.b, z2\.b +** ret +*/ +TEST_UNIFORM_Z (subp_s8_x_untied, svint8_t, + z0 = svsubp_s8_x (p0, z1, z2), + z0 = svsubp_x (p0, z1, z2)) + +/* +** subp_s16_m_tied1: +** subp z0\.h, p0/m, z0\.h, z1\.h +** ret +*/ +TEST_UNIFORM_Z (subp_s16_m_tied1, svint16_t, + z0 = svsubp_s16_m (p0, z0, z1), + z0 = svsubp_m (p0, z0, z1)) + +/* +** subp_s32_m_tied1: +** subp z0\.s, p0/m, z0\.s, z1\.s +** ret +*/ +TEST_UNIFORM_Z (subp_s32_m_tied1, svint32_t, + z0 = svsubp_s32_m (p0, z0, z1), + z0 = svsubp_m (p0, z0, z1)) + +/* +** subp_s64_m_tied1: +** subp z0\.d, p0/m, z0\.d, z1\.d +** ret +*/ +TEST_UNIFORM_Z (subp_s64_m_tied1, svint64_t, + z0 = svsubp_s64_m (p0, z0, z1), + z0 = svsubp_m (p0, z0, z1)) + +/* +** subp_u8_m_tied1: +** subp z0\.b, p0/m, z0\.b, z1\.b +** ret +*/ +TEST_UNIFORM_Z (subp_u8_m_tied1, svuint8_t, + z0 = svsubp_u8_m (p0, z0, z1), + z0 = svsubp_m (p0, z0, z1)) + +/* +** subp_u16_m_tied1: +** subp z0\.h, p0/m, z0\.h, z1\.h +** ret +*/ +TEST_UNIFORM_Z (subp_u16_m_tied1, svuint16_t, + z0 = svsubp_u16_m (p0, z0, z1), + z0 = svsubp_m (p0, z0, z1)) + +/* +** subp_u32_m_tied1: +** subp z0\.s, p0/m, z0\.s, z1\.s +** ret +*/ +TEST_UNIFORM_Z (subp_u32_m_tied1, svuint32_t, + z0 = svsubp_u32_m (p0, z0, z1), + z0 = svsubp_m (p0, z0, z1)) + +/* +** subp_u64_m_tied1: +** subp z0\.d, p0/m, z0\.d, z1\.d +** ret +*/ +TEST_UNIFORM_Z (subp_u64_m_tied1, svuint64_t, + z0 = svsubp_u64_m (p0, z0, z1), + z0 = svsubp_m (p0, z0, z1)) -- 2.53.0
