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