https://gcc.gnu.org/g:c1429e3a8da0cdfe9391e1e9b2c7228d896a3a87
commit r15-1126-gc1429e3a8da0cdfe9391e1e9b2c7228d896a3a87 Author: Richard Biener <rguent...@suse.de> Date: Fri Jun 7 12:15:31 2024 +0200 tree-optimization/115383 - EXTRACT_LAST_REDUCTION with multiple stmt copies The EXTRACT_LAST_REDUCTION code isn't ready to deal with multiple stmt copies but SLP no longer checks for this. The following adjusts code generation to handle the situation. PR tree-optimization/115383 * tree-vect-stmts.cc (vectorizable_condition): Handle generating a chain of .FOLD_EXTRACT_LAST. * gcc.dg/vect/pr115383.c: New testcase. Diff: --- gcc/testsuite/gcc.dg/vect/pr115383.c | 20 ++++++++++++++++++++ gcc/tree-vect-stmts.cc | 20 +++++++++++++++----- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/gcc/testsuite/gcc.dg/vect/pr115383.c b/gcc/testsuite/gcc.dg/vect/pr115383.c new file mode 100644 index 00000000000..92c24699146 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr115383.c @@ -0,0 +1,20 @@ +#include "tree-vect.h" + +int __attribute__((noipa)) +s331 (int i, int n) +{ + int j = 0; + for (; i < n; i++) + if ((float)i < 0.) + j = i; + return j; +} + +int main() +{ + check_vect (); + int j = s331(-13, 17); + if (j != -1) + abort (); + return 0; +} diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 5098b7fab6a..05a169ecb2d 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -12415,6 +12415,9 @@ vectorizable_condition (vec_info *vinfo, reduction_type != EXTRACT_LAST_REDUCTION ? else_clause : NULL, vectype, &vec_oprnds3); + if (reduction_type == EXTRACT_LAST_REDUCTION) + vec_else_clause = else_clause; + /* Arguments are ready. Create the new vector stmt. */ FOR_EACH_VEC_ELT (vec_oprnds0, i, vec_cond_lhs) { @@ -12557,17 +12560,24 @@ vectorizable_condition (vec_info *vinfo, { gimple *old_stmt = vect_orig_stmt (stmt_info)->stmt; tree lhs = gimple_get_lhs (old_stmt); + if ((unsigned)i != vec_oprnds0.length () - 1) + lhs = copy_ssa_name (lhs); if (len) new_stmt = gimple_build_call_internal - (IFN_LEN_FOLD_EXTRACT_LAST, 5, else_clause, vec_compare, - vec_then_clause, len, bias); + (IFN_LEN_FOLD_EXTRACT_LAST, 5, vec_else_clause, vec_compare, + vec_then_clause, len, bias); else new_stmt = gimple_build_call_internal - (IFN_FOLD_EXTRACT_LAST, 3, else_clause, vec_compare, - vec_then_clause); + (IFN_FOLD_EXTRACT_LAST, 3, vec_else_clause, vec_compare, + vec_then_clause); gimple_call_set_lhs (new_stmt, lhs); SSA_NAME_DEF_STMT (lhs) = new_stmt; - if (old_stmt == gsi_stmt (*gsi)) + if ((unsigned)i != vec_oprnds0.length () - 1) + { + vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi); + vec_else_clause = lhs; + } + else if (old_stmt == gsi_stmt (*gsi)) vect_finish_replace_stmt (vinfo, stmt_info, new_stmt); else {