From 9d276bf057459de93ba304cdf780dbff3882491e Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 5 May 2026 10:10:07 +0200 Subject: [PATCH] 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. --- gcc/testsuite/gcc.dg/torture/pr125185.c | 13 ++++++ gcc/tree-vect-slp.cc | 53 ++++++++++++++----------- 2 files changed, 43 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr125185.c diff --git a/gcc/testsuite/gcc.dg/torture/pr125185.c b/gcc/testsuite/gcc.dg/torture/pr125185.c new file mode 100644 index 00000000000..370cc0139e4 --- /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 40ddae3526b..7be8ca03763 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -4356,32 +4356,39 @@ vect_analyze_slp_reduc_chain (loop_vec_info vinfo, auto_vec chain; auto_vec > 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 (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) + 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) { - scalar_stmts.release (); - return false; + 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); } - 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); + 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