The following makes sure to carry out the reduction epilog adjustment in the original computation type which for pointers is an unsigned integer type. There's a similar issue with signed vs. unsigned ops and overflow which is fixed by this as well.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. PR tree-optimization/109473 * tree-vect-loop.cc (vect_create_epilog_for_reduction): Convert scalar result to the computation type before performing the reduction adjustment. * gcc.dg/vect/pr109473.c: New testcase. --- gcc/testsuite/gcc.dg/vect/pr109473.c | 16 ++++++++++++++++ gcc/tree-vect-loop.cc | 7 +++++-- 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr109473.c diff --git a/gcc/testsuite/gcc.dg/vect/pr109473.c b/gcc/testsuite/gcc.dg/vect/pr109473.c new file mode 100644 index 00000000000..9dee5515dc6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr109473.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O" } */ + +struct spa_buffer { + __UINT32_TYPE__ *metas; +}; +void do_port_use_buffers(struct spa_buffer **buffers, void *endptr, void *mem) +{ + for (int i = 0; i < 128; i++) + { + for (int j = 0; j < 128; j++) + endptr = (void *)((__UINTPTR_TYPE__)endptr + buffers[i]->metas[j]); + if (endptr > mem) + return; + } +} diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 1ba9f18d73e..ba28214f09a 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -6297,9 +6297,12 @@ vect_create_epilog_for_reduction (loop_vec_info loop_vinfo, { new_temp = scalar_results[0]; gcc_assert (TREE_CODE (TREE_TYPE (adjustment_def)) != VECTOR_TYPE); - adjustment_def = gimple_convert (&stmts, scalar_type, adjustment_def); - new_temp = gimple_build (&stmts, code, scalar_type, + adjustment_def = gimple_convert (&stmts, TREE_TYPE (vectype), + adjustment_def); + new_temp = gimple_convert (&stmts, TREE_TYPE (vectype), new_temp); + new_temp = gimple_build (&stmts, code, TREE_TYPE (vectype), new_temp, adjustment_def); + new_temp = gimple_convert (&stmts, scalar_type, new_temp); } epilog_stmt = gimple_seq_last_stmt (stmts); -- 2.35.3