https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121536

--- Comment #6 from rguenther at suse dot de <rguenther at suse dot de> ---
On Mon, 18 Aug 2025, tnfchris at gcc dot gnu.org wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121536
> 
> --- Comment #5 from Tamar Christina <tnfchris at gcc dot gnu.org> ---
> (In reply to rguent...@suse.de from comment #4)
> > On Thu, 14 Aug 2025, tnfchris at gcc dot gnu.org wrote:
> > 
> > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121536
> > > 
> > > --- Comment #3 from Tamar Christina <tnfchris at gcc dot gnu.org> ---
> > > Richi: g:fb59c5719c17a04ecfd58b5e566eccd6d2ac583a is problematic for us 
> > > because
> > > without the type we can't tell which one of our scalar register file the
> > > operation is working on.
> > > 
> > > e.g. a + b has different costing between int and float.
> > > 
> > > So we need either the GIMPLE statement of the type of the statement being
> > > costed otherwise we can't distinguish between them. e.g. just 
> > > `scalar_stmt`
> > > does not give us enough information.
> > 
> > See how x86 solves this issue:
> > 
> > unsigned
> > ix86_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind,
> >                                   stmt_vec_info stmt_info, slp_tree node,
> >                                   tree vectype, int,
> >                                   vect_cost_model_location where)
> > {
> >   unsigned retval = 0;
> >   bool scalar_p
> >     = (kind == scalar_stmt || kind == scalar_load || kind == 
> > scalar_store);
> >   int stmt_cost = - 1;
> > 
> >   bool fp = false;
> >   machine_mode mode = scalar_p ? SImode : TImode;
> > 
> >   if (vectype != NULL)
> >     {
> >       fp = FLOAT_TYPE_P (vectype);
> >       mode = TYPE_MODE (vectype);
> >       if (scalar_p)
> >         mode = TYPE_MODE (TREE_TYPE (vectype));
> >     }
> >   /* When we are costing a scalar stmt use the scalar stmt to get at the
> >      type of the operation.  */
> >   else if (scalar_p && stmt_info)
> >     if (tree lhs = gimple_get_lhs (stmt_info->stmt))
> >       {
> >         fp = FLOAT_TYPE_P (TREE_TYPE (lhs));
> >         mode = TYPE_MODE (TREE_TYPE (lhs));
> 
> Wrong costing hook, you're looking at the costing hook when comparing vector 
> vs
> scalar, not the one that sets the initial scalar cost.
> 
> x86 has the same problem here now:
> 
> #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
> #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
>   ix86_builtin_vectorization_cost
> 
> /* Implement targetm.vectorize.builtin_vectorization_cost.  */
> static int
> ix86_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
>                                  tree vectype, int)
> {
>   machine_mode mode = TImode;
>   if (vectype != NULL)
>     mode = TYPE_MODE (vectype);
>   return ix86_default_vector_cost (type_of_cost, mode);
> }
> 
> /* Worker for ix86_builtin_vectorization_cost and the fallback calls
>    from ix86_vector_costs::add_stmt_cost.  */
> static int
> ix86_default_vector_cost (enum vect_cost_for_stmt type_of_cost,
>                           machine_mode mode)
> {
>   bool fp = FLOAT_MODE_P (mode);
>   int index;
>   switch (type_of_cost)
>     {
>       case scalar_stmt:
>         return fp ? ix86_cost->addss : COSTS_N_INSNS (1);
> 
> ...
> 
> so exact same problem, TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST is no 
> longer
> able to distinguish between the scalar types.

That's a legacy hook, the x86 implementation is now in a worker that
takes a mode and ::add_stmt_cost invokes that worker rather than
the legacy hook.  I want to see the legacy hook go away, most
definitely for vector_stmt and scalar_stmt - there are the other
weird cases we use for prologue/epilogue.

Reply via email to