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.
This commit is contained in:
Richard Biener
2026-05-05 10:10:07 +02:00
committed by Richard Biener
parent 72fc51b1ac
commit 9d276bf057
2 changed files with 43 additions and 23 deletions

View File

@@ -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;
}
}

View 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)
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