Add an "else" argument to IFN_COND_* functions
Richard Biener
richard.guenther@gmail.com
Thu May 24 10:17:00 GMT 2018
On Thu, May 24, 2018 at 10:37 AM Richard Sandiford <
richard.sandiford@linaro.org> wrote:
> As suggested by Richard B, this patch changes the IFN_COND_*
> functions so that they take the else value of the ?: operation
> as a final argument, rather than always using argument 1.
> All current callers will still use the equivalent of argument 1,
> so this patch makes the SVE code assert that for now. Later patches
> add the general case.
> This relies on the earlier "Try harder to preserve operand ties in
> maybe_legitimize_operands"
> https://gcc.gnu.org/ml/gcc-patches/2018-05/msg01199.html
> Tested on aarch64-linux-gnu (with and without SVE), aarch64_be-elf
> and x86_64-linux-gnu. OK for the non-AArch64 bits?
OK.
Thanks,
Richard.
> Thanks,
> Richard
> 2018-05-24 Richard Sandiford <richard.sandiford@linaro.org>
> gcc/
> * doc/md.texi: Update the documentation of the cond_* optabs
> to mention the new final operand. Fix GET_MODE_NUNITS call.
> Describe the scalar case too.
> * internal-fn.def (IFN_EXTRACT_LAST): Change type to fold_left.
> * internal-fn.c (expand_cond_unary_optab_fn): Expect 3 operands
> instead of 2.
> (expand_cond_binary_optab_fn): Expect 4 operands instead of 3.
> (get_conditional_internal_fn): Update comment.
> * tree-vect-loop.c (vectorizable_reduction): Pass the original
> accumulator value as a final argument to conditional functions.
> * config/aarch64/aarch64-sve.md (cond_<optab><mode>): Turn into
> a define_expand and add an "else" operand. Assert for now that
> the else operand is equal to operand 2. Use SVE_INT_BINARY and
> SVE_COND_FP_BINARY instead of SVE_COND_INT_OP and SVE_COND_FP_OP.
> (*cond_<optab><mode>): New patterns.
> * config/aarch64/iterators.md (UNSPEC_COND_SMAX, UNSPEC_COND_UMAX)
> (UNSPEC_COND_SMIN, UNSPEC_COND_UMIN, UNSPEC_COND_AND,
UNSPEC_COND_ORR)
> (UNSPEC_COND_EOR): Delete.
> (optab): Remove associated mappings.
> (SVE_INT_BINARY): New code iterator.
> (sve_int_op): Remove int attribute and add "minus" to the code
> attribute.
> (SVE_COND_INT_OP): Delete.
> (SVE_COND_FP_OP): Rename to...
> (SVE_COND_FP_BINARY): ...this.
> Index: gcc/doc/md.texi
> ===================================================================
> --- gcc/doc/md.texi 2018-05-24 09:31:46.687834412 +0100
> +++ gcc/doc/md.texi 2018-05-24 09:32:10.522816506 +0100
> @@ -6349,13 +6349,21 @@ operand 0, otherwise (operand 2 + operan
> @itemx @samp{cond_smax@var{mode}}
> @itemx @samp{cond_umin@var{mode}}
> @itemx @samp{cond_umax@var{mode}}
> -Perform an elementwise operation on vector operands 2 and 3,
> -under the control of the vector mask in operand 1, and store the result
> -in operand 0. This is equivalent to:
> +When operand 1 is true, perform an operation on operands 2 and 3 and
> +store the result in operand 0, otherwise store operand 4 in operand 0.
> +The operation works elementwise if the operands are vectors.
> +
> +The scalar case is equivalent to:
> +
> +@smallexample
> +op0 = op1 ? op2 @var{op} op3 : op4;
> +@end smallexample
> +
> +while the vector case is equivalent to:
> @smallexample
> -for (i = 0; i < GET_MODE_NUNITS (@var{n}); i++)
> - op0[i] = op1[i] ? op2[i] @var{op} op3[i] : op2[i];
> +for (i = 0; i < GET_MODE_NUNITS (@var{m}); i++)
> + op0[i] = op1[i] ? op2[i] @var{op} op3[i] : op4[i];
> @end smallexample
> where, for example, @var{op} is @code{+} for @samp{cond_add@var{mode}}.
> @@ -6364,8 +6372,9 @@ When defined for floating-point modes, t
> are not interpreted if @var{op1[i]} is false, just like they would not
> be in a normal C @samp{?:} condition.
> -Operands 0, 2 and 3 all have mode @var{m}, while operand 1 has the mode
> -returned by @code{TARGET_VECTORIZE_GET_MASK_MODE}.
> +Operands 0, 2, 3 and 4 all have mode @var{m}. Operand 1 is a scalar
> +integer if @var{m} is scalar, otherwise it has the mode returned by
> +@code{TARGET_VECTORIZE_GET_MASK_MODE}.
> @cindex @code{neg@var{mode}cc} instruction pattern
> @item @samp{neg@var{mode}cc}
> Index: gcc/internal-fn.def
> ===================================================================
> --- gcc/internal-fn.def 2018-05-24 09:31:46.687834412 +0100
> +++ gcc/internal-fn.def 2018-05-24 09:32:10.522816506 +0100
> @@ -173,7 +173,7 @@ DEF_INTERNAL_OPTAB_FN (REDUC_XOR, ECF_CO
> /* Extract the last active element from a vector. */
> DEF_INTERNAL_OPTAB_FN (EXTRACT_LAST, ECF_CONST | ECF_NOTHROW,
> - extract_last, cond_unary)
> + extract_last, fold_left)
> /* Same, but return the first argument if no elements are active. */
> DEF_INTERNAL_OPTAB_FN (FOLD_EXTRACT_LAST, ECF_CONST | ECF_NOTHROW,
> Index: gcc/internal-fn.c
> ===================================================================
> --- gcc/internal-fn.c 2018-05-24 09:31:46.687834412 +0100
> +++ gcc/internal-fn.c 2018-05-24 09:32:10.522816506 +0100
> @@ -2988,10 +2988,10 @@ #define expand_ternary_optab_fn(FN, STMT
> expand_direct_optab_fn (FN, STMT, OPTAB, 3)
> #define expand_cond_unary_optab_fn(FN, STMT, OPTAB) \
> - expand_direct_optab_fn (FN, STMT, OPTAB, 2)
> + expand_direct_optab_fn (FN, STMT, OPTAB, 3)
> #define expand_cond_binary_optab_fn(FN, STMT, OPTAB) \
> - expand_direct_optab_fn (FN, STMT, OPTAB, 3)
> + expand_direct_optab_fn (FN, STMT, OPTAB, 4)
> #define expand_fold_extract_optab_fn(FN, STMT, OPTAB) \
> expand_direct_optab_fn (FN, STMT, OPTAB, 3)
> @@ -3219,12 +3219,19 @@ #define DEF_INTERNAL_FN(CODE, FLAGS, FNS
> 0
> };
> -/* Return a function that performs the conditional form of CODE, i.e.:
> +/* Return a function that only performs CODE when a certain condition is
met
> + and that uses a given fallback value otherwise. For example, if CODE
is
> + a binary operation associated with conditional function FN:
> +
> + LHS = FN (COND, A, B, ELSE)
> +
> + is equivalent to the C expression:
> +
> + LHS = COND ? A CODE B : ELSE;
> - LHS = RHS1 ? RHS2 CODE RHS3 : RHS2
> + operating elementwise if the operands are vectors.
> - (operating elementwise if the operands are vectors). Return IFN_LAST
> - if no such function exists. */
> + Return IFN_LAST if no such function exists. */
> internal_fn
> get_conditional_internal_fn (tree_code code)
> Index: gcc/tree-vect-loop.c
> ===================================================================
> --- gcc/tree-vect-loop.c 2018-05-24 09:31:46.687834412 +0100
> +++ gcc/tree-vect-loop.c 2018-05-24 09:32:10.523816456 +0100
> @@ -7222,8 +7222,9 @@ vectorizable_reduction (gimple *stmt, gi
> }
> tree mask = vect_get_loop_mask (gsi, masks, vec_num *
ncopies,
> vectype_in, i * ncopies +
j);
> - gcall *call = gimple_build_call_internal (cond_fn, 3, mask,
> - vop[0], vop[1]);
> + gcall *call = gimple_build_call_internal (cond_fn, 4, mask,
> + vop[0], vop[1],
> + vop[0]);
> new_temp = make_ssa_name (vec_dest, call);
> gimple_call_set_lhs (call, new_temp);
> gimple_call_set_nothrow (call, true);
> Index: gcc/config/aarch64/aarch64-sve.md
> ===================================================================
> --- gcc/config/aarch64/aarch64-sve.md 2018-05-24 09:32:03.433159783
+0100
> +++ gcc/config/aarch64/aarch64-sve.md 2018-05-24 09:32:10.521816556
+0100
> @@ -1787,14 +1787,31 @@ (define_insn "*<maxmin_uns><mode>3"
> "<maxmin_uns_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
> )
> +;; Predicated integer operations with select.
> +(define_expand "cond_<optab><mode>"
> + [(set (match_operand:SVE_I 0 "register_operand")
> + (unspec:SVE_I
> + [(match_operand:<VPRED> 1 "register_operand")
> + (SVE_INT_BINARY:SVE_I
> + (match_operand:SVE_I 2 "register_operand")
> + (match_operand:SVE_I 3 "register_operand"))
> + (match_operand:SVE_I 4 "register_operand")]
> + UNSPEC_SEL))]
> + "TARGET_SVE"
> +{
> + gcc_assert (rtx_equal_p (operands[2], operands[4]));
> +})
> +
> ;; Predicated integer operations.
> -(define_insn "cond_<optab><mode>"
> +(define_insn "*cond_<optab><mode>"
> [(set (match_operand:SVE_I 0 "register_operand" "=w")
> (unspec:SVE_I
> [(match_operand:<VPRED> 1 "register_operand" "Upl")
> - (match_operand:SVE_I 2 "register_operand" "0")
> - (match_operand:SVE_I 3 "register_operand" "w")]
> - SVE_COND_INT_OP))]
> + (SVE_INT_BINARY:SVE_I
> + (match_operand:SVE_I 2 "register_operand" "0")
> + (match_operand:SVE_I 3 "register_operand" "w"))
> + (match_dup 2)]
> + UNSPEC_SEL))]
> "TARGET_SVE"
> "<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
> )
> @@ -2566,14 +2583,35 @@ (define_expand "vec_pack_<su>fix_trunc_v
> }
> )
> +;; Predicated floating-point operations with select.
> +(define_expand "cond_<optab><mode>"
> + [(set (match_operand:SVE_F 0 "register_operand")
> + (unspec:SVE_F
> + [(match_operand:<VPRED> 1 "register_operand")
> + (unspec:SVE_F
> + [(match_dup 1)
> + (match_operand:SVE_F 2 "register_operand")
> + (match_operand:SVE_F 3 "register_operand")]
> + SVE_COND_FP_BINARY)
> + (match_operand:SVE_F 4 "register_operand")]
> + UNSPEC_SEL))]
> + "TARGET_SVE"
> +{
> + gcc_assert (rtx_equal_p (operands[2], operands[4]));
> +})
> +
> ;; Predicated floating-point operations.
> -(define_insn "cond_<optab><mode>"
> +(define_insn "*cond_<optab><mode>"
> [(set (match_operand:SVE_F 0 "register_operand" "=w")
> (unspec:SVE_F
> [(match_operand:<VPRED> 1 "register_operand" "Upl")
> - (match_operand:SVE_F 2 "register_operand" "0")
> - (match_operand:SVE_F 3 "register_operand" "w")]
> - SVE_COND_FP_OP))]
> + (unspec:SVE_F
> + [(match_dup 1)
> + (match_operand:SVE_F 2 "register_operand" "0")
> + (match_operand:SVE_F 3 "register_operand" "w")]
> + SVE_COND_FP_BINARY)
> + (match_dup 2)]
> + UNSPEC_SEL))]
> "TARGET_SVE"
> "<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
> )
> Index: gcc/config/aarch64/iterators.md
> ===================================================================
> --- gcc/config/aarch64/iterators.md 2018-05-24 09:32:03.433159783
+0100
> +++ gcc/config/aarch64/iterators.md 2018-05-24 09:32:10.521816556
+0100
> @@ -464,13 +464,6 @@ (define_c_enum "unspec"
> UNSPEC_UMUL_HIGHPART ; Used in aarch64-sve.md.
> UNSPEC_COND_ADD ; Used in aarch64-sve.md.
> UNSPEC_COND_SUB ; Used in aarch64-sve.md.
> - UNSPEC_COND_SMAX ; Used in aarch64-sve.md.
> - UNSPEC_COND_UMAX ; Used in aarch64-sve.md.
> - UNSPEC_COND_SMIN ; Used in aarch64-sve.md.
> - UNSPEC_COND_UMIN ; Used in aarch64-sve.md.
> - UNSPEC_COND_AND ; Used in aarch64-sve.md.
> - UNSPEC_COND_ORR ; Used in aarch64-sve.md.
> - UNSPEC_COND_EOR ; Used in aarch64-sve.md.
> UNSPEC_COND_LT ; Used in aarch64-sve.md.
> UNSPEC_COND_LE ; Used in aarch64-sve.md.
> UNSPEC_COND_EQ ; Used in aarch64-sve.md.
> @@ -1207,6 +1200,9 @@ (define_code_iterator SVE_INT_UNARY [neg
> ;; SVE floating-point unary operations.
> (define_code_iterator SVE_FP_UNARY [neg abs sqrt])
> +(define_code_iterator SVE_INT_BINARY [plus minus smax umax smin umin
> + and ior xor])
> +
> (define_code_iterator SVE_INT_BINARY_SD [div udiv])
> ;; SVE integer comparisons.
> @@ -1381,6 +1377,7 @@ (define_mode_attr lconst_atomic [(QI "K"
> ;; The integer SVE instruction that implements an rtx code.
> (define_code_attr sve_int_op [(plus "add")
> + (minus "sub")
> (div "sdiv")
> (udiv "udiv")
> (neg "neg")
> @@ -1538,14 +1535,7 @@ (define_int_iterator UNPACK_UNSIGNED [UN
> (define_int_iterator MUL_HIGHPART [UNSPEC_SMUL_HIGHPART
UNSPEC_UMUL_HIGHPART])
> -(define_int_iterator SVE_COND_INT_OP [UNSPEC_COND_ADD UNSPEC_COND_SUB
> - UNSPEC_COND_SMAX UNSPEC_COND_UMAX
> - UNSPEC_COND_SMIN UNSPEC_COND_UMIN
> - UNSPEC_COND_AND
> - UNSPEC_COND_ORR
> - UNSPEC_COND_EOR])
> -
> -(define_int_iterator SVE_COND_FP_OP [UNSPEC_COND_ADD UNSPEC_COND_SUB])
> +(define_int_iterator SVE_COND_FP_BINARY [UNSPEC_COND_ADD
UNSPEC_COND_SUB])
> (define_int_iterator SVE_COND_FP_CMP [UNSPEC_COND_LT UNSPEC_COND_LE
> UNSPEC_COND_EQ UNSPEC_COND_NE
> @@ -1575,14 +1565,7 @@ (define_int_attr optab [(UNSPEC_ANDF "an
> (UNSPEC_IORV "ior")
> (UNSPEC_XORV "xor")
> (UNSPEC_COND_ADD "add")
> - (UNSPEC_COND_SUB "sub")
> - (UNSPEC_COND_SMAX "smax")
> - (UNSPEC_COND_UMAX "umax")
> - (UNSPEC_COND_SMIN "smin")
> - (UNSPEC_COND_UMIN "umin")
> - (UNSPEC_COND_AND "and")
> - (UNSPEC_COND_ORR "ior")
> - (UNSPEC_COND_EOR "xor")])
> + (UNSPEC_COND_SUB "sub")])
> (define_int_attr maxmin_uns [(UNSPEC_UMAXV "umax")
> (UNSPEC_UMINV "umin")
> @@ -1793,15 +1776,5 @@ (define_int_attr cmp_op [(UNSPEC_COND_LT
> (UNSPEC_COND_GE "ge")
> (UNSPEC_COND_GT "gt")])
> -(define_int_attr sve_int_op [(UNSPEC_COND_ADD "add")
> - (UNSPEC_COND_SUB "sub")
> - (UNSPEC_COND_SMAX "smax")
> - (UNSPEC_COND_UMAX "umax")
> - (UNSPEC_COND_SMIN "smin")
> - (UNSPEC_COND_UMIN "umin")
> - (UNSPEC_COND_AND "and")
> - (UNSPEC_COND_ORR "orr")
> - (UNSPEC_COND_EOR "eor")])
> -
> (define_int_attr sve_fp_op [(UNSPEC_COND_ADD "fadd")
> (UNSPEC_COND_SUB "fsub")])
More information about the Gcc-patches
mailing list