On Wed, Sep 09, 2026 at 02:31:52PM +0100, [email protected] wrote:
> From: Ezra Sitorus <[email protected]>
>
> This patch adds support for FEAT_F16F32MM, FEAT_F16MM and FEAT_SVE_B16MM
> intrinsics.
Hi Ezra,
Not an official reviewer, but some comments below:
>
> Changes from v2:
> * vmmlaq_f16_f16 changed to vmmlaq_f16.
> Changes from v1:
> * works on top of the changes made to NEON intrinsics.
> * gating of the svmmla_f16 with +sve2p2.
>
> gcc/ChangeLog:
> * config/aarch64/aarch64-acle-builtins.h
> (TYPES_neon_fmmlaq_f16f16, TYPES_neon_fmmlaq_f32f16): New
> types.
> * config/aarch64/aarch64-c.cc: (aarch64_update_cpp_builtins):
> Add new __ARM_FEATURE__ macros.
> * config/aarch64/aarch64-neon-builtins-base.cc: (gimple_vmmlaq) ?
> New gimple_function_base class. (vmmlaq): Define new function
> base.
> * config/aarch64/aarch64-neon-builtins-base.def (vmmlaq): Define
> new NEON function.
> * config/aarch64/aarch64-simd.md (@aarch64_fmmlaq<mode>): New
> pattern.
> * config/aarch64/aarch64-sve-builtins-base.cc
> (svmmla_impl::expand): Update for new instructions.
> * config/aarch64/aarch64-sve-builtins-sve2.def (svmmla): Define
> new SVE functions for F16MM and SVE_B16MM.
> * config/aarch64/aarch64-sve2.md
> (@aarch64_sve2_fmmla<SVE_FULL_HF_FMMLA:mode><SVE_FULL_HF_FMMLA:mode>):
> New pattern.
> * config/aarch64/aarch64.h (TARGET_F16F32MM, TARGET_F16MM,
> TARGET_SVE_B16MM): New macro.
> * config/aarch64/iterators.md (VDQ_HSF_HF_FMMLA): New iterator.
> (SVE_FULL_HF_FMMLA): Likewise.
>
> gcc/testsuite/ChangeLog:
> * gcc.target/aarch64/advsimd-intrinsics/fmmla-compile.c: New
> test.
> * gcc.target/aarch64/pragma_cpp_predefs_4.c: Test new feature
> macros.
> * gcc.target/aarch64/sve/acle/general-c/mmla_1.c: Remove test
> that now works.
> * gcc.target/aarch64/sve2/acle/asm/fmmla_bf16mm_sve2.c: New
> test.
> * gcc.target/aarch64/sve2/acle/asm/fmmla_f16mm_sve2.c: New test.
> * lib/target-supports.exp ("f16mm", "f16f32mm", "sve-b16mm"):
> Add new extensions.
> ---
> gcc/config/aarch64/aarch64-acle-builtins.h | 7 +++++
> gcc/config/aarch64/aarch64-c.cc | 3 +++
> .../aarch64/aarch64-neon-builtins-base.cc | 18 +++++++++++++
> .../aarch64/aarch64-neon-builtins-base.def | 10 +++++++
> gcc/config/aarch64/aarch64-simd.md | 12 +++++++++
> .../aarch64/aarch64-sve-builtins-base.cc | 8 +++++-
> .../aarch64/aarch64-sve-builtins-sve2.def | 10 +++++++
> gcc/config/aarch64/aarch64-sve2.md | 23 ++++++++++++++++
> gcc/config/aarch64/aarch64.h | 6 +++++
> gcc/config/aarch64/iterators.md | 9 ++++++-
> .../advsimd-intrinsics/fmmla-compile.c | 26 ++++++++++++++++++
> .../gcc.target/aarch64/pragma_cpp_predefs_4.c | 15 +++++++++++
> .../aarch64/sve/acle/general-c/mmla_1.c | 1 -
> .../aarch64/sve2/acle/asm/fmmla_bf16mm_sve2.c | 27 +++++++++++++++++++
> .../aarch64/sve2/acle/asm/fmmla_f16mm_sve2.c | 27 +++++++++++++++++++
> gcc/testsuite/lib/target-supports.exp | 2 +-
> 16 files changed, 200 insertions(+), 4 deletions(-)
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/fmmla-compile.c
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/fmmla_bf16mm_sve2.c
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/fmmla_f16mm_sve2.c
>
> diff --git a/gcc/config/aarch64/aarch64-acle-builtins.h
> b/gcc/config/aarch64/aarch64-acle-builtins.h
> index 481a294c9382..128df8a92936 100644
> --- a/gcc/config/aarch64/aarch64-acle-builtins.h
> +++ b/gcc/config/aarch64/aarch64-acle-builtins.h
> @@ -2018,6 +2018,11 @@ function_expander::result_mode () const
> TYPES_neon_reinterpretq1 (D, p64), \
> TYPES_neon_reinterpretq1 (D, p128)
>
> +#define TYPES_neon_fmmlaq_f16f16(S, D, T) \
> + S (f16)
> +
> +#define TYPES_neon_fmmlaq_f32f16(S, D, T) \
> + D (f32, f16)
No need to tie these to specific mnemonics in case they might be useful
for other instructions at a later time. More importantly, the former
already exists as TYPES_h_float and the latter as TYPES_cvt_f32_f16.
> /* Describe a tuple of type suffixes in which only the first is used. */
> #define DEF_VECTOR_TYPE(X) \
> { TYPE_SUFFIX_ ## X, NUM_TYPE_SUFFIXES, NUM_TYPE_SUFFIXES }
> @@ -2183,6 +2188,8 @@ DEF_SVE_TYPES_ARRAY (neon_rev32);
> DEF_SVE_TYPES_ARRAY (neon_rev64);
> DEF_SVE_TYPES_ARRAY (neon_reinterpret);
> DEF_SVE_TYPES_ARRAY (neon_reinterpretq);
> +DEF_SVE_TYPES_ARRAY (neon_fmmlaq_f32f16);
> +DEF_SVE_TYPES_ARRAY (neon_fmmlaq_f16f16);
>
> static const group_suffix_index groups_none[] = {
> GROUP_none, NUM_GROUP_SUFFIXES
> diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc
> index f392ac8ee795..a4e12c06b9bc 100644
> --- a/gcc/config/aarch64/aarch64-c.cc
> +++ b/gcc/config/aarch64/aarch64-c.cc
> @@ -345,6 +345,9 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
>
> aarch64_def_or_undef (TARGET_F8F16MM, "__ARM_FEATURE_F8F16MM", pfile);
> aarch64_def_or_undef (TARGET_F8F32MM, "__ARM_FEATURE_F8F32MM", pfile);
> + aarch64_def_or_undef (TARGET_F16MM, "__ARM_FEATURE_F16MM", pfile);
> + aarch64_def_or_undef (TARGET_F16F32MM, "__ARM_FEATURE_F16F32MM", pfile);
> + aarch64_def_or_undef (TARGET_SVE_B16MM, "__ARM_FEATURE_SVE_B16MM", pfile);
> aarch64_def_or_undef (TARGET_SVE_F16F32MM, "__ARM_FEATURE_SVE_F16F32MM",
> pfile);
> }
> diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
> b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
> index d8fae81388e5..57f343c09253 100644
> --- a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
> +++ b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
> @@ -720,6 +720,21 @@ struct gimple_reinterpret : public gimple_function_base
> }
> };
>
> +/* FP16 matrix-multiply accumulate (widening and non-widening). */
> +class gimple_vmmlaq : public gimple_function_base
> +{
> +public:
> + gimple *fold (gimple_folder &) const override
> + {
> + return nullptr;
> + }
> +
> + rtx expand (function_expander &e) const override
> + {
> + return e.use_exact_insn (code_for_aarch64_fmmlaq (e.args[0]->mode));
> + }
> +};
> +
> // Reinterpret
> NEON_FUNCTION (vreinterpret, gimple_reinterpret,)
> NEON_FUNCTION (vreinterpretq, gimple_reinterpret,)
> @@ -821,4 +836,7 @@ NEON_FUNCTION (vzip2, gimple_permute,
> (zip_mask<true>))
> NEON_FUNCTION (vzip2q, gimple_permute, (zip_mask<true>))
> NEON_FUNCTION (vzip, gimple_permute_pair, (zip_mask<false>,
> zip_mask<true>))
> NEON_FUNCTION (vzipq, gimple_permute_pair, (zip_mask<false>,
> zip_mask<true>))
> +
> +// FP16 matrix-multiply accumulate
> +NEON_FUNCTION (vmmlaq, gimple_vmmlaq,)
> }
> diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.def
> b/gcc/config/aarch64/aarch64-neon-builtins-base.def
> index 7257f59bbc56..7af510f54c22 100644
> --- a/gcc/config/aarch64/aarch64-neon-builtins-base.def
> +++ b/gcc/config/aarch64/aarch64-neon-builtins-base.def
> @@ -145,3 +145,13 @@ DEF_NEON_FUNCTION (vzip2, bhs_neon, ("D0,D0,D0"))
> DEF_NEON_FUNCTION (vzip2q, bhsd_neon, ("Q0,Q0,Q0"))
> DEF_NEON_FUNCTION (vzipq, bhs_neon, ("Q0x2,Q0,Q0"))
> #undef REQUIRED_EXTENSIONS
> +
> +// FP16 matrix-multiply accumulate (widening)
> +#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_F16F32MM)
> +DEF_NEON_FUNCTION (vmmlaq, neon_fmmlaq_f32f16, ("Q0,Q0,Q1,Q1"))
> +#undef REQUIRED_EXTENSIONS
> +
> +// FP16 matrix-multiply accumulate (non-widening)
> +#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_F16MM)
> +DEF_NEON_FUNCTION (vmmlaq, neon_fmmlaq_f16f16, ("Q0,Q0,Q0,Q0"))
> +#undef REQUIRED_EXTENSIONS
> diff --git a/gcc/config/aarch64/aarch64-simd.md
> b/gcc/config/aarch64/aarch64-simd.md
> index f9b2fd6b2db1..451a38e1fd5a 100644
> --- a/gcc/config/aarch64/aarch64-simd.md
> +++ b/gcc/config/aarch64/aarch64-simd.md
> @@ -10792,6 +10792,18 @@
> [(set_attr "type" "neon_fp_mla_s_q")]
> )
>
> +;; fmmla
> +(define_insn "@aarch64_fmmlaq<mode>"
> + [(set (match_operand:VDQ_HSF_HF_FMMLA 0 "register_operand" "=w")
> + (plus:VDQ_HSF_HF_FMMLA (match_operand:VDQ_HSF_HF_FMMLA 1
> "register_operand" "0")
> + (unspec:VDQ_HSF_HF_FMMLA [(match_operand:V8HF
> 2 "register_operand" "w")
> + (match_operand:V8HF
> 3 "register_operand" "w")]
> + UNSPEC_FMMLA)))]
> + ""
> + "fmmla\t%0.<Vtype>, %2.8h, %3.8h"
> + [(set_attr "type" "neon_fp_mla_s_q")]
> +)
> +
> ;; bfmlal<bt>
> (define_insn "aarch64_bfmlal<bt>v4sf"
> [(set (match_operand:V4SF 0 "register_operand" "=w")
> diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
> b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
> index cf18ce7a205d..8df90b8c6e73 100644
> --- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
> +++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
> @@ -2352,7 +2352,13 @@ public:
> else
> {
> if (e.type_suffix_ids[1] == NUM_TYPE_SUFFIXES)
> - icode = code_for_aarch64_sve (UNSPEC_FMMLA, e.vector_mode (0));
> + {
> + if (e.type_suffix (0).element_bytes == 2)
> + icode = code_for_aarch64_sve2_fmmla (e.vector_mode (0),
> + e.vector_mode (0));
> + else
> + icode = code_for_aarch64_sve (UNSPEC_FMMLA, e.vector_mode (0));
> + }
I think the current implementation of svmmla_impl::expand () should
already be able to handle this, as long as your RTL patterns are defined
? The call to
icode = code_for_aarch64_sve2 (UNSPEC_FMMLA,
e.vector_mode (0),
e.vector_mode (1));
requires that the pattern name uses one iterator for the unspec, followed
by two for operand modes? Something like ...
> else
> icode = code_for_aarch64_sve2 (UNSPEC_FMMLA,
> e.vector_mode (0),
> diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
> b/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
> index 3e9d709f2b85..6ed9243c8dc0 100644
> --- a/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
> +++ b/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
> @@ -496,6 +496,16 @@ DEF_SVE_FUNCTION_GS_FPM (svmmla, mmla, s_float_mf8,
> none, none, set)
> DEF_SVE_FUNCTION (svmmla, mmla, cvt_f32_f16, none)
> #undef REQUIRED_EXTENSIONS
>
> +#define REQUIRED_EXTENSIONS \
> + nonstreaming_sve (AARCH64_FL_SVE_B16MM)
> +DEF_SVE_FUNCTION_GS (svmmla, mmla, h_bfloat, none, none)
> +#undef REQUIRED_EXTENSIONS
> +
> +#define REQUIRED_EXTENSIONS \
> + nonstreaming_sve (AARCH64_FL_SVE2p2 | AARCH64_FL_F16MM)
> +DEF_SVE_FUNCTION_GS (svmmla, mmla, h_float, none, none)
> +#undef REQUIRED_EXTENSIONS
> +
> /*
> - BFSCALE (predicated)
> // Only if __ARM_FEATURE_SVE_BFSCALE != 0 && __ARM_FEATURE_SVE2 != 0
> diff --git a/gcc/config/aarch64/aarch64-sve2.md
> b/gcc/config/aarch64/aarch64-sve2.md
> index c33df283cc2a..a976a9e7a852 100644
> --- a/gcc/config/aarch64/aarch64-sve2.md
> +++ b/gcc/config/aarch64/aarch64-sve2.md
> @@ -145,6 +145,7 @@
> ;;
> ;; == FMMLA extensions
> ;; ---- [FP] Matrix multiply-accumulate widening
> +;; ---- [FP] Matrix multiply-accumulate non-widening
>
> ;; =========================================================================
> ;; == Moves
> @@ -5097,3 +5098,25 @@
> }
> [(set_attr "sve_type" "sve_fp_mul")]
> )
> +
> +;; -------------------------------------------------------------------------
> +;; ---- [FP] Matrix multiply-accumulate non-widening
> +;; -------------------------------------------------------------------------
> +;; Includes:
> +;; - FMMLA (F16MM)
> +;; - BFMMLA (SVE_B16MM)
> +;; -------------------------------------------------------------------------
> +
> +(define_insn
> "@aarch64_sve2_fmmla<SVE_FULL_HF_FMMLA:mode><SVE_FULL_HF_FMMLA:mode>"
... "@aarch64_sve2_<sve_fp_op><mode><mode>" ?
> + [(set (match_operand:SVE_FULL_HF_FMMLA 0 "register_operand")
> + (unspec:SVE_FULL_HF_FMMLA
> + [(match_operand:SVE_FULL_HF_FMMLA 2 "register_operand")
> + (match_operand:SVE_FULL_HF_FMMLA 3 "register_operand")
> + (match_operand:SVE_FULL_HF_FMMLA 1 "register_operand")]
> + FMMLA))]
> + "TARGET_NON_STREAMING && (<is_bf16> ? TARGET_SVE_B16MM : TARGET_SVE2p2)"
> + {@ [ cons: =0 , 1 , 2 , 3 ]
> + [ w , 0 , w , w ] <b>fmmla\t%0.h, %2.h, %3.h
> + }
> + [(set_attr "sve_type" "sve_fp_mul")]
> +)
> diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
> index fdedb0439112..4ed2a6795d56 100644
> --- a/gcc/config/aarch64/aarch64.h
> +++ b/gcc/config/aarch64/aarch64.h
> @@ -435,10 +435,16 @@ constexpr auto AARCH64_FL_DEFAULT_ISA_MODE
> ATTRIBUTE_UNUSED
> #define TARGET_F8F32MM (AARCH64_HAVE_ISA (F8F32MM))
> /* F8F16MM instructions, enabled through +f8f16mm. */
> #define TARGET_F8F16MM (AARCH64_HAVE_ISA (F8F16MM))
> +/* F16F32MM instructions, enabled through +f16f32mm. */
> +#define TARGET_F16F32MM (AARCH64_HAVE_ISA (F16F32MM))
> +/* F16MM instructions, enabled through +f16mm. */
> +#define TARGET_F16MM (AARCH64_HAVE_ISA (F16MM))
> /* SVE_F16F32MM instructions, enabled through +sve-f16f32mm. */
> #define TARGET_SVE_F16F32MM (AARCH64_HAVE_ISA (SVE_F16F32MM))
> /* F16F32DOT instructions enabled through +f16f32dot. */
> #define TARGET_F16F32DOT (AARCH64_HAVE_ISA (F16F32DOT))
> +/* SVE_B16MM instructions, enabled through +sve-b16mm. */
> +#define TARGET_SVE_B16MM (AARCH64_HAVE_ISA (SVE_B16MM))
>
> /* Make sure this is always defined so we don't have to check for ifdefs
> but rather use normal ifs. */
> diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
> index 7b7c2bc34e55..06e8746e1436 100644
> --- a/gcc/config/aarch64/iterators.md
> +++ b/gcc/config/aarch64/iterators.md
> @@ -223,6 +223,10 @@
> (V2SF "TARGET_FP8DOT4")
> (V4SF "TARGET_FP8DOT4")])
>
> +;; Same, but with the appropriate conditions for FMMLA support with FP16
> source.
> +(define_mode_iterator VDQ_HSF_HF_FMMLA [(V8HF "TARGET_F16MM")
> + (V4SF "TARGET_F16F32MM")])
> +
> (define_mode_iterator VDQ_HSF_FMMLA [(V8HF "TARGET_F8F16MM")
> (V4SF "TARGET_F8F32MM")])
>
> @@ -581,7 +585,10 @@
> ;; Fully-packed SVE vector modes that have 16-bit float elements.
> (define_mode_iterator SVE_FULL_HF [VNx8BF VNx8HF])
>
> -;; Pairs of the above.
> +;; Same, but with the appropriate conditions for FMMLA support.
> +(define_mode_iterator SVE_FULL_HF_FMMLA [(VNx8BF "TARGET_SVE_B16MM") (VNx8HF
> "TARGET_F16MM")])
> +
> +;; Pairs of SVE_FULL_HF.
> (define_mode_iterator SVE_FULL_HFx2 [VNx16BF VNx16HF])
>
> ;; {f16}{x1,x2}
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/fmmla-compile.c
> b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/fmmla-compile.c
> new file mode 100644
> index 000000000000..aae99cce41ea
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/fmmla-compile.c
> @@ -0,0 +1,26 @@
> +/* { dg-do assemble { target { aarch64_asm_f16f32mm_ok &&
> aarch64_asm_f16mm_ok } } } */
> +/* { dg-do compile { target { ! { aarch64_asm_f16f32mm_ok &&
> aarch64_asm_f16mm_ok } } } } */
> +/* { dg-additional-options "-O2 -march=armv8-a+f16f32mm+f16mm -save-temps" }
> */
> +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */
> +
> +#include <arm_neon.h>
> +
> +/*
> +** test_fmmla1:
> +** fmmla v0\.4s, v1\.8h, v2\.8h
> +** ret
> +*/
> +float32x4_t test_fmmla1 (float32x4_t r, float16x8_t x, float16x8_t y)
> +{
> + return vmmlaq_f32_f16 (r, x, y);
> +}
> +
> +/*
> +** test_fmmla2:
> +** fmmla v0\.8h, v1\.8h, v2\.8h
> +** ret
> +*/
> +float16x8_t test_fmmla2 (float16x8_t r, float16x8_t x, float16x8_t y)
> +{
> + return vmmlaq_f16 (r, x, y);
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c
> b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c
> index 4caa01bba0f8..9ba60c2be1ec 100644
> --- a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c
> +++ b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c
> @@ -430,3 +430,18 @@
> #ifdef __ARM_FEATURE_CSSC
> #error Foo
> #endif
> +
> +#pragma GCC target "+nothing+f16mm"
> +#ifndef __ARM_FEATURE_F16MM
> +#error Foo
> +#endif
> +
> +#pragma GCC target "+nothing+f16f32mm"
> +#ifndef __ARM_FEATURE_F16F32MM
> +#error Foo
> +#endif
> +
> +#pragma GCC target "+nothing+sve-b16mm"
> +#ifndef __ARM_FEATURE_SVE_B16MM
> +#error Foo
> +#endif
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mmla_1.c
> b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mmla_1.c
> index a23c45c86b14..c616ad425c40 100644
> --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mmla_1.c
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mmla_1.c
> @@ -52,7 +52,6 @@ f2 (svbool_t pg, svint8_t s8, svuint8_t u8, svuint32_t u32,
> svint32_t s32,
> svmmla (f64, f32, f16); /* { dg-error {'svmmla' has no form that takes
> 'svfloat64_t' and 'svfloat32_t' arguments} } */
> svmmla (f64, f64, f16); /* { dg-error {passing 'svfloat16_t' to argument 3
> of 'svmmla', but argument 2 had type 'svfloat64_t'} } */
>
> - svmmla (f16, f16, f16); /* { dg-error {'svmmla' has no form that takes
> 'svfloat16_t' arguments} } */
> svmmla (f32, f32, f32);
> svmmla (f64, f64, f64);
> }
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/fmmla_bf16mm_sve2.c
> b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/fmmla_bf16mm_sve2.c
> new file mode 100644
> index 000000000000..14a567dd4fa4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/fmmla_bf16mm_sve2.c
For SVE-related tests, please note how most of the existing ones have
names of the form $mnemonic_$datatype.c. I would recommend renaming yours
to fmmla_f16.c and fmmla_bf16.c.
> @@ -0,0 +1,27 @@
> +/* { dg-do assemble { target aarch64_asm_sve-b16mm_ok } } */
> +/* { dg-do compile { target { ! aarch64_asm_sve-b16mm_ok } } } */
> +/* { dg-skip-if "" { *-*-* } { "-DSTREAMING_COMPATIBLE" } { "" } } */
> +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */
> +
> +#include "test_sve_acle.h"
> +
> +#pragma GCC target "+sve-b16mm"
> +
> +/*
> +** svmmla_bf16mm_tied:
> +** bfmmla z0\.h, z4\.h, z5\.h
> +** ret
> +*/
> +TEST_DUAL_Z (svmmla_bf16mm_tied, svbfloat16_t, svbfloat16_t,
> + z0 = svmmla_bf16 (z0, z4, z5),
> + z0 = svmmla (z0, z4, z5))
> +
> +/*
> +** svmmla_bf16mm:
> +** bfmmla z1\.h, z4\.h, z5\.h
> +** mov z0\.d, z1\.d
> +** ret
> +*/
> +TEST_DUAL_Z (svmmla_bf16mm, svbfloat16_t, svbfloat16_t,
> + z0 = svmmla_bf16 (z1, z4, z5),
> + z0 = svmmla (z1, z4, z5))
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/fmmla_f16mm_sve2.c
> b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/fmmla_f16mm_sve2.c
> new file mode 100644
> index 000000000000..ff61cb1cccdc
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/fmmla_f16mm_sve2.c
> @@ -0,0 +1,27 @@
> +/* { dg-do assemble { target { aarch64_asm_sve2p2_ok && aarch64_asm_f16mm_ok
> } } } */
> +/* { dg-do compile { target { ! { aarch64_asm_sve2p2_ok &&
> aarch64_asm_f16mm_ok } } } } */
> +/* { dg-skip-if "" { *-*-* } { "-DSTREAMING_COMPATIBLE" } { "" } } */
> +/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */
> +
> +#include "test_sve_acle.h"
> +
> +#pragma GCC target "+sve2p2+f16mm"
> +
> +/*
> +** svmmla_f16mm_tied:
> +** fmmla z0\.h, z4\.h, z5\.h
> +** ret
> +*/
> +TEST_DUAL_Z (svmmla_f16mm_tied, svfloat16_t, svfloat16_t,
> + z0 = svmmla_f16 (z0, z4, z5),
> + z0 = svmmla (z0, z4, z5))
> +
> +/*
> +** svmmla_f16mm:
> +** fmmla z1\.h, z4\.h, z5\.h
> +** mov z0\.d, z1\.d
> +** ret
> +*/
> +TEST_DUAL_Z (svmmla_f16mm, svfloat16_t, svfloat16_t,
> + z0 = svmmla_f16 (z1, z4, z5),
> + z0 = svmmla (z1, z4, z5))
> diff --git a/gcc/testsuite/lib/target-supports.exp
> b/gcc/testsuite/lib/target-supports.exp
> index ab726f729ab3..d37f49f73ba7 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -13141,7 +13141,7 @@ set exts {
> "fp" "fp8" "fp8dot2" "fp8dot4" "fp8fma" "i8mm" "ls64" "lse" "lut"
> "sb" "simd" "sve-b16b16" "sve" "sve2" "sve-sm4" "sve-aes" "sve-aes2"
> "sve-bitperm" "sve-sha3" "f8f16mm" "f8f32mm" "sve-f16f32mm"
> - "sme-f8f16" "sme-f8f32"
> + "f16mm" "f16f32mm" "sve-b16mm" "sme-f8f16" "sme-f8f32"
You might want to place the f16mm and f16f32mm extensions earlier in the
list, so that they don't mix with SVE-related ones.
Thanks,
Artemiy
> "sme-b16b16" "sme-f16f16" "sme-i16i64" "sme" "sme2" "sme2p1" "sme2p2"
> "sme2p3"
> "ssve-fp8dot2" "ssve-fp8dot4" "ssve-fp8fma" "sve-bfscale" "sme-lutv2"
> --
> 2.53.0
>