diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2020-01-21 18:22:38 +0000 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2020-01-22 14:33:19 +0000 |
commit | 7c46e71d016c86971ac26c6fa38d76482859f296 (patch) | |
tree | d9688d2364432c863c54b7e08635fa8e9dda8bba /gcc | |
parent | 7491c17fe01d8cf116f645532d46120029b26408 (diff) | |
download | gcc-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/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/sve/acle/general/stack_vars_1.c | 32 |
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; +} |