[2/6] aarch64: Port NEON reduction intrinsics to pragma-based framework

Message ID 20260902083828.45767-3-dhruvc@nvidia.com
State New
Delegated to: Kyrill Tkachov
Headers
Series aarch64: Port NEON intrinsics to pragma-based framework using IFNs |

Commit Message

Dhruv Chawla Sept. 2, 2026, 8:38 a.m. UTC
  From: Dhruv Chawla <dhruvc@nvidia.com>

Port the following intrinsics to the pragma-based framework:
* vaddv
* vmaxv
* vminv
* vmaxnmv
* vminnmv

The following are not ported in this patch as they cannot be directly
lowered from an IFN through an existing instruction pattern:
* vmaxv_f16
* vmaxv_f32
* vmaxvq_f16
* vmaxvq_f32
* vmaxvq_f64
* vminv_f16
* vminv_f32
* vminvq_f16
* vminvq_f32
* vminvq_f64

This is due to the NaN semantics of these intrinsics which require
mapping to <optab>_nan variants.

Bootstrapped and regtested on aarch64-linux-gnu.

Signed-off-by: Dhruv Chawla <dhruvc@nvidia.com>

gcc/ChangeLog:

	* config/aarch64/aarch64-acle-builtins.h (TYPES_s_float_bhs_integer,
	TYPES_sd_float_all_integer, s_float_bhs_integer,
	sd_float_all_integer): New type lists.
	* config/aarch64/aarch64-neon-builtins-base.cc (vaddv, vaddvq, vmaxv,
	vmaxvq, vminv, vminvq, vmaxnmv, vmaxnmvq, vminnmv, vminnmvq):
	New function bases.
	* config/aarch64/aarch64-neon-builtins-base.def (vaddv, vaddvq, vmaxv,
	vmaxvq, vminv, vminvq, vmaxnmv, vmaxnmvq, vminnmv, vminnmvq):
	New function groups.
	* config/aarch64/arm_neon.h (vaddv_s8, vaddv_s16, vaddv_s32, vaddv_u8,
	vaddv_u16, vaddv_u32, vaddvq_s8, vaddvq_s16, vaddvq_s32, vaddvq_s64,
	vaddvq_u8, vaddvq_u16, vaddvq_u32, vaddvq_u64, vaddv_f32, vaddvq_f32,
	vaddvq_f64, vmaxv_s8, vmaxv_s16, vmaxv_s32, vmaxv_u8, vmaxv_u16,
	vmaxv_u32, vmaxvq_s8, vmaxvq_s16, vmaxvq_s32, vmaxvq_u8, vmaxvq_u16,
	vmaxvq_u32, vmaxnmv_f32, vmaxnmvq_f32, vmaxnmvq_f64, vminv_s8,
	vminv_s16, vminv_s32, vminv_u8, vminv_u16, vminv_u32, vminvq_s8,
	vminvq_s16, vminvq_s32, vminvq_u8, vminvq_u16, vminvq_u32, vminnmv_f32,
	vminnmvq_f32, vminnmvq_f64, vmaxnmv_f16, vmaxnmvq_f16, vminnmv_f16,
	vminnmvq_f16): Delete functions.

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/neon/vaddv.c: New test.
	* gcc.target/aarch64/neon/vmaxnmv.c: New test.
	* gcc.target/aarch64/neon/vmaxv.c: New test.
	* gcc.target/aarch64/neon/vminnmv.c: New test.
	* gcc.target/aarch64/neon/vminv.c: New test.
---
 gcc/config/aarch64/aarch64-acle-builtins.h    |  14 +
 .../aarch64/aarch64-neon-builtins-base.cc     |  12 +
 .../aarch64/aarch64-neon-builtins-base.def    |  22 ++
 gcc/config/aarch64/arm_neon.h                 | 363 ------------------
 gcc/testsuite/gcc.target/aarch64/neon/vaddv.c | 138 +++++++
 .../gcc.target/aarch64/neon/vmaxnmv.c         |  39 ++
 gcc/testsuite/gcc.target/aarch64/neon/vmaxv.c | 135 +++++++
 .../gcc.target/aarch64/neon/vminnmv.c         |  39 ++
 gcc/testsuite/gcc.target/aarch64/neon/vminv.c | 135 +++++++
 9 files changed, 534 insertions(+), 363 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vaddv.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vmaxnmv.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vmaxv.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vminnmv.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vminv.c
  

Patch

diff --git a/gcc/config/aarch64/aarch64-acle-builtins.h b/gcc/config/aarch64/aarch64-acle-builtins.h
index 481a294c938..afbcafa7822 100644
--- a/gcc/config/aarch64/aarch64-acle-builtins.h
+++ b/gcc/config/aarch64/aarch64-acle-builtins.h
@@ -1393,6 +1393,18 @@  function_expander::result_mode () const
 #define TYPES_s_float_sd_integer(S, D, T) \
   TYPES_s_float (S, D, T), TYPES_sd_integer (S, D, T)
 
+/* _f32
+   _s8 _s16 _s32
+   _u8 _u16 _u32.  */
+#define TYPES_s_float_bhs_integer(S, D, T) \
+  TYPES_s_float (S, D, T), TYPES_bhs_integer (S, D, T)
+
+/* _f32 _f64
+   _s8 _s16 _s32 _s64
+   _u8 _u16 _u32 _u64.  */
+#define TYPES_sd_float_all_integer(S, D, T) \
+  TYPES_sd_float (S, D, T), TYPES_all_integer (S, D, T)
+
 /* _s32.  */
 #define TYPES_s_signed(S, D, T) \
   S (s32)
@@ -2084,6 +2096,8 @@  DEF_SVE_TYPES_ARRAY (hsd_integer);
 DEF_SVE_TYPES_ARRAY (hsd_data);
 DEF_SVE_TYPES_ARRAY (s_float);
 DEF_SVE_TYPES_ARRAY (s_float_hsd_integer);
+DEF_SVE_TYPES_ARRAY (s_float_bhs_integer);
+DEF_SVE_TYPES_ARRAY (sd_float_all_integer);
 DEF_SVE_TYPES_ARRAY (s_float_mf8);
 DEF_SVE_TYPES_ARRAY (s_float_sd_integer);
 DEF_SVE_TYPES_ARRAY (s_signed);
diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.cc b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
index 5c886d32f42..ca122d65a51 100644
--- a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
@@ -767,6 +767,18 @@  NEON_FUNCTION (vqsubd, gimple_ifn, (IFN_SAT_SUB))
 NEON_FUNCTION (vqsub,  gimple_ifn, (IFN_SAT_SUB))
 NEON_FUNCTION (vqsubq, gimple_ifn, (IFN_SAT_SUB))
 
+// Reductions
+NEON_FUNCTION (vaddv,    gimple_ifn, (IFN_REDUC_PLUS))
+NEON_FUNCTION (vaddvq,   gimple_ifn, (IFN_REDUC_PLUS))
+NEON_FUNCTION (vmaxv,    gimple_ifn, (IFN_REDUC_MAX))
+NEON_FUNCTION (vmaxvq,   gimple_ifn, (IFN_REDUC_MAX))
+NEON_FUNCTION (vminv,    gimple_ifn, (IFN_REDUC_MIN))
+NEON_FUNCTION (vminvq,   gimple_ifn, (IFN_REDUC_MIN))
+NEON_FUNCTION (vmaxnmv,  gimple_ifn, (IFN_REDUC_FMAX))
+NEON_FUNCTION (vmaxnmvq, gimple_ifn, (IFN_REDUC_FMAX))
+NEON_FUNCTION (vminnmv,  gimple_ifn, (IFN_REDUC_FMIN))
+NEON_FUNCTION (vminnmvq, gimple_ifn, (IFN_REDUC_FMIN))
+
 // 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 52e4746453b..b3c0fc42298 100644
--- a/gcc/config/aarch64/aarch64-neon-builtins-base.def
+++ b/gcc/config/aarch64/aarch64-neon-builtins-base.def
@@ -92,6 +92,28 @@  DEF_NEON_FUNCTION (vqsub,  bhs_integer, ("D0,D0,D0"))
 DEF_NEON_FUNCTION (vqsubq, all_integer, ("Q0,Q0,Q0"))
 #undef REQUIRED_EXTENSIONS
 
+// Reductions
+#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD)
+DEF_NEON_FUNCTION (vaddv,    s_float_bhs_integer,  ("s0,D0"))
+DEF_NEON_FUNCTION (vaddvq,   sd_float_all_integer, ("s0,Q0"))
+DEF_NEON_FUNCTION (vmaxv,    bhs_integer,          ("s0,D0"))
+DEF_NEON_FUNCTION (vmaxvq,   bhs_integer,          ("s0,Q0"))
+DEF_NEON_FUNCTION (vminv,    bhs_integer,          ("s0,D0"))
+DEF_NEON_FUNCTION (vminvq,   bhs_integer,          ("s0,Q0"))
+DEF_NEON_FUNCTION (vmaxnmv,  s_float,              ("s0,D0"))
+DEF_NEON_FUNCTION (vmaxnmvq, sd_float,             ("s0,Q0"))
+DEF_NEON_FUNCTION (vminnmv,  s_float,              ("s0,D0"))
+DEF_NEON_FUNCTION (vminnmvq, sd_float,             ("s0,Q0"))
+#undef REQUIRED_EXTENSIONS
+
+// Reductions (FP16)
+#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD | AARCH64_FL_F16)
+DEF_NEON_FUNCTION (vmaxnmv,  h_float, ("s0,D0"))
+DEF_NEON_FUNCTION (vmaxnmvq, h_float, ("s0,Q0"))
+DEF_NEON_FUNCTION (vminnmv,  h_float, ("s0,D0"))
+DEF_NEON_FUNCTION (vminnmvq, h_float, ("s0,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 985b4bdb6cc..1fccc7e3237 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -5083,127 +5083,6 @@  vabsd_s64 (int64_t __a)
   return __a < 0 ? - (uint64_t) __a : __a;
 }
 
-/* vaddv */
-
-__extension__ extern __inline int8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddv_s8 (int8x8_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v8qi (__a);
-}
-
-__extension__ extern __inline int16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddv_s16 (int16x4_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v4hi (__a);
-}
-
-__extension__ extern __inline int32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddv_s32 (int32x2_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v2si (__a);
-}
-
-__extension__ extern __inline uint8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddv_u8 (uint8x8_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v8qi_uu (__a);
-}
-
-__extension__ extern __inline uint16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddv_u16 (uint16x4_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v4hi_uu (__a);
-}
-
-__extension__ extern __inline uint32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddv_u32 (uint32x2_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v2si_uu (__a);
-}
-
-__extension__ extern __inline int8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddvq_s8 (int8x16_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v16qi (__a);
-}
-
-__extension__ extern __inline int16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddvq_s16 (int16x8_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v8hi (__a);
-}
-
-__extension__ extern __inline int32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddvq_s32 (int32x4_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v4si (__a);
-}
-
-__extension__ extern __inline int64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddvq_s64 (int64x2_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v2di (__a);
-}
-
-__extension__ extern __inline uint8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddvq_u8 (uint8x16_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v16qi_uu (__a);
-}
-
-__extension__ extern __inline uint16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddvq_u16 (uint16x8_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v8hi_uu (__a);
-}
-
-__extension__ extern __inline uint32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddvq_u32 (uint32x4_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v4si_uu (__a);
-}
-
-__extension__ extern __inline uint64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddvq_u64 (uint64x2_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v2di_uu (__a);
-}
-
-__extension__ extern __inline float32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddv_f32 (float32x2_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v2sf (__a);
-}
-
-__extension__ extern __inline float32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddvq_f32 (float32x4_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v4sf (__a);
-}
-
-__extension__ extern __inline float64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vaddvq_f64 (float64x2_t __a)
-{
-  return __builtin_aarch64_reduc_plus_scal_v2df (__a);
-}
-
 /* ARMv8.1-A intrinsics.  */
 #pragma GCC push_options
 #pragma GCC target ("+nothing+rdma")
@@ -12393,48 +12272,6 @@  vmaxv_f32 (float32x2_t __a)
   return __builtin_aarch64_reduc_smax_nan_scal_v2sf (__a);
 }
 
-__extension__ extern __inline int8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxv_s8 (int8x8_t __a)
-{
-  return __builtin_aarch64_reduc_smax_scal_v8qi (__a);
-}
-
-__extension__ extern __inline int16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxv_s16 (int16x4_t __a)
-{
-  return __builtin_aarch64_reduc_smax_scal_v4hi (__a);
-}
-
-__extension__ extern __inline int32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxv_s32 (int32x2_t __a)
-{
-  return __builtin_aarch64_reduc_smax_scal_v2si (__a);
-}
-
-__extension__ extern __inline uint8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxv_u8 (uint8x8_t __a)
-{
-  return __builtin_aarch64_reduc_umax_scal_v8qi_uu (__a);
-}
-
-__extension__ extern __inline uint16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxv_u16 (uint16x4_t __a)
-{
-  return __builtin_aarch64_reduc_umax_scal_v4hi_uu (__a);
-}
-
-__extension__ extern __inline uint32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxv_u32 (uint32x2_t __a)
-{
-  return __builtin_aarch64_reduc_umax_scal_v2si_uu (__a);
-}
-
 __extension__ extern __inline float32_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vmaxvq_f32 (float32x4_t __a)
@@ -12449,71 +12286,6 @@  vmaxvq_f64 (float64x2_t __a)
   return __builtin_aarch64_reduc_smax_nan_scal_v2df (__a);
 }
 
-__extension__ extern __inline int8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxvq_s8 (int8x16_t __a)
-{
-  return __builtin_aarch64_reduc_smax_scal_v16qi (__a);
-}
-
-__extension__ extern __inline int16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxvq_s16 (int16x8_t __a)
-{
-  return __builtin_aarch64_reduc_smax_scal_v8hi (__a);
-}
-
-__extension__ extern __inline int32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxvq_s32 (int32x4_t __a)
-{
-  return __builtin_aarch64_reduc_smax_scal_v4si (__a);
-}
-
-__extension__ extern __inline uint8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxvq_u8 (uint8x16_t __a)
-{
-  return __builtin_aarch64_reduc_umax_scal_v16qi_uu (__a);
-}
-
-__extension__ extern __inline uint16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxvq_u16 (uint16x8_t __a)
-{
-  return __builtin_aarch64_reduc_umax_scal_v8hi_uu (__a);
-}
-
-__extension__ extern __inline uint32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxvq_u32 (uint32x4_t __a)
-{
-  return __builtin_aarch64_reduc_umax_scal_v4si_uu (__a);
-}
-
-/* vmaxnmv  */
-
-__extension__ extern __inline float32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxnmv_f32 (float32x2_t __a)
-{
-  return __builtin_aarch64_reduc_smax_scal_v2sf (__a);
-}
-
-__extension__ extern __inline float32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxnmvq_f32 (float32x4_t __a)
-{
-  return __builtin_aarch64_reduc_smax_scal_v4sf (__a);
-}
-
-__extension__ extern __inline float64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxnmvq_f64 (float64x2_t __a)
-{
-  return __builtin_aarch64_reduc_smax_scal_v2df (__a);
-}
-
 /* vmin  */
 
 __extension__ extern __inline float32x2_t
@@ -12677,48 +12449,6 @@  vminv_f32 (float32x2_t __a)
   return __builtin_aarch64_reduc_smin_nan_scal_v2sf (__a);
 }
 
-__extension__ extern __inline int8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminv_s8 (int8x8_t __a)
-{
-  return __builtin_aarch64_reduc_smin_scal_v8qi (__a);
-}
-
-__extension__ extern __inline int16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminv_s16 (int16x4_t __a)
-{
-  return __builtin_aarch64_reduc_smin_scal_v4hi (__a);
-}
-
-__extension__ extern __inline int32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminv_s32 (int32x2_t __a)
-{
-  return __builtin_aarch64_reduc_smin_scal_v2si (__a);
-}
-
-__extension__ extern __inline uint8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminv_u8 (uint8x8_t __a)
-{
-  return __builtin_aarch64_reduc_umin_scal_v8qi_uu (__a);
-}
-
-__extension__ extern __inline uint16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminv_u16 (uint16x4_t __a)
-{
-  return __builtin_aarch64_reduc_umin_scal_v4hi_uu (__a);
-}
-
-__extension__ extern __inline uint32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminv_u32 (uint32x2_t __a)
-{
-  return __builtin_aarch64_reduc_umin_scal_v2si_uu (__a);
-}
-
 __extension__ extern __inline float32_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
 vminvq_f32 (float32x4_t __a)
@@ -12733,71 +12463,6 @@  vminvq_f64 (float64x2_t __a)
   return __builtin_aarch64_reduc_smin_nan_scal_v2df (__a);
 }
 
-__extension__ extern __inline int8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminvq_s8 (int8x16_t __a)
-{
-  return __builtin_aarch64_reduc_smin_scal_v16qi (__a);
-}
-
-__extension__ extern __inline int16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminvq_s16 (int16x8_t __a)
-{
-  return __builtin_aarch64_reduc_smin_scal_v8hi (__a);
-}
-
-__extension__ extern __inline int32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminvq_s32 (int32x4_t __a)
-{
-  return __builtin_aarch64_reduc_smin_scal_v4si (__a);
-}
-
-__extension__ extern __inline uint8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminvq_u8 (uint8x16_t __a)
-{
-  return __builtin_aarch64_reduc_umin_scal_v16qi_uu (__a);
-}
-
-__extension__ extern __inline uint16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminvq_u16 (uint16x8_t __a)
-{
-  return __builtin_aarch64_reduc_umin_scal_v8hi_uu (__a);
-}
-
-__extension__ extern __inline uint32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminvq_u32 (uint32x4_t __a)
-{
-  return __builtin_aarch64_reduc_umin_scal_v4si_uu (__a);
-}
-
-/* vminnmv  */
-
-__extension__ extern __inline float32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminnmv_f32 (float32x2_t __a)
-{
-  return __builtin_aarch64_reduc_smin_scal_v2sf (__a);
-}
-
-__extension__ extern __inline float32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminnmvq_f32 (float32x4_t __a)
-{
-  return __builtin_aarch64_reduc_smin_scal_v4sf (__a);
-}
-
-__extension__ extern __inline float64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminnmvq_f64 (float64x2_t __a)
-{
-  return __builtin_aarch64_reduc_smin_scal_v2df (__a);
-}
-
 /* vmla */
 
 __extension__ extern __inline float32x2_t
@@ -20541,34 +20206,6 @@  vminvq_f16 (float16x8_t __a)
   return __builtin_aarch64_reduc_smin_nan_scal_v8hf (__a);
 }
 
-__extension__ extern __inline float16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxnmv_f16 (float16x4_t __a)
-{
-  return __builtin_aarch64_reduc_smax_scal_v4hf (__a);
-}
-
-__extension__ extern __inline float16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxnmvq_f16 (float16x8_t __a)
-{
-  return __builtin_aarch64_reduc_smax_scal_v8hf (__a);
-}
-
-__extension__ extern __inline float16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminnmv_f16 (float16x4_t __a)
-{
-  return __builtin_aarch64_reduc_smin_scal_v4hf (__a);
-}
-
-__extension__ extern __inline float16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminnmvq_f16 (float16x8_t __a)
-{
-  return __builtin_aarch64_reduc_smin_scal_v8hf (__a);
-}
-
 #pragma GCC pop_options
 
 /* AdvSIMD Dot Product intrinsics.  */
diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vaddv.c b/gcc/testsuite/gcc.target/aarch64/neon/vaddv.c
new file mode 100644
index 00000000000..43b91b102cf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/neon/vaddv.c
@@ -0,0 +1,138 @@ 
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_neon_test.h"
+
+/*
+** test_vaddv_u8:
+** addv	b([0-9]+), v0\.8b
+** umov	w0, v\1\.b\[0\]
+** ret
+*/
+TEST_UNARY (vaddv_u8, uint8_t, uint8x8_t)
+
+/*
+** test_vaddv_s8:
+** addv	b([0-9]+), v0\.8b
+** umov	w0, v\1\.b\[0\]
+** ret
+*/
+TEST_UNARY (vaddv_s8, int8_t, int8x8_t)
+
+/*
+** test_vaddv_u16:
+** addv	h([0-9]+), v0\.4h
+** umov	w0, v\1\.h\[0\]
+** ret
+*/
+TEST_UNARY (vaddv_u16, uint16_t, uint16x4_t)
+
+/*
+** test_vaddv_s16:
+** addv	h([0-9]+), v0\.4h
+** umov	w0, v\1\.h\[0\]
+** ret
+*/
+TEST_UNARY (vaddv_s16, int16_t, int16x4_t)
+
+/*
+** test_vaddv_u32:
+** addp	v([0-9]+)\.2s, v0\.2s, v0\.2s
+** fmov	w0, s\1
+** ret
+*/
+TEST_UNARY (vaddv_u32, uint32_t, uint32x2_t)
+
+/*
+** test_vaddv_s32:
+** addp	v([0-9]+)\.2s, v0\.2s, v0\.2s
+** fmov	w0, s\1
+** ret
+*/
+TEST_UNARY (vaddv_s32, int32_t, int32x2_t)
+
+/*
+** test_vaddvq_u8:
+** addv	b([0-9]+), v0\.16b
+** umov	w0, v\1\.b\[0\]
+** ret
+*/
+TEST_UNARY (vaddvq_u8, uint8_t, uint8x16_t)
+
+/*
+** test_vaddvq_s8:
+** addv	b([0-9]+), v0\.16b
+** umov	w0, v\1\.b\[0\]
+** ret
+*/
+TEST_UNARY (vaddvq_s8, int8_t, int8x16_t)
+
+/*
+** test_vaddvq_u16:
+** addv	h([0-9]+), v0\.8h
+** umov	w0, v\1\.h\[0\]
+** ret
+*/
+TEST_UNARY (vaddvq_u16, uint16_t, uint16x8_t)
+
+/*
+** test_vaddvq_s16:
+** addv	h([0-9]+), v0\.8h
+** umov	w0, v\1\.h\[0\]
+** ret
+*/
+TEST_UNARY (vaddvq_s16, int16_t, int16x8_t)
+
+/*
+** test_vaddvq_u32:
+** addv	(s[0-9]+), v0\.4s
+** fmov	w0, \1
+** ret
+*/
+TEST_UNARY (vaddvq_u32, uint32_t, uint32x4_t)
+
+/*
+** test_vaddvq_s32:
+** addv	(s[0-9]+), v0\.4s
+** fmov	w0, \1
+** ret
+*/
+TEST_UNARY (vaddvq_s32, int32_t, int32x4_t)
+
+/*
+** test_vaddvq_u64:
+** addp	(d[0-9]+), v0\.2d
+** fmov	x0, \1
+** ret
+*/
+TEST_UNARY (vaddvq_u64, uint64_t, uint64x2_t)
+
+/*
+** test_vaddvq_s64:
+** addp	(d[0-9]+), v0\.2d
+** fmov	x0, \1
+** ret
+*/
+TEST_UNARY (vaddvq_s64, int64_t, int64x2_t)
+
+/*
+** test_vaddv_f32:
+** faddp	s0, v0\.2s
+** ret
+*/
+TEST_UNARY (vaddv_f32, float32_t, float32x2_t)
+
+/*
+** test_vaddvq_f32:
+** faddp	(v[0-9]+\.4s), v0\.4s, v0\.4s
+** faddp	v0\.4s, \1, \1
+** ret
+*/
+TEST_UNARY (vaddvq_f32, float32_t, float32x4_t)
+
+/*
+** test_vaddvq_f64:
+** faddp	d0, v0\.2d
+** ret
+*/
+TEST_UNARY (vaddvq_f64, float64_t, float64x2_t)
diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vmaxnmv.c b/gcc/testsuite/gcc.target/aarch64/neon/vmaxnmv.c
new file mode 100644
index 00000000000..47f54144fdb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/neon/vmaxnmv.c
@@ -0,0 +1,39 @@ 
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_neon_test.h"
+
+/*
+** test_vmaxnmv_f16:
+** fmaxnmv	h0, v0\.4h
+** ret
+*/
+TEST_UNARY (vmaxnmv_f16, float16_t, float16x4_t)
+
+/*
+** test_vmaxnmv_f32:
+** fmaxnmp	s0, v0\.2s
+** ret
+*/
+TEST_UNARY (vmaxnmv_f32, float32_t, float32x2_t)
+
+/*
+** test_vmaxnmvq_f16:
+** fmaxnmv	h0, v0\.8h
+** ret
+*/
+TEST_UNARY (vmaxnmvq_f16, float16_t, float16x8_t)
+
+/*
+** test_vmaxnmvq_f32:
+** fmaxnmv	s0, v0\.4s
+** ret
+*/
+TEST_UNARY (vmaxnmvq_f32, float32_t, float32x4_t)
+
+/*
+** test_vmaxnmvq_f64:
+** fmaxnmp	d0, v0\.2d
+** ret
+*/
+TEST_UNARY (vmaxnmvq_f64, float64_t, float64x2_t)
diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vmaxv.c b/gcc/testsuite/gcc.target/aarch64/neon/vmaxv.c
new file mode 100644
index 00000000000..a28da5fbb70
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/neon/vmaxv.c
@@ -0,0 +1,135 @@ 
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_neon_test.h"
+
+/*
+** test_vmaxv_u8:
+** umaxv	b([0-9]+), v0\.8b
+** umov	x0, v\1\.d\[0\]
+** ret
+*/
+TEST_UNARY (vmaxv_u8, uint8_t, uint8x8_t)
+
+/*
+** test_vmaxv_s8:
+** smaxv	b([0-9]+), v0\.8b
+** umov	x0, v\1\.d\[0\]
+** ret
+*/
+TEST_UNARY (vmaxv_s8, int8_t, int8x8_t)
+
+/*
+** test_vmaxv_u16:
+** umaxv	h([0-9]+), v0\.4h
+** umov	x0, v\1\.d\[0\]
+** ret
+*/
+TEST_UNARY (vmaxv_u16, uint16_t, uint16x4_t)
+
+/*
+** test_vmaxv_s16:
+** smaxv	h([0-9]+), v0\.4h
+** umov	x0, v\1\.d\[0\]
+** ret
+*/
+TEST_UNARY (vmaxv_s16, int16_t, int16x4_t)
+
+/*
+** test_vmaxv_u32:
+** umaxp	v([0-9]+)\.2s, v0\.2s, v0\.2s
+** umov	x0, v\1\.d\[0\]
+** ret
+*/
+TEST_UNARY (vmaxv_u32, uint32_t, uint32x2_t)
+
+/*
+** test_vmaxv_s32:
+** smaxp	v([0-9]+)\.2s, v0\.2s, v0\.2s
+** umov	x0, v\1\.d\[0\]
+** ret
+*/
+TEST_UNARY (vmaxv_s32, int32_t, int32x2_t)
+
+/*
+** test_vmaxvq_u8:
+** umaxv	b([0-9]+), v0\.16b
+** umov	w0, v\1\.b\[0\]
+** ret
+*/
+TEST_UNARY (vmaxvq_u8, uint8_t, uint8x16_t)
+
+/*
+** test_vmaxvq_s8:
+** smaxv	b([0-9]+), v0\.16b
+** umov	w0, v\1\.b\[0\]
+** ret
+*/
+TEST_UNARY (vmaxvq_s8, int8_t, int8x16_t)
+
+/*
+** test_vmaxvq_u16:
+** umaxv	h([0-9]+), v0\.8h
+** umov	w0, v\1\.h\[0\]
+** ret
+*/
+TEST_UNARY (vmaxvq_u16, uint16_t, uint16x8_t)
+
+/*
+** test_vmaxvq_s16:
+** smaxv	h([0-9]+), v0\.8h
+** umov	w0, v\1\.h\[0\]
+** ret
+*/
+TEST_UNARY (vmaxvq_s16, int16_t, int16x8_t)
+
+/*
+** test_vmaxvq_u32:
+** umaxv	(s[0-9]+), v0\.4s
+** fmov	w0, \1
+** ret
+*/
+TEST_UNARY (vmaxvq_u32, uint32_t, uint32x4_t)
+
+/*
+** test_vmaxvq_s32:
+** smaxv	(s[0-9]+), v0\.4s
+** fmov	w0, \1
+** ret
+*/
+TEST_UNARY (vmaxvq_s32, int32_t, int32x4_t)
+
+/*
+** test_vmaxv_f16:
+** fmaxv	h0, v0\.4h
+** ret
+*/
+TEST_UNARY (vmaxv_f16, float16_t, float16x4_t)
+
+/*
+** test_vmaxv_f32:
+** fmaxp	s0, v0\.2s
+** ret
+*/
+TEST_UNARY (vmaxv_f32, float32_t, float32x2_t)
+
+/*
+** test_vmaxvq_f16:
+** fmaxv	h0, v0\.8h
+** ret
+*/
+TEST_UNARY (vmaxvq_f16, float16_t, float16x8_t)
+
+/*
+** test_vmaxvq_f32:
+** fmaxv	s0, v0\.4s
+** ret
+*/
+TEST_UNARY (vmaxvq_f32, float32_t, float32x4_t)
+
+/*
+** test_vmaxvq_f64:
+** fmaxp	d0, v0\.2d
+** ret
+*/
+TEST_UNARY (vmaxvq_f64, float64_t, float64x2_t)
diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vminnmv.c b/gcc/testsuite/gcc.target/aarch64/neon/vminnmv.c
new file mode 100644
index 00000000000..04765f7d3bc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/neon/vminnmv.c
@@ -0,0 +1,39 @@ 
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_neon_test.h"
+
+/*
+** test_vminnmv_f16:
+** fminnmv	h0, v0\.4h
+** ret
+*/
+TEST_UNARY (vminnmv_f16, float16_t, float16x4_t)
+
+/*
+** test_vminnmv_f32:
+** fminnmp	s0, v0\.2s
+** ret
+*/
+TEST_UNARY (vminnmv_f32, float32_t, float32x2_t)
+
+/*
+** test_vminnmvq_f16:
+** fminnmv	h0, v0\.8h
+** ret
+*/
+TEST_UNARY (vminnmvq_f16, float16_t, float16x8_t)
+
+/*
+** test_vminnmvq_f32:
+** fminnmv	s0, v0\.4s
+** ret
+*/
+TEST_UNARY (vminnmvq_f32, float32_t, float32x4_t)
+
+/*
+** test_vminnmvq_f64:
+** fminnmp	d0, v0\.2d
+** ret
+*/
+TEST_UNARY (vminnmvq_f64, float64_t, float64x2_t)
diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vminv.c b/gcc/testsuite/gcc.target/aarch64/neon/vminv.c
new file mode 100644
index 00000000000..9b7657357fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/neon/vminv.c
@@ -0,0 +1,135 @@ 
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_neon_test.h"
+
+/*
+** test_vminv_u8:
+** uminv	b([0-9]+), v0\.8b
+** umov	x0, v\1\.d\[0\]
+** ret
+*/
+TEST_UNARY (vminv_u8, uint8_t, uint8x8_t)
+
+/*
+** test_vminv_s8:
+** sminv	b([0-9]+), v0\.8b
+** umov	x0, v\1\.d\[0\]
+** ret
+*/
+TEST_UNARY (vminv_s8, int8_t, int8x8_t)
+
+/*
+** test_vminv_u16:
+** uminv	h([0-9]+), v0\.4h
+** umov	x0, v\1\.d\[0\]
+** ret
+*/
+TEST_UNARY (vminv_u16, uint16_t, uint16x4_t)
+
+/*
+** test_vminv_s16:
+** sminv	h([0-9]+), v0\.4h
+** umov	x0, v\1\.d\[0\]
+** ret
+*/
+TEST_UNARY (vminv_s16, int16_t, int16x4_t)
+
+/*
+** test_vminv_u32:
+** uminp	v([0-9]+)\.2s, v0\.2s, v0\.2s
+** umov	x0, v\1\.d\[0\]
+** ret
+*/
+TEST_UNARY (vminv_u32, uint32_t, uint32x2_t)
+
+/*
+** test_vminv_s32:
+** sminp	v([0-9]+)\.2s, v0\.2s, v0\.2s
+** umov	x0, v\1\.d\[0\]
+** ret
+*/
+TEST_UNARY (vminv_s32, int32_t, int32x2_t)
+
+/*
+** test_vminvq_u8:
+** uminv	b([0-9]+), v0\.16b
+** umov	w0, v\1\.b\[0\]
+** ret
+*/
+TEST_UNARY (vminvq_u8, uint8_t, uint8x16_t)
+
+/*
+** test_vminvq_s8:
+** sminv	b([0-9]+), v0\.16b
+** umov	w0, v\1\.b\[0\]
+** ret
+*/
+TEST_UNARY (vminvq_s8, int8_t, int8x16_t)
+
+/*
+** test_vminvq_u16:
+** uminv	h([0-9]+), v0\.8h
+** umov	w0, v\1\.h\[0\]
+** ret
+*/
+TEST_UNARY (vminvq_u16, uint16_t, uint16x8_t)
+
+/*
+** test_vminvq_s16:
+** sminv	h([0-9]+), v0\.8h
+** umov	w0, v\1\.h\[0\]
+** ret
+*/
+TEST_UNARY (vminvq_s16, int16_t, int16x8_t)
+
+/*
+** test_vminvq_u32:
+** uminv	(s[0-9]+), v0\.4s
+** fmov	w0, \1
+** ret
+*/
+TEST_UNARY (vminvq_u32, uint32_t, uint32x4_t)
+
+/*
+** test_vminvq_s32:
+** sminv	(s[0-9]+), v0\.4s
+** fmov	w0, \1
+** ret
+*/
+TEST_UNARY (vminvq_s32, int32_t, int32x4_t)
+
+/*
+** test_vminv_f16:
+** fminv	h0, v0\.4h
+** ret
+*/
+TEST_UNARY (vminv_f16, float16_t, float16x4_t)
+
+/*
+** test_vminv_f32:
+** fminp	s0, v0\.2s
+** ret
+*/
+TEST_UNARY (vminv_f32, float32_t, float32x2_t)
+
+/*
+** test_vminvq_f16:
+** fminv	h0, v0\.8h
+** ret
+*/
+TEST_UNARY (vminvq_f16, float16_t, float16x8_t)
+
+/*
+** test_vminvq_f32:
+** fminv	s0, v0\.4s
+** ret
+*/
+TEST_UNARY (vminvq_f32, float32_t, float32x4_t)
+
+/*
+** test_vminvq_f64:
+** fminp	d0, v0\.2d
+** ret
+*/
+TEST_UNARY (vminvq_f64, float64_t, float64x2_t)