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

Reply via email to