tree-optimization/109473 - ICE with reduction epilog adjustment op

Message ID 20230412102406.9F5BC3858C83@sourceware.org
State Repeat Merge
Headers
Series tree-optimization/109473 - ICE with reduction epilog adjustment op |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Richard Biener April 12, 2023, 10:23 a.m. UTC
  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
  

Patch

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);