aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2020-01-21 18:22:38 +0000
committerRichard Sandiford <richard.sandiford@arm.com>2020-01-22 14:33:19 +0000
commit7c46e71d016c86971ac26c6fa38d76482859f296 (patch)
treed9688d2364432c863c54b7e08635fa8e9dda8bba /gcc
parent7491c17fe01d8cf116f645532d46120029b26408 (diff)
downloadgcc-7c46e71d016c86971ac26c6fa38d76482859f296.zip
gcc-7c46e71d016c86971ac26c6fa38d76482859f296.tar.gz
gcc-7c46e71d016c86971ac26c6fa38d76482859f296.tar.bz2
cfgexpand: Update partition size when merging variables
cfgexpand sorts variables by decreasing size, so when merging a later variable into an earlier one, there's usually no need to update the merged size. But for poly_int sizes, the sort function just uses a lexicographical comparison of the coefficients, so e.g. 2X+2 comes before 0X+32. Which is bigger depends on the runtime value of X. This patch therefore takes the upper bound of the two sizes, which is conservatively correct for variable-length vectors and a no-op on other targets. It's probably a bad idea to merge fixed-length and variable-length variables in practice, but that's really an optimisation decision. I think we should have this patch as a correctness fix either way. This is easiest to test using the ACLE, but in principle it could happen for autovectorised code too, e.g. when using OpenMP vector variables. It's therefore a regression from GCC 8. 2020-01-22 Richard Sandiford <richard.sandiford@arm.com> gcc/ * cfgexpand.c (union_stack_vars): Update the size. gcc/testsuite/ * gcc.target/aarch64/sve/acle/general/stack_vars_1.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/cfgexpand.c3
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/general/stack_vars_1.c32
4 files changed, 43 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2f229b9..272968a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,7 @@
+2020-01-22 Richard Sandiford <richard.sandiford@arm.com>
+
+ * cfgexpand.c (union_stack_vars): Update the size.
+
2020-01-22 Richard Biener <rguenther@suse.de>
PR tree-optimization/93381
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index fb0575b1..9864e43 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -862,6 +862,9 @@ union_stack_vars (size_t a, size_t b)
stack_vars[b].representative = a;
stack_vars[a].next = b;
+ /* Make sure A is big enough to hold B. */
+ stack_vars[a].size = upper_bound (stack_vars[a].size, stack_vars[b].size);
+
/* Update the required alignment of partition A to account for B. */
if (stack_vars[a].alignb < stack_vars[b].alignb)
stack_vars[a].alignb = stack_vars[b].alignb;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3bd6407..d22747b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2020-01-22 Richard Sandiford <richard.sandiford@arm.com>
+ * gcc.target/aarch64/sve/acle/general/stack_vars_1.c: New test.
+
+2020-01-22 Richard Sandiford <richard.sandiford@arm.com>
+
* gcc.target/aarch64/sve/tls_preserve_1.c: Require tls_native.
* gcc.target/aarch64/sve/tls_preserve_2.c: Likewise.
* gcc.target/aarch64/sve/tls_preserve_3.c: Likewise.
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/stack_vars_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/stack_vars_1.c
new file mode 100644
index 0000000..860fa67f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/stack_vars_1.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-additional-options "-O2" } */
+
+#include <arm_sve.h>
+
+struct s { int x[32]; };
+
+void __attribute__((noipa)) consume (void *ptr) {}
+
+void __attribute__((noipa))
+check_var (svint32_t *ptr)
+{
+ svbool_t pg = svptrue_b8 ();
+ if (svptest_any (pg, svcmpne (pg, *ptr, svindex_s32 (0, 1))))
+ __builtin_abort ();
+}
+
+int
+main (void)
+{
+ svint32_t res = svindex_s32 (0, 1);
+ {
+ __SVBool_t pg = svptrue_b8 ();
+ consume (&pg);
+ }
+ {
+ struct s zeros = { 0 };
+ consume (&zeros);
+ }
+ check_var (&res);
+ return 0;
+}