aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-09-09 15:26:26 +0930
committerAlan Modra <amodra@gcc.gnu.org>2015-09-09 15:26:26 +0930
commit04e49571a086621e33261b8e25b35a577195f2d6 (patch)
tree486c315e02a987f8585cd2f7bd62d8f8f61f5ff8 /gcc
parent6b3ebcdda18d2b6b0e2bf3857726ab02fbac5ad4 (diff)
downloadgcc-04e49571a086621e33261b8e25b35a577195f2d6.zip
gcc-04e49571a086621e33261b8e25b35a577195f2d6.tar.gz
gcc-04e49571a086621e33261b8e25b35a577195f2d6.tar.bz2
Fix PowerPC ICE due to secondary_reload ignoring reload replacements
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: r227573
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/rs6000/rs6000.c15
2 files changed, 20 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d697edd..542abcf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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-09 Sebastian Pop <s.pop@samsung.com>
PR tree-optimization/53852
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 8107bec..941592a 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -18198,8 +18198,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);