Hi gcc-patches mailing list, Richard Ball via Sourceware Forge <[email protected]> has requested that the following forgejo pull request be published on the mailing list.
Created on: 2026-05-31 11:04:41+00:00 Latest update: 2026-07-16 23:51:13+00:00 Changes: 11 changed files, 385 additions, 12 deletions Head revision: ricbal02/gcc-TEST ref sve2p3-dot-product commit 633249b21a2c7aa9736b9a8a49bd2477042def24 Base revision: gcc/gcc ref trunk commit 9e9e22587f7954e079ac68e0e878f1feec7977f8 r17-2414-g9e9e22587f7954 Merge base: 9e9e22587f7954e079ac68e0e878f1feec7977f8 Full diff url: https://forge.sourceware.org/gcc/gcc/pulls/164.diff Discussion: https://forge.sourceware.org/gcc/gcc/pulls/164 Requested Reviewers: aarch64: Add support for SVE2p3 and SME2p3 dot product intrinsics gcc/ChangeLog: * config/aarch64/aarch64-acle-builtins.h (TYPES_s_narrow_su): New type array. (s_narrow_su): Likewise. * config/aarch64/aarch64-sve-builtins-base.cc (class svdot_impl): Update impl. (FUNCTION): Likewise. * config/aarch64/aarch64-sve-builtins-sve2.def (REQUIRED_EXTENSIONS): New function. (svdot): Likewise. (svdot_lane): Likewise. * config/aarch64/aarch64-sve2.md (<sur>dot_prodvnx4sivnx8hi): Renamed. (@<sur>dot_prod<VNx4SI_ONLY:mode><VNx8HI_ONLY:mode>): New Name. (@<sur>dot_prod<VNx8HI_ONLY:mode><VNx16QI_ONLY:mode>): New pattern. (@aarch64_<sur>dot_prod_lane<VNx8HI_ONLY:mode><VNx16QI_ONLY:mode>): Likewise. * config/aarch64/aarch64.h (TARGET_SVE2p3): New Target Flag. (TARGET_SME2p3): Likewise. (TARGET_STREAMING_SME2p3): Likewise. (TARGET_SVE2p3_OR_SME2p3): Likewise. * doc/invoke.texi: Add sve2p3/sme2p3. gcc/testsuite/ChangeLog: * gcc.target/aarch64/sme2/acle-asm/dot_lane_s16.c: New test. * gcc.target/aarch64/sme2/acle-asm/dot_lane_u16.c: New test. * gcc.target/aarch64/sme2/acle-asm/dot_s16.c: New test. * gcc.target/aarch64/sme2/acle-asm/dot_u16.c: New test. * gcc.target/aarch64/sve2/dotproduct_intrinsicless.c: New test. Changed files: - A: gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_lane_s16.c - A: gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_lane_u16.c - A: gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_s16.c - A: gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_u16.c - A: gcc/testsuite/gcc.target/aarch64/sve2/dotproduct_intrinsicless.c - M: gcc/config/aarch64/aarch64-acle-builtins.h - M: gcc/config/aarch64/aarch64-sve-builtins-base.cc - M: gcc/config/aarch64/aarch64-sve-builtins-sve2.def - M: gcc/config/aarch64/aarch64-sve2.md - M: gcc/config/aarch64/aarch64.h - M: gcc/doc/invoke.texi Richard Ball (1): aarch64: Add Support for SVE2p3/SME2p3 dot product intrinsics gcc/config/aarch64/aarch64-acle-builtins.h | 6 ++ .../aarch64/aarch64-sve-builtins-base.cc | 13 ++- .../aarch64/aarch64-sve-builtins-sve2.def | 5 + gcc/config/aarch64/aarch64-sve2.md | 49 ++++++++-- gcc/config/aarch64/aarch64.h | 10 ++ gcc/doc/invoke.texi | 6 ++ .../aarch64/sme2/acle-asm/dot_lane_s16.c | 94 +++++++++++++++++++ .../aarch64/sme2/acle-asm/dot_lane_u16.c | 94 +++++++++++++++++++ .../aarch64/sme2/acle-asm/dot_s16.c | 45 +++++++++ .../aarch64/sme2/acle-asm/dot_u16.c | 45 +++++++++ .../aarch64/sve2/dotproduct_intrinsicless.c | 30 ++++++ 11 files changed, 385 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_lane_s16.c create mode 100644 gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_lane_u16.c create mode 100644 gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_s16.c create mode 100644 gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_u16.c create mode 100644 gcc/testsuite/gcc.target/aarch64/sve2/dotproduct_intrinsicless.c Range-diff against v1: 1: 7b44d2ae151c ! 1: 633249b21a2c aarch64: Add Support for SVE2p3/SME2p3 dot product intrinsics @@ Metadata ## Commit message ## aarch64: Add Support for SVE2p3/SME2p3 dot product intrinsics - This patch adds support for intrinsics which utilise the - dot product instructions added in SVE2p3/SME2p3. + aarch64: Add support for SVE2p3 and SME2p3 dot product intrinsics gcc/ChangeLog: - * config/aarch64/aarch64-sve-builtins-base.cc: Update impl. + * config/aarch64/aarch64-acle-builtins.h + (TYPES_s_narrow_su): New type array. + (s_narrow_su): Likewise. + * config/aarch64/aarch64-sve-builtins-base.cc + (class svdot_impl): Update impl. + (FUNCTION): Likewise. * config/aarch64/aarch64-sve-builtins-sve2.def (REQUIRED_EXTENSIONS): New function. (svdot): Likewise. (svdot_lane): Likewise. - * config/aarch64/aarch64-sve-builtins.cc - (TYPES_s_narrow_fsu_sve2p3): New type array. - (s_narrow_fsu_sve2p3): Likewise. * config/aarch64/aarch64-sve2.md - (<sur>dot_prodvnx8hivnx16qi): New pattern. - (<sur>dot_prod_lanevnx8hivnx16qi): Likewise. + (<sur>dot_prodvnx4sivnx8hi): Renamed. + (@<sur>dot_prod<VNx4SI_ONLY:mode><VNx8HI_ONLY:mode>): New Name. + (@<sur>dot_prod<VNx8HI_ONLY:mode><VNx16QI_ONLY:mode>): New pattern. + (@aarch64_<sur>dot_prod_lane<VNx8HI_ONLY:mode><VNx16QI_ONLY:mode>): Likewise. * config/aarch64/aarch64.h (TARGET_SVE2p3): New Target Flag. (TARGET_SME2p3): Likewise. @@ Commit message gcc/testsuite/ChangeLog: - * gcc.target/aarch64/dotproduct_intrinsicless.c: New test. * gcc.target/aarch64/sme2/acle-asm/dot_lane_s16.c: New test. * gcc.target/aarch64/sme2/acle-asm/dot_lane_u16.c: New test. * gcc.target/aarch64/sme2/acle-asm/dot_s16.c: New test. * gcc.target/aarch64/sme2/acle-asm/dot_u16.c: New test. + * gcc.target/aarch64/sve2/dotproduct_intrinsicless.c: New test. + + ## gcc/config/aarch64/aarch64-acle-builtins.h ## +@@ gcc/config/aarch64/aarch64-acle-builtins.h: function_expander::result_mode () const + #define TYPES_s_narrow_fsu(S, D, T) \ + D (f32, f16), D (s32, s16), D (u32, u16) + ++/* _s16_s8 ++ _u16_u8. */ ++#define TYPES_s_narrow_su(S, D, T) \ ++ D (s16, s8), D (u16, u8) ++ + /* _za8 _za16 _za32 _za64 _za128. */ + #define TYPES_all_za(S, D, T) \ + S (za8), S (za16), S (za32), S (za64), S (za128) +@@ gcc/config/aarch64/aarch64-acle-builtins.h: DEF_SVE_TYPES_ARRAY (while); + DEF_SVE_TYPES_ARRAY (while_x); + DEF_SVE_TYPES_ARRAY (while_x_c); + DEF_SVE_TYPES_ARRAY (s_narrow_fsu); ++DEF_SVE_TYPES_ARRAY (s_narrow_su); + DEF_SVE_TYPES_ARRAY (all_za); + DEF_SVE_TYPES_ARRAY (d_za); + DEF_SVE_TYPES_ARRAY (za_bhsd_data); ## gcc/config/aarch64/aarch64-sve-builtins-base.cc ## @@ gcc/config/aarch64/aarch64-sve-builtins-base.cc: public: - 0, e.result_mode (), - GET_MODE (e.args[0])); + }; + + +-class svdot_impl : public function_base ++class svdot_impl : public unspec_based_function_base + { + public: ++ using unspec_based_function_base::unspec_based_function_base; ++ + rtx + expand (function_expander &e) const override + { + insn_code icode; ++ machine_mode mode0 = GET_MODE (e.args[0]); ++ machine_mode mode1 = GET_MODE (e.args[1]); + if (e.fpm_mode == aarch64_acle::FPM_set) + icode = code_for_aarch64_sve_dot (e.result_mode ()); + else +@@ gcc/config/aarch64/aarch64-sve-builtins-base.cc: public: + /* In the optab, the multiplication operands come before the accumulator + operand. The optab is keyed off the multiplication mode. */ + e.rotate_inputs_left (0, 3); ++ int unspec = unspec_for (e); + if (e.type_suffix_ids[1] == NUM_TYPE_SUFFIXES) + icode = e.convert_optab_handler_for_sign (sdot_prod_optab, + udot_prod_optab, +@@ gcc/config/aarch64/aarch64-sve-builtins-base.cc: public: else -- icode = (e.type_suffix (0).float_p -+ { -+ if (e.type_suffix (0).element_bits > 16) -+ { -+ icode = (e.type_suffix (0).float_p + icode = (e.type_suffix (0).float_p ? CODE_FOR_aarch64_sve_fdotvnx4sfvnx8hf - : e.type_suffix (0).unsigned_p - ? CODE_FOR_udot_prodvnx4sivnx8hi - : CODE_FOR_sdot_prodvnx4sivnx8hi); -+ } -+ else -+ { -+ icode = (e.type_suffix (0).unsigned_p -+ ? CODE_FOR_udot_prodvnx8hivnx16qi -+ : CODE_FOR_sdot_prodvnx8hivnx16qi); -+ } -+ } -+ +- : e.type_suffix (0).unsigned_p +- ? CODE_FOR_udot_prodvnx4sivnx8hi +- : CODE_FOR_sdot_prodvnx4sivnx8hi); ++ : code_for_dot_prod (unspec, mode0, mode1)); } return e.use_unpred_insn (icode); } -@@ gcc/config/aarch64/aarch64-sve-builtins-base.cc: public: - accumulator last. */ - e.rotate_inputs_left (0, 4); - int unspec = unspec_for (e); -- if (unspec == UNSPEC_FDOT) -- icode = CODE_FOR_aarch64_fdot_prod_lanevnx4sfvnx8hf; -+ if (e.type_suffix (0).element_bits > 16) -+ { -+ if (unspec == UNSPEC_FDOT) -+ icode = CODE_FOR_aarch64_fdot_prod_lanevnx4sfvnx8hf; -+ else -+ icode = code_for_aarch64_dot_prod_lane (unspec, mode0, mode1); -+ } - else -- icode = code_for_aarch64_dot_prod_lane (unspec, mode0, mode1); -+ { -+ icode = (e.type_suffix (0).unsigned_p -+ ? CODE_FOR_udot_prod_lanevnx8hivnx16qi -+ : CODE_FOR_sdot_prod_lanevnx8hivnx16qi); -+ } - } - return e.use_exact_insn (icode); - } +@@ gcc/config/aarch64/aarch64-sve-builtins-base.cc: FUNCTION (svcvt, svcvt_impl,) + FUNCTION (svcvtnt, NARROWING_TOP_CONVERT0 (aarch64_sve_cvtnt),) + FUNCTION (svdiv, svdiv_impl,) + FUNCTION (svdivr, rtx_code_function_rotated, (DIV, UDIV, UNSPEC_COND_FDIV)) +-FUNCTION (svdot, svdot_impl,) ++FUNCTION (svdot, svdot_impl,(UNSPEC_SDOT, UNSPEC_UDOT, UNSPEC_FDOT)) + FUNCTION (svdot_lane, svdotprod_lane_impl, (UNSPEC_SDOT, UNSPEC_UDOT, + UNSPEC_FDOT, UNSPEC_DOT_LANE_FP8)) + FUNCTION (svdup, svdup_impl,) ## gcc/config/aarch64/aarch64-sve-builtins-sve2.def ## @@ gcc/config/aarch64/aarch64-sve-builtins-sve2.def: DEF_SVE_FUNCTION_GS_FPM (svmmla, mmla, h_float_mf8, none, none, set) @@ gcc/config/aarch64/aarch64-sve-builtins-sve2.def: DEF_SVE_FUNCTION_GS_FPM (svmml #undef REQUIRED_EXTENSIONS +#define REQUIRED_EXTENSIONS sve_and_sme (AARCH64_FL_SVE2p3, AARCH64_FL_SME2p3) -+DEF_SVE_FUNCTION (svdot, ternary_qq_opt_n_or_011, s_narrow_fsu_sve2p3, none) -+DEF_SVE_FUNCTION (svdot_lane, ternary_qq_or_011_lane, s_narrow_fsu_sve2p3, none) ++DEF_SVE_FUNCTION (svdot, ternary_qq_opt_n_or_011, s_narrow_su, none) ++DEF_SVE_FUNCTION (svdot_lane, ternary_qq_or_011_lane, s_narrow_su, none) +#undef REQUIRED_EXTENSIONS + #define REQUIRED_EXTENSIONS nonstreaming_sve (AARCH64_FL_SVE_F16F32MM) DEF_SVE_FUNCTION (svmmla, mmla, cvt_f32_f16, none) #undef REQUIRED_EXTENSIONS - ## gcc/config/aarch64/aarch64-sve-builtins.cc ## -@@ gcc/config/aarch64/aarch64-sve-builtins.cc: CONSTEXPR const group_suffix_info group_suffixes[] = { - #define TYPES_s_narrow_fsu(S, D, T) \ - D (f32, f16), D (s32, s16), D (u32, u16) - -+/* _s16_s8 -+ _u16_u8. */ -+#define TYPES_s_narrow_fsu_sve2p3(S, D, T) \ -+ D (s16, s8), D (u16, u8) -+ - /* _za8 _za16 _za32 _za64 _za128. */ - #define TYPES_all_za(S, D, T) \ - S (za8), S (za16), S (za32), S (za64), S (za128) -@@ gcc/config/aarch64/aarch64-sve-builtins.cc: DEF_SVE_TYPES_ARRAY (while); - DEF_SVE_TYPES_ARRAY (while_x); - DEF_SVE_TYPES_ARRAY (while_x_c); - DEF_SVE_TYPES_ARRAY (s_narrow_fsu); -+DEF_SVE_TYPES_ARRAY (s_narrow_fsu_sve2p3); - DEF_SVE_TYPES_ARRAY (all_za); - DEF_SVE_TYPES_ARRAY (d_za); - DEF_SVE_TYPES_ARRAY (za_bhsd_data); - ## gcc/config/aarch64/aarch64-sve2.md ## +@@ + ) + + ;; Two-way dot-product. +-(define_insn "<sur>dot_prodvnx4sivnx8hi" +- [(set (match_operand:VNx4SI 0 "register_operand") +- (plus:VNx4SI +- (unspec:VNx4SI +- [(match_operand:VNx8HI 1 "register_operand") +- (match_operand:VNx8HI 2 "register_operand")] ++(define_insn "@<sur>dot_prod<VNx4SI_ONLY:mode><VNx8HI_ONLY:mode>" ++ [(set (match_operand:VNx4SI_ONLY 0 "register_operand") ++ (plus:VNx4SI_ONLY ++ (unspec:VNx4SI_ONLY ++ [(match_operand:VNx8HI_ONLY 1 "register_operand") ++ (match_operand:VNx8HI_ONLY 2 "register_operand")] + DOTPROD) +- (match_operand:VNx4SI 3 "register_operand")))] ++ (match_operand:VNx4SI_ONLY 3 "register_operand")))] + "TARGET_SVE2p1_OR_SME2" + {@ [ cons: =0 , 1 , 2 , 3 ; attrs: movprfx ] + [ w , w , w , 0 ; * ] <sur>dot\t%0.s, %1.h, %2.h @@ [(set_attr "sve_type" "sve_int_dot")] ) +;; Two-way dot-product SME2p3 || SVE2p3. -+(define_insn "<sur>dot_prodvnx8hivnx16qi" -+ [(set (match_operand:VNx8HI 0 "register_operand") -+ (plus:VNx8HI -+ (unspec:VNx8HI -+ [(match_operand:VNx16QI 1 "register_operand") -+ (match_operand:VNx16QI 2 "register_operand")] ++(define_insn "@<sur>dot_prod<VNx8HI_ONLY:mode><VNx16QI_ONLY:mode>" ++ [(set (match_operand:VNx8HI_ONLY 0 "register_operand") ++ (plus:VNx8HI_ONLY ++ (unspec:VNx8HI_ONLY ++ [(match_operand:VNx16QI_ONLY 1 "register_operand") ++ (match_operand:VNx16QI_ONLY 2 "register_operand")] + DOTPROD) -+ (match_operand:VNx8HI 3 "register_operand")))] ++ (match_operand:VNx8HI_ONLY 3 "register_operand")))] + "TARGET_SVE2p3_OR_SME2p3" + {@ [ cons: =0 , 1 , 2 , 3 ; attrs: movprfx ] + [ w , w , w , 0 ; * ] <sur>dot\t%0.h, %1.b, %2.b @@ gcc/config/aarch64/aarch64-sve2.md + [(set_attr "sve_type" "sve_int_dot")] +) + -+(define_insn "<sur>dot_prod_lanevnx8hivnx16qi" -+ [(set (match_operand:VNx8HI 0 "register_operand") -+ (plus:VNx8HI -+ (unspec:VNx8HI -+ [(match_operand:VNx16QI 1 "register_operand") -+ (unspec:VNx16QI -+ [(match_operand:VNx16QI 2 "register_operand") ++(define_insn "@aarch64_<sur>dot_prod_lane<VNx8HI_ONLY:mode><VNx16QI_ONLY:mode>" ++ [(set (match_operand:VNx8HI_ONLY 0 "register_operand") ++ (plus:VNx8HI_ONLY ++ (unspec:VNx8HI_ONLY ++ [(match_operand:VNx16QI_ONLY 1 "register_operand") ++ (unspec:VNx16QI_ONLY ++ [(match_operand:VNx16QI_ONLY 2 "register_operand") + (match_operand:SI 3 "const_int_operand")] + UNSPEC_SVE_LANE_SELECT)] + DOTPROD) -+ (match_operand:VNx8HI 4 "register_operand")))] ++ (match_operand:VNx8HI_ONLY 4 "register_operand")))] + "TARGET_SVE2p3_OR_SME2p3" + {@ [ cons: =0 , 1 , 2 , 4 ; attrs: movprfx ] + [ w , w , y , 0 ; * ] <sur>dot\t%0.h, %1.b, %2.b[%3] @@ gcc/config/aarch64/aarch64.h: constexpr auto AARCH64_FL_DEFAULT_ISA_MODE ATTRIBU /* SVE2p2 instructions, enabled through +sve2p2. */ #define TARGET_SVE2p2 AARCH64_HAVE_ISA (SVE2p2) ++/* SVE2p3 instructions, enabled through +sve2p3. */ +#define TARGET_SVE2p3 AARCH64_HAVE_ISA (SVE2p3) + /* SME instructions, enabled through +sme. Note that this does not @@ gcc/config/aarch64/aarch64.h: constexpr auto AARCH64_FL_DEFAULT_ISA_MODE ATTRIBU /* SME2p2 instructions, enabled through +sme2p2. */ #define TARGET_SME2p2 AARCH64_HAVE_ISA (SME2p2) ++/* SME2p3 instructions, enabled through +sme2p3. */ +#define TARGET_SME2p3 AARCH64_HAVE_ISA (SME2p3) + /* Same with streaming mode enabled. */ @@ gcc/doc/invoke.texi: Enable SVE2 sha3 instructions. This also enables SVE2 inst @item sve2p2 Enable SVE2.2 instructions. This also enables SVE2 and SVE2.1 instructions. +@item sve2p3 -+Enable SVE2.3 instructions. This also enables SVE2 instructions. ++Enable SVE2.3 instructions. This also enables SVE2 and SVE2.1 and ++SVE2.2 instructions. @item tme Enable the Transactional Memory Extension. @item i8mm @@ gcc/doc/invoke.texi: instructions. Enable the Scalable Matrix Extension version 2.2. This also enables SME2 and SME2.1 instructions. +@item sme2p3 -+Enable the Scalable Matrix Extension version 2.3. This also enables SME2 ++Enable the Scalable Matrix Extension version 2.3. This also enables SME2, ++SME2.1 and SME2.2 instructions. @item fcma Enable the complex number SIMD extensions. @item jscvt - ## gcc/testsuite/gcc.target/aarch64/dotproduct_intrinsicless.c (new) ## -@@ -+/* { dg-do compile } */ -+/* { dg-options "-O3 -march=armv9-a+sve2p3 -mautovec-preference=sve-only --param=aarch64-vect-unroll-limit=1" } */ -+ -+#include <stdint.h> -+#include <stddef.h> -+int16_t dot_s8_s8_to_s16(const int8_t *restrict a, -+ const int8_t *restrict b, -+ unsigned n) { -+ int16_t acc = 0; -+ -+ -+ for (unsigned i = 0; i < n; ++i) -+ acc += (int16_t)a[i] * (int16_t)b[i]; -+ -+ return acc; -+} -+ -+uint16_t dot_u8_u8_to_u16(const uint8_t *restrict a, -+ const uint8_t *restrict b, -+ unsigned n) { -+ uint16_t acc = 0; -+ -+ for (unsigned i = 0; i < n; ++i) -+ acc += (uint16_t)a[i] * (uint16_t)b[i]; -+ -+ return acc; -+} -+ -+/* { dg-final { scan-assembler "sdot" } } */ -+/* { dg-final { scan-assembler "udot" } } */ - \ No newline at end of file - ## gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_lane_s16.c (new) ## @@ +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */ @@ gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_s16.c (new) +#pragma GCC target "+sme2p3" + +/* -+** dot_f32_tied1: ++** dot_s16_tied1: +** sdot z0\.h, z4\.b, z5\.b +** ret +*/ -+TEST_DUAL_Z (dot_f32_tied1, svint16_t, svint8_t, ++TEST_DUAL_Z (dot_s16_tied1, svint16_t, svint8_t, + z0 = svdot_s16_s8 (z0, z4, z5), + z0 = svdot (z0, z4, z5)) + +/* -+** dot_f32_tied2: ++** dot_s16_tied2: +** mov (z[0-9]+)\.d, z0\.d +** movprfx z0, z4 +** sdot z0\.h, \1\.b, z1\.b +** ret +*/ -+TEST_DUAL_Z_REV (dot_f32_tied2, svint16_t, svint8_t, ++TEST_DUAL_Z_REV (dot_s16_tied2, svint16_t, svint8_t, + z0_res = svdot_s16_s8 (z4, z0, z1), + z0_res = svdot (z4, z0, z1)) + +/* -+** dot_f32_tied3: ++** dot_s16_tied3: +** mov (z[0-9]+)\.d, z0\.d +** movprfx z0, z4 +** sdot z0\.h, z1\.b, \1\.b +** ret +*/ -+TEST_DUAL_Z_REV (dot_f32_tied3, svint16_t, svint8_t, ++TEST_DUAL_Z_REV (dot_s16_tied3, svint16_t, svint8_t, + z0_res = svdot_s16_s8 (z4, z1, z0), + z0_res = svdot (z4, z1, z0)) + +/* -+** dot_f32_untied: ++** dot_s16_untied: +** movprfx z0, z1 +** sdot z0\.h, z4\.b, z5\.b +** ret +*/ -+TEST_DUAL_Z (dot_f32_untied, svint16_t, svint8_t, ++TEST_DUAL_Z (dot_s16_untied, svint16_t, svint8_t, + z0 = svdot_s16_s8 (z1, z4, z5), + z0 = svdot (z1, z4, z5)) \ No newline at end of file @@ gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_u16.c (new) +#pragma GCC target "+sme2p3" + +/* -+** dot_f32_tied1: ++** dot_u16_tied1: +** udot z0\.h, z4\.b, z5\.b +** ret +*/ -+TEST_DUAL_Z (dot_f32_tied1, svuint16_t, svuint8_t, ++TEST_DUAL_Z (dot_u16_tied1, svuint16_t, svuint8_t, + z0 = svdot_u16_u8 (z0, z4, z5), + z0 = svdot (z0, z4, z5)) + +/* -+** dot_f32_tied2: ++** dot_u16_tied2: +** mov (z[0-9]+)\.d, z0\.d +** movprfx z0, z4 +** udot z0\.h, \1\.b, z1\.b +** ret +*/ -+TEST_DUAL_Z_REV (dot_f32_tied2, svuint16_t, svuint8_t, ++TEST_DUAL_Z_REV (dot_u16_tied2, svuint16_t, svuint8_t, + z0_res = svdot_u16_u8 (z4, z0, z1), + z0_res = svdot (z4, z0, z1)) + +/* -+** dot_f32_tied3: ++** dot_u16_tied3: +** mov (z[0-9]+)\.d, z0\.d +** movprfx z0, z4 +** udot z0\.h, z1\.b, \1\.b +** ret +*/ -+TEST_DUAL_Z_REV (dot_f32_tied3, svuint16_t, svuint8_t, ++TEST_DUAL_Z_REV (dot_u16_tied3, svuint16_t, svuint8_t, + z0_res = svdot_u16_u8 (z4, z1, z0), + z0_res = svdot (z4, z1, z0)) + +/* -+** dot_f32_untied: ++** dot_u16_untied: +** movprfx z0, z1 +** udot z0\.h, z4\.b, z5\.b +** ret +*/ -+TEST_DUAL_Z (dot_f32_untied, svuint16_t, svuint8_t, ++TEST_DUAL_Z (dot_u16_untied, svuint16_t, svuint8_t, + z0 = svdot_u16_u8 (z1, z4, z5), + z0 = svdot (z1, z4, z5)) \ No newline at end of file + + ## gcc/testsuite/gcc.target/aarch64/sve2/dotproduct_intrinsicless.c (new) ## +@@ ++/* { dg-do compile } */ ++/* { dg-options "-O3 -march=armv9-a+sve2p3 -mautovec-preference=sve-only --param=aarch64-vect-unroll-limit=1" } */ ++ ++#include <stdint.h> ++#include <stddef.h> ++int16_t dot_s8_s8_to_s16(const int8_t *restrict a, ++ const int8_t *restrict b, ++ unsigned n) { ++ int16_t acc = 0; ++ ++ ++ for (unsigned i = 0; i < n; ++i) ++ acc += (int16_t)a[i] * (int16_t)b[i]; ++ ++ return acc; ++} ++ ++uint16_t dot_u8_u8_to_u16(const uint8_t *restrict a, ++ const uint8_t *restrict b, ++ unsigned n) { ++ uint16_t acc = 0; ++ ++ for (unsigned i = 0; i < n; ++i) ++ acc += (uint16_t)a[i] * (uint16_t)b[i]; ++ ++ return acc; ++} ++ ++/* { dg-final { scan-assembler "sdot" } } */ ++/* { dg-final { scan-assembler "udot" } } */ + \ No newline at end of file -- 2.54.0
