The floating point variants of `vmin` and `vmax` were not ported to the
pragma-based framework when the integer variants were, because the
semantics AArch64's `fmin`/`fmax` instructions don't match the semantics
of GCC's `MIN_EXPR`/`MAX_EXPR`. This commit ports them to the pragma
framework, by expanding them to `UNSPEC_FMIN` and `UNSPEC_FMAX`.
There are no test changes, as tests for FP variants of vmin/vmax were
already included in vmin.c and vmax.c. The absence of any changes to the
tests does show that there were no changes in codegen (ie no
regressions).
Also delete the `__builtin_aarch64_{u,s}{min,max}` functions which were
mistakenly left behind when the integer min/max intrinsics were ported.
gcc/ChangeLog:
* config/aarch64/aarch64-neon-builtins-base.cc (struct
gimple_minmax): New struct.
* config/aarch64/aarch64-neon-builtins-base.def (vmax, vmaxq,
vmin, vminq): New intrinsic function definitions.
* config/aarch64/aarch64-simd-builtins.def (smax, smin, umax,
umin, fmax, fmin): Delete now-unused builtin function declarations.
(fmax_nan, fmin_nan): Only define for float16_t, as they are
only now called from `arm_fp16.h`.
* config/aarch64/arm_fp16.h (vmaxh_f16, vminh_f16): Call the
correct `_nan` variant of the `__aarch64_builtin` functions.
(vmaxnmh_f16, vminnmh_f16): Use the platform-agnostic
`__builtin_f{min,max}f16` functions rather than the now-deleted
aarch64-specific builtins.
* config/aarch64/arm_neon.h (vmax_f32, vmax_f64, vmaxq_f32,
vmaxq_f64, vmin_f32, vmin_f64, vminq_f32, vminq_f64, vmax_f16,
vmaxq_f16, vmin_f16, vminq_f16): Delete intrinsic function
definitions.
---
.../aarch64/aarch64-neon-builtins-base.cc | 40 +++++++-
.../aarch64/aarch64-neon-builtins-base.def | 8 ++
gcc/config/aarch64/aarch64-simd-builtins.def | 14 +--
gcc/config/aarch64/arm_fp16.h | 4 +-
gcc/config/aarch64/arm_neon.h | 92 -------------------
5 files changed, 52 insertions(+), 106 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
index 4b66a93d0f0..8c3bcc6eb74 100644
--- a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
@@ -1140,6 +1140,42 @@ public:
}
};
+template <bool min_p>
+struct gimple_minmax : public gimple_function_base
+{
+ rtx expand (function_expander &e) const override
+ {
+ auto ret_mode = e.result_mode ();
+ auto singleton_p = (ret_mode == V1DFmode);
+ auto unspec = min_p ? UNSPEC_FMIN : UNSPEC_FMAX;
+
+ if (singleton_p)
+ {
+ for (int i = 0; i < 2; i++)
+ e.args[i] = simplify_gen_subreg (DFmode, e.args[i], V1DFmode, 0);
+ ret_mode = DFmode;
+ }
+
+ auto ret = gen_reg_rtx (ret_mode);
+ auto args = gen_rtvec_v (e.args.length (), e.args.address ());
+ emit_insn (gen_rtx_SET (ret, gen_rtx_UNSPEC (ret_mode, args, unspec)));
+
+ if (singleton_p)
+ ret = simplify_gen_subreg (V1DFmode, ret, DFmode, 0);
+
+ return ret;
+ }
+
+ gimple *fold (gimple_folder &f) const override {
+ auto lhs = gimple_call_arg (f.call, 0);
+ auto rhs = gimple_call_arg (f.call, 1);
+ auto ret_type = TREE_TYPE (f.lhs);
+ if (FLOAT_TYPE_P (ret_type))
+ return nullptr;
+ return gimple_build_assign (f.lhs, min_p ? MIN_EXPR : MAX_EXPR, lhs, rhs);
+ }
+};
+
// Reinterpret
NEON_FUNCTION (vreinterpret, vreinterpretq, gimple_reinterpret,)
@@ -1175,8 +1211,8 @@ NEON_FUNCTION (vqaddb, vqaddh, vqadds, vqaddd, vqadd,
vqaddq, gimple_ifn, (IFN_S
NEON_FUNCTION (vqsubb, vqsubh, vqsubs, vqsubd, vqsub, vqsubq, gimple_ifn,
(IFN_SAT_SUB))
// Max/min
-NEON_FUNCTION (vmax, vmaxq, gimple_expr, (MAX_EXPR))
-NEON_FUNCTION (vmin, vminq, gimple_expr, (MIN_EXPR))
+NEON_FUNCTION (vmax, vmaxq, gimple_minmax<false>,)
+NEON_FUNCTION (vmin, vminq, gimple_minmax<true>,)
NEON_FUNCTION (vmaxnm, vmaxnmq, gimple_ifn, (IFN_FMAX))
NEON_FUNCTION (vminnm, vminnmq, gimple_ifn, (IFN_FMIN))
diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.def
b/gcc/config/aarch64/aarch64-neon-builtins-base.def
index db9defc454c..e8edb2679b9 100644
--- a/gcc/config/aarch64/aarch64-neon-builtins-base.def
+++ b/gcc/config/aarch64/aarch64-neon-builtins-base.def
@@ -180,9 +180,13 @@ DEF_NEON_FUNCTION (vqsubq, all_integer, ("Q0,Q0,Q0"))
// Max/min
#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD)
DEF_NEON_FUNCTION (vmax, bhs_integer, ("D0,D0,D0"))
+DEF_NEON_FUNCTION (vmax, sd_float, ("D0,D0,D0"))
DEF_NEON_FUNCTION (vmaxq, bhs_integer, ("Q0,Q0,Q0"))
+DEF_NEON_FUNCTION (vmaxq, sd_float, ("Q0,Q0,Q0"))
DEF_NEON_FUNCTION (vmin, bhs_integer, ("D0,D0,D0"))
+DEF_NEON_FUNCTION (vmin, sd_float, ("D0,D0,D0"))
DEF_NEON_FUNCTION (vminq, bhs_integer, ("Q0,Q0,Q0"))
+DEF_NEON_FUNCTION (vminq, sd_float, ("Q0,Q0,Q0"))
DEF_NEON_FUNCTION (vmaxnm, sd_float, ("D0,D0,D0"))
DEF_NEON_FUNCTION (vmaxnmq, sd_float, ("Q0,Q0,Q0"))
DEF_NEON_FUNCTION (vminnm, sd_float, ("D0,D0,D0"))
@@ -191,6 +195,10 @@ DEF_NEON_FUNCTION (vminnmq, sd_float, ("Q0,Q0,Q0"))
// Max/min (FP16)
#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD |
AARCH64_FL_F16)
+DEF_NEON_FUNCTION (vmax, h_float, ("D0,D0,D0"))
+DEF_NEON_FUNCTION (vmaxq, h_float, ("Q0,Q0,Q0"))
+DEF_NEON_FUNCTION (vmin, h_float, ("D0,D0,D0"))
+DEF_NEON_FUNCTION (vminq, h_float, ("Q0,Q0,Q0"))
DEF_NEON_FUNCTION (vmaxnm, h_float, ("D0,D0,D0"))
DEF_NEON_FUNCTION (vmaxnmq, h_float, ("Q0,Q0,Q0"))
DEF_NEON_FUNCTION (vminnm, h_float, ("D0,D0,D0"))
diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def
b/gcc/config/aarch64/aarch64-simd-builtins.def
index 0a84dfd459d..d1a19cebe97 100644
--- a/gcc/config/aarch64/aarch64-simd-builtins.def
+++ b/gcc/config/aarch64/aarch64-simd-builtins.def
@@ -503,17 +503,11 @@
BUILTIN_VHSDF (UNOP, reduc_smax_nan_scal_, 10, DEFAULT)
BUILTIN_VHSDF (UNOP, reduc_smin_nan_scal_, 10, DEFAULT)
- /* Implemented by <optab><mode>3. */
- BUILTIN_VDQ_BHSI (BINOP, smax, 3, DEFAULT)
- BUILTIN_VDQ_BHSI (BINOP, smin, 3, DEFAULT)
- BUILTIN_VDQ_BHSI (BINOP, umax, 3, DEFAULT)
- BUILTIN_VDQ_BHSI (BINOP, umin, 3, DEFAULT)
-
/* Implemented by <fmaxmin><mode>3. */
- BUILTIN_VHSDF_HSDF (BINOP, fmax, 3, FP)
- BUILTIN_VHSDF_HSDF (BINOP, fmin, 3, FP)
- BUILTIN_VHSDF_DF (BINOP, fmax_nan, 3, FP)
- BUILTIN_VHSDF_DF (BINOP, fmin_nan, 3, FP)
+ VAR1 (BINOP, fmax, 3, FP, hf)
+ VAR1 (BINOP, fmin, 3, FP, hf)
+ VAR1 (BINOP, fmax_nan, 3, FP, hf)
+ VAR1 (BINOP, fmin_nan, 3, FP, hf)
/* Implemented by aarch64_<optab>p<mode>. */
BUILTIN_VDQ_BHSI (BINOP, smaxp, 0, DEFAULT)
diff --git a/gcc/config/aarch64/arm_fp16.h b/gcc/config/aarch64/arm_fp16.h
index d932d8ab1c9..d353eea65ab 100644
--- a/gcc/config/aarch64/arm_fp16.h
+++ b/gcc/config/aarch64/arm_fp16.h
@@ -588,7 +588,7 @@ __extension__ extern __inline float16_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vmaxh_f16 (float16_t __a, float16_t __b)
{
- return __builtin_aarch64_fmaxhf (__a, __b);
+ return __builtin_aarch64_fmax_nanhf (__a, __b);
}
__extension__ extern __inline float16_t
@@ -602,7 +602,7 @@ __extension__ extern __inline float16_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vminh_f16 (float16_t __a, float16_t __b)
{
- return __builtin_aarch64_fminhf (__a, __b);
+ return __builtin_aarch64_fmin_nanhf (__a, __b);
}
__extension__ extern __inline float16_t
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index a0dca5e8da9..a8d1c4f61da 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -10613,38 +10613,6 @@ vld4q_lane_p64 (const poly64_t * __ptr, poly64x2x4_t
__b, const int __c)
(__builtin_aarch64_simd_di *) __ptr, __b, __c);
}
-/* vmax */
-
-__extension__ extern __inline float32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmax_f32 (float32x2_t __a, float32x2_t __b)
-{
- return __builtin_aarch64_fmax_nanv2sf (__a, __b);
-}
-
-__extension__ extern __inline float64x1_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmax_f64 (float64x1_t __a, float64x1_t __b)
-{
- return (float64x1_t)
- { __builtin_aarch64_fmax_nandf (vget_lane_f64 (__a, 0),
- vget_lane_f64 (__b, 0)) };
-}
-
-__extension__ extern __inline float32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxq_f32 (float32x4_t __a, float32x4_t __b)
-{
- return __builtin_aarch64_fmax_nanv4sf (__a, __b);
-}
-
-__extension__ extern __inline float64x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxq_f64 (float64x2_t __a, float64x2_t __b)
-{
- return __builtin_aarch64_fmax_nanv2df (__a, __b);
-}
-
/* vmulx */
__extension__ extern __inline float32x2_t
@@ -11124,38 +11092,6 @@ vmaxvq_f64 (float64x2_t __a)
return __builtin_aarch64_reduc_smax_nan_scal_v2df (__a);
}
-/* vmin */
-
-__extension__ extern __inline float32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmin_f32 (float32x2_t __a, float32x2_t __b)
-{
- return __builtin_aarch64_fmin_nanv2sf (__a, __b);
-}
-
-__extension__ extern __inline float64x1_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmin_f64 (float64x1_t __a, float64x1_t __b)
-{
- return (float64x1_t)
- { __builtin_aarch64_fmin_nandf (vget_lane_f64 (__a, 0),
- vget_lane_f64 (__b, 0)) };
-}
-
-__extension__ extern __inline float32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminq_f32 (float32x4_t __a, float32x4_t __b)
-{
- return __builtin_aarch64_fmin_nanv4sf (__a, __b);
-}
-
-__extension__ extern __inline float64x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminq_f64 (float64x2_t __a, float64x2_t __b)
-{
- return __builtin_aarch64_fmin_nanv2df (__a, __b);
-}
-
/* vminv */
__extension__ extern __inline float32_t
@@ -17170,34 +17106,6 @@ vcvtq_n_u16_f16 (float16x8_t __a, const int __b)
return __builtin_aarch64_fcvtzuv8hf_uss (__a, __b);
}
-__extension__ extern __inline float16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmax_f16 (float16x4_t __a, float16x4_t __b)
-{
- return __builtin_aarch64_fmax_nanv4hf (__a, __b);
-}
-
-__extension__ extern __inline float16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmaxq_f16 (float16x8_t __a, float16x8_t __b)
-{
- return __builtin_aarch64_fmax_nanv8hf (__a, __b);
-}
-
-__extension__ extern __inline float16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmin_f16 (float16x4_t __a, float16x4_t __b)
-{
- return __builtin_aarch64_fmin_nanv4hf (__a, __b);
-}
-
-__extension__ extern __inline float16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vminq_f16 (float16x8_t __a, float16x8_t __b)
-{
- return __builtin_aarch64_fmin_nanv8hf (__a, __b);
-}
-
__extension__ extern __inline float16x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vmulx_f16 (float16x4_t __a, float16x4_t __b)
--
2.56.0