diff mbox

[RS6000] Fix PowerPC ICE due to secondary_reload ignoring reload replacements

Message ID 20150908034744.GA13304@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra Sept. 8, 2015, 3:47 a.m. UTC
In https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67378 analysis I show
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.

Bootstrapped and regression tested powerpc64-linux.  OK to apply?
gcc-5 and gcc-4.9 branches too?

I haven't included a testcase in this patch, because the testcase in
the PR is quite horrible, and testcases triggering reload misbehaviour
tend to be unreliable.  By unreliable, I mean a small change anywhere
in the compiler can result in the testcase passing even if this bug
was reintroduced at some future date.  The testcase doesn't fail on
gcc-5, even though I'm fairly sure the same bug lurks there..

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

Comments

David Edelsohn Sept. 8, 2015, 12:26 p.m. UTC | #1
On Mon, Sep 7, 2015 at 11:47 PM, Alan Modra <amodra@gmail.com> wrote:
> In https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67378 analysis I show
> 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.
>
> Bootstrapped and regression tested powerpc64-linux.  OK to apply?
> gcc-5 and gcc-4.9 branches too?
>
> I haven't included a testcase in this patch, because the testcase in
> the PR is quite horrible, and testcases triggering reload misbehaviour
> tend to be unreliable.  By unreliable, I mean a small change anywhere
> in the compiler can result in the testcase passing even if this bug
> was reintroduced at some future date.  The testcase doesn't fail on
> gcc-5, even though I'm fairly sure the same bug lurks there..
>
>         PR target/67378
>         * config/rs6000/rs6000.c (rs6000_secondary_reload_gpr): Find
>         reload replacement for PRE_MODIFY address reg.

I'm okay with this patch, but I'd like Uli to double-check it when he
has a moment.

Thanks, David
diff mbox

Patch

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index cfd5675..51046d4 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -18199,8 +18199,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);