aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2024-06-07 12:15:31 +0200
committerRichard Biener <rguenther@suse.de>2024-06-10 08:27:25 +0200
commitc1429e3a8da0cdfe9391e1e9b2c7228d896a3a87 (patch)
treea098cb1f29664e374178d5f2a7c1464072e6360d
parenteb316013a7c841094577a57407f605b5a7ca5eee (diff)
downloadgcc-c1429e3a8da0cdfe9391e1e9b2c7228d896a3a87.zip
gcc-c1429e3a8da0cdfe9391e1e9b2c7228d896a3a87.tar.gz
gcc-c1429e3a8da0cdfe9391e1e9b2c7228d896a3a87.tar.bz2
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.
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr115383.c20
-rw-r--r--gcc/tree-vect-stmts.cc20
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 0000000..92c2469
--- /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 5098b7f..05a169e 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
{