On Wed, Aug 27, 2025 at 03:50:26PM +0200, Richard Biener wrote:
> Ah, thanks for the write-up how to compute the number of uses.
> 
> I'll test the following.
> --- a/gcc/tree-vect-patterns.cc
> +++ b/gcc/tree-vect-patterns.cc
> @@ -4303,6 +4303,8 @@ vect_synth_mult_by_constant (vec_info *vinfo, tree op, 
> tree val,
>    /* Targets that don't support vector shifts but support vector additions
>       can synthesize shifts that way.  */
>    bool synth_shift_p = !vect_supportable_shift (vinfo, LSHIFT_EXPR, 
> multtype);
> +  if (synth_shift_p)
> +    return NULL;

This is wrong, that will punt no matter what, for reductions/non-reductions,
and even when not really used.  Just the other hunk should do it.

Also, I'd probably do it only after the target_supports_mult_synth_alg
check, not before it.

>    HOST_WIDE_INT hwval = tree_to_shwi (val);
>    /* Use MAX_COST here as we don't want to limit the sequence on rtx costs.
> @@ -4314,6 +4316,35 @@ vect_synth_mult_by_constant (vec_info *vinfo, tree op, 
> tree val,
>    if (!possible)
>      return NULL;
>  
> +  if (vect_is_reduction (stmt_vinfo))
> +    {
> +      int op_uses = alg.op[0] != alg_zero;
> +      for (int i = 1; i < alg.ops; i++)
> +     switch (alg.op[i])
> +       {
> +       case alg_add_t_m2:
> +       case alg_sub_t_m2:
> +         if (synth_shift_p && alg.log[i])
> +           return NULL;
> +         else
> +           op_uses++;
> +         break;
> +       case alg_add_t2_m:
> +       case alg_sub_t2_m:
> +         op_uses++;
> +         break;
> +       default:
> +         break;
> +       }
> +      if (variant == add_variant)
> +     op_uses++;
> +      /* When we'll synthesize more than a single use of the reduction
> +      operand the reduction constraints are violated.  Avoid this
> +      situation.  */
> +      if (op_uses > 1)
> +     return NULL;
> +    }
> +
>    if (!target_supports_mult_synth_alg (&alg, variant, vectype, 
> synth_shift_p))
>      return NULL;
>  
> -- 
> 2.43.0

        Jakub

Reply via email to