]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix PowerPC ICE due to secondary_reload ignoring reload replacements
authorAlan Modra <amodra@gmail.com>
Wed, 9 Sep 2015 06:07:14 +0000 (15:37 +0930)
committerAlan Modra <amodra@gcc.gnu.org>
Wed, 9 Sep 2015 06:07:14 +0000 (15:37 +0930)
The reason for this PR is that insns emitted by secondary reload
patterns are being generated without taking into account other reloads
that may have occurred.  We run into this problem when an insn has a
pseudo that doesn't get a hard reg, and the pseudo is used in a way
that requires a secondary reload.  In this case the secondary reload
is needed due to gcc generating a 64-bit gpr load from memory insn
with an address offset not a multiple of 4.

PR target/67378
* config/rs6000/rs6000.c (rs6000_secondary_reload_gpr): Find
reload replacement for PRE_MODIFY address reg.

From-SVN: r227575

gcc/ChangeLog
gcc/config/rs6000/rs6000.c

index c05558fc750980e0af97f88545a542fde7c692b0..31a500be769748fdcf4a10b45c002eec7cb94358 100644 (file)
@@ -1,3 +1,9 @@
+2015-09-09  Alan Modra  <amodra@gmail.com>
+
+       PR target/67378
+       * config/rs6000/rs6000.c (rs6000_secondary_reload_gpr): Find
+       reload replacement for PRE_MODIFY address reg.
+
 2015-09-02  Alan Modra  <amodra@gmail.com>
 
        PR target/67417
index 859476aafa8afa3ec88c5c2c2184acc8328f13e3..7218e279d83adeb1282186e3cf06e6557fed8704 100644 (file)
@@ -17235,8 +17235,21 @@ rs6000_secondary_reload_gpr (rtx reg, rtx mem, rtx scratch, bool store_p)
 
   if (GET_CODE (addr) == PRE_MODIFY)
     {
+      gcc_assert (REG_P (XEXP (addr, 0))
+                 && GET_CODE (XEXP (addr, 1)) == PLUS
+                 && XEXP (XEXP (addr, 1), 0) == XEXP (addr, 0));
       scratch_or_premodify = XEXP (addr, 0);
-      gcc_assert (REG_P (scratch_or_premodify));
+      if (!HARD_REGISTER_P (scratch_or_premodify))
+       /* If we have a pseudo here then reload will have arranged
+          to have it replaced, but only in the original insn.
+          Use the replacement here too.  */
+       scratch_or_premodify = find_replacement (&XEXP (addr, 0));
+
+      /* RTL emitted by rs6000_secondary_reload_gpr uses RTL
+        expressions from the original insn, without unsharing them.
+        Any RTL that points into the original insn will of course
+        have register replacements applied.  That is why we don't
+        need to look for replacements under the PLUS.  */
       addr = XEXP (addr, 1);
     }
   gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);