summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-04-12 10:22:08 +0200
committerRichard Biener <rguenther@suse.de>2023-04-12 11:31:28 +0200
commitdf7f55cb2ae550adeda339a57b657ebe1ad39367 (patch)
treea39baaef47641c9471cbb52814cb84ed93e8d139
parent2273fd5a6fdbe8f7da2c0e217c279bcbaaa7df9e (diff)
downloadgcc-df7f55cb2ae550adeda339a57b657ebe1ad39367.tar.gz
tree-optimization/109473 - ICE with reduction epilog adjustment op
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.
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr109473.c16
-rw-r--r--gcc/tree-vect-loop.cc7
2 files changed, 21 insertions, 2 deletions
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);