Port the `vabd` and `vaba` families of NEON intrinscs to pragma-based
framework, and add assembly tests for every variant.
Also delete the following builtin functions, which have been made
obsolete:
* `__builtin_aarch64_fabd<mode>`
* `__builtin_aarch64_uabd<mode>_uuu`
* `__builtin_aarch64_sabd<mode>`
gcc/ChangeLog:
* config/aarch64/aarch64-neon-builtins-base.cc (build_abs_diff):
New function.
(struct gimple_abs_diff, struct gimple_abs_diff_accumulate): New
structs.
(vabdh, vabds, vabdd, vabd, vabdq, vaba, vabaq): New function
bases.
* config/aarch64/aarch64-neon-builtins-base.def (vabds, vabdd,
vabd, vabdq, vaba, vabaq, vabdh): New function declarations.
* config/aarch64/aarch64-simd-builtins.def (sabd, uabd, saba,
uaba): Delete builtin functions functions.
* config/aarch64/arm_neon.h (vaba_s8, vaba_s16, vaba_s32,
vaba_u8, vaba_u16, vaba_u32, vabaq_s8, vabaq_s16, vabaq_s32,
vabaq_u8, vabaq_u16, vabaq_u32, vabd_s8, vabd_s16, vabd_s32,
vabd_u8, vabd_u16, vabd_u32, vabdq_s8, vabdq_s16, vabdq_s32,
vabdq_u8, vabdq_u16, vabdq_u32, vabds_f32, vabdd_f64,
vabd_f32, vabd_f64, vabdq_f32, vabdq_f64, vabd_f16,
vabdq_f16): Delete function definitions.
* config/aarch64/arm_fp16.h (vabdh_f16): Use
`__builtin_fabs(a - b)` instead of `__builtin_aarch64_abdhf` now
that the latter has been deleted.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/neon/vaba.c: New test.
* gcc.target/aarch64/neon/vabd.c: New test.
---
.../aarch64/aarch64-neon-builtins-base.cc | 56 +++++
.../aarch64/aarch64-neon-builtins-base.def | 16 ++
gcc/config/aarch64/aarch64-simd-builtins.def | 11 -
gcc/config/aarch64/arm_fp16.h | 2 +-
gcc/config/aarch64/arm_neon.h | 227 ------------------
gcc/testsuite/gcc.target/aarch64/neon/vaba.c | 88 +++++++
gcc/testsuite/gcc.target/aarch64/neon/vabd.c | 144 +++++++++++
7 files changed, 305 insertions(+), 239 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vaba.c
create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vabd.c
diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
index ac9b27666a4..10a2eff5f9f 100644
--- a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
@@ -793,6 +793,52 @@ struct gimple_abs : public gimple_function_base
}
};
+/* Build a tree representing the absolute difference between LHS and RHS.
+ For floating-point types, this is just `ABS (LHS - RHS)`.
+ For integer types, it is `.ABD (LHS, RHS)`. */
+tree
+build_abs_diff (gimple_folder &f, tree lhs, tree rhs)
+{
+ auto type = TREE_TYPE (lhs);
+
+ if (FLOAT_TYPE_P (type))
+ return fold_build1 (ABS_EXPR, type,
+ f.force_val (fold_build2 (MINUS_EXPR, type, lhs, rhs)));
+
+ auto ret = create_tmp_var (type);
+ vec<tree> args{};
+ args.safe_push (lhs);
+ args.safe_push (rhs);
+ auto call = gimple_build_call_internal_vec (IFN_ABD, args);
+ gsi_insert_before (f.gsi, call, GSI_SAME_STMT);
+ gimple_call_set_lhs (call, ret);
+ return ret;
+}
+
+struct gimple_abs_diff : public gimple_function_base
+{
+ gimple *fold (gimple_folder &f) const override
+ {
+ auto lhs = gimple_call_arg (f.call, 0);
+ auto rhs = gimple_call_arg (f.call, 1);
+ return gimple_build_assign (f.lhs, build_abs_diff (f, lhs, rhs));
+ }
+};
+
+struct gimple_abs_diff_accumulate : public gimple_function_base
+{
+ gimple *fold (gimple_folder &f) const override
+ {
+ auto accumulator = gimple_call_arg (f.call, 0);
+ auto lhs = gimple_call_arg (f.call, 1);
+ auto rhs = gimple_call_arg (f.call, 2);
+ auto abs_diff = f.force_val (build_abs_diff (f, lhs, rhs));
+ auto sum
+ = fold_build2 (PLUS_EXPR, TREE_TYPE (accumulator), accumulator,
abs_diff);
+ return gimple_build_assign (f.lhs, sum);
+ }
+};
+
// Reinterpret
NEON_FUNCTION (vreinterpret, gimple_reinterpret,)
NEON_FUNCTION (vreinterpretq, gimple_reinterpret,)
@@ -850,6 +896,16 @@ NEON_FUNCTION (vabsd, gimple_abs,)
NEON_FUNCTION (vabs, gimple_abs,)
NEON_FUNCTION (vabsq, gimple_abs,)
+// Absolute difference
+NEON_FUNCTION (vabds, gimple_abs_diff,)
+NEON_FUNCTION (vabdd, gimple_abs_diff,)
+NEON_FUNCTION (vabd, gimple_abs_diff,)
+NEON_FUNCTION (vabdq, gimple_abs_diff,)
+
+// Absolute difference and accumulate
+NEON_FUNCTION (vaba, gimple_abs_diff_accumulate,)
+NEON_FUNCTION (vabaq, gimple_abs_diff_accumulate,)
+
// Bitwise operations
NEON_FUNCTION (vand, gimple_expr, (BIT_AND_EXPR))
NEON_FUNCTION (vandq, gimple_expr, (BIT_AND_EXPR))
diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.def
b/gcc/config/aarch64/aarch64-neon-builtins-base.def
index 3dd7763a67d..9760e945876 100644
--- a/gcc/config/aarch64/aarch64-neon-builtins-base.def
+++ b/gcc/config/aarch64/aarch64-neon-builtins-base.def
@@ -100,6 +100,18 @@ DEF_NEON_FUNCTION (vabs, all_signed, ("D0,D0"))
DEF_NEON_FUNCTION (vabsq, all_signed, ("Q0,Q0"))
DEF_NEON_FUNCTION (vabs, sd_float, ("D0,D0"))
DEF_NEON_FUNCTION (vabsq, sd_float, ("Q0,Q0"))
+
+// Absolute difference
+DEF_NEON_FUNCTION (vabds, s_float, ("s0,s0,s0"))
+DEF_NEON_FUNCTION (vabdd, d_float, ("s0,s0,s0"))
+DEF_NEON_FUNCTION (vabd, bhs_integer, ("D0,D0,D0"))
+DEF_NEON_FUNCTION (vabdq, bhs_integer, ("Q0,Q0,Q0"))
+DEF_NEON_FUNCTION (vabd, sd_float, ("D0,D0,D0"))
+DEF_NEON_FUNCTION (vabdq, sd_float, ("Q0,Q0,Q0"))
+
+// Absolute difference and accumulate
+DEF_NEON_FUNCTION (vaba, bhs_integer, ("D0,D0,D0,D0"))
+DEF_NEON_FUNCTION (vabaq, bhs_integer, ("Q0,Q0,Q0,Q0"))
#undef REQUIRED_EXTENSIONS
// Lanewise arithmetic (FP16)
@@ -127,6 +139,10 @@ DEF_NEON_FUNCTION (vnegq, h_float, ("Q0,Q0"))
// Absolute value
DEF_NEON_FUNCTION (vabs, h_float, ("D0,D0"))
DEF_NEON_FUNCTION (vabsq, h_float, ("Q0,Q0"))
+
+// Absolute difference
+DEF_NEON_FUNCTION (vabd, h_float, ("D0,D0,D0"))
+DEF_NEON_FUNCTION (vabdq, h_float, ("Q0,Q0,Q0"))
#undef REQUIRED_EXTENSIONS
// Bitwise operations
diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def
b/gcc/config/aarch64/aarch64-simd-builtins.def
index ff6ced34deb..528e02afa11 100644
--- a/gcc/config/aarch64/aarch64-simd-builtins.def
+++ b/gcc/config/aarch64/aarch64-simd-builtins.def
@@ -187,14 +187,6 @@
BUILTIN_VDQV_L (UNOP, saddlv, 0, DEFAULT)
BUILTIN_VDQV_L (UNOPU, uaddlv, 0, DEFAULT)
- /* Implemented by aarch64_<su>abd<mode>. */
- BUILTIN_VDQ_BHSI (BINOP, sabd, 0, DEFAULT)
- BUILTIN_VDQ_BHSI (BINOPU, uabd, 0, DEFAULT)
-
- /* Implemented by aarch64_<su>aba<mode>. */
- BUILTIN_VDQ_BHSI (TERNOP, saba, 0, DEFAULT)
- BUILTIN_VDQ_BHSI (TERNOPU, uaba, 0, DEFAULT)
-
BUILTIN_VDQV_L (BINOP, sadalp, 0, DEFAULT)
BUILTIN_VDQV_L (BINOPU, uadalp, 0, DEFAULT)
@@ -813,9 +805,6 @@
/* Implemented by aarch64_ursqrte<mode>. */
BUILTIN_VDQ_SI (UNOPU, ursqrte, 0, DEFAULT)
- /* Implemented by fabd<mode>3. */
- BUILTIN_VHSDF_HSDF (BINOP, fabd, 3, FP)
-
/* Implemented by aarch64_faddp<mode>. */
BUILTIN_VHSDF (BINOP, faddp, 0, FP)
diff --git a/gcc/config/aarch64/arm_fp16.h b/gcc/config/aarch64/arm_fp16.h
index f67a9e19988..d932d8ab1c9 100644
--- a/gcc/config/aarch64/arm_fp16.h
+++ b/gcc/config/aarch64/arm_fp16.h
@@ -427,7 +427,7 @@ __extension__ extern __inline float16_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vabdh_f16 (float16_t __a, float16_t __b)
{
- return __builtin_aarch64_fabdhf (__a, __b);
+ return __builtin_fabs (__a - __b);
}
__extension__ extern __inline uint16_t
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index b4ce93f8219..435a7025939 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -1423,48 +1423,6 @@ vqrdmulhq_s32 (int32x4_t __a, int32x4_t __b)
/* Start of temporary inline asm implementations. */
-__extension__ extern __inline int8x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaba_s8 (int8x8_t __a, int8x8_t __b, int8x8_t __c)
-{
- return __builtin_aarch64_sabav8qi (__a, __b, __c);
-}
-
-__extension__ extern __inline int16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaba_s16 (int16x4_t __a, int16x4_t __b, int16x4_t __c)
-{
- return __builtin_aarch64_sabav4hi (__a, __b, __c);
-}
-
-__extension__ extern __inline int32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaba_s32 (int32x2_t __a, int32x2_t __b, int32x2_t __c)
-{
- return __builtin_aarch64_sabav2si (__a, __b, __c);
-}
-
-__extension__ extern __inline uint8x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaba_u8 (uint8x8_t __a, uint8x8_t __b, uint8x8_t __c)
-{
- return __builtin_aarch64_uabav8qi_uuuu (__a, __b, __c);
-}
-
-__extension__ extern __inline uint16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaba_u16 (uint16x4_t __a, uint16x4_t __b, uint16x4_t __c)
-{
- return __builtin_aarch64_uabav4hi_uuuu (__a, __b, __c);
-}
-
-__extension__ extern __inline uint32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaba_u32 (uint32x2_t __a, uint32x2_t __b, uint32x2_t __c)
-{
- return __builtin_aarch64_uabav2si_uuuu (__a, __b, __c);
-}
-
__extension__ extern __inline int16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vabal_high_s8 (int16x8_t __a, int8x16_t __b, int8x16_t __c)
@@ -1549,90 +1507,6 @@ vabal_u32 (uint64x2_t __a, uint32x2_t __b, uint32x2_t
__c)
return __builtin_aarch64_uabalv2si_uuuu (__a, __b, __c);
}
-__extension__ extern __inline int8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabaq_s8 (int8x16_t __a, int8x16_t __b, int8x16_t __c)
-{
- return __builtin_aarch64_sabav16qi (__a, __b, __c);
-}
-
-__extension__ extern __inline int16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabaq_s16 (int16x8_t __a, int16x8_t __b, int16x8_t __c)
-{
- return __builtin_aarch64_sabav8hi (__a, __b, __c);
-}
-
-__extension__ extern __inline int32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabaq_s32 (int32x4_t __a, int32x4_t __b, int32x4_t __c)
-{
- return __builtin_aarch64_sabav4si (__a, __b, __c);
-}
-
-__extension__ extern __inline uint8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabaq_u8 (uint8x16_t __a, uint8x16_t __b, uint8x16_t __c)
-{
- return __builtin_aarch64_uabav16qi_uuuu (__a, __b, __c);
-}
-
-__extension__ extern __inline uint16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabaq_u16 (uint16x8_t __a, uint16x8_t __b, uint16x8_t __c)
-{
- return __builtin_aarch64_uabav8hi_uuuu (__a, __b, __c);
-}
-
-__extension__ extern __inline uint32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabaq_u32 (uint32x4_t __a, uint32x4_t __b, uint32x4_t __c)
-{
- return __builtin_aarch64_uabav4si_uuuu (__a, __b, __c);
-}
-
-__extension__ extern __inline int8x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabd_s8 (int8x8_t __a, int8x8_t __b)
-{
- return __builtin_aarch64_sabdv8qi (__a, __b);
-}
-
-__extension__ extern __inline int16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabd_s16 (int16x4_t __a, int16x4_t __b)
-{
- return __builtin_aarch64_sabdv4hi (__a, __b);
-}
-
-__extension__ extern __inline int32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabd_s32 (int32x2_t __a, int32x2_t __b)
-{
- return __builtin_aarch64_sabdv2si (__a, __b);
-}
-
-__extension__ extern __inline uint8x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabd_u8 (uint8x8_t __a, uint8x8_t __b)
-{
- return __builtin_aarch64_uabdv8qi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabd_u16 (uint16x4_t __a, uint16x4_t __b)
-{
- return __builtin_aarch64_uabdv4hi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabd_u32 (uint32x2_t __a, uint32x2_t __b)
-{
- return __builtin_aarch64_uabdv2si_uuu (__a, __b);
-}
-
__extension__ extern __inline int16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vabdl_high_s8 (int8x16_t __a, int8x16_t __b)
@@ -1717,48 +1591,6 @@ vabdl_u32 (uint32x2_t __a, uint32x2_t __b)
return __builtin_aarch64_uabdlv2si_uuu (__a, __b);
}
-__extension__ extern __inline int8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabdq_s8 (int8x16_t __a, int8x16_t __b)
-{
- return __builtin_aarch64_sabdv16qi (__a, __b);
-}
-
-__extension__ extern __inline int16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabdq_s16 (int16x8_t __a, int16x8_t __b)
-{
- return __builtin_aarch64_sabdv8hi (__a, __b);
-}
-
-__extension__ extern __inline int32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabdq_s32 (int32x4_t __a, int32x4_t __b)
-{
- return __builtin_aarch64_sabdv4si (__a, __b);
-}
-
-__extension__ extern __inline uint8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabdq_u8 (uint8x16_t __a, uint8x16_t __b)
-{
- return __builtin_aarch64_uabdv16qi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabdq_u16 (uint16x8_t __a, uint16x8_t __b)
-{
- return __builtin_aarch64_uabdv8hi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabdq_u32 (uint32x4_t __a, uint32x4_t __b)
-{
- return __builtin_aarch64_uabdv4si_uuu (__a, __b);
-}
-
__extension__ extern __inline int16_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vaddlv_s8 (int8x8_t __a)
@@ -4856,51 +4688,6 @@ vtbx2_p8 (poly8x8_t __r, poly8x8x2_t __tab, uint8x8_t
__idx)
/* Start of optimal implementations in approved order. */
-/* vabd. */
-
-__extension__ extern __inline float32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabds_f32 (float32_t __a, float32_t __b)
-{
- return __builtin_aarch64_fabdsf (__a, __b);
-}
-
-__extension__ extern __inline float64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabdd_f64 (float64_t __a, float64_t __b)
-{
- return __builtin_aarch64_fabddf (__a, __b);
-}
-
-__extension__ extern __inline float32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabd_f32 (float32x2_t __a, float32x2_t __b)
-{
- return __builtin_aarch64_fabdv2sf (__a, __b);
-}
-
-__extension__ extern __inline float64x1_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabd_f64 (float64x1_t __a, float64x1_t __b)
-{
- return (float64x1_t) {vabdd_f64 (vget_lane_f64 (__a, 0),
- vget_lane_f64 (__b, 0))};
-}
-
-__extension__ extern __inline float32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabdq_f32 (float32x4_t __a, float32x4_t __b)
-{
- return __builtin_aarch64_fabdv4sf (__a, __b);
-}
-
-__extension__ extern __inline float64x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabdq_f64 (float64x2_t __a, float64x2_t __b)
-{
- return __builtin_aarch64_fabdv2df (__a, __b);
-}
-
/* vaddv */
__extension__ extern __inline int8_t
@@ -19638,20 +19425,6 @@ vsqrtq_f16 (float16x8_t __a)
/* ARMv8.2-A FP16 two operands vector intrinsics. */
-__extension__ extern __inline float16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabd_f16 (float16x4_t __a, float16x4_t __b)
-{
- return __builtin_aarch64_fabdv4hf (__a, __b);
-}
-
-__extension__ extern __inline float16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vabdq_f16 (float16x8_t __a, float16x8_t __b)
-{
- return __builtin_aarch64_fabdv8hf (__a, __b);
-}
-
__extension__ extern __inline uint16x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vcage_f16 (float16x4_t __a, float16x4_t __b)
diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vaba.c
b/gcc/testsuite/gcc.target/aarch64/neon/vaba.c
new file mode 100644
index 00000000000..e54c88fe82e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/neon/vaba.c
@@ -0,0 +1,88 @@
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_neon_test.h"
+
+/*
+** test_vaba_s8:
+** saba v0\.8b, v1\.8b, v2\.8b
+** ret
+*/
+TEST_UNIFORM_TERNARY (vaba_s8, int8x8_t)
+
+/*
+** test_vabaq_s8:
+** saba v0\.16b, v1\.16b, v2\.16b
+** ret
+*/
+TEST_UNIFORM_TERNARY (vabaq_s8, int8x16_t)
+
+/*
+** test_vaba_s16:
+** saba v0\.4h, v1\.4h, v2\.4h
+** ret
+*/
+TEST_UNIFORM_TERNARY (vaba_s16, int16x4_t)
+
+/*
+** test_vabaq_s16:
+** saba v0\.8h, v1\.8h, v2\.8h
+** ret
+*/
+TEST_UNIFORM_TERNARY (vabaq_s16, int16x8_t)
+
+/*
+** test_vaba_s32:
+** saba v0\.2s, v1\.2s, v2\.2s
+** ret
+*/
+TEST_UNIFORM_TERNARY (vaba_s32, int32x2_t)
+
+/*
+** test_vabaq_s32:
+** saba v0\.4s, v1\.4s, v2\.4s
+** ret
+*/
+TEST_UNIFORM_TERNARY (vabaq_s32, int32x4_t)
+
+/*
+** test_vaba_u8:
+** uaba v0\.8b, v1\.8b, v2\.8b
+** ret
+*/
+TEST_UNIFORM_TERNARY (vaba_u8, uint8x8_t)
+
+/*
+** test_vabaq_u8:
+** uaba v0\.16b, v1\.16b, v2\.16b
+** ret
+*/
+TEST_UNIFORM_TERNARY (vabaq_u8, uint8x16_t)
+
+/*
+** test_vaba_u16:
+** uaba v0\.4h, v1\.4h, v2\.4h
+** ret
+*/
+TEST_UNIFORM_TERNARY (vaba_u16, uint16x4_t)
+
+/*
+** test_vabaq_u16:
+** uaba v0\.8h, v1\.8h, v2\.8h
+** ret
+*/
+TEST_UNIFORM_TERNARY (vabaq_u16, uint16x8_t)
+
+/*
+** test_vaba_u32:
+** uaba v0\.2s, v1\.2s, v2\.2s
+** ret
+*/
+TEST_UNIFORM_TERNARY (vaba_u32, uint32x2_t)
+
+/*
+** test_vabaq_u32:
+** uaba v0\.4s, v1\.4s, v2\.4s
+** ret
+*/
+TEST_UNIFORM_TERNARY (vabaq_u32, uint32x4_t)
diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vabd.c
b/gcc/testsuite/gcc.target/aarch64/neon/vabd.c
new file mode 100644
index 00000000000..101d7cf5b0d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/neon/vabd.c
@@ -0,0 +1,144 @@
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_neon_test.h"
+
+/*
+** test_vabd_s8:
+** sabd v0\.8b, v0\.8b, v1\.8b
+** ret
+*/
+TEST_UNIFORM_BINARY (vabd_s8, int8x8_t)
+
+/*
+** test_vabdq_s8:
+** sabd v0\.16b, v0\.16b, v1\.16b
+** ret
+*/
+TEST_UNIFORM_BINARY (vabdq_s8, int8x16_t)
+
+/*
+** test_vabd_s16:
+** sabd v0\.4h, v0\.4h, v1\.4h
+** ret
+*/
+TEST_UNIFORM_BINARY (vabd_s16, int16x4_t)
+
+/*
+** test_vabdq_s16:
+** sabd v0\.8h, v0\.8h, v1\.8h
+** ret
+*/
+TEST_UNIFORM_BINARY (vabdq_s16, int16x8_t)
+
+/*
+** test_vabd_s32:
+** sabd v0\.2s, v0\.2s, v1\.2s
+** ret
+*/
+TEST_UNIFORM_BINARY (vabd_s32, int32x2_t)
+
+/*
+** test_vabdq_s32:
+** sabd v0\.4s, v0\.4s, v1\.4s
+** ret
+*/
+TEST_UNIFORM_BINARY (vabdq_s32, int32x4_t)
+
+/*
+** test_vabd_u8:
+** uabd v0\.8b, v0\.8b, v1\.8b
+** ret
+*/
+TEST_UNIFORM_BINARY (vabd_u8, uint8x8_t)
+
+/*
+** test_vabdq_u8:
+** uabd v0\.16b, v0\.16b, v1\.16b
+** ret
+*/
+TEST_UNIFORM_BINARY (vabdq_u8, uint8x16_t)
+
+/*
+** test_vabd_u16:
+** uabd v0\.4h, v0\.4h, v1\.4h
+** ret
+*/
+TEST_UNIFORM_BINARY (vabd_u16, uint16x4_t)
+
+/*
+** test_vabdq_u16:
+** uabd v0\.8h, v0\.8h, v1\.8h
+** ret
+*/
+TEST_UNIFORM_BINARY (vabdq_u16, uint16x8_t)
+
+/*
+** test_vabd_u32:
+** uabd v0\.2s, v0\.2s, v1\.2s
+** ret
+*/
+TEST_UNIFORM_BINARY (vabd_u32, uint32x2_t)
+
+/*
+** test_vabdq_u32:
+** uabd v0\.4s, v0\.4s, v1\.4s
+** ret
+*/
+TEST_UNIFORM_BINARY (vabdq_u32, uint32x4_t)
+
+/*
+** test_vabd_f16:
+** fabd v0\.4h, v0\.4h, v1\.4h
+** ret
+*/
+TEST_UNIFORM_BINARY (vabd_f16, float16x4_t)
+
+/*
+** test_vabdq_f16:
+** fabd v0\.8h, v0\.8h, v1\.8h
+** ret
+*/
+TEST_UNIFORM_BINARY (vabdq_f16, float16x8_t)
+
+/*
+** test_vabd_f32:
+** fabd v0\.2s, v0\.2s, v1\.2s
+** ret
+*/
+TEST_UNIFORM_BINARY (vabd_f32, float32x2_t)
+
+/*
+** test_vabdq_f32:
+** fabd v0\.4s, v0\.4s, v1\.4s
+** ret
+*/
+TEST_UNIFORM_BINARY (vabdq_f32, float32x4_t)
+
+/*
+** test_vabd_f64:
+** fabd d0, d0, d1
+** ret
+*/
+TEST_UNIFORM_BINARY (vabd_f64, float64x1_t)
+
+/*
+** test_vabdq_f64:
+** fabd v0\.2d, v0\.2d, v1\.2d
+** ret
+*/
+TEST_UNIFORM_BINARY (vabdq_f64, float64x2_t)
+
+/*
+** test_vabds_f32:
+** fabd s0, s0, s1
+** ret
+*/
+TEST_UNIFORM_BINARY (vabds_f32, float32_t)
+
+/*
+** test_vabdd_f64:
+** fabd d0, d0, d1
+** ret
+*/
+TEST_UNIFORM_BINARY (vabdd_f64, float64_t)
--
2.51.0