]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/115395 - wrong-code with SLP reduction in epilog
authorRichard Biener <rguenther@suse.de>
Mon, 10 Jun 2024 08:12:52 +0000 (10:12 +0200)
committerRichard Biener <rguenther@suse.de>
Mon, 10 Jun 2024 09:38:41 +0000 (11:38 +0200)
When we continue a non-SLP reduction from the main loop in the
epilog with a SLP reduction we currently fail to handle an
adjustment by the initial value because that's not a thing with SLP.
As long as we have the possibility to mix SLP and non-SLP we have
to handle it though.

PR tree-optimization/115395
* tree-vect-loop.cc (vect_create_epilog_for_reduction):
Handle STMT_VINFO_REDUC_EPILOGUE_ADJUSTMENT also for SLP
reductions of group_size one.

* gcc.dg/vect/pr115395.c: New testcase.

gcc/testsuite/gcc.dg/vect/pr115395.c [new file with mode: 0644]
gcc/tree-vect-loop.cc

diff --git a/gcc/testsuite/gcc.dg/vect/pr115395.c b/gcc/testsuite/gcc.dg/vect/pr115395.c
new file mode 100644 (file)
index 0000000..cd1cee9
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-additional-options "-mavx2" { target avx2_runtime } } */
+
+#include "tree-vect.h"
+
+struct {
+  long header_size;
+  long start_offset;
+  long end_offset;
+} myrar_dbo[5] = {{0, 87, 6980}, {0, 7087, 13980}, {0, 14087, 0}};
+
+int i;
+long offset;
+
+int main()
+{
+  check_vect ();
+
+  offset += myrar_dbo[0].start_offset;
+  while (i < 2) {
+    i++;
+    offset += myrar_dbo[i].start_offset - myrar_dbo[i - 1].end_offset;
+  }
+  if (offset != 301)
+    abort();
+
+  return 0;
+}
index 028692614bbcd8fcdf2acff31753eae02af50d7c..c471f1564a72f019170f3cfab1270d6bbb70efd2 100644 (file)
@@ -6030,25 +6030,14 @@ vect_create_epilog_for_reduction (loop_vec_info loop_vinfo,
 
   tree induc_val = NULL_TREE;
   tree adjustment_def = NULL;
-  if (slp_node)
-    {
-      /* Optimize: for induction condition reduction, if we can't use zero
-        for induc_val, use initial_def.  */
-      if (STMT_VINFO_REDUC_TYPE (reduc_info) == INTEGER_INDUC_COND_REDUCTION)
-       induc_val = STMT_VINFO_VEC_INDUC_COND_INITIAL_VAL (reduc_info);
-      /* ???  Coverage for 'else' isn't clear.  */
-    }
+  /* Optimize: for induction condition reduction, if we can't use zero
+     for induc_val, use initial_def.  */
+  if (STMT_VINFO_REDUC_TYPE (reduc_info) == INTEGER_INDUC_COND_REDUCTION)
+    induc_val = STMT_VINFO_VEC_INDUC_COND_INITIAL_VAL (reduc_info);
+  else if (double_reduc)
+    ;
   else
-    {
-      /* Optimize: for induction condition reduction, if we can't use zero
-         for induc_val, use initial_def.  */
-      if (STMT_VINFO_REDUC_TYPE (reduc_info) == INTEGER_INDUC_COND_REDUCTION)
-       induc_val = STMT_VINFO_VEC_INDUC_COND_INITIAL_VAL (reduc_info);
-      else if (double_reduc)
-       ;
-      else
-       adjustment_def = STMT_VINFO_REDUC_EPILOGUE_ADJUSTMENT (reduc_info);
-    }
+    adjustment_def = STMT_VINFO_REDUC_EPILOGUE_ADJUSTMENT (reduc_info);
 
   stmt_vec_info single_live_out_stmt[] = { stmt_info };
   array_slice<const stmt_vec_info> live_out_stmts = single_live_out_stmt;
@@ -6873,7 +6862,7 @@ vect_create_epilog_for_reduction (loop_vec_info loop_vinfo,
 
   if (adjustment_def)
     {
-      gcc_assert (!slp_reduc);
+      gcc_assert (!slp_reduc || group_size == 1);
       gimple_seq stmts = NULL;
       if (double_reduc)
        {