Hi Victor, > -----Original Message----- > From: Victor Do Nascimento <victor.donascime...@arm.com> > Sent: Tuesday, August 13, 2024 1:42 PM > To: gcc-patches@gcc.gnu.org > Cc: Tamar Christina <tamar.christ...@arm.com>; claz...@gmail.com; > hongtao....@intel.com; s...@gcc.gnu.org; bernds_...@t-online.de; > al...@redhat.com; Victor Do Nascimento <victor.donascime...@arm.com> > Subject: [PATCH V2 02/10] autovectorizer: Add basic support for convert optabs > > Given the shift from modeling dot products as direct optabs to > treating them as conversion optabs, we make necessary changes to the > autovectorizer code to ensure that given the relevant tree code, > together with the input and output data modes, we can retrieve the > relevant optab and subsequently the insn_code for it. > > gcc/ChangeLog: > > * gimple-match-exports.cc (directly_supported_p): Add overload > for conversion-type optabs. > * gimple-match.h (directly_supported_p): Add new function > prototype. > * optabs.cc (expand_widen_pattern_expr): Make the > DOT_PROD_EXPR tree code use `find_widening_optab_handler' to > retrieve icode. > * tree-vect-loop.cc (vect_is_emulated_mixed_dot_prod): make it > call conversion-type overloaded `directly_supported_p'. > * tree-vect-patterns.cc (vect_supportable_conv_optab_p): New. > (vect_recog_dot_prod_pattern): s/direct/conv/ in call to > `vect_supportable_direct_optab_p'. > --- > gcc/gimple-match-exports.cc | 23 ++++++++++++++++++++ > gcc/gimple-match.h | 2 ++ > gcc/optabs.cc | 3 ++- > gcc/tree-vect-loop.cc | 1 + > gcc/tree-vect-patterns.cc | 43 +++++++++++++++++++++++++++++++++++-- > 5 files changed, 69 insertions(+), 3 deletions(-) > > diff --git a/gcc/gimple-match-exports.cc b/gcc/gimple-match-exports.cc > index aacf3ff0414..d18497e7c83 100644 > --- a/gcc/gimple-match-exports.cc > +++ b/gcc/gimple-match-exports.cc > @@ -1381,6 +1381,29 @@ directly_supported_p (code_helper code, tree type, > optab_subtype query_type) > && direct_internal_fn_supported_p (ifn, type, OPTIMIZE_FOR_SPEED)); > } > > +/* As above, overloading the function for conversion-type optabs. */ > +bool > +directly_supported_p (code_helper code, tree type_out, tree type_in, > + optab_subtype query_type) > +{ > + if (code.is_tree_code ()) > + { > + convert_optab optab = optab_for_tree_code (tree_code (code), type_in, > + query_type); > + return (optab != unknown_optab > + && convert_optab_handler (optab, TYPE_MODE (type_out), > + TYPE_MODE (type_in)) != > CODE_FOR_nothing); > + } > + gcc_assert (query_type == optab_default > + || (query_type == optab_vector && VECTOR_TYPE_P (type_in)) > + || (query_type == optab_scalar && !VECTOR_TYPE_P (type_in))); > + internal_fn ifn = associated_internal_fn (combined_fn (code), type_in); > + return (direct_internal_fn_p (ifn) > + && direct_internal_fn_supported_p (ifn, tree_pair (type_out, type_in), > + OPTIMIZE_FOR_SPEED)); > +} > + > + > /* A wrapper around the internal-fn.cc versions of > get_conditional_internal_fn > for a code_helper CODE operating on type TYPE. */ > > diff --git a/gcc/gimple-match.h b/gcc/gimple-match.h > index d710fcbace2..0333a5db00a 100644 > --- a/gcc/gimple-match.h > +++ b/gcc/gimple-match.h > @@ -419,6 +419,8 @@ code_helper canonicalize_code (code_helper, tree); > > #ifdef GCC_OPTABS_TREE_H > bool directly_supported_p (code_helper, tree, optab_subtype = optab_default); > +bool directly_supported_p (code_helper, tree, tree, > + optab_subtype = optab_default); > #endif > > internal_fn get_conditional_internal_fn (code_helper, tree); > diff --git a/gcc/optabs.cc b/gcc/optabs.cc > index 185c5b1a705..32737fb80e8 100644 > --- a/gcc/optabs.cc > +++ b/gcc/optabs.cc > @@ -317,7 +317,8 @@ expand_widen_pattern_expr (const_sepops ops, rtx op0, > rtx op1, rtx wide_op, > widen_pattern_optab > = optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default); > if (ops->code == WIDEN_MULT_PLUS_EXPR > - || ops->code == WIDEN_MULT_MINUS_EXPR) > + || ops->code == WIDEN_MULT_MINUS_EXPR > + || ops->code == DOT_PROD_EXPR) > icode = find_widening_optab_handler (widen_pattern_optab, > TYPE_MODE (TREE_TYPE (ops->op2)), > tmode0); > diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc > index 6456220cdc9..5f3de7b72a8 100644 > --- a/gcc/tree-vect-loop.cc > +++ b/gcc/tree-vect-loop.cc > @@ -5289,6 +5289,7 @@ vect_is_emulated_mixed_dot_prod (stmt_vec_info > stmt_info) > > gcc_assert (STMT_VINFO_REDUC_VECTYPE_IN (stmt_info)); > return !directly_supported_p (DOT_PROD_EXPR, > + STMT_VINFO_VECTYPE (stmt_info), > STMT_VINFO_REDUC_VECTYPE_IN (stmt_info), > optab_vector_mixed_sign); > } > diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc > index f52de2b6972..3afedc9199b 100644 > --- a/gcc/tree-vect-patterns.cc > +++ b/gcc/tree-vect-patterns.cc > @@ -250,6 +250,45 @@ vect_supportable_direct_optab_p (vec_info *vinfo, tree > otype, tree_code code, > return true; > } > > +/* Return true if the target supports a vector version of CODE, > + where CODE is known to map to a conversion optab with the given SUBTYPE. > + ITYPE specifies the type of (some of) the scalar inputs and OTYPE > + specifies the type of the scalar result. > + > + When returning true, set *VECOTYPE_OUT to the vector version of OTYPE. > + Also set *VECITYPE_OUT to the vector version of ITYPE if VECITYPE_OUT > + is nonnull. */ > + > +static bool > +vect_supportable_conv_optab_p (vec_info *vinfo, tree otype, tree_code code, > + tree itype, tree *vecotype_out, > + tree *vecitype_out = NULL, > + enum optab_subtype subtype = optab_default) > +{ > + tree vecitype = get_vectype_for_scalar_type (vinfo, itype); > + tree vecotype = get_vectype_for_scalar_type (vinfo, otype); > + if (!vecitype || !vecotype) > + return false; > + > + optab optab = optab_for_tree_code (code, vecitype, subtype); > + if (!optab) > + return false; > + > + insn_code icode = convert_optab_handler (optab, TYPE_MODE (vecotype), > + TYPE_MODE (vecitype)); > + > + if (icode == CODE_FOR_nothing > + || insn_data[icode].operand[0].mode != TYPE_MODE (vecotype) > + || insn_data[icode].operand[1].mode != TYPE_MODE (vecitype)) > + return false; > + > + *vecotype_out = vecotype; > + if (vecitype_out) > + *vecitype_out = vecitype; > + return true; > +}
You never responded to the previous review for this change, so I have the same question. You've now added directly_supported_p which takes a convert optab and calls convert_optab_handler Which checks both mode. So why does this function not use it? It seems to be doing duplicate work and limits itself unnecessarily to tree_code. It seems to me that this should take a code_helper, create the vector modes and call directly_supported_p, or am I missing something? Thanks, Tamar > + > + > /* Round bit precision PRECISION up to a full element. */ > > static unsigned int > @@ -1270,13 +1309,13 @@ vect_recog_dot_prod_pattern (vec_info *vinfo, > half_type = signed_type_for (half_type); > > tree half_vectype; > - if (!vect_supportable_direct_optab_p (vinfo, type, DOT_PROD_EXPR, > half_type, > + if (!vect_supportable_conv_optab_p (vinfo, type, DOT_PROD_EXPR, half_type, > type_out, &half_vectype, subtype)) > { > /* We can emulate a mixed-sign dot-product using a sequence of > signed dot-products; see vect_emulate_mixed_dot_prod for details. */ > if (subtype != optab_vector_mixed_sign > - || !vect_supportable_direct_optab_p (vinfo, signed_type_for (type), > + || !vect_supportable_conv_optab_p (vinfo, signed_type_for (type), > DOT_PROD_EXPR, half_type, > type_out, &half_vectype, > optab_vector)) > -- > 2.34.1