| Message ID | 20260902083828.45767-2-dhruvc@nvidia.com |
|---|---|
| State | New |
| Headers | show |
| Series | aarch64: Port NEON intrinsics to pragma-based framework using IFNs | expand |
Hi Dhruv, > On 2 Sep 2026, at 10:38, Dhruv Chawla <dhruvc@nvidia.com> wrote: > > From: Dhruv Chawla <dhruvc@nvidia.com> > > Port the following intrinsics to the pragma-based framework: > * vqadd > * vqsub > > Plus their scalar variants: vq{add,sub}{b,h,s,d}. > > The following are not ported in this patch as they cannot be directly > lowered from an IFN through an existing instruction pattern: > * vqadd_s64 > * vqadd_u64 > * vqsub_s64 > * vqsub_u64 > > This is because the pattern does not iterate through the modes (V1DI) required > to lower them (it uses the VSDQ_I_QI_HI iterator). > I see this is an issue with many intrinsics groups. We’ll need to figure out a way to handle this, but in another patch. This patch is ok. Thanks, Kyrill > Bootstrapped and regtested on aarch64-linux-gnu. > > Signed-off-by: Dhruv Chawla <dhruvc@nvidia.com> > > gcc/ChangeLog: > > * config/aarch64/aarch64-neon-builtins-base.cc (vqaddb, vqaddh, > vqadds, vqaddd, vqadd, vqaddq, vqsubb, vqsubh, vqsubs, vqsubd, vqsub, > vqsubq): New function bases. > * config/aarch64/aarch64-neon-builtins-base.def (vqaddb, vqaddh, > vqadds, vqaddd, vqadd, vqaddq, vqsubb, vqsubh, vqsubs, vqsubd, vqsub, > vqsubq): New function groups. > * config/aarch64/arm_neon.h (vqadd_s8, vqadd_s16, vqadd_s32, > vqadd_u8, vqadd_u16, vqadd_u32, vqaddq_s8, vqaddq_s16, vqaddq_s32, > vqaddq_s64, vqaddq_u8, vqaddq_u16, vqaddq_u32, vqaddq_u64, vqsub_s8, > vqsub_s16, vqsub_s32, vqsub_u8, vqsub_u16, vqsub_u32, vqsubq_s8, > vqsubq_s16, vqsubq_s32, vqsubq_s64, vqsubq_u8, vqsubq_u16, vqsubq_u32, > vqsubq_u64, vqaddb_s8, vqaddh_s16, vqadds_s32, vqaddd_s64, vqaddb_u8, > vqaddh_u16, vqadds_u32, vqaddd_u64, vqsubb_s8, vqsubh_s16, vqsubs_s32, > vqsubd_s64, vqsubb_u8, vqsubh_u16, vqsubs_u32, vqsubd_u64): Delete > functions. > (vqadd_s64): Relocate to be grouped with the other {s,u}64 > functions. > > gcc/testsuite/ChangeLog: > > * gcc.target/aarch64/neon/vqadd.c: New test. > * gcc.target/aarch64/neon/vqsub.c: Likewise. > --- > .../aarch64/aarch64-neon-builtins-base.cc | 14 + > .../aarch64/aarch64-neon-builtins-base.def | 16 + > gcc/config/aarch64/arm_neon.h | 318 +----------------- > gcc/testsuite/gcc.target/aarch64/neon/vqadd.c | 192 +++++++++++ > gcc/testsuite/gcc.target/aarch64/neon/vqsub.c | 192 +++++++++++ > 5 files changed, 417 insertions(+), 315 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vqadd.c > create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vqsub.c > > diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.cc b/gcc/config/aarch64/aarch64-neon-builtins-base.cc > index d8fae81388e..5c886d32f42 100644 > --- a/gcc/config/aarch64/aarch64-neon-builtins-base.cc > +++ b/gcc/config/aarch64/aarch64-neon-builtins-base.cc > @@ -753,6 +753,20 @@ NEON_FUNCTION (vaddd, gimple_expr, (PLUS_EXPR)) > NEON_FUNCTION (vadd, gimple_expr, (PLUS_EXPR, PLUS_EXPR, BIT_XOR_EXPR)) > NEON_FUNCTION (vaddq, gimple_expr, (PLUS_EXPR, PLUS_EXPR, BIT_XOR_EXPR)) > > +// Saturating arithmetic > +NEON_FUNCTION (vqaddb, gimple_ifn, (IFN_SAT_ADD)) > +NEON_FUNCTION (vqaddh, gimple_ifn, (IFN_SAT_ADD)) > +NEON_FUNCTION (vqadds, gimple_ifn, (IFN_SAT_ADD)) > +NEON_FUNCTION (vqaddd, gimple_ifn, (IFN_SAT_ADD)) > +NEON_FUNCTION (vqadd, gimple_ifn, (IFN_SAT_ADD)) > +NEON_FUNCTION (vqaddq, gimple_ifn, (IFN_SAT_ADD)) > +NEON_FUNCTION (vqsubb, gimple_ifn, (IFN_SAT_SUB)) > +NEON_FUNCTION (vqsubh, gimple_ifn, (IFN_SAT_SUB)) > +NEON_FUNCTION (vqsubs, gimple_ifn, (IFN_SAT_SUB)) > +NEON_FUNCTION (vqsubd, gimple_ifn, (IFN_SAT_SUB)) > +NEON_FUNCTION (vqsub, gimple_ifn, (IFN_SAT_SUB)) > +NEON_FUNCTION (vqsubq, gimple_ifn, (IFN_SAT_SUB)) > + > // 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 7257f59bbc5..52e4746453b 100644 > --- a/gcc/config/aarch64/aarch64-neon-builtins-base.def > +++ b/gcc/config/aarch64/aarch64-neon-builtins-base.def > @@ -76,6 +76,22 @@ DEF_NEON_FUNCTION (vadd, h_float, ("D0,D0,D0")) > DEF_NEON_FUNCTION (vaddq, h_float, ("Q0,Q0,Q0")) > #undef REQUIRED_EXTENSIONS > > +// Saturating arithmetic > +#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD) > +DEF_NEON_FUNCTION (vqaddb, b_integer, ("s0,s0,s0")) > +DEF_NEON_FUNCTION (vqaddh, h_integer, ("s0,s0,s0")) > +DEF_NEON_FUNCTION (vqadds, s_integer, ("s0,s0,s0")) > +DEF_NEON_FUNCTION (vqaddd, d_integer, ("s0,s0,s0")) > +DEF_NEON_FUNCTION (vqadd, bhs_integer, ("D0,D0,D0")) > +DEF_NEON_FUNCTION (vqaddq, all_integer, ("Q0,Q0,Q0")) > +DEF_NEON_FUNCTION (vqsubb, b_integer, ("s0,s0,s0")) > +DEF_NEON_FUNCTION (vqsubh, h_integer, ("s0,s0,s0")) > +DEF_NEON_FUNCTION (vqsubs, s_integer, ("s0,s0,s0")) > +DEF_NEON_FUNCTION (vqsubd, d_integer, ("s0,s0,s0")) > +DEF_NEON_FUNCTION (vqsub, bhs_integer, ("D0,D0,D0")) > +DEF_NEON_FUNCTION (vqsubq, all_integer, ("Q0,Q0,Q0")) > +#undef REQUIRED_EXTENSIONS > + > // Bitwise operations > #define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD) > DEF_NEON_FUNCTION (vand, all_integer, ("D0,D0,D0")) > diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h > index 873a1195d3e..985b4bdb6cc 100644 > --- a/gcc/config/aarch64/arm_neon.h > +++ b/gcc/config/aarch64/arm_neon.h > @@ -1071,41 +1071,6 @@ vsubw_high_u32 (uint64x2_t __a, uint32x4_t __b) > return __builtin_aarch64_usubw2v4si_uuu (__a, __b); > } > > -__extension__ extern __inline int8x8_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqadd_s8 (int8x8_t __a, int8x8_t __b) > -{ > - return (int8x8_t) __builtin_aarch64_ssaddv8qi (__a, __b); > -} > - > -__extension__ extern __inline int16x4_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqadd_s16 (int16x4_t __a, int16x4_t __b) > -{ > - return (int16x4_t) __builtin_aarch64_ssaddv4hi (__a, __b); > -} > - > -__extension__ extern __inline int32x2_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqadd_s32 (int32x2_t __a, int32x2_t __b) > -{ > - return (int32x2_t) __builtin_aarch64_ssaddv2si (__a, __b); > -} > - > -__extension__ extern __inline int64x1_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqadd_s64 (int64x1_t __a, int64x1_t __b) > -{ > - return (int64x1_t) {__builtin_aarch64_ssadddi (__a[0], __b[0])}; > -} > - > -__extension__ extern __inline uint8x8_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqadd_u8 (uint8x8_t __a, uint8x8_t __b) > -{ > - return __builtin_aarch64_usaddv8qi_uuu (__a, __b); > -} > - > __extension__ extern __inline int8x8_t > __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > vhsub_s8 (int8x8_t __a, int8x8_t __b) > @@ -1358,18 +1323,11 @@ vsubhn_high_u64 (uint32x2_t __a, uint64x2_t __b, uint64x2_t __c) > return __builtin_aarch64_subhn2v2di_uuuu (__a, __b, __c); > } > > -__extension__ extern __inline uint16x4_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqadd_u16 (uint16x4_t __a, uint16x4_t __b) > -{ > - return __builtin_aarch64_usaddv4hi_uuu (__a, __b); > -} > - > -__extension__ extern __inline uint32x2_t > +__extension__ extern __inline int64x1_t > __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqadd_u32 (uint32x2_t __a, uint32x2_t __b) > +vqadd_s64 (int64x1_t __a, int64x1_t __b) > { > - return __builtin_aarch64_usaddv2si_uuu (__a, __b); > + return (int64x1_t) {__builtin_aarch64_ssadddi (__a[0], __b[0])}; > } > > __extension__ extern __inline uint64x1_t > @@ -1379,83 +1337,6 @@ vqadd_u64 (uint64x1_t __a, uint64x1_t __b) > return (uint64x1_t) {__builtin_aarch64_usadddi_uuu (__a[0], __b[0])}; > } > > -__extension__ extern __inline int8x16_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqaddq_s8 (int8x16_t __a, int8x16_t __b) > -{ > - return (int8x16_t) __builtin_aarch64_ssaddv16qi (__a, __b); > -} > - > -__extension__ extern __inline int16x8_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqaddq_s16 (int16x8_t __a, int16x8_t __b) > -{ > - return (int16x8_t) __builtin_aarch64_ssaddv8hi (__a, __b); > -} > - > -__extension__ extern __inline int32x4_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqaddq_s32 (int32x4_t __a, int32x4_t __b) > -{ > - return (int32x4_t) __builtin_aarch64_ssaddv4si (__a, __b); > -} > - > -__extension__ extern __inline int64x2_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqaddq_s64 (int64x2_t __a, int64x2_t __b) > -{ > - return (int64x2_t) __builtin_aarch64_ssaddv2di (__a, __b); > -} > - > -__extension__ extern __inline uint8x16_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqaddq_u8 (uint8x16_t __a, uint8x16_t __b) > -{ > - return __builtin_aarch64_usaddv16qi_uuu (__a, __b); > -} > - > -__extension__ extern __inline uint16x8_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqaddq_u16 (uint16x8_t __a, uint16x8_t __b) > -{ > - return __builtin_aarch64_usaddv8hi_uuu (__a, __b); > -} > - > -__extension__ extern __inline uint32x4_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqaddq_u32 (uint32x4_t __a, uint32x4_t __b) > -{ > - return __builtin_aarch64_usaddv4si_uuu (__a, __b); > -} > - > -__extension__ extern __inline uint64x2_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqaddq_u64 (uint64x2_t __a, uint64x2_t __b) > -{ > - return __builtin_aarch64_usaddv2di_uuu (__a, __b); > -} > - > -__extension__ extern __inline int8x8_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsub_s8 (int8x8_t __a, int8x8_t __b) > -{ > - return (int8x8_t) __builtin_aarch64_sssubv8qi (__a, __b); > -} > - > -__extension__ extern __inline int16x4_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsub_s16 (int16x4_t __a, int16x4_t __b) > -{ > - return (int16x4_t) __builtin_aarch64_sssubv4hi (__a, __b); > -} > - > -__extension__ extern __inline int32x2_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsub_s32 (int32x2_t __a, int32x2_t __b) > -{ > - return (int32x2_t) __builtin_aarch64_sssubv2si (__a, __b); > -} > - > __extension__ extern __inline int64x1_t > __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > vqsub_s64 (int64x1_t __a, int64x1_t __b) > @@ -1463,27 +1344,6 @@ vqsub_s64 (int64x1_t __a, int64x1_t __b) > return (int64x1_t) {__builtin_aarch64_sssubdi (__a[0], __b[0])}; > } > > -__extension__ extern __inline uint8x8_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsub_u8 (uint8x8_t __a, uint8x8_t __b) > -{ > - return __builtin_aarch64_ussubv8qi_uuu (__a, __b); > -} > - > -__extension__ extern __inline uint16x4_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsub_u16 (uint16x4_t __a, uint16x4_t __b) > -{ > - return __builtin_aarch64_ussubv4hi_uuu (__a, __b); > -} > - > -__extension__ extern __inline uint32x2_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsub_u32 (uint32x2_t __a, uint32x2_t __b) > -{ > - return __builtin_aarch64_ussubv2si_uuu (__a, __b); > -} > - > __extension__ extern __inline uint64x1_t > __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > vqsub_u64 (uint64x1_t __a, uint64x1_t __b) > @@ -1491,62 +1351,6 @@ vqsub_u64 (uint64x1_t __a, uint64x1_t __b) > return (uint64x1_t) {__builtin_aarch64_ussubdi_uuu (__a[0], __b[0])}; > } > > -__extension__ extern __inline int8x16_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubq_s8 (int8x16_t __a, int8x16_t __b) > -{ > - return (int8x16_t) __builtin_aarch64_sssubv16qi (__a, __b); > -} > - > -__extension__ extern __inline int16x8_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubq_s16 (int16x8_t __a, int16x8_t __b) > -{ > - return (int16x8_t) __builtin_aarch64_sssubv8hi (__a, __b); > -} > - > -__extension__ extern __inline int32x4_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubq_s32 (int32x4_t __a, int32x4_t __b) > -{ > - return (int32x4_t) __builtin_aarch64_sssubv4si (__a, __b); > -} > - > -__extension__ extern __inline int64x2_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubq_s64 (int64x2_t __a, int64x2_t __b) > -{ > - return (int64x2_t) __builtin_aarch64_sssubv2di (__a, __b); > -} > - > -__extension__ extern __inline uint8x16_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubq_u8 (uint8x16_t __a, uint8x16_t __b) > -{ > - return __builtin_aarch64_ussubv16qi_uuu (__a, __b); > -} > - > -__extension__ extern __inline uint16x8_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubq_u16 (uint16x8_t __a, uint16x8_t __b) > -{ > - return __builtin_aarch64_ussubv8hi_uuu (__a, __b); > -} > - > -__extension__ extern __inline uint32x4_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubq_u32 (uint32x4_t __a, uint32x4_t __b) > -{ > - return __builtin_aarch64_ussubv4si_uuu (__a, __b); > -} > - > -__extension__ extern __inline uint64x2_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubq_u64 (uint64x2_t __a, uint64x2_t __b) > -{ > - return __builtin_aarch64_ussubv2di_uuu (__a, __b); > -} > - > __extension__ extern __inline int8x8_t > __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > vqneg_s8 (int8x8_t __a) > @@ -13921,64 +13725,6 @@ vqabsd_s64 (int64_t __a) > return __builtin_aarch64_sqabsdi (__a); > } > > -/* vqadd */ > - > -__extension__ extern __inline int8_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqaddb_s8 (int8_t __a, int8_t __b) > -{ > - return (int8_t) __builtin_aarch64_ssaddqi (__a, __b); > -} > - > -__extension__ extern __inline int16_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqaddh_s16 (int16_t __a, int16_t __b) > -{ > - return (int16_t) __builtin_aarch64_ssaddhi (__a, __b); > -} > - > -__extension__ extern __inline int32_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqadds_s32 (int32_t __a, int32_t __b) > -{ > - return (int32_t) __builtin_aarch64_ssaddsi (__a, __b); > -} > - > -__extension__ extern __inline int64_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqaddd_s64 (int64_t __a, int64_t __b) > -{ > - return __builtin_aarch64_ssadddi (__a, __b); > -} > - > -__extension__ extern __inline uint8_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqaddb_u8 (uint8_t __a, uint8_t __b) > -{ > - return (uint8_t) __builtin_aarch64_usaddqi_uuu (__a, __b); > -} > - > -__extension__ extern __inline uint16_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqaddh_u16 (uint16_t __a, uint16_t __b) > -{ > - return (uint16_t) __builtin_aarch64_usaddhi_uuu (__a, __b); > -} > - > -__extension__ extern __inline uint32_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqadds_u32 (uint32_t __a, uint32_t __b) > -{ > - return (uint32_t) __builtin_aarch64_usaddsi_uuu (__a, __b); > -} > - > -__extension__ extern __inline uint64_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqaddd_u64 (uint64_t __a, uint64_t __b) > -{ > - return __builtin_aarch64_usadddi_uuu (__a, __b); > -} > - > /* vqdmlal */ > > __extension__ extern __inline int32x4_t > @@ -15620,64 +15366,6 @@ vqshrund_n_s64 (int64_t __a, const int __b) > return (int32_t) __builtin_aarch64_sqshrun_ndi (__a, __b); > } > > -/* vqsub */ > - > -__extension__ extern __inline int8_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubb_s8 (int8_t __a, int8_t __b) > -{ > - return (int8_t) __builtin_aarch64_sssubqi (__a, __b); > -} > - > -__extension__ extern __inline int16_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubh_s16 (int16_t __a, int16_t __b) > -{ > - return (int16_t) __builtin_aarch64_sssubhi (__a, __b); > -} > - > -__extension__ extern __inline int32_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubs_s32 (int32_t __a, int32_t __b) > -{ > - return (int32_t) __builtin_aarch64_sssubsi (__a, __b); > -} > - > -__extension__ extern __inline int64_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubd_s64 (int64_t __a, int64_t __b) > -{ > - return __builtin_aarch64_sssubdi (__a, __b); > -} > - > -__extension__ extern __inline uint8_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubb_u8 (uint8_t __a, uint8_t __b) > -{ > - return (uint8_t) __builtin_aarch64_ussubqi_uuu (__a, __b); > -} > - > -__extension__ extern __inline uint16_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubh_u16 (uint16_t __a, uint16_t __b) > -{ > - return (uint16_t) __builtin_aarch64_ussubhi_uuu (__a, __b); > -} > - > -__extension__ extern __inline uint32_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubs_u32 (uint32_t __a, uint32_t __b) > -{ > - return (uint32_t) __builtin_aarch64_ussubsi_uuu (__a, __b); > -} > - > -__extension__ extern __inline uint64_t > -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) > -vqsubd_u64 (uint64_t __a, uint64_t __b) > -{ > - return __builtin_aarch64_ussubdi_uuu (__a, __b); > -} > - > /* vqtbl2 */ > > __extension__ extern __inline int8x8_t > diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vqadd.c b/gcc/testsuite/gcc.target/aarch64/neon/vqadd.c > new file mode 100644 > index 00000000000..322f54c5a42 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/neon/vqadd.c > @@ -0,0 +1,192 @@ > +/* { dg-do compile } */ > +/* { dg-final { check-function-bodies "**" "" } } */ > + > +#include "arm_neon_test.h" > + > +/* > +** test_vqadd_u8: > +** uqadd v0\.8b, (v0\.8b, v1\.8b|v1\.8b, v0\.8b) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqadd_u8, uint8x8_t) > + > +/* > +** test_vqadd_s8: > +** sqadd v0\.8b, (v0\.8b, v1\.8b|v1\.8b, v0\.8b) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqadd_s8, int8x8_t) > + > +/* > +** test_vqadd_u16: > +** uqadd v0\.4h, (v0\.4h, v1\.4h|v1\.4h, v0\.4h) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqadd_u16, uint16x4_t) > + > +/* > +** test_vqadd_s16: > +** sqadd v0\.4h, (v0\.4h, v1\.4h|v1\.4h, v0\.4h) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqadd_s16, int16x4_t) > + > +/* > +** test_vqadd_u32: > +** uqadd v0\.2s, (v0\.2s, v1\.2s|v1\.2s, v0\.2s) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqadd_u32, uint32x2_t) > + > +/* > +** test_vqadd_s32: > +** sqadd v0\.2s, (v0\.2s, v1\.2s|v1\.2s, v0\.2s) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqadd_s32, int32x2_t) > + > +/* > +** test_vqadd_u64: > +** uqadd d0, (d0, d1|d1, d0) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqadd_u64, uint64x1_t) > + > +/* > +** test_vqadd_s64: > +** sqadd d0, (d0, d1|d1, d0) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqadd_s64, int64x1_t) > + > +/* > +** test_vqaddq_u8: > +** uqadd v0\.16b, (v0\.16b, v1\.16b|v1\.16b, v0\.16b) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqaddq_u8, uint8x16_t) > + > +/* > +** test_vqaddq_s8: > +** sqadd v0\.16b, (v0\.16b, v1\.16b|v1\.16b, v0\.16b) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqaddq_s8, int8x16_t) > + > +/* > +** test_vqaddq_u16: > +** uqadd v0\.8h, (v0\.8h, v1\.8h|v1\.8h, v0\.8h) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqaddq_u16, uint16x8_t) > + > +/* > +** test_vqaddq_s16: > +** sqadd v0\.8h, (v0\.8h, v1\.8h|v1\.8h, v0\.8h) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqaddq_s16, int16x8_t) > + > +/* > +** test_vqaddq_u32: > +** uqadd v0\.4s, (v0\.4s, v1\.4s|v1\.4s, v0\.4s) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqaddq_u32, uint32x4_t) > + > +/* > +** test_vqaddq_s32: > +** sqadd v0\.4s, (v0\.4s, v1\.4s|v1\.4s, v0\.4s) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqaddq_s32, int32x4_t) > + > +/* > +** test_vqaddq_u64: > +** uqadd v0\.2d, (v0\.2d, v1\.2d|v1\.2d, v0\.2d) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqaddq_u64, uint64x2_t) > + > +/* > +** test_vqaddq_s64: > +** sqadd v0\.2d, (v0\.2d, v1\.2d|v1\.2d, v0\.2d) > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqaddq_s64, int64x2_t) > + > +/* > +** test_vqaddb_u8: > +** dup v([0-9]+)\.8b, w[0-9]+ > +** dup v([0-9]+)\.8b, w[0-9]+ > +** uqadd b([0-9]+), (b\2, b\1|b\1, b\2) > +** umov w0, v\3\.b\[0\] > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqaddb_u8, uint8_t) > + > +/* > +** test_vqaddb_s8: > +** dup v([0-9]+)\.8b, w[0-9]+ > +** dup v([0-9]+)\.8b, w[0-9]+ > +** sqadd b([0-9]+), (b\2, b\1|b\1, b\2) > +** umov w0, v\3\.b\[0\] > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqaddb_s8, int8_t) > + > +/* > +** test_vqaddh_u16: > +** dup v([0-9]+)\.4h, w[0-9]+ > +** dup v([0-9]+)\.4h, w[0-9]+ > +** uqadd h([0-9]+), (h\2, h\1|h\1, h\2) > +** umov w0, v\3\.h\[0\] > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqaddh_u16, uint16_t) > + > +/* > +** test_vqaddh_s16: > +** dup v([0-9]+)\.4h, w[0-9]+ > +** dup v([0-9]+)\.4h, w[0-9]+ > +** sqadd h([0-9]+), (h\2, h\1|h\1, h\2) > +** umov w0, v\3\.h\[0\] > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqaddh_s16, int16_t) > + > +/* > +** test_vqadds_u32: > +** adds (w[0-9]+), (w0, w1|w1, w0) > +** csinv w0, \1, wzr, cc > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqadds_u32, uint32_t) > + > +/* > +** test_vqadds_s32: > +** fmov (s[0-9]+), w[0-9]+ > +** fmov (s[0-9]+), w[0-9]+ > +** sqadd s([0-9]+), (\2, \1|\1, \2) > +** fmov w0, s\3 > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqadds_s32, int32_t) > + > +/* > +** test_vqaddd_u64: > +** adds (x[0-9]+), (x0, x1|x1, x0) > +** csinv x0, \1, xzr, cc > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqaddd_u64, uint64_t) > + > +/* > +** test_vqaddd_s64: > +** fmov (d[0-9]+), x[0-9]+ > +** fmov (d[0-9]+), x[0-9]+ > +** sqadd d([0-9]+), (\2, \1|\1, \2) > +** fmov x0, d\3 > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqaddd_s64, int64_t) > diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vqsub.c b/gcc/testsuite/gcc.target/aarch64/neon/vqsub.c > new file mode 100644 > index 00000000000..52ac2f102eb > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/neon/vqsub.c > @@ -0,0 +1,192 @@ > +/* { dg-do compile } */ > +/* { dg-final { check-function-bodies "**" "" } } */ > + > +#include "arm_neon_test.h" > + > +/* > +** test_vqsub_u8: > +** uqsub v0\.8b, v0\.8b, v1\.8b > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsub_u8, uint8x8_t) > + > +/* > +** test_vqsub_s8: > +** sqsub v0\.8b, v0\.8b, v1\.8b > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsub_s8, int8x8_t) > + > +/* > +** test_vqsub_u16: > +** uqsub v0\.4h, v0\.4h, v1\.4h > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsub_u16, uint16x4_t) > + > +/* > +** test_vqsub_s16: > +** sqsub v0\.4h, v0\.4h, v1\.4h > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsub_s16, int16x4_t) > + > +/* > +** test_vqsub_u32: > +** uqsub v0\.2s, v0\.2s, v1\.2s > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsub_u32, uint32x2_t) > + > +/* > +** test_vqsub_s32: > +** sqsub v0\.2s, v0\.2s, v1\.2s > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsub_s32, int32x2_t) > + > +/* > +** test_vqsub_u64: > +** uqsub d0, d0, d1 > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsub_u64, uint64x1_t) > + > +/* > +** test_vqsub_s64: > +** sqsub d0, d0, d1 > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsub_s64, int64x1_t) > + > +/* > +** test_vqsubq_u8: > +** uqsub v0\.16b, v0\.16b, v1\.16b > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubq_u8, uint8x16_t) > + > +/* > +** test_vqsubq_s8: > +** sqsub v0\.16b, v0\.16b, v1\.16b > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubq_s8, int8x16_t) > + > +/* > +** test_vqsubq_u16: > +** uqsub v0\.8h, v0\.8h, v1\.8h > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubq_u16, uint16x8_t) > + > +/* > +** test_vqsubq_s16: > +** sqsub v0\.8h, v0\.8h, v1\.8h > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubq_s16, int16x8_t) > + > +/* > +** test_vqsubq_u32: > +** uqsub v0\.4s, v0\.4s, v1\.4s > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubq_u32, uint32x4_t) > + > +/* > +** test_vqsubq_s32: > +** sqsub v0\.4s, v0\.4s, v1\.4s > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubq_s32, int32x4_t) > + > +/* > +** test_vqsubq_u64: > +** uqsub v0\.2d, v0\.2d, v1\.2d > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubq_u64, uint64x2_t) > + > +/* > +** test_vqsubq_s64: > +** sqsub v0\.2d, v0\.2d, v1\.2d > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubq_s64, int64x2_t) > + > +/* > +** test_vqsubb_u8: > +** dup v([0-9]+)\.8b, w0 > +** dup v([0-9]+)\.8b, w1 > +** uqsub b([0-9]+), b\1, b\2 > +** umov w0, v\3\.b\[0\] > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubb_u8, uint8_t) > + > +/* > +** test_vqsubb_s8: > +** dup v([0-9]+)\.8b, w0 > +** dup v([0-9]+)\.8b, w1 > +** sqsub b([0-9]+), b\1, b\2 > +** umov w0, v\3\.b\[0\] > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubb_s8, int8_t) > + > +/* > +** test_vqsubh_u16: > +** dup v([0-9]+)\.4h, w0 > +** dup v([0-9]+)\.4h, w1 > +** uqsub h([0-9]+), h\1, h\2 > +** umov w0, v\3\.h\[0\] > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubh_u16, uint16_t) > + > +/* > +** test_vqsubh_s16: > +** dup v([0-9]+)\.4h, w0 > +** dup v([0-9]+)\.4h, w1 > +** sqsub h([0-9]+), h\1, h\2 > +** umov w0, v\3\.h\[0\] > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubh_s16, int16_t) > + > +/* > +** test_vqsubs_u32: > +** subs (w[0-9]+), w0, w1 > +** csel w0, \1, wzr, cs > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubs_u32, uint32_t) > + > +/* > +** test_vqsubs_s32: > +** fmov (s[0-9]+), w0 > +** fmov (s[0-9]+), w1 > +** sqsub s([0-9]+), \1, \2 > +** fmov w0, s\3 > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubs_s32, int32_t) > + > +/* > +** test_vqsubd_u64: > +** subs (x[0-9]+), x0, x1 > +** csel x0, \1, xzr, cs > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubd_u64, uint64_t) > + > +/* > +** test_vqsubd_s64: > +** fmov (d[0-9]+), x0 > +** fmov (d[0-9]+), x1 > +** sqsub d([0-9]+), \1, \2 > +** fmov x0, d\3 > +** ret > +*/ > +TEST_UNIFORM_BINARY (vqsubd_s64, int64_t) > -- > 2.43.0 >
diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.cc b/gcc/config/aarch64/aarch64-neon-builtins-base.cc index d8fae81388e..5c886d32f42 100644 --- a/gcc/config/aarch64/aarch64-neon-builtins-base.cc +++ b/gcc/config/aarch64/aarch64-neon-builtins-base.cc @@ -753,6 +753,20 @@ NEON_FUNCTION (vaddd, gimple_expr, (PLUS_EXPR)) NEON_FUNCTION (vadd, gimple_expr, (PLUS_EXPR, PLUS_EXPR, BIT_XOR_EXPR)) NEON_FUNCTION (vaddq, gimple_expr, (PLUS_EXPR, PLUS_EXPR, BIT_XOR_EXPR)) +// Saturating arithmetic +NEON_FUNCTION (vqaddb, gimple_ifn, (IFN_SAT_ADD)) +NEON_FUNCTION (vqaddh, gimple_ifn, (IFN_SAT_ADD)) +NEON_FUNCTION (vqadds, gimple_ifn, (IFN_SAT_ADD)) +NEON_FUNCTION (vqaddd, gimple_ifn, (IFN_SAT_ADD)) +NEON_FUNCTION (vqadd, gimple_ifn, (IFN_SAT_ADD)) +NEON_FUNCTION (vqaddq, gimple_ifn, (IFN_SAT_ADD)) +NEON_FUNCTION (vqsubb, gimple_ifn, (IFN_SAT_SUB)) +NEON_FUNCTION (vqsubh, gimple_ifn, (IFN_SAT_SUB)) +NEON_FUNCTION (vqsubs, gimple_ifn, (IFN_SAT_SUB)) +NEON_FUNCTION (vqsubd, gimple_ifn, (IFN_SAT_SUB)) +NEON_FUNCTION (vqsub, gimple_ifn, (IFN_SAT_SUB)) +NEON_FUNCTION (vqsubq, gimple_ifn, (IFN_SAT_SUB)) + // 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 7257f59bbc5..52e4746453b 100644 --- a/gcc/config/aarch64/aarch64-neon-builtins-base.def +++ b/gcc/config/aarch64/aarch64-neon-builtins-base.def @@ -76,6 +76,22 @@ DEF_NEON_FUNCTION (vadd, h_float, ("D0,D0,D0")) DEF_NEON_FUNCTION (vaddq, h_float, ("Q0,Q0,Q0")) #undef REQUIRED_EXTENSIONS +// Saturating arithmetic +#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD) +DEF_NEON_FUNCTION (vqaddb, b_integer, ("s0,s0,s0")) +DEF_NEON_FUNCTION (vqaddh, h_integer, ("s0,s0,s0")) +DEF_NEON_FUNCTION (vqadds, s_integer, ("s0,s0,s0")) +DEF_NEON_FUNCTION (vqaddd, d_integer, ("s0,s0,s0")) +DEF_NEON_FUNCTION (vqadd, bhs_integer, ("D0,D0,D0")) +DEF_NEON_FUNCTION (vqaddq, all_integer, ("Q0,Q0,Q0")) +DEF_NEON_FUNCTION (vqsubb, b_integer, ("s0,s0,s0")) +DEF_NEON_FUNCTION (vqsubh, h_integer, ("s0,s0,s0")) +DEF_NEON_FUNCTION (vqsubs, s_integer, ("s0,s0,s0")) +DEF_NEON_FUNCTION (vqsubd, d_integer, ("s0,s0,s0")) +DEF_NEON_FUNCTION (vqsub, bhs_integer, ("D0,D0,D0")) +DEF_NEON_FUNCTION (vqsubq, all_integer, ("Q0,Q0,Q0")) +#undef REQUIRED_EXTENSIONS + // Bitwise operations #define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD) DEF_NEON_FUNCTION (vand, all_integer, ("D0,D0,D0")) diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h index 873a1195d3e..985b4bdb6cc 100644 --- a/gcc/config/aarch64/arm_neon.h +++ b/gcc/config/aarch64/arm_neon.h @@ -1071,41 +1071,6 @@ vsubw_high_u32 (uint64x2_t __a, uint32x4_t __b) return __builtin_aarch64_usubw2v4si_uuu (__a, __b); } -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqadd_s8 (int8x8_t __a, int8x8_t __b) -{ - return (int8x8_t) __builtin_aarch64_ssaddv8qi (__a, __b); -} - -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqadd_s16 (int16x4_t __a, int16x4_t __b) -{ - return (int16x4_t) __builtin_aarch64_ssaddv4hi (__a, __b); -} - -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqadd_s32 (int32x2_t __a, int32x2_t __b) -{ - return (int32x2_t) __builtin_aarch64_ssaddv2si (__a, __b); -} - -__extension__ extern __inline int64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqadd_s64 (int64x1_t __a, int64x1_t __b) -{ - return (int64x1_t) {__builtin_aarch64_ssadddi (__a[0], __b[0])}; -} - -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqadd_u8 (uint8x8_t __a, uint8x8_t __b) -{ - return __builtin_aarch64_usaddv8qi_uuu (__a, __b); -} - __extension__ extern __inline int8x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vhsub_s8 (int8x8_t __a, int8x8_t __b) @@ -1358,18 +1323,11 @@ vsubhn_high_u64 (uint32x2_t __a, uint64x2_t __b, uint64x2_t __c) return __builtin_aarch64_subhn2v2di_uuuu (__a, __b, __c); } -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqadd_u16 (uint16x4_t __a, uint16x4_t __b) -{ - return __builtin_aarch64_usaddv4hi_uuu (__a, __b); -} - -__extension__ extern __inline uint32x2_t +__extension__ extern __inline int64x1_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqadd_u32 (uint32x2_t __a, uint32x2_t __b) +vqadd_s64 (int64x1_t __a, int64x1_t __b) { - return __builtin_aarch64_usaddv2si_uuu (__a, __b); + return (int64x1_t) {__builtin_aarch64_ssadddi (__a[0], __b[0])}; } __extension__ extern __inline uint64x1_t @@ -1379,83 +1337,6 @@ vqadd_u64 (uint64x1_t __a, uint64x1_t __b) return (uint64x1_t) {__builtin_aarch64_usadddi_uuu (__a[0], __b[0])}; } -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqaddq_s8 (int8x16_t __a, int8x16_t __b) -{ - return (int8x16_t) __builtin_aarch64_ssaddv16qi (__a, __b); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqaddq_s16 (int16x8_t __a, int16x8_t __b) -{ - return (int16x8_t) __builtin_aarch64_ssaddv8hi (__a, __b); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqaddq_s32 (int32x4_t __a, int32x4_t __b) -{ - return (int32x4_t) __builtin_aarch64_ssaddv4si (__a, __b); -} - -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqaddq_s64 (int64x2_t __a, int64x2_t __b) -{ - return (int64x2_t) __builtin_aarch64_ssaddv2di (__a, __b); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqaddq_u8 (uint8x16_t __a, uint8x16_t __b) -{ - return __builtin_aarch64_usaddv16qi_uuu (__a, __b); -} - -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqaddq_u16 (uint16x8_t __a, uint16x8_t __b) -{ - return __builtin_aarch64_usaddv8hi_uuu (__a, __b); -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqaddq_u32 (uint32x4_t __a, uint32x4_t __b) -{ - return __builtin_aarch64_usaddv4si_uuu (__a, __b); -} - -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqaddq_u64 (uint64x2_t __a, uint64x2_t __b) -{ - return __builtin_aarch64_usaddv2di_uuu (__a, __b); -} - -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsub_s8 (int8x8_t __a, int8x8_t __b) -{ - return (int8x8_t) __builtin_aarch64_sssubv8qi (__a, __b); -} - -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsub_s16 (int16x4_t __a, int16x4_t __b) -{ - return (int16x4_t) __builtin_aarch64_sssubv4hi (__a, __b); -} - -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsub_s32 (int32x2_t __a, int32x2_t __b) -{ - return (int32x2_t) __builtin_aarch64_sssubv2si (__a, __b); -} - __extension__ extern __inline int64x1_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vqsub_s64 (int64x1_t __a, int64x1_t __b) @@ -1463,27 +1344,6 @@ vqsub_s64 (int64x1_t __a, int64x1_t __b) return (int64x1_t) {__builtin_aarch64_sssubdi (__a[0], __b[0])}; } -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsub_u8 (uint8x8_t __a, uint8x8_t __b) -{ - return __builtin_aarch64_ussubv8qi_uuu (__a, __b); -} - -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsub_u16 (uint16x4_t __a, uint16x4_t __b) -{ - return __builtin_aarch64_ussubv4hi_uuu (__a, __b); -} - -__extension__ extern __inline uint32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsub_u32 (uint32x2_t __a, uint32x2_t __b) -{ - return __builtin_aarch64_ussubv2si_uuu (__a, __b); -} - __extension__ extern __inline uint64x1_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vqsub_u64 (uint64x1_t __a, uint64x1_t __b) @@ -1491,62 +1351,6 @@ vqsub_u64 (uint64x1_t __a, uint64x1_t __b) return (uint64x1_t) {__builtin_aarch64_ussubdi_uuu (__a[0], __b[0])}; } -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubq_s8 (int8x16_t __a, int8x16_t __b) -{ - return (int8x16_t) __builtin_aarch64_sssubv16qi (__a, __b); -} - -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubq_s16 (int16x8_t __a, int16x8_t __b) -{ - return (int16x8_t) __builtin_aarch64_sssubv8hi (__a, __b); -} - -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubq_s32 (int32x4_t __a, int32x4_t __b) -{ - return (int32x4_t) __builtin_aarch64_sssubv4si (__a, __b); -} - -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubq_s64 (int64x2_t __a, int64x2_t __b) -{ - return (int64x2_t) __builtin_aarch64_sssubv2di (__a, __b); -} - -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubq_u8 (uint8x16_t __a, uint8x16_t __b) -{ - return __builtin_aarch64_ussubv16qi_uuu (__a, __b); -} - -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubq_u16 (uint16x8_t __a, uint16x8_t __b) -{ - return __builtin_aarch64_ussubv8hi_uuu (__a, __b); -} - -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubq_u32 (uint32x4_t __a, uint32x4_t __b) -{ - return __builtin_aarch64_ussubv4si_uuu (__a, __b); -} - -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubq_u64 (uint64x2_t __a, uint64x2_t __b) -{ - return __builtin_aarch64_ussubv2di_uuu (__a, __b); -} - __extension__ extern __inline int8x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vqneg_s8 (int8x8_t __a) @@ -13921,64 +13725,6 @@ vqabsd_s64 (int64_t __a) return __builtin_aarch64_sqabsdi (__a); } -/* vqadd */ - -__extension__ extern __inline int8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqaddb_s8 (int8_t __a, int8_t __b) -{ - return (int8_t) __builtin_aarch64_ssaddqi (__a, __b); -} - -__extension__ extern __inline int16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqaddh_s16 (int16_t __a, int16_t __b) -{ - return (int16_t) __builtin_aarch64_ssaddhi (__a, __b); -} - -__extension__ extern __inline int32_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqadds_s32 (int32_t __a, int32_t __b) -{ - return (int32_t) __builtin_aarch64_ssaddsi (__a, __b); -} - -__extension__ extern __inline int64_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqaddd_s64 (int64_t __a, int64_t __b) -{ - return __builtin_aarch64_ssadddi (__a, __b); -} - -__extension__ extern __inline uint8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqaddb_u8 (uint8_t __a, uint8_t __b) -{ - return (uint8_t) __builtin_aarch64_usaddqi_uuu (__a, __b); -} - -__extension__ extern __inline uint16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqaddh_u16 (uint16_t __a, uint16_t __b) -{ - return (uint16_t) __builtin_aarch64_usaddhi_uuu (__a, __b); -} - -__extension__ extern __inline uint32_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqadds_u32 (uint32_t __a, uint32_t __b) -{ - return (uint32_t) __builtin_aarch64_usaddsi_uuu (__a, __b); -} - -__extension__ extern __inline uint64_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqaddd_u64 (uint64_t __a, uint64_t __b) -{ - return __builtin_aarch64_usadddi_uuu (__a, __b); -} - /* vqdmlal */ __extension__ extern __inline int32x4_t @@ -15620,64 +15366,6 @@ vqshrund_n_s64 (int64_t __a, const int __b) return (int32_t) __builtin_aarch64_sqshrun_ndi (__a, __b); } -/* vqsub */ - -__extension__ extern __inline int8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubb_s8 (int8_t __a, int8_t __b) -{ - return (int8_t) __builtin_aarch64_sssubqi (__a, __b); -} - -__extension__ extern __inline int16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubh_s16 (int16_t __a, int16_t __b) -{ - return (int16_t) __builtin_aarch64_sssubhi (__a, __b); -} - -__extension__ extern __inline int32_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubs_s32 (int32_t __a, int32_t __b) -{ - return (int32_t) __builtin_aarch64_sssubsi (__a, __b); -} - -__extension__ extern __inline int64_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubd_s64 (int64_t __a, int64_t __b) -{ - return __builtin_aarch64_sssubdi (__a, __b); -} - -__extension__ extern __inline uint8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubb_u8 (uint8_t __a, uint8_t __b) -{ - return (uint8_t) __builtin_aarch64_ussubqi_uuu (__a, __b); -} - -__extension__ extern __inline uint16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubh_u16 (uint16_t __a, uint16_t __b) -{ - return (uint16_t) __builtin_aarch64_ussubhi_uuu (__a, __b); -} - -__extension__ extern __inline uint32_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubs_u32 (uint32_t __a, uint32_t __b) -{ - return (uint32_t) __builtin_aarch64_ussubsi_uuu (__a, __b); -} - -__extension__ extern __inline uint64_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vqsubd_u64 (uint64_t __a, uint64_t __b) -{ - return __builtin_aarch64_ussubdi_uuu (__a, __b); -} - /* vqtbl2 */ __extension__ extern __inline int8x8_t diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vqadd.c b/gcc/testsuite/gcc.target/aarch64/neon/vqadd.c new file mode 100644 index 00000000000..322f54c5a42 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/neon/vqadd.c @@ -0,0 +1,192 @@ +/* { dg-do compile } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include "arm_neon_test.h" + +/* +** test_vqadd_u8: +** uqadd v0\.8b, (v0\.8b, v1\.8b|v1\.8b, v0\.8b) +** ret +*/ +TEST_UNIFORM_BINARY (vqadd_u8, uint8x8_t) + +/* +** test_vqadd_s8: +** sqadd v0\.8b, (v0\.8b, v1\.8b|v1\.8b, v0\.8b) +** ret +*/ +TEST_UNIFORM_BINARY (vqadd_s8, int8x8_t) + +/* +** test_vqadd_u16: +** uqadd v0\.4h, (v0\.4h, v1\.4h|v1\.4h, v0\.4h) +** ret +*/ +TEST_UNIFORM_BINARY (vqadd_u16, uint16x4_t) + +/* +** test_vqadd_s16: +** sqadd v0\.4h, (v0\.4h, v1\.4h|v1\.4h, v0\.4h) +** ret +*/ +TEST_UNIFORM_BINARY (vqadd_s16, int16x4_t) + +/* +** test_vqadd_u32: +** uqadd v0\.2s, (v0\.2s, v1\.2s|v1\.2s, v0\.2s) +** ret +*/ +TEST_UNIFORM_BINARY (vqadd_u32, uint32x2_t) + +/* +** test_vqadd_s32: +** sqadd v0\.2s, (v0\.2s, v1\.2s|v1\.2s, v0\.2s) +** ret +*/ +TEST_UNIFORM_BINARY (vqadd_s32, int32x2_t) + +/* +** test_vqadd_u64: +** uqadd d0, (d0, d1|d1, d0) +** ret +*/ +TEST_UNIFORM_BINARY (vqadd_u64, uint64x1_t) + +/* +** test_vqadd_s64: +** sqadd d0, (d0, d1|d1, d0) +** ret +*/ +TEST_UNIFORM_BINARY (vqadd_s64, int64x1_t) + +/* +** test_vqaddq_u8: +** uqadd v0\.16b, (v0\.16b, v1\.16b|v1\.16b, v0\.16b) +** ret +*/ +TEST_UNIFORM_BINARY (vqaddq_u8, uint8x16_t) + +/* +** test_vqaddq_s8: +** sqadd v0\.16b, (v0\.16b, v1\.16b|v1\.16b, v0\.16b) +** ret +*/ +TEST_UNIFORM_BINARY (vqaddq_s8, int8x16_t) + +/* +** test_vqaddq_u16: +** uqadd v0\.8h, (v0\.8h, v1\.8h|v1\.8h, v0\.8h) +** ret +*/ +TEST_UNIFORM_BINARY (vqaddq_u16, uint16x8_t) + +/* +** test_vqaddq_s16: +** sqadd v0\.8h, (v0\.8h, v1\.8h|v1\.8h, v0\.8h) +** ret +*/ +TEST_UNIFORM_BINARY (vqaddq_s16, int16x8_t) + +/* +** test_vqaddq_u32: +** uqadd v0\.4s, (v0\.4s, v1\.4s|v1\.4s, v0\.4s) +** ret +*/ +TEST_UNIFORM_BINARY (vqaddq_u32, uint32x4_t) + +/* +** test_vqaddq_s32: +** sqadd v0\.4s, (v0\.4s, v1\.4s|v1\.4s, v0\.4s) +** ret +*/ +TEST_UNIFORM_BINARY (vqaddq_s32, int32x4_t) + +/* +** test_vqaddq_u64: +** uqadd v0\.2d, (v0\.2d, v1\.2d|v1\.2d, v0\.2d) +** ret +*/ +TEST_UNIFORM_BINARY (vqaddq_u64, uint64x2_t) + +/* +** test_vqaddq_s64: +** sqadd v0\.2d, (v0\.2d, v1\.2d|v1\.2d, v0\.2d) +** ret +*/ +TEST_UNIFORM_BINARY (vqaddq_s64, int64x2_t) + +/* +** test_vqaddb_u8: +** dup v([0-9]+)\.8b, w[0-9]+ +** dup v([0-9]+)\.8b, w[0-9]+ +** uqadd b([0-9]+), (b\2, b\1|b\1, b\2) +** umov w0, v\3\.b\[0\] +** ret +*/ +TEST_UNIFORM_BINARY (vqaddb_u8, uint8_t) + +/* +** test_vqaddb_s8: +** dup v([0-9]+)\.8b, w[0-9]+ +** dup v([0-9]+)\.8b, w[0-9]+ +** sqadd b([0-9]+), (b\2, b\1|b\1, b\2) +** umov w0, v\3\.b\[0\] +** ret +*/ +TEST_UNIFORM_BINARY (vqaddb_s8, int8_t) + +/* +** test_vqaddh_u16: +** dup v([0-9]+)\.4h, w[0-9]+ +** dup v([0-9]+)\.4h, w[0-9]+ +** uqadd h([0-9]+), (h\2, h\1|h\1, h\2) +** umov w0, v\3\.h\[0\] +** ret +*/ +TEST_UNIFORM_BINARY (vqaddh_u16, uint16_t) + +/* +** test_vqaddh_s16: +** dup v([0-9]+)\.4h, w[0-9]+ +** dup v([0-9]+)\.4h, w[0-9]+ +** sqadd h([0-9]+), (h\2, h\1|h\1, h\2) +** umov w0, v\3\.h\[0\] +** ret +*/ +TEST_UNIFORM_BINARY (vqaddh_s16, int16_t) + +/* +** test_vqadds_u32: +** adds (w[0-9]+), (w0, w1|w1, w0) +** csinv w0, \1, wzr, cc +** ret +*/ +TEST_UNIFORM_BINARY (vqadds_u32, uint32_t) + +/* +** test_vqadds_s32: +** fmov (s[0-9]+), w[0-9]+ +** fmov (s[0-9]+), w[0-9]+ +** sqadd s([0-9]+), (\2, \1|\1, \2) +** fmov w0, s\3 +** ret +*/ +TEST_UNIFORM_BINARY (vqadds_s32, int32_t) + +/* +** test_vqaddd_u64: +** adds (x[0-9]+), (x0, x1|x1, x0) +** csinv x0, \1, xzr, cc +** ret +*/ +TEST_UNIFORM_BINARY (vqaddd_u64, uint64_t) + +/* +** test_vqaddd_s64: +** fmov (d[0-9]+), x[0-9]+ +** fmov (d[0-9]+), x[0-9]+ +** sqadd d([0-9]+), (\2, \1|\1, \2) +** fmov x0, d\3 +** ret +*/ +TEST_UNIFORM_BINARY (vqaddd_s64, int64_t) diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vqsub.c b/gcc/testsuite/gcc.target/aarch64/neon/vqsub.c new file mode 100644 index 00000000000..52ac2f102eb --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/neon/vqsub.c @@ -0,0 +1,192 @@ +/* { dg-do compile } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include "arm_neon_test.h" + +/* +** test_vqsub_u8: +** uqsub v0\.8b, v0\.8b, v1\.8b +** ret +*/ +TEST_UNIFORM_BINARY (vqsub_u8, uint8x8_t) + +/* +** test_vqsub_s8: +** sqsub v0\.8b, v0\.8b, v1\.8b +** ret +*/ +TEST_UNIFORM_BINARY (vqsub_s8, int8x8_t) + +/* +** test_vqsub_u16: +** uqsub v0\.4h, v0\.4h, v1\.4h +** ret +*/ +TEST_UNIFORM_BINARY (vqsub_u16, uint16x4_t) + +/* +** test_vqsub_s16: +** sqsub v0\.4h, v0\.4h, v1\.4h +** ret +*/ +TEST_UNIFORM_BINARY (vqsub_s16, int16x4_t) + +/* +** test_vqsub_u32: +** uqsub v0\.2s, v0\.2s, v1\.2s +** ret +*/ +TEST_UNIFORM_BINARY (vqsub_u32, uint32x2_t) + +/* +** test_vqsub_s32: +** sqsub v0\.2s, v0\.2s, v1\.2s +** ret +*/ +TEST_UNIFORM_BINARY (vqsub_s32, int32x2_t) + +/* +** test_vqsub_u64: +** uqsub d0, d0, d1 +** ret +*/ +TEST_UNIFORM_BINARY (vqsub_u64, uint64x1_t) + +/* +** test_vqsub_s64: +** sqsub d0, d0, d1 +** ret +*/ +TEST_UNIFORM_BINARY (vqsub_s64, int64x1_t) + +/* +** test_vqsubq_u8: +** uqsub v0\.16b, v0\.16b, v1\.16b +** ret +*/ +TEST_UNIFORM_BINARY (vqsubq_u8, uint8x16_t) + +/* +** test_vqsubq_s8: +** sqsub v0\.16b, v0\.16b, v1\.16b +** ret +*/ +TEST_UNIFORM_BINARY (vqsubq_s8, int8x16_t) + +/* +** test_vqsubq_u16: +** uqsub v0\.8h, v0\.8h, v1\.8h +** ret +*/ +TEST_UNIFORM_BINARY (vqsubq_u16, uint16x8_t) + +/* +** test_vqsubq_s16: +** sqsub v0\.8h, v0\.8h, v1\.8h +** ret +*/ +TEST_UNIFORM_BINARY (vqsubq_s16, int16x8_t) + +/* +** test_vqsubq_u32: +** uqsub v0\.4s, v0\.4s, v1\.4s +** ret +*/ +TEST_UNIFORM_BINARY (vqsubq_u32, uint32x4_t) + +/* +** test_vqsubq_s32: +** sqsub v0\.4s, v0\.4s, v1\.4s +** ret +*/ +TEST_UNIFORM_BINARY (vqsubq_s32, int32x4_t) + +/* +** test_vqsubq_u64: +** uqsub v0\.2d, v0\.2d, v1\.2d +** ret +*/ +TEST_UNIFORM_BINARY (vqsubq_u64, uint64x2_t) + +/* +** test_vqsubq_s64: +** sqsub v0\.2d, v0\.2d, v1\.2d +** ret +*/ +TEST_UNIFORM_BINARY (vqsubq_s64, int64x2_t) + +/* +** test_vqsubb_u8: +** dup v([0-9]+)\.8b, w0 +** dup v([0-9]+)\.8b, w1 +** uqsub b([0-9]+), b\1, b\2 +** umov w0, v\3\.b\[0\] +** ret +*/ +TEST_UNIFORM_BINARY (vqsubb_u8, uint8_t) + +/* +** test_vqsubb_s8: +** dup v([0-9]+)\.8b, w0 +** dup v([0-9]+)\.8b, w1 +** sqsub b([0-9]+), b\1, b\2 +** umov w0, v\3\.b\[0\] +** ret +*/ +TEST_UNIFORM_BINARY (vqsubb_s8, int8_t) + +/* +** test_vqsubh_u16: +** dup v([0-9]+)\.4h, w0 +** dup v([0-9]+)\.4h, w1 +** uqsub h([0-9]+), h\1, h\2 +** umov w0, v\3\.h\[0\] +** ret +*/ +TEST_UNIFORM_BINARY (vqsubh_u16, uint16_t) + +/* +** test_vqsubh_s16: +** dup v([0-9]+)\.4h, w0 +** dup v([0-9]+)\.4h, w1 +** sqsub h([0-9]+), h\1, h\2 +** umov w0, v\3\.h\[0\] +** ret +*/ +TEST_UNIFORM_BINARY (vqsubh_s16, int16_t) + +/* +** test_vqsubs_u32: +** subs (w[0-9]+), w0, w1 +** csel w0, \1, wzr, cs +** ret +*/ +TEST_UNIFORM_BINARY (vqsubs_u32, uint32_t) + +/* +** test_vqsubs_s32: +** fmov (s[0-9]+), w0 +** fmov (s[0-9]+), w1 +** sqsub s([0-9]+), \1, \2 +** fmov w0, s\3 +** ret +*/ +TEST_UNIFORM_BINARY (vqsubs_s32, int32_t) + +/* +** test_vqsubd_u64: +** subs (x[0-9]+), x0, x1 +** csel x0, \1, xzr, cs +** ret +*/ +TEST_UNIFORM_BINARY (vqsubd_u64, uint64_t) + +/* +** test_vqsubd_s64: +** fmov (d[0-9]+), x0 +** fmov (d[0-9]+), x1 +** sqsub d([0-9]+), \1, \2 +** fmov x0, d\3 +** ret +*/ +TEST_UNIFORM_BINARY (vqsubd_s64, int64_t)