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 ();

Reply via email to