> On 21 Aug 2026, at 15:18, Karl Meakin <[email protected]> wrote:
>
> 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;
> +}
One problem here is inlining across streaming boundaries. This may happen
during LTO as IPA doesn’t retain the streaming information for the IFN_.
I guess there are two ways of avoiding this: either avoid folding and leave it
only till expand, or add logic aarch64_update_ipa_fn_target_info to set
AARCH64_IPA_SM_FIXED for fixed-width IFN_ABD.
Thanks,
Kyrill
> +
> +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
>