aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-11-01 08:54:22 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-11-01 08:54:22 +0000
commita9b76c8962410173ba0351b5b05b5f1f91742fc6 (patch)
tree15cc0b6bcadb90da797eecab3ad626c487496ade
parent6e0cb45f0c11d30f03498039b2f650ead28658bd (diff)
downloadgcc-a9b76c8962410173ba0351b5b05b5f1f91742fc6.zip
gcc-a9b76c8962410173ba0351b5b05b5f1f91742fc6.tar.gz
gcc-a9b76c8962410173ba0351b5b05b5f1f91742fc6.tar.bz2
Prevent invalid register mode changes in combine
This patch stops combine from changing the mode of an existing register in-place if doing so would change the size of the underlying register allocation size, as given by REGMODE_NATURAL_SIZE. Without this, many tests fail in adjust_reg_mode after SVE is added. One example is gcc.c-torture/compile/20090401-1.c. 2017-11-01 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * combine.c (can_change_dest_mode): Reject changes in REGMODE_NATURAL_SIZE. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r254291
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/combine.c6
2 files changed, 13 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4c65319..1886218 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2017-11-01 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
+ * combine.c (can_change_dest_mode): Reject changes in
+ REGMODE_NATURAL_SIZE.
+
2017-10-31 Sandra Loosemore <sandra@codesourcery.com>
* configure.ac (--enable-libssp): New.
diff --git a/gcc/combine.c b/gcc/combine.c
index 93adfc1..4afae21 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -2478,6 +2478,12 @@ can_change_dest_mode (rtx x, int added_sets, machine_mode mode)
!= REGMODE_NATURAL_SIZE (GET_MODE (x)))
return false;
+ /* Don't change between modes with different underlying register sizes,
+ since this could lead to invalid subregs. */
+ if (REGMODE_NATURAL_SIZE (mode)
+ != REGMODE_NATURAL_SIZE (GET_MODE (x)))
+ return false;
+
regno = REGNO (x);
/* Allow hard registers if the new mode is legal, and occupies no more
registers than the old mode. */