[gcc r17-3328] aarch64: Add new absolute diff accumulate intrinsic

Abhishek Kaushik via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:940432eaa242f4e050233feafbbf63fd2cf1b940

commit r17-3328-g940432eaa242f4e050233feafbbf63fd2cf1b940
Author: Abhishek Kaushik <[email protected]>
Date:   Wed Aug 12 13:38:31 2026 +0000

    aarch64: Add new absolute diff accumulate intrinsic
    
    This patch adds support for the following absolute difference accumulation
    intrinsics defined by SVE/SME2.3:
    
    - svabal_s16
    - svabal_n_s16
    - svabal_s32
    - svabal_n_s32
    - svabal_s64
    - svabal_n_s64
    - svabal_u16
    - svabal_n_u16
    - svabal_u32
    - svabal_n_u32
    - svabal_u64
    - svabal_n_u64
    
    gcc/ChangeLog:
    
            * config/aarch64/aarch64-sve-builtins-sve2.cc (svabal): Define.
            * config/aarch64/aarch64-sve-builtins-sve2.def (svabal): New
            function.
            * config/aarch64/aarch64-sve-builtins-sve2.h (svabal): Declare.
            * config/aarch64/iterators.md (UNSPEC_SABAL, UNSPEC_UABAL): New
            unspecs.
            (SVE2_INT_BINARY_LONG, SVE2_INT_ADD_BINARY_LONG): Add
            UNSPEC_SABAL and UNSPEC_UABAL.
            (sve_int_op, sve_int_add_op, sve_type_unspec): Handle them.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/aarch64/sve2/acle/asm/abal_s16.c: New test.
            * gcc.target/aarch64/sve2/acle/asm/abal_s32.c: Likewise.
            * gcc.target/aarch64/sve2/acle/asm/abal_s64.c: Likewise.
            * gcc.target/aarch64/sve2/acle/asm/abal_u16.c: Likewise.
            * gcc.target/aarch64/sve2/acle/asm/abal_u32.c: Likewise.
            * gcc.target/aarch64/sve2/acle/asm/abal_u64.c: Likewise.

Diff:
---
 gcc/config/aarch64/aarch64-sve-builtins-sve2.cc    |  2 +
 gcc/config/aarch64/aarch64-sve-builtins-sve2.def   |  1 +
 gcc/config/aarch64/aarch64-sve-builtins-sve2.h     |  1 +
 gcc/config/aarch64/iterators.md                    | 18 ++++-
 .../gcc.target/aarch64/sve2/acle/asm/abal_s16.c    | 90 ++++++++++++++++++++++
 .../gcc.target/aarch64/sve2/acle/asm/abal_s32.c    | 90 ++++++++++++++++++++++
 .../gcc.target/aarch64/sve2/acle/asm/abal_s64.c    | 90 ++++++++++++++++++++++
 .../gcc.target/aarch64/sve2/acle/asm/abal_u16.c    | 90 ++++++++++++++++++++++
 .../gcc.target/aarch64/sve2/acle/asm/abal_u32.c    | 90 ++++++++++++++++++++++
 .../gcc.target/aarch64/sve2/acle/asm/abal_u64.c    | 90 ++++++++++++++++++++++
 10 files changed, 559 insertions(+), 3 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc b/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc
index 520a96cecd05..0b59de34e056 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc
@@ -1052,6 +1052,8 @@ public:
 namespace aarch64_acle {
 
 FUNCTION (svaba, svaba_impl,)
+FUNCTION (svabal, unspec_based_add_function, (UNSPEC_SABAL,
+					      UNSPEC_UABAL, UNSPEC_NONE))
 FUNCTION (svabalb, unspec_based_add_function, (UNSPEC_SABDLB, UNSPEC_UABDLB))
 FUNCTION (svabalt, unspec_based_add_function, (UNSPEC_SABDLT, UNSPEC_UABDLT))
 FUNCTION (svabdlb, unspec_based_function, (UNSPEC_SABDLB, UNSPEC_UABDLB))
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sve2.def b/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
index 7cd6d2d48ea6..3e9d709f2b85 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
+++ b/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
@@ -340,6 +340,7 @@ DEF_SVE_FUNCTION_GS (svqshrn, shift_right_imm_narrowxn,
 		     qshr_x2, x2, none)
 DEF_SVE_FUNCTION_GS (svqshrun, shift_right_imm_narrowxn,
 		     qshru_x2, x2, none)
+DEF_SVE_FUNCTION (svabal, ternary_long_opt_n, hsd_integer, none)
 #undef REQUIRED_EXTENSIONS
 
 #define REQUIRED_EXTENSIONS streaming_only (AARCH64_FL_SME2)
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sve2.h b/gcc/config/aarch64/aarch64-sve-builtins-sve2.h
index 2b363b4f4d53..393c2c8ca2c8 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-sve2.h
+++ b/gcc/config/aarch64/aarch64-sve-builtins-sve2.h
@@ -25,6 +25,7 @@ namespace aarch64_acle
   namespace functions
   {
     extern const function_base *const svaba;
+    extern const function_base *const svabal;
     extern const function_base *const svabalb;
     extern const function_base *const svabalt;
     extern const function_base *const svabdlb;
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 3fe2f5ed5242..f5e6ad8bfb3b 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -1192,6 +1192,7 @@
     UNSPEC_RSHRNT	; Used in aarch64-sve2.md.
     UNSPEC_RSUBHNB	; Used in aarch64-sve2.md.
     UNSPEC_RSUBHNT	; Used in aarch64-sve2.md.
+    UNSPEC_SABAL	; Used in aarch64-sve2.md.
     UNSPEC_SABDLB	; Used in aarch64-sve2.md.
     UNSPEC_SABDLT	; Used in aarch64-sve2.md.
     UNSPEC_SADDLB	; Used in aarch64-sve2.md.
@@ -1252,6 +1253,7 @@
     UNSPEC_SUBHNT	; Used in aarch64-sve2.md.
     UNSPEC_TBL2		; Used in aarch64-sve2.md.
     UNSPEC_TRN		; Used in aarch64-builtins.cc
+    UNSPEC_UABAL	; Used in aarch64-sve2.md.
     UNSPEC_UABDLB	; Used in aarch64-sve2.md.
     UNSPEC_UABDLT	; Used in aarch64-sve2.md.
     UNSPEC_UADDLB	; Used in aarch64-sve2.md.
@@ -3995,7 +3997,8 @@
 (define_int_iterator SVE2_INT_BINARY_LANE [UNSPEC_SQDMULH
 					   UNSPEC_SQRDMULH])
 
-(define_int_iterator SVE2_INT_BINARY_LONG [UNSPEC_SABDLB
+(define_int_iterator SVE2_INT_BINARY_LONG [UNSPEC_SABAL
+					   UNSPEC_SABDLB
 					   UNSPEC_SABDLT
 					   UNSPEC_SADDLB
 					   UNSPEC_SADDLBT
@@ -4008,6 +4011,7 @@
 					   UNSPEC_SSUBLBT
 					   UNSPEC_SSUBLT
 					   UNSPEC_SSUBLTB
+					   UNSPEC_UABAL
 					   UNSPEC_UABDLB
 					   UNSPEC_UABDLT
 					   UNSPEC_UADDLB
@@ -4154,10 +4158,12 @@
 				    UNSPEC_CDOT180
 				    UNSPEC_CDOT270])
 
-(define_int_iterator SVE2_INT_ADD_BINARY_LONG [UNSPEC_SABDLB
+(define_int_iterator SVE2_INT_ADD_BINARY_LONG [UNSPEC_SABAL
+					       UNSPEC_SABDLB
 					       UNSPEC_SABDLT
 					       UNSPEC_SMULLB
 					       UNSPEC_SMULLT
+					       UNSPEC_UABAL
 					       UNSPEC_UABDLB
 					       UNSPEC_UABDLT
 					       UNSPEC_UMULLB
@@ -4942,6 +4948,7 @@
 			     (UNSPEC_RSQRTE "ursqrte")
 			     (UNSPEC_RSUBHNB "rsubhnb")
 			     (UNSPEC_RSUBHNT "rsubhnt")
+			     (UNSPEC_SABAL "sabal")
 			     (UNSPEC_SABDLB "sabdlb")
 			     (UNSPEC_SABDLT "sabdlt")
 			     (UNSPEC_SADALP "sadalp")
@@ -5013,6 +5020,7 @@
 			     (UNSPEC_SUBHNB "subhnb")
 			     (UNSPEC_SUBHNT "subhnt")
 			     (UNSPEC_SUQADD "suqadd")
+			     (UNSPEC_UABAL "uabal")
 			     (UNSPEC_UABDLB "uabdlb")
 			     (UNSPEC_UABDLT "uabdlt")
 			     (UNSPEC_UADALP "uadalp")
@@ -5064,10 +5072,12 @@
 				 (UNSPEC_URHADD "urhadd")
 				 (UNSPEC_URSHL "urshlr")])
 
-(define_int_attr sve_int_add_op [(UNSPEC_SABDLB "sabalb")
+(define_int_attr sve_int_add_op [(UNSPEC_SABAL "sabal")
+				 (UNSPEC_SABDLB "sabalb")
 				 (UNSPEC_SABDLT "sabalt")
 				 (UNSPEC_SMULLB "smlalb")
 				 (UNSPEC_SMULLT "smlalt")
+				 (UNSPEC_UABAL "uabal")
 				 (UNSPEC_UABDLB "uabalb")
 				 (UNSPEC_UABDLT "uabalt")
 				 (UNSPEC_UMULLB "umlalb")
@@ -5132,6 +5142,7 @@
 				  (UNSPEC_SBCLT "int_general")
 				  (UNSPEC_SQRDMLAH "int_mul")
 				  (UNSPEC_SQRDMLSH "int_mul")
+				  (UNSPEC_SABAL "int_general")
 				  (UNSPEC_SABDLB "int_general")
 				  (UNSPEC_SABDLT "int_general")
 				  (UNSPEC_SADDLB "int_general")
@@ -5146,6 +5157,7 @@
 				  (UNSPEC_SSUBLBT "int_general")
 				  (UNSPEC_SSUBLT "int_general")
 				  (UNSPEC_SSUBLTB "int_general")
+				  (UNSPEC_UABAL "int_general")
 				  (UNSPEC_UABDLB "int_general")
 				  (UNSPEC_UABDLT "int_general")
 				  (UNSPEC_UADDLB "int_general")
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_s16.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_s16.c
new file mode 100644
index 000000000000..47de5be3e238
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_s16.c
@@ -0,0 +1,90 @@
+/* { dg-do assemble { target aarch64_asm_sme2p3_ok } } */
+/* { dg-do compile { target { ! aarch64_asm_sme2p3_ok } } } */
+/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */
+
+#include "test_sve_acle.h"
+#pragma GCC target "+sve2p3"
+#pragma GCC target "+sme2p3"
+
+/*
+** abal_s16_tied1:
+**	sabal	z0\.h, z4\.b, z5\.b
+**	ret
+*/
+TEST_DUAL_Z (abal_s16_tied1, svint16_t, svint8_t,
+	     z0 = svabal_s16 (z0, z4, z5),
+	     z0 = svabal (z0, z4, z5))
+
+/*
+** abal_s16_tied2:
+**	mov	(z[0-9]+)\.d, z0\.d
+**	movprfx	z0, z4
+**	sabal	z0\.h, \1\.b, z1\.b
+**	ret
+*/
+TEST_DUAL_Z_REV (abal_s16_tied2, svint16_t, svint8_t,
+		 z0_res = svabal_s16 (z4, z0, z1),
+		 z0_res = svabal (z4, z0, z1))
+
+/*
+** abal_s16_tied3:
+**	mov	(z[0-9]+)\.d, z0\.d
+**	movprfx	z0, z4
+**	sabal	z0\.h, z1\.b, \1\.b
+**	ret
+*/
+TEST_DUAL_Z_REV (abal_s16_tied3, svint16_t, svint8_t,
+		 z0_res = svabal_s16 (z4, z1, z0),
+		 z0_res = svabal (z4, z1, z0))
+
+/*
+** abal_s16_untied:
+**	movprfx	z0, z1
+**	sabal	z0\.h, z4\.b, z5\.b
+**	ret
+*/
+TEST_DUAL_Z (abal_s16_untied, svint16_t, svint8_t,
+	     z0 = svabal_s16 (z1, z4, z5),
+	     z0 = svabal (z1, z4, z5))
+
+/*
+** abal_w0_s16_tied1:
+**	mov	(z[0-9]+\.b), w0
+**	sabal	z0\.h, z4\.b, \1
+**	ret
+*/
+TEST_DUAL_ZX (abal_w0_s16_tied1, svint16_t, svint8_t, int8_t,
+	      z0 = svabal_n_s16 (z0, z4, x0),
+	      z0 = svabal (z0, z4, x0))
+
+/*
+** abal_w0_s16_untied:
+**	mov	(z[0-9]+\.b), w0
+**	movprfx	z0, z1
+**	sabal	z0\.h, z4\.b, \1
+**	ret
+*/
+TEST_DUAL_ZX (abal_w0_s16_untied, svint16_t, svint8_t, int8_t,
+	      z0 = svabal_n_s16 (z1, z4, x0),
+	      z0 = svabal (z1, z4, x0))
+
+/*
+** abal_11_s16_tied1:
+**	mov	(z[0-9]+\.b), #11
+**	sabal	z0\.h, z4\.b, \1
+**	ret
+*/
+TEST_DUAL_Z (abal_11_s16_tied1, svint16_t, svint8_t,
+	     z0 = svabal_n_s16 (z0, z4, 11),
+	     z0 = svabal (z0, z4, 11))
+
+/*
+** abal_11_s16_untied:
+**	mov	(z[0-9]+\.b), #11
+**	movprfx	z0, z1
+**	sabal	z0\.h, z4\.b, \1
+**	ret
+*/
+TEST_DUAL_Z (abal_11_s16_untied, svint16_t, svint8_t,
+	     z0 = svabal_n_s16 (z1, z4, 11),
+	     z0 = svabal (z1, z4, 11))
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_s32.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_s32.c
new file mode 100644
index 000000000000..7962fffca08a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_s32.c
@@ -0,0 +1,90 @@
+/* { dg-do assemble { target aarch64_asm_sme2p3_ok } } */
+/* { dg-do compile { target { ! aarch64_asm_sme2p3_ok } } } */
+/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */
+
+#include "test_sve_acle.h"
+#pragma GCC target "+sve2p3"
+#pragma GCC target "+sme2p3"
+
+/*
+** abal_s32_tied1:
+**	sabal	z0\.s, z4\.h, z5\.h
+**	ret
+*/
+TEST_DUAL_Z (abal_s32_tied1, svint32_t, svint16_t,
+	     z0 = svabal_s32 (z0, z4, z5),
+	     z0 = svabal (z0, z4, z5))
+
+/*
+** abal_s32_tied2:
+**	mov	(z[0-9]+)\.d, z0\.d
+**	movprfx	z0, z4
+**	sabal	z0\.s, \1\.h, z1\.h
+**	ret
+*/
+TEST_DUAL_Z_REV (abal_s32_tied2, svint32_t, svint16_t,
+		 z0_res = svabal_s32 (z4, z0, z1),
+		 z0_res = svabal (z4, z0, z1))
+
+/*
+** abal_s32_tied3:
+**	mov	(z[0-9]+)\.d, z0\.d
+**	movprfx	z0, z4
+**	sabal	z0\.s, z1\.h, \1\.h
+**	ret
+*/
+TEST_DUAL_Z_REV (abal_s32_tied3, svint32_t, svint16_t,
+		 z0_res = svabal_s32 (z4, z1, z0),
+		 z0_res = svabal (z4, z1, z0))
+
+/*
+** abal_s32_untied:
+**	movprfx	z0, z1
+**	sabal	z0\.s, z4\.h, z5\.h
+**	ret
+*/
+TEST_DUAL_Z (abal_s32_untied, svint32_t, svint16_t,
+	     z0 = svabal_s32 (z1, z4, z5),
+	     z0 = svabal (z1, z4, z5))
+
+/*
+** abal_w0_s32_tied1:
+**	mov	(z[0-9]+\.h), w0
+**	sabal	z0\.s, z4\.h, \1
+**	ret
+*/
+TEST_DUAL_ZX (abal_w0_s32_tied1, svint32_t, svint16_t, int16_t,
+	      z0 = svabal_n_s32 (z0, z4, x0),
+	      z0 = svabal (z0, z4, x0))
+
+/*
+** abal_w0_s32_untied:
+**	mov	(z[0-9]+\.h), w0
+**	movprfx	z0, z1
+**	sabal	z0\.s, z4\.h, \1
+**	ret
+*/
+TEST_DUAL_ZX (abal_w0_s32_untied, svint32_t, svint16_t, int16_t,
+	      z0 = svabal_n_s32 (z1, z4, x0),
+	      z0 = svabal (z1, z4, x0))
+
+/*
+** abal_11_s32_tied1:
+**	mov	(z[0-9]+\.h), #11
+**	sabal	z0\.s, z4\.h, \1
+**	ret
+*/
+TEST_DUAL_Z (abal_11_s32_tied1, svint32_t, svint16_t,
+	     z0 = svabal_n_s32 (z0, z4, 11),
+	     z0 = svabal (z0, z4, 11))
+
+/*
+** abal_11_s32_untied:
+**	mov	(z[0-9]+\.h), #11
+**	movprfx	z0, z1
+**	sabal	z0\.s, z4\.h, \1
+**	ret
+*/
+TEST_DUAL_Z (abal_11_s32_untied, svint32_t, svint16_t,
+	     z0 = svabal_n_s32 (z1, z4, 11),
+	     z0 = svabal (z1, z4, 11))
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_s64.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_s64.c
new file mode 100644
index 000000000000..9b09fe981096
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_s64.c
@@ -0,0 +1,90 @@
+/* { dg-do assemble { target aarch64_asm_sme2p3_ok } } */
+/* { dg-do compile { target { ! aarch64_asm_sme2p3_ok } } } */
+/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */
+
+#include "test_sve_acle.h"
+#pragma GCC target "+sve2p3"
+#pragma GCC target "+sme2p3"
+
+/*
+** abal_s64_tied1:
+**	sabal	z0\.d, z4\.s, z5\.s
+**	ret
+*/
+TEST_DUAL_Z (abal_s64_tied1, svint64_t, svint32_t,
+	     z0 = svabal_s64 (z0, z4, z5),
+	     z0 = svabal (z0, z4, z5))
+
+/*
+** abal_s64_tied2:
+**	mov	(z[0-9]+)\.d, z0\.d
+**	movprfx	z0, z4
+**	sabal	z0\.d, \1\.s, z1\.s
+**	ret
+*/
+TEST_DUAL_Z_REV (abal_s64_tied2, svint64_t, svint32_t,
+		 z0_res = svabal_s64 (z4, z0, z1),
+		 z0_res = svabal (z4, z0, z1))
+
+/*
+** abal_s64_tied3:
+**	mov	(z[0-9]+)\.d, z0\.d
+**	movprfx	z0, z4
+**	sabal	z0\.d, z1\.s, \1\.s
+**	ret
+*/
+TEST_DUAL_Z_REV (abal_s64_tied3, svint64_t, svint32_t,
+		 z0_res = svabal_s64 (z4, z1, z0),
+		 z0_res = svabal (z4, z1, z0))
+
+/*
+** abal_s64_untied:
+**	movprfx	z0, z1
+**	sabal	z0\.d, z4\.s, z5\.s
+**	ret
+*/
+TEST_DUAL_Z (abal_s64_untied, svint64_t, svint32_t,
+	     z0 = svabal_s64 (z1, z4, z5),
+	     z0 = svabal (z1, z4, z5))
+
+/*
+** abal_w0_s64_tied1:
+**	mov	(z[0-9]+\.s), w0
+**	sabal	z0\.d, z4\.s, \1
+**	ret
+*/
+TEST_DUAL_ZX (abal_w0_s64_tied1, svint64_t, svint32_t, int32_t,
+	      z0 = svabal_n_s64 (z0, z4, x0),
+	      z0 = svabal (z0, z4, x0))
+
+/*
+** abal_w0_s64_untied:
+**	mov	(z[0-9]+\.s), w0
+**	movprfx	z0, z1
+**	sabal	z0\.d, z4\.s, \1
+**	ret
+*/
+TEST_DUAL_ZX (abal_w0_s64_untied, svint64_t, svint32_t, int32_t,
+	      z0 = svabal_n_s64 (z1, z4, x0),
+	      z0 = svabal (z1, z4, x0))
+
+/*
+** abal_11_s64_tied1:
+**	mov	(z[0-9]+\.s), #11
+**	sabal	z0\.d, z4\.s, \1
+**	ret
+*/
+TEST_DUAL_Z (abal_11_s64_tied1, svint64_t, svint32_t,
+	     z0 = svabal_n_s64 (z0, z4, 11),
+	     z0 = svabal (z0, z4, 11))
+
+/*
+** abal_11_s64_untied:
+**	mov	(z[0-9]+\.s), #11
+**	movprfx	z0, z1
+**	sabal	z0\.d, z4\.s, \1
+**	ret
+*/
+TEST_DUAL_Z (abal_11_s64_untied, svint64_t, svint32_t,
+	     z0 = svabal_n_s64 (z1, z4, 11),
+	     z0 = svabal (z1, z4, 11))
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_u16.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_u16.c
new file mode 100644
index 000000000000..a633770b8fd3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_u16.c
@@ -0,0 +1,90 @@
+/* { dg-do assemble { target aarch64_asm_sme2p3_ok } } */
+/* { dg-do compile { target { ! aarch64_asm_sme2p3_ok } } } */
+/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */
+
+#include "test_sve_acle.h"
+#pragma GCC target "+sve2p3"
+#pragma GCC target "+sme2p3"
+
+/*
+** abal_u16_tied1:
+**	uabal	z0\.h, z4\.b, z5\.b
+**	ret
+*/
+TEST_DUAL_Z (abal_u16_tied1, svuint16_t, svuint8_t,
+	     z0 = svabal_u16 (z0, z4, z5),
+	     z0 = svabal (z0, z4, z5))
+
+/*
+** abal_u16_tied2:
+**	mov	(z[0-9]+)\.d, z0\.d
+**	movprfx	z0, z4
+**	uabal	z0\.h, \1\.b, z1\.b
+**	ret
+*/
+TEST_DUAL_Z_REV (abal_u16_tied2, svuint16_t, svuint8_t,
+		 z0_res = svabal_u16 (z4, z0, z1),
+		 z0_res = svabal (z4, z0, z1))
+
+/*
+** abal_u16_tied3:
+**	mov	(z[0-9]+)\.d, z0\.d
+**	movprfx	z0, z4
+**	uabal	z0\.h, z1\.b, \1\.b
+**	ret
+*/
+TEST_DUAL_Z_REV (abal_u16_tied3, svuint16_t, svuint8_t,
+		 z0_res = svabal_u16 (z4, z1, z0),
+		 z0_res = svabal (z4, z1, z0))
+
+/*
+** abal_u16_untied:
+**	movprfx	z0, z1
+**	uabal	z0\.h, z4\.b, z5\.b
+**	ret
+*/
+TEST_DUAL_Z (abal_u16_untied, svuint16_t, svuint8_t,
+	     z0 = svabal_u16 (z1, z4, z5),
+	     z0 = svabal (z1, z4, z5))
+
+/*
+** abal_w0_u16_tied1:
+**	mov	(z[0-9]+\.b), w0
+**	uabal	z0\.h, z4\.b, \1
+**	ret
+*/
+TEST_DUAL_ZX (abal_w0_u16_tied1, svuint16_t, svuint8_t, uint8_t,
+	      z0 = svabal_n_u16 (z0, z4, x0),
+	      z0 = svabal (z0, z4, x0))
+
+/*
+** abal_w0_u16_untied:
+**	mov	(z[0-9]+\.b), w0
+**	movprfx	z0, z1
+**	uabal	z0\.h, z4\.b, \1
+**	ret
+*/
+TEST_DUAL_ZX (abal_w0_u16_untied, svuint16_t, svuint8_t, uint8_t,
+	      z0 = svabal_n_u16 (z1, z4, x0),
+	      z0 = svabal (z1, z4, x0))
+
+/*
+** abal_11_u16_tied1:
+**	mov	(z[0-9]+\.b), #11
+**	uabal	z0\.h, z4\.b, \1
+**	ret
+*/
+TEST_DUAL_Z (abal_11_u16_tied1, svuint16_t, svuint8_t,
+	     z0 = svabal_n_u16 (z0, z4, 11),
+	     z0 = svabal (z0, z4, 11))
+
+/*
+** abal_11_u16_untied:
+**	mov	(z[0-9]+\.b), #11
+**	movprfx	z0, z1
+**	uabal	z0\.h, z4\.b, \1
+**	ret
+*/
+TEST_DUAL_Z (abal_11_u16_untied, svuint16_t, svuint8_t,
+	     z0 = svabal_n_u16 (z1, z4, 11),
+	     z0 = svabal (z1, z4, 11))
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_u32.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_u32.c
new file mode 100644
index 000000000000..fef851db8446
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_u32.c
@@ -0,0 +1,90 @@
+/* { dg-do assemble { target aarch64_asm_sme2p3_ok } } */
+/* { dg-do compile { target { ! aarch64_asm_sme2p3_ok } } } */
+/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */
+
+#include "test_sve_acle.h"
+#pragma GCC target "+sve2p3"
+#pragma GCC target "+sme2p3"
+
+/*
+** abal_u32_tied1:
+**	uabal	z0\.s, z4\.h, z5\.h
+**	ret
+*/
+TEST_DUAL_Z (abal_u32_tied1, svuint32_t, svuint16_t,
+	     z0 = svabal_u32 (z0, z4, z5),
+	     z0 = svabal (z0, z4, z5))
+
+/*
+** abal_u32_tied2:
+**	mov	(z[0-9]+)\.d, z0\.d
+**	movprfx	z0, z4
+**	uabal	z0\.s, \1\.h, z1\.h
+**	ret
+*/
+TEST_DUAL_Z_REV (abal_u32_tied2, svuint32_t, svuint16_t,
+		 z0_res = svabal_u32 (z4, z0, z1),
+		 z0_res = svabal (z4, z0, z1))
+
+/*
+** abal_u32_tied3:
+**	mov	(z[0-9]+)\.d, z0\.d
+**	movprfx	z0, z4
+**	uabal	z0\.s, z1\.h, \1\.h
+**	ret
+*/
+TEST_DUAL_Z_REV (abal_u32_tied3, svuint32_t, svuint16_t,
+		 z0_res = svabal_u32 (z4, z1, z0),
+		 z0_res = svabal (z4, z1, z0))
+
+/*
+** abal_u32_untied:
+**	movprfx	z0, z1
+**	uabal	z0\.s, z4\.h, z5\.h
+**	ret
+*/
+TEST_DUAL_Z (abal_u32_untied, svuint32_t, svuint16_t,
+	     z0 = svabal_u32 (z1, z4, z5),
+	     z0 = svabal (z1, z4, z5))
+
+/*
+** abal_w0_u32_tied1:
+**	mov	(z[0-9]+\.h), w0
+**	uabal	z0\.s, z4\.h, \1
+**	ret
+*/
+TEST_DUAL_ZX (abal_w0_u32_tied1, svuint32_t, svuint16_t, uint16_t,
+	      z0 = svabal_n_u32 (z0, z4, x0),
+	      z0 = svabal (z0, z4, x0))
+
+/*
+** abal_w0_u32_untied:
+**	mov	(z[0-9]+\.h), w0
+**	movprfx	z0, z1
+**	uabal	z0\.s, z4\.h, \1
+**	ret
+*/
+TEST_DUAL_ZX (abal_w0_u32_untied, svuint32_t, svuint16_t, uint16_t,
+	      z0 = svabal_n_u32 (z1, z4, x0),
+	      z0 = svabal (z1, z4, x0))
+
+/*
+** abal_11_u32_tied1:
+**	mov	(z[0-9]+\.h), #11
+**	uabal	z0\.s, z4\.h, \1
+**	ret
+*/
+TEST_DUAL_Z (abal_11_u32_tied1, svuint32_t, svuint16_t,
+	     z0 = svabal_n_u32 (z0, z4, 11),
+	     z0 = svabal (z0, z4, 11))
+
+/*
+** abal_11_u32_untied:
+**	mov	(z[0-9]+\.h), #11
+**	movprfx	z0, z1
+**	uabal	z0\.s, z4\.h, \1
+**	ret
+*/
+TEST_DUAL_Z (abal_11_u32_untied, svuint32_t, svuint16_t,
+	     z0 = svabal_n_u32 (z1, z4, 11),
+	     z0 = svabal (z1, z4, 11))
diff --git a/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_u64.c b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_u64.c
new file mode 100644
index 000000000000..1d981ca353a6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/abal_u64.c
@@ -0,0 +1,90 @@
+/* { dg-do assemble { target aarch64_asm_sme2p3_ok } } */
+/* { dg-do compile { target { ! aarch64_asm_sme2p3_ok } } } */
+/* { dg-final { check-function-bodies "**" "" "-DCHECK_ASM" } } */
+
+#include "test_sve_acle.h"
+#pragma GCC target "+sve2p3"
+#pragma GCC target "+sme2p3"
+
+/*
+** abal_u64_tied1:
+**	uabal	z0\.d, z4\.s, z5\.s
+**	ret
+*/
+TEST_DUAL_Z (abal_u64_tied1, svuint64_t, svuint32_t,
+	     z0 = svabal_u64 (z0, z4, z5),
+	     z0 = svabal (z0, z4, z5))
+
+/*
+** abal_u64_tied2:
+**	mov	(z[0-9]+)\.d, z0\.d
+**	movprfx	z0, z4
+**	uabal	z0\.d, \1\.s, z1\.s
+**	ret
+*/
+TEST_DUAL_Z_REV (abal_u64_tied2, svuint64_t, svuint32_t,
+		 z0_res = svabal_u64 (z4, z0, z1),
+		 z0_res = svabal (z4, z0, z1))
+
+/*
+** abal_u64_tied3:
+**	mov	(z[0-9]+)\.d, z0\.d
+**	movprfx	z0, z4
+**	uabal	z0\.d, z1\.s, \1\.s
+**	ret
+*/
+TEST_DUAL_Z_REV (abal_u64_tied3, svuint64_t, svuint32_t,
+		 z0_res = svabal_u64 (z4, z1, z0),
+		 z0_res = svabal (z4, z1, z0))
+
+/*
+** abal_u64_untied:
+**	movprfx	z0, z1
+**	uabal	z0\.d, z4\.s, z5\.s
+**	ret
+*/
+TEST_DUAL_Z (abal_u64_untied, svuint64_t, svuint32_t,
+	     z0 = svabal_u64 (z1, z4, z5),
+	     z0 = svabal (z1, z4, z5))
+
+/*
+** abal_w0_u64_tied1:
+**	mov	(z[0-9]+\.s), w0
+**	uabal	z0\.d, z4\.s, \1
+**	ret
+*/
+TEST_DUAL_ZX (abal_w0_u64_tied1, svuint64_t, svuint32_t, uint32_t,
+	      z0 = svabal_n_u64 (z0, z4, x0),
+	      z0 = svabal (z0, z4, x0))
+
+/*
+** abal_w0_u64_untied:
+**	mov	(z[0-9]+\.s), w0
+**	movprfx	z0, z1
+**	uabal	z0\.d, z4\.s, \1
+**	ret
+*/
+TEST_DUAL_ZX (abal_w0_u64_untied, svuint64_t, svuint32_t, uint32_t,
+	      z0 = svabal_n_u64 (z1, z4, x0),
+	      z0 = svabal (z1, z4, x0))
+
+/*
+** abal_11_u64_tied1:
+**	mov	(z[0-9]+\.s), #11
+**	uabal	z0\.d, z4\.s, \1
+**	ret
+*/
+TEST_DUAL_Z (abal_11_u64_tied1, svuint64_t, svuint32_t,
+	     z0 = svabal_n_u64 (z0, z4, 11),
+	     z0 = svabal (z0, z4, 11))
+
+/*
+** abal_11_u64_untied:
+**	mov	(z[0-9]+\.s), #11
+**	movprfx	z0, z1
+**	uabal	z0\.d, z4\.s, \1
+**	ret
+*/
+TEST_DUAL_Z (abal_11_u64_untied, svuint64_t, svuint32_t,
+	     z0 = svabal_n_u64 (z1, z4, 11),
+	     z0 = svabal (z1, z4, 11))
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.