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.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
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_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
--
2.51.0