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