combine.c (try_combine): When changing the mode of a hard reg, make sure that doing...
authorBernd Schmidt <bernd.schmidt@analog.com>
Sat, 19 Mar 2005 15:01:45 +0000 (15:01 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Sat, 19 Mar 2005 15:01:45 +0000 (15:01 +0000)
* combine.c (try_combine): When changing the mode of a hard reg, make
sure that doing so is valid.

From-SVN: r96730

gcc/ChangeLog
gcc/combine.c

index c6f64c141f4210e19ec6a697062ba04d7f0883cb..c55ed73260e85581106f207cd23e9eb799c66ff3 100644 (file)
@@ -1,3 +1,8 @@
+2005-03-19  Bernd Schmidt  <bernd.schmidt@analog.com>
+
+       * combine.c (try_combine): When changing the mode of a hard reg, make
+       sure that doing so is valid.
+
 2005-03-19  Richard Sandiford  <rsandifo@redhat.com>
 
        * config/avr/avr.c (avr_init_stack, avr_mcu_name): Make static.
index d6ec6ac69c3ed2c54b48c8c5bde821a5b5548128..87a2f8dc1cfc49b7174df8f3bf9be98f3ff6de01 100644 (file)
@@ -2373,11 +2373,17 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
          && REG_P (i2dest)
 #endif
          /* We need I2DEST in the proper mode.  If it is a hard register
-            or the only use of a pseudo, we can change its mode.  */
+            or the only use of a pseudo, we can change its mode.
+            Make sure we don't change a hard register to have a mode that
+            isn't valid for it, or change the number of registers.  */
          && (GET_MODE (*split) == GET_MODE (i2dest)
              || GET_MODE (*split) == VOIDmode
-             || REGNO (i2dest) < FIRST_PSEUDO_REGISTER
-             || (REG_N_SETS (REGNO (i2dest)) == 1 && ! added_sets_2
+             || (REGNO (i2dest) < FIRST_PSEUDO_REGISTER
+                 && HARD_REGNO_MODE_OK (REGNO (i2dest), GET_MODE (*split))
+                 && (HARD_REGNO_NREGS (REGNO (i2dest), GET_MODE (i2dest))
+                     == HARD_REGNO_NREGS (REGNO (i2dest), GET_MODE (*split))))
+             || (REGNO (i2dest) >= FIRST_PSEUDO_REGISTER
+                 && REG_N_SETS (REGNO (i2dest)) == 1 && ! added_sets_2
                  && ! REG_USERVAR_P (i2dest)))
          && (next_real_insn (i2) == i3
              || ! use_crosses_set_p (*split, INSN_CUID (i2)))