* 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