diff mbox series

tree-optimization/115383 - EXTRACT_LAST_REDUCTION with multiple stmt copies

Message ID 20240607101930.338BD133F3@imap1.dmz-prg2.suse.org
State New
Headers show
Series tree-optimization/115383 - EXTRACT_LAST_REDUCTION with multiple stmt copies | expand

Commit Message

Richard Biener June 7, 2024, 10:19 a.m. UTC
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.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Testing on aarch64 appreciated, note the testcase in the testsuite
likely doesn't exercise .FOLD_EXTRACT_LAST with default opts,
the PR asks for a SVE capable CPU but fixed-length vectorization.

	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.
---
 gcc/testsuite/gcc.dg/vect/pr115383.c | 20 ++++++++++++++++++++
 gcc/tree-vect-stmts.cc               | 20 +++++++++++++++-----
 2 files changed, 35 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/vect/pr115383.c
diff mbox series

Patch

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 69ba906a33f..0a76e81a0ea 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -12413,6 +12413,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)
     {
@@ -12555,17 +12558,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
 	    {