Hi Ezra, Sorry it's been a while! Comments inline below.
On 09/09/2026 14:31, [email protected] wrote: > From: Ezra Sitorus <[email protected]> > > This patch adds support for FEAT_F16F32MM, FEAT_F16MM and FEAT_SVE_B16MM > intrinsics. > > 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) As Artemiy suggested, please reuse the existing TYPES macros here instead. > /* 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 I realise this is a convention you are following from the file, but I don't think this class has much to do with gimple. How about calling it vmmlaq_impl instead, following the convention that the SVE intrinsics use? Also, you're probably better off inheriting directly from function_base here (rather than gimple_function_base). That way, you won't have to override fold, as the default implementation will already do what you want. > +{ > +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)); It would be more conventional (and arguably less error-prone) to use e.vector_mode (0) here. > + } > +}; > + > // 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)); > + } As Artemiy & Richard already pointed out, we should avoid trying to further complicate this expansion code. The current code (in the FP case) is trying to distinguish between the earlier non-widening extensions (+f32mm, +f64mm) and the newer widening FMMLA extensions (+f8f16mm,+f8f32mm,+sve-f16f32mm) which Alfie added recently. At the time, this was a convenient way of avoiding changing the older patterns by looking at the number of type suffixes. But this falls apart now that we have newer non-widening extensions. As Richard suggested, I think we should rename the earlier non-widening patterns to take two modes. We should also then rename the patterns for the newer widening extensions I mentioned above to change sve2 to sve, and thus we should be able to use a single: code_for_aarch64_sve (UNSPEC_FMMLA, e.vector_mode (0), omode); call for all fp fmmla cases, where omode is e.vector_mode (0) if there's only a single type suffix, and e.vector_mode (1) otherwise. Please do the renaming of the existing patterns as a pre-patch. > 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>" > + [(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)" I think the condition here should just be TARGET_NON_STREAMING. We shouldn't dispatch on <is_bf16>, see my comment on the SVE_FULL_HF_FMMLA iterator below. > + {@ [ cons: =0 , 1 , 2 , 3 ] > + [ w , 0 , w , w ] <b>fmmla\t%0.h, %2.h, %3.h I think we probably want a movprfx alternative too. > + } > + [(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")]) Ah, I see there's a name collision with the below. Can we use F16 instead of HF to disambiguate? Arguably we should rename the below and insert an F8 there to make things consistent. I think it's more readable/maintainable if we reserve the mode letters (HSF) for referring to the modes used in the iterator itself, and then use something else (e.g. F8, F16) to refer to the source operands, which disambiguate the different conditions needed in the two cases. Also, I realise this is pre-existing, and it's my fault for missing this from a previous review, but I don't think we want the D in VDQ at the start of either name. AIUI, in VDQ, V stands for vector, D stands for doubleword, and Q stands for quadword. In this case, we're dealing with modern AdvSIMD instructions which don't have non-Q (= D) variants, thus the register width is always Q. So I think the names of these two iterators should be: VQ_HSF_F16_FMMLA (for your new one above), and VQ_HSF_F8_FMMLA (for the fp8 one below). Hope that all makes sense, and sorry for the nitpicking. > + > (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")]) I think we need to use the full condition for VNx8HF here, i.e. "TARGET_F16MM && TARGET_SVE2p2". If you like, you could create a target macro (say TARGET_SVE_F16MM) to abbreviate the above, but it's fine either way imo. Thanks, Alex > + > +;; 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 > @@ -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" > "sme-b16b16" "sme-f16f16" "sme-i16i64" "sme" "sme2" "sme2p1" "sme2p2" > "sme2p3" > "ssve-fp8dot2" "ssve-fp8dot4" "ssve-fp8fma" "sve-bfscale" "sme-lutv2" > -- > 2.53.0 >
