The reorg showed that we had an unnecessary separation between the bitwise and max/min reductions for integers, and the addition and max/min reductions for fp.
Tested on aarch64-linux-gnu (with and without SVE) and aarch64_be-elf. Applied as r274190. Richard 2019-08-07 Richard Sandiford <richard.sandif...@arm.com> gcc/ * config/aarch64/iterators.md (BITWISEV): Delete. (SVE_INT_REDUCTION, SVE_FP_REDUCTION): New int iterators. (optab): Handle UNSPEC_UMAXV, UNSPEC_UMINV, UNSPEC_SMAXV, UNSPEC_SMINV, UNSPEC_FADDV, UNSPEC_FMAXNMV, UNSPEC_FMAXV, UNSPEC_FMINNMV, UNSPEC_FMINV. (bit_reduc_op): Delete. (sve_int_op): New int attribute. (sve_fp_op): Handle UNSPEC_FADDV, UNSPEC_FMAXNMV, UNSPEC_FMAXV, UNSPEC_FMINNMV, UNSPEC_FMINV. * config/aarch64/aarch64-sve.md (reduc_<MAXMINV:maxmin_uns>_scal_<SVE_I:mode>) (*reduc_<MAXMINV:maxmin_uns>_scal_<SVE_I:mode>) (reduc_<BITWISEV:optab>_scal_<SVE_I:mode>) (*reduc_<BITWISEV:optab>_scal_<SVE_I:mode>): Merge into... (reduc_<SVE_INT_REDUCTION:optab>_scal_<SVE_I:mode>) (*reduc_<SVE_INT_REDUCTION:optab>_scal_<SVE_I:mode>): ...these new patterns. (reduc_plus_scal_<SVE_F:mode>, *reduc_plus_scal_<SVE_I:mode>) (reduc_<FMAXMINV:optab>_scal_<SVE_F:mode>) (*reduc_<FMAXMINV:optab>_scal_<SVE_F:mode>): Merge into... (reduc_<SVE_FP_REDUCTION:optab>_scal_<SVE_F:mode>) (*reduc_<SVE_FP_REDUCTION:optab>_scal_<SVE_F:mode>): ...these new patterns. Index: gcc/config/aarch64/iterators.md =================================================================== --- gcc/config/aarch64/iterators.md 2019-08-07 19:56:41.377879110 +0100 +++ gcc/config/aarch64/iterators.md 2019-08-07 20:03:03.667034750 +0100 @@ -1501,8 +1501,6 @@ (define_int_iterator MAXMINV [UNSPEC_UMA (define_int_iterator FMAXMINV [UNSPEC_FMAXV UNSPEC_FMINV UNSPEC_FMAXNMV UNSPEC_FMINNMV]) -(define_int_iterator BITWISEV [UNSPEC_ANDV UNSPEC_IORV UNSPEC_XORV]) - (define_int_iterator LOGICALF [UNSPEC_ANDF UNSPEC_IORF UNSPEC_XORF]) (define_int_iterator HADDSUB [UNSPEC_SHADD UNSPEC_UHADD @@ -1612,6 +1610,20 @@ (define_int_iterator UNPACK_UNSIGNED [UN (define_int_iterator MUL_HIGHPART [UNSPEC_SMUL_HIGHPART UNSPEC_UMUL_HIGHPART]) +(define_int_iterator SVE_INT_REDUCTION [UNSPEC_ANDV + UNSPEC_IORV + UNSPEC_SMAXV + UNSPEC_SMINV + UNSPEC_UMAXV + UNSPEC_UMINV + UNSPEC_XORV]) + +(define_int_iterator SVE_FP_REDUCTION [UNSPEC_FADDV + UNSPEC_FMAXV + UNSPEC_FMAXNMV + UNSPEC_FMINV + UNSPEC_FMINNMV]) + (define_int_iterator SVE_COND_FP_UNARY [UNSPEC_COND_FABS UNSPEC_COND_FNEG UNSPEC_COND_FRINTA @@ -1682,6 +1694,15 @@ (define_int_attr optab [(UNSPEC_ANDF "an (UNSPEC_ANDV "and") (UNSPEC_IORV "ior") (UNSPEC_XORV "xor") + (UNSPEC_UMAXV "umax") + (UNSPEC_UMINV "umin") + (UNSPEC_SMAXV "smax") + (UNSPEC_SMINV "smin") + (UNSPEC_FADDV "plus") + (UNSPEC_FMAXNMV "smax") + (UNSPEC_FMAXV "smax_nan") + (UNSPEC_FMINNMV "smin") + (UNSPEC_FMINV "smin_nan") (UNSPEC_COND_FABS "abs") (UNSPEC_COND_FADD "add") (UNSPEC_COND_FDIV "div") @@ -1731,10 +1752,6 @@ (define_int_attr maxmin_uns_op [(UNSPEC (UNSPEC_FMAXNM "fmaxnm") (UNSPEC_FMINNM "fminnm")]) -(define_int_attr bit_reduc_op [(UNSPEC_ANDV "andv") - (UNSPEC_IORV "orv") - (UNSPEC_XORV "eorv")]) - ;; The SVE logical instruction that implements an unspec. (define_int_attr logicalf_op [(UNSPEC_ANDF "and") (UNSPEC_IORF "orr") @@ -1932,7 +1949,20 @@ (define_int_attr cmp_op [(UNSPEC_COND_FC (UNSPEC_COND_FCMLT "lt") (UNSPEC_COND_FCMNE "ne")]) -(define_int_attr sve_fp_op [(UNSPEC_COND_FABS "fabs") +(define_int_attr sve_int_op [(UNSPEC_ANDV "andv") + (UNSPEC_IORV "orv") + (UNSPEC_XORV "eorv") + (UNSPEC_UMAXV "umaxv") + (UNSPEC_UMINV "uminv") + (UNSPEC_SMAXV "smaxv") + (UNSPEC_SMINV "sminv")]) + +(define_int_attr sve_fp_op [(UNSPEC_FADDV "faddv") + (UNSPEC_FMAXNMV "fmaxnmv") + (UNSPEC_FMAXV "fmaxv") + (UNSPEC_FMINNMV "fminnmv") + (UNSPEC_FMINV "fminv") + (UNSPEC_COND_FABS "fabs") (UNSPEC_COND_FADD "fadd") (UNSPEC_COND_FDIV "fdiv") (UNSPEC_COND_FMAXNM "fmaxnm") Index: gcc/config/aarch64/aarch64-sve.md =================================================================== --- gcc/config/aarch64/aarch64-sve.md 2019-08-07 20:01:33.967702013 +0100 +++ gcc/config/aarch64/aarch64-sve.md 2019-08-07 20:03:03.667034750 +0100 @@ -3152,46 +3152,26 @@ (define_insn "*reduc_plus_scal_<mode>" "uaddv\t%d0, %1, %2.<Vetype>" ) -;; Unpredicated integer MAX/MIN reduction. -(define_expand "reduc_<maxmin_uns>_scal_<mode>" - [(set (match_operand:<VEL> 0 "register_operand") - (unspec:<VEL> [(match_dup 2) - (match_operand:SVE_I 1 "register_operand")] - MAXMINV))] - "TARGET_SVE" - { - operands[2] = aarch64_ptrue_reg (<VPRED>mode); - } -) - -;; Predicated integer MAX/MIN reduction. -(define_insn "*reduc_<maxmin_uns>_scal_<mode>" - [(set (match_operand:<VEL> 0 "register_operand" "=w") - (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl") - (match_operand:SVE_I 2 "register_operand" "w")] - MAXMINV))] - "TARGET_SVE" - "<maxmin_uns_op>v\t%<Vetype>0, %1, %2.<Vetype>" -) - +;; Unpredicated integer reductions. (define_expand "reduc_<optab>_scal_<mode>" [(set (match_operand:<VEL> 0 "register_operand") (unspec:<VEL> [(match_dup 2) (match_operand:SVE_I 1 "register_operand")] - BITWISEV))] + SVE_INT_REDUCTION))] "TARGET_SVE" { operands[2] = aarch64_ptrue_reg (<VPRED>mode); } ) +;; Predicated integer reductions. (define_insn "*reduc_<optab>_scal_<mode>" [(set (match_operand:<VEL> 0 "register_operand" "=w") (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl") (match_operand:SVE_I 2 "register_operand" "w")] - BITWISEV))] + SVE_INT_REDUCTION))] "TARGET_SVE" - "<bit_reduc_op>\t%<Vetype>0, %1, %2.<Vetype>" + "<sve_int_op>\t%<Vetype>0, %1, %2.<Vetype>" ) ;; ------------------------------------------------------------------------- @@ -3205,48 +3185,26 @@ (define_insn "*reduc_<optab>_scal_<mode> ;; - FMINV ;; ------------------------------------------------------------------------- -;; Unpredicated floating-point add reduction. -(define_expand "reduc_plus_scal_<mode>" - [(set (match_operand:<VEL> 0 "register_operand") - (unspec:<VEL> [(match_dup 2) - (match_operand:SVE_F 1 "register_operand")] - UNSPEC_FADDV))] - "TARGET_SVE" - { - operands[2] = aarch64_ptrue_reg (<VPRED>mode); - } -) - -;; Predicated floating-point add reduction. -(define_insn "*reduc_plus_scal_<mode>" - [(set (match_operand:<VEL> 0 "register_operand" "=w") - (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl") - (match_operand:SVE_F 2 "register_operand" "w")] - UNSPEC_FADDV))] - "TARGET_SVE" - "faddv\t%<Vetype>0, %1, %2.<Vetype>" -) - -;; Unpredicated floating-point MAX/MIN reduction. -(define_expand "reduc_<maxmin_uns>_scal_<mode>" +;; Unpredicated floating-point tree reductions. +(define_expand "reduc_<optab>_scal_<mode>" [(set (match_operand:<VEL> 0 "register_operand") (unspec:<VEL> [(match_dup 2) (match_operand:SVE_F 1 "register_operand")] - FMAXMINV))] + SVE_FP_REDUCTION))] "TARGET_SVE" { operands[2] = aarch64_ptrue_reg (<VPRED>mode); } ) -;; Predicated floating-point MAX/MIN reduction. -(define_insn "*reduc_<maxmin_uns>_scal_<mode>" +;; Predicated floating-point tree reductions. +(define_insn "*reduc_<optab>_scal_<mode>" [(set (match_operand:<VEL> 0 "register_operand" "=w") (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl") (match_operand:SVE_F 2 "register_operand" "w")] - FMAXMINV))] + SVE_FP_REDUCTION))] "TARGET_SVE" - "<maxmin_uns_op>v\t%<Vetype>0, %1, %2.<Vetype>" + "<sve_fp_op>\t%<Vetype>0, %1, %2.<Vetype>" ) ;; -------------------------------------------------------------------------