tree-optimization/109473 - ICE with reduction epilog adjustment op
authorRichard Biener <rguenther@suse.de>
Wed, 12 Apr 2023 08:22:08 +0000 (10:22 +0200)
committerRichard Biener <rguenther@suse.de>
Wed, 12 Apr 2023 09:31:28 +0000 (11:31 +0200)
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.

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 [new file with mode: 0644]
gcc/tree-vect-loop.cc

diff --git a/gcc/testsuite/gcc.dg/vect/pr109473.c b/gcc/testsuite/gcc.dg/vect/pr109473.c
new file mode 100644 (file)
index 0000000..9dee551
--- /dev/null
@@ -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;
+    }
+}
index 1ba9f18..ba28214 100644 (file)
@@ -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);