On Thu, Aug 15, 2024 at 10:46 AM Victor Do Nascimento
<victor.donascime...@arm.com> wrote:
>
> 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.

OK.

> 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   | 33 +++++++++++++++++++++++++++++++--
>  5 files changed, 59 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..b5af2f001b1 100644
> --- a/gcc/tree-vect-patterns.cc
> +++ b/gcc/tree-vect-patterns.cc
> @@ -250,6 +250,35 @@ 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;
> +
> +  if (!directly_supported_p (code, vecotype, vecitype, subtype))
> +    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 +1299,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
>

Reply via email to