https://gcc.gnu.org/g:d718835414482b7b2b9d622ddb64ac66fbeafb19
commit r16-6893-gd718835414482b7b2b9d622ddb64ac66fbeafb19 Author: Jakub Jelinek <[email protected]> Date: Mon Jan 19 09:46:36 2026 +0100 vect-generic: Fix up expand_vector_mult [PR123656] 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. 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. Diff: --- gcc/testsuite/gcc.dg/pr123656.c | 21 +++++++++++++++++++++ gcc/tree-vect-generic.cc | 6 +++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/gcc/testsuite/gcc.dg/pr123656.c b/gcc/testsuite/gcc.dg/pr123656.c new file mode 100644 index 000000000000..98439857c49a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr123656.c @@ -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 (); +} diff --git a/gcc/tree-vect-generic.cc b/gcc/tree-vect-generic.cc index d34d2c5fa48d..77066bbb2e1b 100644 --- a/gcc/tree-vect-generic.cc +++ b/gcc/tree-vect-generic.cc @@ -643,9 +643,9 @@ expand_vector_mult (gimple_stmt_iterator *gsi, tree type, tree op0, 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 *gsi, tree type, tree op0, 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 ();
