Message ID | 20240813124150.1168825-3-victor.donascimento@arm.com |
---|---|
State | New |
Headers | show |
Series | optabs: Make all `*dot_prod_optab's modeled as conversions | expand |
Hi Victor, > -----Original Message----- > From: Victor Do Nascimento <victor.donascimento@arm.com> > Sent: Tuesday, August 13, 2024 1:42 PM > To: gcc-patches@gcc.gnu.org > Cc: Tamar Christina <Tamar.Christina@arm.com>; claziss@gmail.com; > hongtao.liu@intel.com; syq@gcc.gnu.org; bernds_cb1@t-online.de; > aldyh@redhat.com; Victor Do Nascimento <Victor.DoNascimento@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
On 8/14/24 13:24, Tamar Christina wrote: > Hi Victor, > >> -----Original Message----- >> From: Victor Do Nascimento <victor.donascimento@arm.com> >> Sent: Tuesday, August 13, 2024 1:42 PM >> To: gcc-patches@gcc.gnu.org >> Cc: Tamar Christina <Tamar.Christina@arm.com>; claziss@gmail.com; >> hongtao.liu@intel.com; syq@gcc.gnu.org; bernds_cb1@t-online.de; >> aldyh@redhat.com; Victor Do Nascimento <Victor.DoNascimento@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. Darn, it seems I clearly missed the point of your feedback given in your previous review, with it having been seemingly overlooked upon my return from the summer break. > 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? Yes, there clearly is unnecessary code duplication we can do without and your approach does away with that quite nicely. The use of the code_helper also makes for an easily-implementable improvement over the current way of handling things. Thanks for taking the time to look over the code, greatly appreciated. Cheers, Victor > 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 >
On 8/14/24 13:24, Tamar Christina wrote:
> 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?
Ok. Having done some digging around in the git history, I see that
`vect_supportable_direct_optab_p', upon which I based my implementation
of `vect_supportable_conv_optab_p', was committed before you wrote the
`directly_supported_p' function, which I guess explains why
`vect_supportable_direct_optab_p' does not take advantage of the latter
function to avoid code duplication.
I'd wrongly presumed that we'd have been aware of the existence of
`directly_supported_p' when writing `vect_supportable_direct_optab_p',
such that any apparent code duplication would have been a conscious
choice by the author, thus making it a relevant design consideration in
my own implementation.
Anyway, will submit updated patch shortly.
Cheers,
Victor
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; +} + + /* 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))