> On 17 Jul 2026, at 01:51, Richard Ball via Sourceware Forge 
> <[email protected]> wrote:
> 
> From: Richard Ball <[email protected]>
> 
> 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.
> ---
> 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
> 
> diff --git a/gcc/config/aarch64/aarch64-acle-builtins.h 
> b/gcc/config/aarch64/aarch64-acle-builtins.h
> index d330ac7897a7..bf495bd74a0d 100644
> --- a/gcc/config/aarch64/aarch64-acle-builtins.h
> +++ b/gcc/config/aarch64/aarch64-acle-builtins.h
> @@ -1646,6 +1646,11 @@ 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)
> @@ -2025,6 +2030,7 @@ 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);
> diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc 
> b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
> index e841972cb422..7f047bb64686 100644
> --- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
> +++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
> @@ -938,13 +938,17 @@ public:
> };
> 
> 
> -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
> @@ -952,6 +956,7 @@ 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,
> @@ -960,9 +965,7 @@ public:
> else
>  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);
> +   : code_for_dot_prod (unspec, mode0, mode1));
>       }
>     return e.use_unpred_insn (icode);
>   }
> @@ -3617,7 +3620,7 @@ 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,)
> diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sve2.def 
> b/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
> index 16524cfedab0..62474935b49c 100644
> --- a/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
> +++ b/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
> @@ -465,6 +465,11 @@ DEF_SVE_FUNCTION_GS_FPM (svmmla, mmla, h_float_mf8, 
> none, none, set)
> DEF_SVE_FUNCTION_GS_FPM (svmmla, mmla, s_float_mf8, none, none, set)
> #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_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
> diff --git a/gcc/config/aarch64/aarch64-sve2.md 
> b/gcc/config/aarch64/aarch64-sve2.md
> index 860c63460eb9..873d47368294 100644
> --- a/gcc/config/aarch64/aarch64-sve2.md
> +++ b/gcc/config/aarch64/aarch64-sve2.md
> @@ -2862,14 +2862,14 @@
> )
> 
> ;; 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
> @@ -2878,6 +2878,41 @@
>   [(set_attr "sve_type" "sve_int_dot")]
> )
> 
> +;; Two-way dot-product SME2p3 || SVE2p3.
> +(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_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
> +     [ ?&w      , w , w , w ; yes            ] movprfx\t%0, 
> %3\;<sur>dot\t%0.h, %1.b, %2.b
> +  }
> +  [(set_attr "sve_type" "sve_int_dot")]
> +)
> +
> +(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_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]
> +     [ ?&w      , w , y , w ; yes            ] movprfx\t%0, 
> %4\;<sur>dot\t%0.h, %1.b, %2.b[%3]
> +  }
> +  [(set_attr "sve_type" "sve_fp_mul")]
> +)
> ;; -------------------------------------------------------------------------
> ;; ---- [FP] Multi-register operations
> ;; -------------------------------------------------------------------------
> diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
> index 26db4958a80f..752f74386c6e 100644
> --- a/gcc/config/aarch64/aarch64.h
> +++ b/gcc/config/aarch64/aarch64.h
> @@ -318,6 +318,9 @@ constexpr auto AARCH64_FL_DEFAULT_ISA_MODE 
> ATTRIBUTE_UNUSED
> /* 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
>    imply anything about the state of PSTATE.SM; instructions that require
>    SME and streaming mode should use TARGET_STREAMING instead.  */
> @@ -351,6 +354,9 @@ constexpr auto AARCH64_FL_DEFAULT_ISA_MODE 
> ATTRIBUTE_UNUSED
> /* 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.  */
> #define TARGET_STREAMING_SME2 (TARGET_STREAMING && TARGET_SME2)
> 
> @@ -358,6 +364,8 @@ constexpr auto AARCH64_FL_DEFAULT_ISA_MODE 
> ATTRIBUTE_UNUSED
> 
> #define TARGET_STREAMING_SME2p2 (TARGET_STREAMING && AARCH64_HAVE_ISA 
> (SME2p2))
> 
> +#define TARGET_STREAMING_SME2p3 (TARGET_STREAMING && AARCH64_HAVE_ISA 
> (SME2p3))
> +
> #define TARGET_SME_B16B16 AARCH64_HAVE_ISA (SME_B16B16)
> 
> /* ARMv8.3-A features.  */
> @@ -532,6 +540,8 @@ constexpr auto AARCH64_FL_DEFAULT_ISA_MODE 
> ATTRIBUTE_UNUSED
>    functions, since streaming mode itself implies SME.  */
> #define TARGET_SVE2p1_OR_SME (TARGET_SVE2p1 || TARGET_STREAMING)
> 
> +#define TARGET_SVE2p3_OR_SME2p3 (TARGET_SVE2p3 || TARGET_SME2p3)
> +
> #define TARGET_SVE2p1_OR_SME2 \
>   ((TARGET_SVE2p1 || TARGET_STREAMING) \
>    && (TARGET_SME2 || TARGET_NON_STREAMING))
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 78052b229a58..c61b17e219af 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -21991,6 +21991,9 @@ Enable SVE2 sha3 instructions.  This also enables 
> SVE2 instructions.
> Enable SVE2.1 instructions.  This also enables SVE2 instructions.
> @item sve2p2
> Enable SVE2.2 instructions.  This also enables SVE2 and SVE2.1 instructions.
> +@item sve2p3
> +Enable SVE2.3 instructions.  This also enables SVE2 and SVE2.1 and
> +SVE2.2 instructions.
> @item tme
> Enable the Transactional Memory Extension.
> @item i8mm
> @@ -22056,6 +22059,9 @@ instructions.
> @item sme2p2
> 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,
> +SME2.1 and SME2.2 instructions.
> @item fcma
> Enable the complex number SIMD extensions.
> @item jscvt
> diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_lane_s16.c 
> b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_lane_s16.c
> new file mode 100644
> index 000000000000..f51cba33e697
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_lane_s16.c
> @@ -0,0 +1,94 @@
> +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */
> +
> +#include "test_sme2_acle.h"
> +#pragma GCC target "+sme2p3"
> +
> +/*
> +** dot_lane_0_s16_tied1:
> +** sdot z0\.h, z4\.b, z5\.b\[0\]
> +** ret
> +*/
> +TEST_DUAL_Z (dot_lane_0_s16_tied1, svint16_t, svint8_t,
> +     z0 = svdot_lane_s16_s8 (z0, z4, z5, 0),
> +     z0 = svdot_lane (z0, z4, z5, 0))
> +
> +/*
> +** dot_lane_0_s16_tied2:
> +** mov (z[0-9]+)\.d, z0\.d
> +** movprfx z0, z4
> +** sdot z0\.h, \1\.b, z1\.b\[0\]
> +** ret
> +*/
> +TEST_DUAL_Z_REV (dot_lane_0_s16_tied2, svint16_t, svint8_t,
> + z0_res = svdot_lane_s16_s8 (z4, z0, z1, 0),
> + z0_res = svdot_lane (z4, z0, z1, 0))
> +
> +/*
> +** dot_lane_0_s16_tied3:
> +** mov (z[0-9]+)\.d, z0\.d
> +** movprfx z0, z4
> +** sdot z0\.h, z1\.b, \1\.b\[0\]
> +** ret
> +*/
> +TEST_DUAL_Z_REV (dot_lane_0_s16_tied3, svint16_t, svint8_t,
> + z0_res = svdot_lane_s16_s8 (z4, z1, z0, 0),
> + z0_res = svdot_lane (z4, z1, z0, 0))
> +
> +/*
> +** dot_lane_0_s16_untied:
> +** movprfx z0, z1
> +** sdot z0\.h, z4\.b, z5\.b\[0\]
> +** ret
> +*/
> +TEST_DUAL_Z (dot_lane_0_s16_untied, svint16_t, svint8_t,
> +     z0 = svdot_lane_s16_s8 (z1, z4, z5, 0),
> +     z0 = svdot_lane (z1, z4, z5, 0))
> +
> +/*
> +** dot_lane_1_s16:
> +** sdot z0\.h, z4\.b, z5\.b\[1\]
> +** ret
> +*/
> +TEST_DUAL_Z (dot_lane_1_s16, svint16_t, svint8_t,
> +     z0 = svdot_lane_s16_s8 (z0, z4, z5, 1),
> +     z0 = svdot_lane (z0, z4, z5, 1))
> +
> +/*
> +** dot_lane_2_s16:
> +** sdot z0\.h, z4\.b, z5\.b\[2\]
> +** ret
> +*/
> +TEST_DUAL_Z (dot_lane_2_s16, svint16_t, svint8_t,
> +     z0 = svdot_lane_s16_s8 (z0, z4, z5, 2),
> +     z0 = svdot_lane (z0, z4, z5, 2))
> +
> +/*
> +** dot_lane_3_s16:
> +** sdot z0\.h, z4\.b, z5\.b\[3\]
> +** ret
> +*/
> +TEST_DUAL_Z (dot_lane_3_s16, svint16_t, svint8_t,
> +     z0 = svdot_lane_s16_s8 (z0, z4, z5, 3),
> +     z0 = svdot_lane (z0, z4, z5, 3))
> +
> +/*
> +** dot_lane_z8_s16:
> +** str d8, \[sp, -16\]!
> +** mov (z[0-7])\.d, z8\.d
> +** sdot z0\.h, z1\.b, \1\.b\[1\]
> +** ldr d8, \[sp\], 16
> +** ret
> +*/
> +TEST_DUAL_LANE_REG (dot_lane_z8_s16, svint16_t, svint8_t, z8,
> +    z0 = svdot_lane_s16_s8 (z0, z1, z8, 1),
> +    z0 = svdot_lane (z0, z1, z8, 1))
> +
> +/*
> +** dot_lane_z16_s16:
> +** mov (z[0-7])\.d, z16\.d
> +** sdot z0\.h, z1\.b, \1\.b\[1\]
> +** ret
> +*/
> +TEST_DUAL_LANE_REG (dot_lane_z16_s16, svint16_t, svint8_t, z16,
> +    z0 = svdot_lane_s16_s8 (z0, z1, z16, 1),
> +    z0 = svdot_lane (z0, z1, z16, 1))
> diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_lane_u16.c 
> b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_lane_u16.c
> new file mode 100644
> index 000000000000..f6f5b81dec39
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_lane_u16.c
> @@ -0,0 +1,94 @@
> +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */
> +
> +#include "test_sme2_acle.h"
> +#pragma GCC target "+sme2p3"
> +
> +/*
> +** dot_lane_0_u16_tied1:
> +** udot z0\.h, z4\.b, z5\.b\[0\]
> +** ret
> +*/
> +TEST_DUAL_Z (dot_lane_0_u16_tied1, svuint16_t, svuint8_t,
> +     z0 = svdot_lane_u16_u8 (z0, z4, z5, 0),
> +     z0 = svdot_lane (z0, z4, z5, 0))
> +
> +/*
> +** dot_lane_0_u16_tied2:
> +** mov (z[0-9]+)\.d, z0\.d
> +** movprfx z0, z4
> +** udot z0\.h, \1\.b, z1\.b\[0\]
> +** ret
> +*/
> +TEST_DUAL_Z_REV (dot_lane_0_u16_tied2, svuint16_t, svuint8_t,
> + z0_res = svdot_lane_u16_u8 (z4, z0, z1, 0),
> + z0_res = svdot_lane (z4, z0, z1, 0))
> +
> +/*
> +** dot_lane_0_u16_tied3:
> +** mov (z[0-9]+)\.d, z0\.d
> +** movprfx z0, z4
> +** udot z0\.h, z1\.b, \1\.b\[0\]
> +** ret
> +*/
> +TEST_DUAL_Z_REV (dot_lane_0_u16_tied3, svuint16_t, svuint8_t,
> + z0_res = svdot_lane_u16_u8 (z4, z1, z0, 0),
> + z0_res = svdot_lane (z4, z1, z0, 0))
> +
> +/*
> +** dot_lane_0_u16_untied:
> +** movprfx z0, z1
> +** udot z0\.h, z4\.b, z5\.b\[0\]
> +** ret
> +*/
> +TEST_DUAL_Z (dot_lane_0_u16_untied, svuint16_t, svuint8_t,
> +     z0 = svdot_lane_u16_u8 (z1, z4, z5, 0),
> +     z0 = svdot_lane (z1, z4, z5, 0))
> +
> +/*
> +** dot_lane_1_u16:
> +** udot z0\.h, z4\.b, z5\.b\[1\]
> +** ret
> +*/
> +TEST_DUAL_Z (dot_lane_1_u16, svuint16_t, svuint8_t,
> +     z0 = svdot_lane_u16_u8 (z0, z4, z5, 1),
> +     z0 = svdot_lane (z0, z4, z5, 1))
> +
> +/*
> +** dot_lane_2_u16:
> +** udot z0\.h, z4\.b, z5\.b\[2\]
> +** ret
> +*/
> +TEST_DUAL_Z (dot_lane_2_u16, svuint16_t, svuint8_t,
> +     z0 = svdot_lane_u16_u8 (z0, z4, z5, 2),
> +     z0 = svdot_lane (z0, z4, z5, 2))
> +
> +/*
> +** dot_lane_3_u16:
> +** udot z0\.h, z4\.b, z5\.b\[3\]
> +** ret
> +*/
> +TEST_DUAL_Z (dot_lane_3_u16, svuint16_t, svuint8_t,
> +     z0 = svdot_lane_u16_u8 (z0, z4, z5, 3),
> +     z0 = svdot_lane (z0, z4, z5, 3))
> +
> +/*
> +** dot_lane_z8_u16:
> +** str d8, \[sp, -16\]!
> +** mov (z[0-7])\.d, z8\.d
> +** udot z0\.h, z1\.b, \1\.b\[1\]
> +** ldr d8, \[sp\], 16
> +** ret
> +*/
> +TEST_DUAL_LANE_REG (dot_lane_z8_u16, svuint16_t, svuint8_t, z8,
> +    z0 = svdot_lane_u16_u8 (z0, z1, z8, 1),
> +    z0 = svdot_lane (z0, z1, z8, 1))
> +
> +/*
> +** dot_lane_z16_u16:
> +** mov (z[0-7])\.d, z16\.d
> +** udot z0\.h, z1\.b, \1\.b\[1\]
> +** ret
> +*/
> +TEST_DUAL_LANE_REG (dot_lane_z16_u16, svuint16_t, svuint8_t, z16,
> +    z0 = svdot_lane_u16_u8 (z0, z1, z16, 1),
> +    z0 = svdot_lane (z0, z1, z16, 1))
> diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_s16.c 
> b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_s16.c
> new file mode 100644
> index 000000000000..6e9507c091b4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_s16.c
> @@ -0,0 +1,45 @@
> +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */
> +
> +#include "test_sme2_acle.h"
> +#pragma GCC target "+sme2p3"
> +
> +/*
> +** dot_s16_tied1:
> +** sdot z0\.h, z4\.b, z5\.b
> +** ret
> +*/
> +TEST_DUAL_Z (dot_s16_tied1, svint16_t, svint8_t,
> +     z0 = svdot_s16_s8 (z0, z4, z5),
> +     z0 = svdot (z0, z4, z5))
> +
> +/*
> +** 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_s16_tied2, svint16_t, svint8_t,
> + z0_res = svdot_s16_s8 (z4, z0, z1),
> + z0_res = svdot (z4, z0, z1))
> +
> +/*
> +** 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_s16_tied3, svint16_t, svint8_t,
> + z0_res = svdot_s16_s8 (z4, z1, z0),
> + z0_res = svdot (z4, z1, z0))
> +
> +/*
> +** dot_s16_untied:
> +** movprfx z0, z1
> +** sdot z0\.h, z4\.b, z5\.b
> +** ret
> +*/
> +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
> diff --git a/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_u16.c 
> b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_u16.c
> new file mode 100644
> index 000000000000..3fd95fcb1403
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sme2/acle-asm/dot_u16.c
> @@ -0,0 +1,45 @@
> +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */
> +
> +#include "test_sme2_acle.h"
> +#pragma GCC target "+sme2p3"
> +
> +/*
> +** dot_u16_tied1:
> +** udot z0\.h, z4\.b, z5\.b
> +** ret
> +*/
> +TEST_DUAL_Z (dot_u16_tied1, svuint16_t, svuint8_t,
> +     z0 = svdot_u16_u8 (z0, z4, z5),
> +     z0 = svdot (z0, z4, z5))
> +
> +/*
> +** 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_u16_tied2, svuint16_t, svuint8_t,
> + z0_res = svdot_u16_u8 (z4, z0, z1),
> + z0_res = svdot (z4, z0, z1))
> +
> +/*
> +** 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_u16_tied3, svuint16_t, svuint8_t,
> + z0_res = svdot_u16_u8 (z4, z1, z0),
> + z0_res = svdot (z4, z1, z0))
> +
> +/*
> +** dot_u16_untied:
> +** movprfx z0, z1
> +** udot z0\.h, z4\.b, z5\.b
> +** ret
> +*/
> +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
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/dotproduct_intrinsicless.c 
> b/gcc/testsuite/gcc.target/aarch64/sve2/dotproduct_intrinsicless.c
> new file mode 100644
> index 000000000000..5fc3ae675afc
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve2/dotproduct_intrinsicless.c
> @@ -0,0 +1,30 @@
> +/* { 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" } } */

Let’s expand this pattern to also match the registers at least minimally.
Otherwise if the functions in the file get renamed to sdot or udot this may 
create false matches (we’ve had cases of this in the past with other tests).
Ok with that change.
Thanks,
Kyrill  

> \ No newline at end of file
> -- 
> 2.54.0
> 

Reply via email to