diff mbox

[AArch64] Refactor vector max and min RTL and builtins.

Message ID 1367335149-23404-1-git-send-email-james.greenhalgh@arm.com
State New
Headers show

Commit Message

James Greenhalgh April 30, 2013, 3:19 p.m. UTC
Hi,

This patch moves around the max/min infrastructure such that
we can more uniformly access the backend RTL patterns and such
that it uses the standard pattern names.

We also fixup the bugs this introduces in arm_neon.h which expected
the older names.

Regression tested on aarch64-none-elf with no issues.

Thanks,
James

---
gcc/

2013-04-30  James Greenhalgh  <james.greenhalgh@arm.com>

	* config/aarch64/aarch64-simd-builtins.def
	(reduc_smax_): New.
	(reduc_smin_): Likewise.
	(reduc_umax_): Likewise.
	(reduc_umin_): Likewise.
	(reduc_smax_nan_): Likewise.
	(reduc_smin_nan_): Likewise.
	(fmax): Remove.
	(fmin): Likewise.
	(smax): Update for V2SF, V4SF and V2DF modes.
	(smin): Likewise.
	(smax_nan): New.
	(smin_nan): Likewise.
	* config/aarch64/aarch64-simd.md (<maxmin><mode>3): Rename to...
	(<su><maxmin><mode>3): ...This, refactor.
	(s<maxmin><mode>3): New.
	(<maxmin_uns><mode>3): Likewise.
	(reduc_<maxmin_uns>_<mode>): Refactor.
	(reduc_<maxmin_uns>_v4sf): Likewise.
	(reduc_<maxmin_uns>_v2si): Likewise.
	(aarch64_<fmaxmin><mode>: Remove.
	* config/aarch64/arm_neon.h (vmax<q>_f<32,64>): Rewrite to use
	new builtin names.
	(vmin<q>_f<32,64>): Likewise.
	* config/iterators.md (unspec): Add UNSPEC_FMAXNMV, UNSPEC_FMINNMV.
	(FMAXMIN): New.
	(su): Add mappings for smax, smin, umax, umin.
	(maxmin): New.
	(FMAXMINV): Add UNSPEC_FMAXNMV, UNSPEC_FMINNMV.
	(FMAXMIN): Rename as...
	(FMAXMIN_UNS): ...This.
	(maxminv): Remove.
	(fmaxminv): Likewise.
	(fmaxmin): Likewise.
	(maxmin_uns): New.
	(maxmin_uns_op): Likewise.

Comments

Marcus Shawcroft April 30, 2013, 5:28 p.m. UTC | #1
OK
/Marcus

On 30 April 2013 16:19, James Greenhalgh <james.greenhalgh@arm.com> wrote:
>
> Hi,
>
> This patch moves around the max/min infrastructure such that
> we can more uniformly access the backend RTL patterns and such
> that it uses the standard pattern names.
>
> We also fixup the bugs this introduces in arm_neon.h which expected
> the older names.
>
> Regression tested on aarch64-none-elf with no issues.
>
> Thanks,
> James
>
> ---
> gcc/
>
> 2013-04-30  James Greenhalgh  <james.greenhalgh@arm.com>
>
>         * config/aarch64/aarch64-simd-builtins.def
>         (reduc_smax_): New.
>         (reduc_smin_): Likewise.
>         (reduc_umax_): Likewise.
>         (reduc_umin_): Likewise.
>         (reduc_smax_nan_): Likewise.
>         (reduc_smin_nan_): Likewise.
>         (fmax): Remove.
>         (fmin): Likewise.
>         (smax): Update for V2SF, V4SF and V2DF modes.
>         (smin): Likewise.
>         (smax_nan): New.
>         (smin_nan): Likewise.
>         * config/aarch64/aarch64-simd.md (<maxmin><mode>3): Rename to...
>         (<su><maxmin><mode>3): ...This, refactor.
>         (s<maxmin><mode>3): New.
>         (<maxmin_uns><mode>3): Likewise.
>         (reduc_<maxmin_uns>_<mode>): Refactor.
>         (reduc_<maxmin_uns>_v4sf): Likewise.
>         (reduc_<maxmin_uns>_v2si): Likewise.
>         (aarch64_<fmaxmin><mode>: Remove.
>         * config/aarch64/arm_neon.h (vmax<q>_f<32,64>): Rewrite to use
>         new builtin names.
>         (vmin<q>_f<32,64>): Likewise.
>         * config/iterators.md (unspec): Add UNSPEC_FMAXNMV, UNSPEC_FMINNMV.
>         (FMAXMIN): New.
>         (su): Add mappings for smax, smin, umax, umin.
>         (maxmin): New.
>         (FMAXMINV): Add UNSPEC_FMAXNMV, UNSPEC_FMINNMV.
>         (FMAXMIN): Rename as...
>         (FMAXMIN_UNS): ...This.
>         (maxminv): Remove.
>         (fmaxminv): Likewise.
>         (fmaxmin): Likewise.
>         (maxmin_uns): New.
>         (maxmin_uns_op): Likewise.
diff mbox

Patch

diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def
index 620406b..97a597e 100644
--- a/gcc/config/aarch64/aarch64-simd-builtins.def
+++ b/gcc/config/aarch64/aarch64-simd-builtins.def
@@ -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)
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 21c2a68..8a48739 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -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"
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index 5f1ab11..30a59a7 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -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__))
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 00e315d..3f9a584 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -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")