From: Ezra Sitorus <[email protected]>
This patch adds support for FEAT_F16F32MM, FEAT_F16MM and FEAT_SVE_B16MM
intrinsics.
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 d330ac7897a7..dac45dbe058a 100644
--- a/gcc/config/aarch64/aarch64-acle-builtins.h
+++ b/gcc/config/aarch64/aarch64-acle-builtins.h
@@ -1920,6 +1920,11 @@ function_expander::result_mode () const
TYPES_neon_reinterpretq1 (D, p64), \
TYPES_neon_reinterpretq1 (D, p128)
+#define TYPES_neon_fmmlaq_f16f16(S, D, T) \
+ D (f16, f16)
+
+#define TYPES_neon_fmmlaq_f32f16(S, D, T) \
+ D (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 }
@@ -2071,6 +2076,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 c4ddcc6d717d..2f34ddda473e 100644
--- a/gcc/config/aarch64/aarch64-c.cc
+++ b/gcc/config/aarch64/aarch64-c.cc
@@ -337,6 +337,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 9e61ba7688ce..964031c3d31a 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 23a8a47263ae..b10f8b37b169 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -10685,6 +10685,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 cfa4df9a9440..e7b04bfd3f4a 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
@@ -2325,7 +2325,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));
+ }
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 16524cfedab0..964a8314c8d8 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
+++ b/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
@@ -469,6 +469,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 860c63460eb9..6fca1632ee80 100644
--- a/gcc/config/aarch64/aarch64-sve2.md
+++ b/gcc/config/aarch64/aarch64-sve2.md
@@ -144,6 +144,7 @@
;;
;; == FMMLA extensions
;; ---- [FP] Matrix multiply-accumulate widening
+;; ---- [FP] Matrix multiply-accumulate non-widening
;; =========================================================================
;; == Moves
@@ -4875,3 +4876,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)"
+ {@ [ 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 ff82148fcb93..169e0a54d218 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -431,8 +431,14 @@ 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))
+/* 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 d90b83df8578..b7f29199fbc1 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -220,6 +220,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")])
@@ -572,7 +576,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])
;; Fully-packed SVE vector modes that have 16-bit, 32-bit or 64-bit elements.
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..20a44c4e5097
--- /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_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 fd85b40cc8d5..9395cb78ce62 100644
--- a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c
@@ -388,3 +388,18 @@
#ifndef __ARM_FEATURE_SSVE_FEXPA
#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 030d158b9050..a5c0b98b6a7d 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -12911,7 +12911,7 @@ set exts {
"fp" "fp8" "fp8dot2" "fp8dot4" "fp8fma" "i8mm" "ls64" "lse" "lut"
"sb" "simd" "sve-b16b16" "sve" "sve2" "sve2p1" "sve2p2" "sve2p3"
"sve-sm4" "sve-aes" "sve-bitperm"
- "sve-sha3" "f8f16mm" "f8f32mm" "sve-f16f32mm"
+ "sve-sha3" "f8f16mm" "f8f32mm" "sve-f16f32mm" "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