@@ -234,18 +234,26 @@
BUILTIN_VSDQ_I_DI (BINOP, cmgtu, 0)
BUILTIN_VSDQ_I_DI (BINOP, cmtst, 0)
- /* Implemented by aarch64_<fmaxmin><mode>. */
- BUILTIN_VDQF (BINOP, fmax, 0)
- BUILTIN_VDQF (BINOP, fmin, 0)
-
/* Implemented by aarch64_addv<mode>. */
BUILTIN_VDQF (UNOP, addv, 0)
- /* Implemented by <maxmin><mode>3. */
- BUILTIN_VDQ_BHSI (BINOP, smax, 3)
- BUILTIN_VDQ_BHSI (BINOP, smin, 3)
+ /* Implemented by reduc_<maxmin_uns>_<mode>. */
+ BUILTIN_VDQIF (UNOP, reduc_smax_, 10)
+ BUILTIN_VDQIF (UNOP, reduc_smin_, 10)
+ BUILTIN_VDQ_BHSI (UNOP, reduc_umax_, 10)
+ BUILTIN_VDQ_BHSI (UNOP, reduc_umin_, 10)
+ BUILTIN_VDQF (UNOP, reduc_smax_nan_, 10)
+ BUILTIN_VDQF (UNOP, reduc_smin_nan_, 10)
+
+ /* Implemented by <maxmin><mode>3.
+ smax variants map to fmaxnm,
+ smax_nan variants map to fmax. */
+ BUILTIN_VDQIF (BINOP, smax, 3)
+ BUILTIN_VDQIF (BINOP, smin, 3)
BUILTIN_VDQ_BHSI (BINOP, umax, 3)
BUILTIN_VDQ_BHSI (BINOP, umin, 3)
+ BUILTIN_VDQF (BINOP, smax_nan, 3)
+ BUILTIN_VDQF (BINOP, smin_nan, 3)
/* Implemented by <frint_pattern><mode>2. */
BUILTIN_VDQF (UNOP, btrunc, 2)
@@ -940,12 +940,12 @@
)
;; Max/Min operations.
-(define_insn "<maxmin><mode>3"
+(define_insn "<su><maxmin><mode>3"
[(set (match_operand:VQ_S 0 "register_operand" "=w")
(MAXMIN:VQ_S (match_operand:VQ_S 1 "register_operand" "w")
(match_operand:VQ_S 2 "register_operand" "w")))]
"TARGET_SIMD"
- "<maxmin>\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
+ "<su><maxmin>\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
[(set_attr "simd_type" "simd_minmax")
(set_attr "simd_mode" "<MODE>")]
)
@@ -1417,44 +1417,23 @@
;; only introduces MIN_EXPR/MAX_EXPR in fast math mode or when not honouring
;; NaNs.
-(define_insn "smax<mode>3"
+(define_insn "<su><maxmin><mode>3"
[(set (match_operand:VDQF 0 "register_operand" "=w")
- (smax:VDQF (match_operand:VDQF 1 "register_operand" "w")
+ (FMAXMIN:VDQF (match_operand:VDQF 1 "register_operand" "w")
(match_operand:VDQF 2 "register_operand" "w")))]
"TARGET_SIMD"
- "fmaxnm\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
+ "f<maxmin>nm\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
[(set_attr "simd_type" "simd_fminmax")
(set_attr "simd_mode" "<MODE>")]
)
-(define_insn "smin<mode>3"
+(define_insn "<maxmin_uns><mode>3"
[(set (match_operand:VDQF 0 "register_operand" "=w")
- (smin:VDQF (match_operand:VDQF 1 "register_operand" "w")
- (match_operand:VDQF 2 "register_operand" "w")))]
+ (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")
+ (match_operand:VDQF 2 "register_operand" "w")]
+ FMAXMIN_UNS))]
"TARGET_SIMD"
- "fminnm\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fminmax")
- (set_attr "simd_mode" "<MODE>")]
-)
-
-;; FP 'across lanes' max and min ops.
-
-(define_insn "reduc_s<fmaxminv>_v4sf"
- [(set (match_operand:V4SF 0 "register_operand" "=w")
- (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")]
- FMAXMINV))]
- "TARGET_SIMD"
- "f<fmaxminv>nmv\\t%s0, %1.4s";
- [(set_attr "simd_type" "simd_fminmaxv")
- (set_attr "simd_mode" "V4SF")]
-)
-
-(define_insn "reduc_s<fmaxminv>_<mode>"
- [(set (match_operand:V2F 0 "register_operand" "=w")
- (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
- FMAXMINV))]
- "TARGET_SIMD"
- "f<fmaxminv>nmp\\t%0.<Vtype>, %1.<Vtype>, %1.<Vtype>";
+ "<maxmin_uns_op>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
[(set_attr "simd_type" "simd_fminmax")
(set_attr "simd_mode" "<MODE>")]
)
@@ -1609,26 +1588,58 @@
""
)
-(define_insn "reduc_<maxminv>_<mode>"
+;; 'across lanes' max and min ops.
+
+(define_insn "reduc_<maxmin_uns>_<mode>"
[(set (match_operand:VDQV 0 "register_operand" "=w")
(unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
MAXMINV))]
"TARGET_SIMD"
- "<maxminv>v\\t%<Vetype>0, %1.<Vtype>"
+ "<maxmin_uns_op>v\\t%<Vetype>0, %1.<Vtype>"
[(set_attr "simd_type" "simd_minmaxv")
(set_attr "simd_mode" "<MODE>")]
)
-(define_insn "reduc_<maxminv>_v2si"
+(define_insn "reduc_<maxmin_uns>_v2di"
+ [(set (match_operand:V2DI 0 "register_operand" "=w")
+ (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "w")]
+ MAXMINV))]
+ "TARGET_SIMD"
+ "<maxmin_uns_op>p\\t%d0, %1.2d"
+ [(set_attr "simd_type" "simd_minmaxv")
+ (set_attr "simd_mode" "V2DI")]
+)
+
+(define_insn "reduc_<maxmin_uns>_v2si"
[(set (match_operand:V2SI 0 "register_operand" "=w")
(unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
MAXMINV))]
"TARGET_SIMD"
- "<maxminv>p\\t%0.2s, %1.2s, %1.2s"
- [(set_attr "simd_type" "simd_minmax")
+ "<maxmin_uns_op>p\\t%0.2s, %1.2s, %1.2s"
+ [(set_attr "simd_type" "simd_minmaxv")
(set_attr "simd_mode" "V2SI")]
)
+(define_insn "reduc_<maxmin_uns>_<mode>"
+ [(set (match_operand:V2F 0 "register_operand" "=w")
+ (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
+ FMAXMINV))]
+ "TARGET_SIMD"
+ "<maxmin_uns_op>p\\t%<Vetype>0, %1.<Vtype>"
+ [(set_attr "simd_type" "simd_fminmaxv")
+ (set_attr "simd_mode" "<MODE>")]
+)
+
+(define_insn "reduc_<maxmin_uns>_v4sf"
+ [(set (match_operand:V4SF 0 "register_operand" "=w")
+ (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "w")]
+ FMAXMINV))]
+ "TARGET_SIMD"
+ "<maxmin_uns_op>v\\t%s0, %1.4s"
+ [(set_attr "simd_type" "simd_fminmaxv")
+ (set_attr "simd_mode" "V4SF")]
+)
+
;; aarch64_simd_bsl may compile to any of bsl/bif/bit depending on register
;; allocation.
;; Operand 1 is the mask, operands 2 and 3 are the bitfields from which
@@ -3442,17 +3453,6 @@
(set_attr "simd_mode" "DI")]
)
-(define_insn "aarch64_<fmaxmin><mode>"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")
- (match_operand:VDQF 2 "register_operand" "w")]
- FMAXMIN))]
- "TARGET_SIMD"
- "<fmaxmin>\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
- [(set_attr "simd_type" "simd_fminmax")
- (set_attr "simd_mode" "<MODE>")]
-)
-
;; sqrt
(define_insn "sqrt<mode>2"
@@ -21544,7 +21544,7 @@ vld4q_f64 (const float64_t * __a)
__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
vmax_f32 (float32x2_t __a, float32x2_t __b)
{
- return __builtin_aarch64_fmaxv2sf (__a, __b);
+ return __builtin_aarch64_smax_nanv2sf (__a, __b);
}
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
@@ -21589,13 +21589,13 @@ vmax_u32 (uint32x2_t __a, uint32x2_t __b)
__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
vmaxq_f32 (float32x4_t __a, float32x4_t __b)
{
- return __builtin_aarch64_fmaxv4sf (__a, __b);
+ return __builtin_aarch64_smax_nanv4sf (__a, __b);
}
__extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
vmaxq_f64 (float64x2_t __a, float64x2_t __b)
{
- return __builtin_aarch64_fmaxv2df (__a, __b);
+ return __builtin_aarch64_smax_nanv2df (__a, __b);
}
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
@@ -21642,7 +21642,7 @@ vmaxq_u32 (uint32x4_t __a, uint32x4_t __b)
__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
vmin_f32 (float32x2_t __a, float32x2_t __b)
{
- return __builtin_aarch64_fminv2sf (__a, __b);
+ return __builtin_aarch64_smin_nanv2sf (__a, __b);
}
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
@@ -21687,13 +21687,13 @@ vmin_u32 (uint32x2_t __a, uint32x2_t __b)
__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
vminq_f32 (float32x4_t __a, float32x4_t __b)
{
- return __builtin_aarch64_fminv4sf (__a, __b);
+ return __builtin_aarch64_smin_nanv4sf (__a, __b);
}
__extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
vminq_f64 (float64x2_t __a, float64x2_t __b)
{
- return __builtin_aarch64_fminv2df (__a, __b);
+ return __builtin_aarch64_smin_nanv2df (__a, __b);
}
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
@@ -163,7 +163,11 @@
[
UNSPEC_ASHIFT_SIGNED ; Used in aarch-simd.md.
UNSPEC_ASHIFT_UNSIGNED ; Used in aarch64-simd.md.
+ UNSPEC_FMAX ; Used in aarch64-simd.md.
+ UNSPEC_FMAXNMV ; Used in aarch64-simd.md.
UNSPEC_FMAXV ; Used in aarch64-simd.md.
+ UNSPEC_FMIN ; Used in aarch64-simd.md.
+ UNSPEC_FMINNMV ; Used in aarch64-simd.md.
UNSPEC_FMINV ; Used in aarch64-simd.md.
UNSPEC_FADDV ; Used in aarch64-simd.md.
UNSPEC_ADDV ; Used in aarch64-simd.md.
@@ -223,8 +227,6 @@
UNSPEC_SSHLL ; Used in aarch64-simd.md.
UNSPEC_USHLL ; Used in aarch64-simd.md.
UNSPEC_ADDP ; Used in aarch64-simd.md.
- UNSPEC_FMAX ; Used in aarch64-simd.md.
- UNSPEC_FMIN ; Used in aarch64-simd.md.
UNSPEC_TBL ; Used in vector permute patterns.
UNSPEC_CONCAT ; Used in vector permute patterns.
UNSPEC_ZIP1 ; Used in vector permute patterns.
@@ -535,6 +537,8 @@
;; Code iterator for variants of vector max and min.
(define_code_iterator MAXMIN [smax smin umax umin])
+(define_code_iterator FMAXMIN [smax smin])
+
;; Code iterator for variants of vector max and min.
(define_code_iterator ADDSUB [plus minus])
@@ -643,7 +647,9 @@
(define_code_attr su [(sign_extend "s") (zero_extend "u")
(sign_extract "s") (zero_extract "u")
(fix "s") (unsigned_fix "u")
- (div "s") (udiv "u")])
+ (div "s") (udiv "u")
+ (smax "s") (umax "u")
+ (smin "s") (umin "u")])
;; Emit cbz/cbnz depending on comparison type.
(define_code_attr cbz [(eq "cbz") (ne "cbnz") (lt "cbnz") (ge "cbz")])
@@ -652,10 +658,10 @@
(define_code_attr tbz [(eq "tbz") (ne "tbnz") (lt "tbnz") (ge "tbz")])
;; Max/min attributes.
-(define_code_attr maxmin [(smax "smax")
- (smin "smin")
- (umax "umax")
- (umin "umin")])
+(define_code_attr maxmin [(smax "max")
+ (smin "min")
+ (umax "max")
+ (umin "min")])
;; MLA/MLS attributes.
(define_code_attr as [(ss_plus "a") (ss_minus "s")])
@@ -677,7 +683,8 @@
(define_int_iterator MAXMINV [UNSPEC_UMAXV UNSPEC_UMINV
UNSPEC_SMAXV UNSPEC_SMINV])
-(define_int_iterator FMAXMINV [UNSPEC_FMAXV UNSPEC_FMINV])
+(define_int_iterator FMAXMINV [UNSPEC_FMAXV UNSPEC_FMINV
+ UNSPEC_FMAXNMV UNSPEC_FMINNMV])
(define_int_iterator HADDSUB [UNSPEC_SHADD UNSPEC_UHADD
UNSPEC_SRHADD UNSPEC_URHADD
@@ -691,7 +698,7 @@
(define_int_iterator ADDSUBHN2 [UNSPEC_ADDHN2 UNSPEC_RADDHN2
UNSPEC_SUBHN2 UNSPEC_RSUBHN2])
-(define_int_iterator FMAXMIN [UNSPEC_FMAX UNSPEC_FMIN])
+(define_int_iterator FMAXMIN_UNS [UNSPEC_FMAX UNSPEC_FMIN])
(define_int_iterator VQDMULH [UNSPEC_SQDMULH UNSPEC_SQRDMULH])
@@ -738,16 +745,27 @@
;; -------------------------------------------------------------------
;; Int Iterators Attributes.
;; -------------------------------------------------------------------
-(define_int_attr maxminv [(UNSPEC_UMAXV "umax")
- (UNSPEC_UMINV "umin")
- (UNSPEC_SMAXV "smax")
- (UNSPEC_SMINV "smin")])
-
-(define_int_attr fmaxminv [(UNSPEC_FMAXV "max")
- (UNSPEC_FMINV "min")])
-
-(define_int_attr fmaxmin [(UNSPEC_FMAX "fmax")
- (UNSPEC_FMIN "fmin")])
+(define_int_attr maxmin_uns [(UNSPEC_UMAXV "umax")
+ (UNSPEC_UMINV "umin")
+ (UNSPEC_SMAXV "smax")
+ (UNSPEC_SMINV "smin")
+ (UNSPEC_FMAX "smax_nan")
+ (UNSPEC_FMAXNMV "smax")
+ (UNSPEC_FMAXV "smax_nan")
+ (UNSPEC_FMIN "smin_nan")
+ (UNSPEC_FMINNMV "smin")
+ (UNSPEC_FMINV "smin_nan")])
+
+(define_int_attr maxmin_uns_op [(UNSPEC_UMAXV "umax")
+ (UNSPEC_UMINV "umin")
+ (UNSPEC_SMAXV "smax")
+ (UNSPEC_SMINV "smin")
+ (UNSPEC_FMAX "fmax")
+ (UNSPEC_FMAXNMV "fmaxnm")
+ (UNSPEC_FMAXV "fmax")
+ (UNSPEC_FMIN "fmin")
+ (UNSPEC_FMINNMV "fminnm")
+ (UNSPEC_FMINV "fmin")])
(define_int_attr sur [(UNSPEC_SHADD "s") (UNSPEC_UHADD "u")
(UNSPEC_SRHADD "sr") (UNSPEC_URHADD "ur")