The following adjusts the SLP build for only-live stmts to not only consider vect_induction_def and vect_internal_def that are not part of a reduction but instead consider all non-reduction defs that are not part of a reduction, specifically in this case a recurrence def. This is also a missed optimization on the gcc-15 branch (but IMO a very minor one).
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. PR tree-optimization/121686 * tree-vect-slp.cc (vect_analyze_slp): Consider all only-live non-reduction defs for discovery. * gcc.dg/vect/pr121686.c: New testcase. --- gcc/testsuite/gcc.dg/vect/pr121686.c | 32 ++++++++++++++++++++++++++++ gcc/tree-vect-slp.cc | 5 ++--- 2 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr121686.c diff --git a/gcc/testsuite/gcc.dg/vect/pr121686.c b/gcc/testsuite/gcc.dg/vect/pr121686.c new file mode 100644 index 00000000000..5a9284c3d31 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr121686.c @@ -0,0 +1,32 @@ +/* { dg-additional-options "-O3" } */ + +#include "tree-vect.h" + +signed char a, b, c, f; +int d, e, g, h; + +int main() +{ + int j, k; + signed char m; + check_vect (); + while (f < 4) { + k = b = 3; + for (; b >= 0; b--) { + j = a < 0 ? a : a >> h; + g = k; + e = j; + k = 0; + while (1) { + if (j) + break; + k = f == 0; + break; + } + } + m = g * 87; + if (m < 70) + __builtin_abort(); + return 0; + } +} diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index 2df9d2b3c6d..86508e22f49 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -5312,9 +5312,8 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size, && ((stmt_info = vect_stmt_to_vectorize (stmt_info)), true) && STMT_VINFO_RELEVANT (stmt_info) == vect_used_only_live && STMT_VINFO_LIVE_P (stmt_info) - && (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def - || (STMT_VINFO_DEF_TYPE (stmt_info) == vect_internal_def - && STMT_VINFO_REDUC_IDX (stmt_info) == -1))) + && !VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info)) + && STMT_VINFO_REDUC_IDX (stmt_info) == -1) { vec<stmt_vec_info> stmts; vec<stmt_vec_info> roots = vNULL; -- 2.43.0