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.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
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 | 27 +++++++++++++++++++++++++++
gcc/tree-vect-loop.cc | 27 ++++++++-------------------
2 files changed, 35 insertions(+), 19 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/vect/pr115395.c
diff --git a/gcc/testsuite/gcc.dg/vect/pr115395.c
b/gcc/testsuite/gcc.dg/vect/pr115395.c
new file mode 100644
index 00000000000..cd1cee9f3df
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr115395.c
@@ -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;
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index f598403df46..d894ac1c067 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -6047,25 +6047,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;
@@ -6890,7 +6879,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)
{
--
2.35.3