Prevent invalid register mode changes in combine
authorRichard Sandiford <richard.sandiford@linaro.org>
Fri, 13 Oct 2017 09:58:23 +0000 (09:58 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 13 Oct 2017 09:58:23 +0000 (09:58 +0000)
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-10-13  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: r253717

gcc/ChangeLog
gcc/combine.c

index 0e29ae8a95d363c7e8e7b80f2a2d0e02e3ec0c09..3b897e2dde741535068086fa58600dbd346aba88 100644 (file)
@@ -1,3 +1,10 @@
+2017-10-13  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-13  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index aa246e67babd1128b60fdad2449ef624a78e3d1c..3b96d86bdb3711aa2923440e1f8dadf5486bfb2c 100644 (file)
@@ -2475,6 +2475,12 @@ can_change_dest_mode (rtx x, int added_sets, machine_mode mode)
   if (!REG_P (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.  */