diff mbox

PR69195, Reload confused by invalid reg equivs

Message ID 20160315022728.GA12055@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra March 15, 2016, 2:27 a.m. UTC
On Mon, Mar 14, 2016 at 01:00:39PM -0600, Jeff Law wrote:
> Right.  Tolerant as in not crash.

So can someone please approve my ira.c:indirect_jump_optimize patch?
I'm not quite audacious enough to claim it is obvious.  The original
is at https://gcc.gnu.org/ml/gcc-patches/2016-03/msg00720.html,
reposted here with some additional comments.  Bootstrapped and
regression tested powerpc64le-linux and x86_64-linux.

(In the thread I mentioned we could use DF_REF_INSN_INFO in place of
!DF_REF_IS_ARTIFICAL.  I believe that is true, and it saves an access
to another field of df_ref, but !DF_REF_IS_ARTIFICIAL before access to
DF_REF_INSN or DF_REF_INSN_UID is somewhat more prevalent in the gcc
sources.)

	PR rtl-optimization/69195
	PR rtl-optimization/47992
	* ira.c (indirect_jump_optimize): Ignore artificial defs.
	Add comments.

Comments

Bernd Schmidt March 15, 2016, 12:17 p.m. UTC | #1
On 03/15/2016 03:27 AM, Alan Modra wrote:
> On Mon, Mar 14, 2016 at 01:00:39PM -0600, Jeff Law wrote:
>> Right.  Tolerant as in not crash.
>
> So can someone please approve my ira.c:indirect_jump_optimize patch?
> I'm not quite audacious enough to claim it is obvious.

Looks good to me.


Bernd
diff mbox

Patch

diff --git a/gcc/ira.c b/gcc/ira.c
index 5e7a2ed..a543d90 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -3842,7 +3842,8 @@  update_equiv_regs (void)
   free (pdx_subregs);
 }
 
-/* A pass over indirect jumps, converting simple cases to direct jumps.  */
+/* A pass over indirect jumps, converting simple cases to direct jumps.
+   Combine does this optimization too, but only within a basic block.  */
 static void
 indirect_jump_optimize (void)
 {
@@ -3862,14 +3863,23 @@  indirect_jump_optimize (void)
       int regno = REGNO (SET_SRC (x));
       if (DF_REG_DEF_COUNT (regno) == 1)
 	{
-	  rtx_insn *def_insn = DF_REF_INSN (DF_REG_DEF_CHAIN (regno));
-	  rtx note = find_reg_note (def_insn, REG_LABEL_OPERAND, NULL_RTX);
-
-	  if (note)
+	  df_ref def = DF_REG_DEF_CHAIN (regno);
+	  if (!DF_REF_IS_ARTIFICIAL (def))
 	    {
-	      rtx lab = gen_rtx_LABEL_REF (Pmode, XEXP (note, 0));
-	      if (validate_replace_rtx (SET_SRC (x), lab, insn))
-		rebuild_p = true;
+	      rtx_insn *def_insn = DF_REF_INSN (def);
+	      rtx note = find_reg_note (def_insn, REG_LABEL_OPERAND, NULL_RTX);
+
+	      if (note)
+		{
+		  /* Substitute a LABEL_REF to the label given by the
+		     note rather than using SET_SRC of DEF_INSN.
+		     DEF_INSN might be loading the label constant from
+		     a constant pool, which isn't what we want in a
+		     direct branch.  */
+		  rtx lab = gen_rtx_LABEL_REF (Pmode, XEXP (note, 0));
+		  if (validate_replace_rtx (SET_SRC (x), lab, insn))
+		    rebuild_p = true;
+		}
 	    }
 	}
     }