]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/125185 - fix ICE with associating DOT_PROD_EXPR
authorRichard Biener <rguenther@suse.de>
Tue, 5 May 2026 08:10:07 +0000 (10:10 +0200)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 5 May 2026 09:23:32 +0000 (11:23 +0200)
When trying to discover a SLP reduction chain we eventually feed
non-binary associatable stmts to vect_slp_linearize_chain which
isn't prepared for that.  Don't.

PR tree-optimization/125185
* tree-vect-slp.cc (vect_analyze_slp_reduc_chain): Guard
first vect_slp_linearize_chain call.

* gcc.dg/torture/pr125185.c: New testcase.

gcc/testsuite/gcc.dg/torture/pr125185.c [new file with mode: 0644]
gcc/tree-vect-slp.cc

diff --git a/gcc/testsuite/gcc.dg/torture/pr125185.c b/gcc/testsuite/gcc.dg/torture/pr125185.c
new file mode 100644 (file)
index 0000000..370cc01
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-ftree-vectorize" } */
+/* { dg-additional-options "-mxop" { target { x86_64-*-* || i?86-*-* } } } */
+
+long sum;
+int *coef1;
+
+void ac3_sum_square_butterfly_int32_c(int i, int cap) {
+  for (; i < cap; i++) {
+    int md = i + coef1[i];
+    sum += (long)md * md;
+  }
+}
index 40ddae3526b16e0cf9cb6c8a3ff2d7dc65cab1eb..7be8ca037633bfff2395e5f4dc7ae77e779ecf6c 100644 (file)
@@ -4356,32 +4356,39 @@ vect_analyze_slp_reduc_chain (loop_vec_info vinfo,
       auto_vec<chain_op_t> chain;
       auto_vec<std::pair<tree_code, gimple *> > worklist;
       gimple *op_stmt = NULL, *other_op_stmt = NULL;
-      vect_slp_linearize_chain (vinfo, worklist, chain, (tree_code)code,
-                               scalar_stmts[0]->stmt, op_stmt, other_op_stmt,
-                               NULL);
-
-      scalar_stmts.truncate (0);
-      stmt_vec_info tail = NULL;
-      for (auto el : chain)
+      if (is_a <gassign *> (scalar_stmts[0]->stmt)
+         /* We cannot linearize an operation that vect_slp_linearize_chain
+            would not put on its worklist.  */
+         && gimple_assign_rhs_code (scalar_stmts[0]->stmt) == (tree_code)code)
        {
-         if (el.dt == vect_external_def
-             || el.dt == vect_constant_def
-             || el.code != (tree_code) code)
-           {
-             scalar_stmts.release ();
-             return false;
-           }
-         stmt_vec_info stmt = vinfo->lookup_def (el.op);
-         if (STMT_VINFO_REDUC_IDX (stmt) != -1
-             || STMT_VINFO_REDUC_DEF (stmt))
+         vect_slp_linearize_chain (vinfo, worklist, chain, (tree_code)code,
+                                   scalar_stmts[0]->stmt, op_stmt,
+                                   other_op_stmt,
+                                   NULL);
+
+         scalar_stmts.truncate (0);
+         stmt_vec_info tail = NULL;
+         for (auto el : chain)
            {
-             gcc_assert (tail == NULL);
-             tail = stmt;
-             continue;
+             if (el.dt == vect_external_def
+                 || el.dt == vect_constant_def
+                 || el.code != (tree_code) code)
+               {
+                 scalar_stmts.release ();
+                 return false;
+               }
+             stmt_vec_info stmt = vinfo->lookup_def (el.op);
+             if (STMT_VINFO_REDUC_IDX (stmt) != -1
+                 || STMT_VINFO_REDUC_DEF (stmt))
+               {
+                 gcc_assert (tail == NULL);
+                 tail = stmt;
+                 continue;
+               }
+             scalar_stmts.safe_push (stmt);
            }
-         scalar_stmts.safe_push (stmt);
+         gcc_assert (tail);
        }
-      gcc_assert (tail);
 
       /* When this linearization didn't produce a chain see if stripping
         a wrapping sign conversion produces one.  */
@@ -4411,7 +4418,7 @@ vect_analyze_slp_reduc_chain (loop_vec_info vinfo,
                                    stmt, op_stmt, other_op_stmt, NULL);
 
          scalar_stmts.truncate (0);
-         tail = NULL;
+         stmt_vec_info tail = NULL;
          for (auto el : chain)
            {
              if (el.dt == vect_external_def