reload.c (find_dummy_reload): Don't use OUT as a reload reg for IN if it overlaps...
authorRichard Earnshaw <rearnsha@arm.com>
Fri, 14 Sep 2012 17:02:04 +0000 (17:02 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Fri, 14 Sep 2012 17:02:04 +0000 (17:02 +0000)
* reload.c (find_dummy_reload): Don't use OUT as a reload reg
for IN if it overlaps a fixed register.

From-SVN: r191305

gcc/ChangeLog
gcc/reload.c

index 847b12089d97379d2ec41d162768e7139f57dbe3..cbe531ad86f3e4f16dce86e3ef037449c767eeeb 100644 (file)
@@ -1,3 +1,8 @@
+2012-09-14  Richard Earnshaw  <rearnsha@arm.com>
+
+       * reload.c (find_dummy_reload): Don't use OUT as a reload reg
+       for IN if it overlaps a fixed register.
+
 2012-09-14  Eric Botcazou  <ebotcazou@adacore.com>
 
        PR rtl-optimization/44194
index f4f3ed03d859fb59a251cc3bfc32fe592d041b2d..2e41ed6498e6a394dc01c6c4ed3d1f6df6da6ec6 100644 (file)
@@ -2036,7 +2036,12 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
         However, we only ignore IN in its role as this reload.
         If the insn uses IN elsewhere and it contains OUT,
         that counts.  We can't be sure it's the "same" operand
-        so it might not go through this reload.  */
+        so it might not go through this reload.  
+
+         We also need to avoid using OUT if it, or part of it, is a
+         fixed register.  Modifying such registers, even transiently,
+         may have undefined effects on the machine, such as modifying
+         the stack pointer.  */
       saved_rtx = *inloc;
       *inloc = const0_rtx;
 
@@ -2049,7 +2054,8 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
 
          for (i = 0; i < nwords; i++)
            if (! TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
-                                    regno + i))
+                                    regno + i)
+               || fixed_regs[regno + i])
              break;
 
          if (i == nwords)