Hi! The alg_sub_factor handling in expand_vector_mult had the arguments reversed. As documented in expmed.h, the algorithms should be These are the operations: alg_zero total := 0; alg_m total := multiplicand; alg_shift total := total * coeff alg_add_t_m2 total := total + multiplicand * coeff; alg_sub_t_m2 total := total - multiplicand * coeff; alg_add_factor total := total * coeff + total; alg_sub_factor total := total * coeff - total; alg_add_t2_m total := total * coeff + multiplicand; alg_sub_t2_m total := total * coeff - multiplicand; The first operand must be either alg_zero or alg_m. */ So, alg_sub_factor should be identical to alg_sub_t2_m with the difference that one subtracts accumulator and the other subtracts op0. I went through all the other ones and they seem to match the description except for alg_sub_factor and tree-vect-patterns.cc seems to be fully correct. expand_vector_mult at times has pretty random order of PLUS_EXPR arguments, but that is a commutative operation, so makes no difference.
Furthermore, I saw weird formatting in the alg_add_t_m2 case, so fixed that too. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2026-01-19 Jakub Jelinek <[email protected]> PR tree-optimization/123656 * tree-vect-generic.cc (expand_vector_mult): Fix up alg_sub_factor handling. Fix up formatting in alg_add_t_m2 handling. * gcc.dg/pr123656.c: New test. --- gcc/tree-vect-generic.cc.jj 2026-01-12 12:39:40.467100902 +0100 +++ gcc/tree-vect-generic.cc 2026-01-18 20:31:20.976023238 +0100 @@ -643,9 +643,9 @@ expand_vector_mult (gimple_stmt_iterator LSHIFT_EXPR); break; case alg_add_t_m2: - tmp_var = add_shift (gsi, vectype, op0, shifts, LSHIFT_EXPR); + tmp_var = add_shift (gsi, vectype, op0, shifts, LSHIFT_EXPR); accumulator = gimplify_build2 (gsi, PLUS_EXPR, vectype, tmp_var, - accumulator); + accumulator); break; case alg_sub_t_m2: tmp_var = add_shift (gsi, vectype, op0, shifts, LSHIFT_EXPR); @@ -674,7 +674,7 @@ expand_vector_mult (gimple_stmt_iterator tmp_var = add_shift (gsi, vectype, accumulator, shifts, LSHIFT_EXPR); accumulator = gimplify_build2 (gsi, MINUS_EXPR, vectype, - accumulator, tmp_var); + tmp_var, accumulator); break; default: gcc_unreachable (); --- gcc/testsuite/gcc.dg/pr123656.c.jj 2026-01-18 20:35:49.807429350 +0100 +++ gcc/testsuite/gcc.dg/pr123656.c 2026-01-18 20:35:29.796771300 +0100 @@ -0,0 +1,21 @@ +/* PR tree-optimization/123656 */ +/* { dg-do run } */ +/* { dg-options "-Og -Wno-psabi" } */ + +#define C 210 + +typedef __attribute__((__vector_size__ (2))) unsigned char V; + +V +foo (V v) +{ + return v * C; +} + +int +main () +{ + V x = foo ((V) {1, 1}); + if (x[0] != C || x[1] != C) + __builtin_abort (); +} Jakub
