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