* config/aarch64/iterators.md (SVE_INT_BINARY_REV): Remove.
        (SVE_COND_FP_BINARY_REV): Remove.
        (sve_int_op_rev, sve_fp_op_rev): New.
        * config/aarch64/aarch64-sve.md (*cond_<SVE_INT_BINARY><SVE_I>_0): New.
        (*cond_<SVE_INT_BINARY_SD><SVE_SDI>_0): New.
        (*cond_<SVE_COND_FP_BINARY><SVE_F>_0): New.
        (*cond_<SVE_INT_BINARY><SVE_I>_2): Rename, add movprfx alternative.
        (*cond_<SVE_INT_BINARY_SD><SVE_SDI>_2): Similarly.
        (*cond_<SVE_COND_FP_BINARY><SVE_F>_2): Similarly.
        (*cond_<SVE_INT_BINARY><SVE_I>_3): Similarly; use sve_int_op_rev.
        (*cond_<SVE_INT_BINARY_SD><SVE_SDI>_3): Similarly.
        (*cond_<SVE_COND_FP_BINARY><SVE_F>_3): Similarly; use sve_fp_op_rev.
---
 gcc/config/aarch64/aarch64.c      |   8 +-
 gcc/config/aarch64/aarch64-sve.md | 163 ++++++++++++++++++++++--------
 gcc/config/aarch64/iterators.md   |  26 ++++-
 3 files changed, 149 insertions(+), 48 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index b88e7cac27a..3af7e98e166 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -16098,7 +16098,13 @@ aarch64_sve_prepare_conditional_op (rtx *operands, 
unsigned int nops,
      whereas selecting the input avoids the MOVPRFX:
 
        SEL Z0.S, P1, Z2.S, Z4.S
-       ADD Z0.S, P1/M, Z0.S, Z3.S.  */
+       ADD Z0.S, P1/M, Z0.S, Z3.S.
+
+     ??? Matching the other input can produce
+
+       MOVPRFX Z4.S, P1/M, Z2.S
+       ADD Z4.S, P1/M, Z4.S, Z3.S
+   */
   machine_mode mode = GET_MODE (operands[0]);
   rtx temp = gen_reg_rtx (mode);
   rtvec vec = gen_rtvec (3, operands[1], operands[2], operands[nops - 1]);
diff --git a/gcc/config/aarch64/aarch64-sve.md 
b/gcc/config/aarch64/aarch64-sve.md
index 2aceef65c80..db16affc093 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -1841,57 +1841,108 @@
 })
 
 ;; Predicated integer operations.
-(define_insn "*cond_<optab><mode>"
-  [(set (match_operand:SVE_I 0 "register_operand" "=w")
+;; All other things being equal, prefer the patterns for which the
+;; destination matches the select input, as that gives us the most
+;; freedom to swap the other operands.
+
+(define_insn "*cond_<optab><mode>_0"
+  [(set (match_operand:SVE_I 0 "register_operand" "+w, w, ?&w")
        (unspec:SVE_I
-         [(match_operand:<VPRED> 1 "register_operand" "Upl")
+         [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
           (SVE_INT_BINARY:SVE_I
-            (match_operand:SVE_I 2 "register_operand" "0")
-            (match_operand:SVE_I 3 "register_operand" "w"))
-          (match_dup 2)]
+            (match_operand:SVE_I 2 "register_operand" "0, w, w")
+            (match_operand:SVE_I 3 "register_operand" "w, 0, w"))
+          (match_dup 0)]
          UNSPEC_SEL))]
   "TARGET_SVE"
-  "<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+  "@
+   <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+   <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+   movprfx\t%0, %1/m, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, 
%3.<Vetype>"
+  [(set_attr "movprfx" "*,*,yes")]
 )
 
-(define_insn "*cond_<optab><mode>"
-  [(set (match_operand:SVE_SDI 0 "register_operand" "=w")
+(define_insn "*cond_<optab><mode>_0"
+  [(set (match_operand:SVE_SDI 0 "register_operand" "+w, w, ?&w")
        (unspec:SVE_SDI
-         [(match_operand:<VPRED> 1 "register_operand" "Upl")
+         [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
           (SVE_INT_BINARY_SD:SVE_SDI
-            (match_operand:SVE_SDI 2 "register_operand" "0")
-            (match_operand:SVE_SDI 3 "register_operand" "w"))
-          (match_dup 2)]
+            (match_operand:SVE_SDI 2 "register_operand" "0, w, w")
+            (match_operand:SVE_SDI 3 "register_operand" "w, 0, w"))
+          (match_dup 0)]
          UNSPEC_SEL))]
   "TARGET_SVE"
-  "<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+  "@
+   <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+   <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+   movprfx\t%0, %1/m, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, 
%3.<Vetype>"
+  [(set_attr "movprfx" "*,*,yes")]
 )
 
-;; Predicated integer operations with the operands reversed.
-(define_insn "*cond_<optab><mode>"
-  [(set (match_operand:SVE_I 0 "register_operand" "=w")
+;; Predicated integer operations with select matching the first operand.
+(define_insn "*cond_<optab><mode>_2"
+  [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
        (unspec:SVE_I
-         [(match_operand:<VPRED> 1 "register_operand" "Upl")
-          (SVE_INT_BINARY_REV:SVE_I
-            (match_operand:SVE_I 2 "register_operand" "w")
-            (match_operand:SVE_I 3 "register_operand" "0"))
-          (match_dup 3)]
+         [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+          (SVE_INT_BINARY:SVE_I
+            (match_operand:SVE_I 2 "register_operand" "0, w")
+            (match_operand:SVE_I 3 "register_operand" "w, w"))
+          (match_dup 2)]
          UNSPEC_SEL))]
   "TARGET_SVE"
-  "<sve_int_op>r\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
+  "@
+   <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+   movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+  [(set_attr "movprfx" "*,yes")]
 )
 
-(define_insn "*cond_<optab><mode>"
-  [(set (match_operand:SVE_SDI 0 "register_operand" "=w")
+(define_insn "*cond_<optab><mode>_2"
+  [(set (match_operand:SVE_SDI 0 "register_operand" "=w, ?&w")
        (unspec:SVE_SDI
-         [(match_operand:<VPRED> 1 "register_operand" "Upl")
+         [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
           (SVE_INT_BINARY_SD:SVE_SDI
-            (match_operand:SVE_SDI 2 "register_operand" "w")
-            (match_operand:SVE_SDI 3 "register_operand" "0"))
+            (match_operand:SVE_SDI 2 "register_operand" "0, w")
+            (match_operand:SVE_SDI 3 "register_operand" "w, w"))
+          (match_dup 2)]
+         UNSPEC_SEL))]
+  "TARGET_SVE"
+  "@
+   <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+   movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+  [(set_attr "movprfx" "*,yes")]
+)
+
+;; Predicated integer operations with select matching the second operand.
+(define_insn "*cond_<optab><mode>_3"
+  [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+       (unspec:SVE_I
+         [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+          (SVE_INT_BINARY:SVE_I
+            (match_operand:SVE_I 2 "register_operand" "w, w")
+            (match_operand:SVE_I 3 "register_operand" "0, w"))
           (match_dup 3)]
          UNSPEC_SEL))]
   "TARGET_SVE"
-  "<sve_int_op>r\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
+  "@
+   <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+   movprfx\t%0, %3\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, 
%2.<Vetype>"
+  [(set_attr "movprfx" "*,yes")]
+)
+
+(define_insn "*cond_<optab><mode>_3"
+  [(set (match_operand:SVE_SDI 0 "register_operand" "=w, ?&w")
+       (unspec:SVE_SDI
+         [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+          (SVE_INT_BINARY_SD:SVE_SDI
+            (match_operand:SVE_SDI 2 "register_operand" "w, w")
+            (match_operand:SVE_SDI 3 "register_operand" "0, w"))
+          (match_dup 3)]
+         UNSPEC_SEL))]
+  "TARGET_SVE"
+  "@
+   <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+   movprfx\t%0, %3\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, 
%2.<Vetype>"
+  [(set_attr "movprfx" "*,yes")]
 )
 
 ;; Set operand 0 to the last active element in operand 3, or to tied
@@ -2687,34 +2738,60 @@
   aarch64_sve_prepare_conditional_op (operands, 5, <commutative>);
 })
 
-;; Predicated floating-point operations.
-(define_insn "*cond_<optab><mode>"
-  [(set (match_operand:SVE_F 0 "register_operand" "=w")
+;; Predicated floating-point operations with select matching output.
+(define_insn "*cond_<optab><mode>_0"
+  [(set (match_operand:SVE_F 0 "register_operand" "+w, w, ?&w")
        (unspec:SVE_F
-         [(match_operand:<VPRED> 1 "register_operand" "Upl")
+         [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
           (unspec:SVE_F
-            [(match_operand:SVE_F 2 "register_operand" "0")
-             (match_operand:SVE_F 3 "register_operand" "w")]
+            [(match_dup 1)
+             (match_operand:SVE_F 2 "register_operand" "0, w, w")
+             (match_operand:SVE_F 3 "register_operand" "w, 0, w")]
+            SVE_COND_FP_BINARY)
+          (match_dup 0)]
+         UNSPEC_SEL))]
+  "TARGET_SVE"
+  "@
+   <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+   <sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+   movprfx\t%0, %1/m, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, 
%3.<Vetype>"
+  [(set_attr "movprfx" "*,*,yes")]
+)
+
+;; Predicated floating-point operations with select matching first operand.
+(define_insn "*cond_<optab><mode>_2"
+  [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
+       (unspec:SVE_F
+         [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+          (unspec:SVE_F
+            [(match_operand:SVE_F 2 "register_operand" "0, w")
+             (match_operand:SVE_F 3 "register_operand" "w, w")]
             SVE_COND_FP_BINARY)
           (match_dup 2)]
          UNSPEC_SEL))]
   "TARGET_SVE"
-  "<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+  "@
+   <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+   movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+  [(set_attr "movprfx" "*,yes")]
 )
 
-;; Predicated floating-point operations with the operands reversed.
-(define_insn "*cond_<optab><mode>"
-  [(set (match_operand:SVE_F 0 "register_operand" "=w")
+;; Predicated floating-point operations with select matching second operand.
+(define_insn "*cond_<optab><mode>_3"
+  [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
        (unspec:SVE_F
-         [(match_operand:<VPRED> 1 "register_operand" "Upl")
+         [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
           (unspec:SVE_F
-            [(match_operand:SVE_F 2 "register_operand" "w")
-             (match_operand:SVE_F 3 "register_operand" "0")]
+            [(match_operand:SVE_F 2 "register_operand" "w, w")
+             (match_operand:SVE_F 3 "register_operand" "0, w")]
             SVE_COND_FP_BINARY)
           (match_dup 3)]
          UNSPEC_SEL))]
   "TARGET_SVE"
-  "<sve_fp_op>r\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
+  "@
+   <sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+   movprfx\t%0, %3\;<sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, 
%2.<Vetype>"
+  [(set_attr "movprfx" "*,yes")]
 )
 
 ;; Shift an SVE vector left and insert a scalar into element 0.
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index c5ef2eecf20..965dc6bf4f3 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -1207,11 +1207,11 @@
 ;; SVE floating-point unary operations.
 (define_code_iterator SVE_FP_UNARY [neg abs sqrt])
 
+;; SVE integer binary operations.
 (define_code_iterator SVE_INT_BINARY [plus minus mult smax umax smin umin
                                      and ior xor])
 
-(define_code_iterator SVE_INT_BINARY_REV [minus])
-
+;; SVE integer binary division operations.
 (define_code_iterator SVE_INT_BINARY_SD [div udiv])
 
 ;; SVE integer comparisons.
@@ -1402,6 +1402,19 @@
                              (not "not")
                              (popcount "cnt")])
 
+(define_code_attr sve_int_op_rev [(plus "add")
+                                 (minus "subr")
+                                 (mult "mul")
+                                 (div "sdivr")
+                                 (udiv "udivr")
+                                 (smin "smin")
+                                 (smax "smax")
+                                 (umin "umin")
+                                 (umax "umax")
+                                 (and "and")
+                                 (ior "orr")
+                                 (xor "eor")])
+
 ;; The floating-point SVE instruction that implements an rtx code.
 (define_code_attr sve_fp_op [(plus "fadd")
                             (neg "fneg")
@@ -1550,8 +1563,6 @@
                                         UNSPEC_COND_MUL UNSPEC_COND_DIV
                                         UNSPEC_COND_MAX UNSPEC_COND_MIN])
 
-(define_int_iterator SVE_COND_FP_BINARY_REV [UNSPEC_COND_SUB UNSPEC_COND_DIV])
-
 (define_int_iterator SVE_COND_FP_CMP [UNSPEC_COND_LT UNSPEC_COND_LE
                                      UNSPEC_COND_EQ UNSPEC_COND_NE
                                      UNSPEC_COND_GE UNSPEC_COND_GT])
@@ -1802,6 +1813,13 @@
                            (UNSPEC_COND_MAX "fmaxnm")
                            (UNSPEC_COND_MIN "fminnm")])
 
+(define_int_attr sve_fp_op_rev [(UNSPEC_COND_ADD "fadd")
+                               (UNSPEC_COND_SUB "fsubr")
+                               (UNSPEC_COND_MUL "fmul")
+                               (UNSPEC_COND_DIV "fdivr")
+                               (UNSPEC_COND_MAX "fmaxnm")
+                               (UNSPEC_COND_MIN "fminnm")])
+
 (define_int_attr commutative [(UNSPEC_COND_ADD "true")
                              (UNSPEC_COND_SUB "false")
                              (UNSPEC_COND_MUL "true")
-- 
2.17.1

Reply via email to