https://gcc.gnu.org/g:27b8544e08922d4625a4e2787bd00f36af13d12f
commit r16-8886-g27b8544e08922d4625a4e2787bd00f36af13d12f Author: Richard Biener <[email protected]> Date: Tue May 5 10:10:07 2026 +0200 tree-optimization/125185 - fix ICE with associating DOT_PROD_EXPR 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. (cherry picked from commit 9d276bf057459de93ba304cdf780dbff3882491e) Diff: --- gcc/testsuite/gcc.dg/torture/pr125185.c | 13 ++++++++ gcc/tree-vect-slp.cc | 53 +++++++++++++++++++-------------- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/gcc/testsuite/gcc.dg/torture/pr125185.c b/gcc/testsuite/gcc.dg/torture/pr125185.c new file mode 100644 index 000000000000..370cc0139e4b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr125185.c @@ -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; + } +} diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index aeb8ebeda1d6..c114c5d6175e 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -4281,32 +4281,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. */ @@ -4336,7 +4343,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
