]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix thinko in indirect_jump_optimize
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 15 Mar 2016 22:04:42 +0000 (22:04 +0000)
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 15 Mar 2016 22:04:42 +0000 (22:04 +0000)
PR rtl-optimization/69195
PR rtl-optimization/47992
* ira.c (indirect_jump_optimize): Ignore artificial defs.
Add comments.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@234235 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/ira.c

index 8909a99e08b7776371523d74b851a82d58ed00aa..7359f0b483e96f2a0fe644812986d12bb7f41827 100644 (file)
@@ -1,3 +1,10 @@
+2016-03-16  Alan Modra  <amodra@gmail.com>
+
+       PR rtl-optimization/69195
+       PR rtl-optimization/47992
+       * ira.c (indirect_jump_optimize): Ignore artificial defs.
+       Add comments.
+
 2016-03-15  Eric Botcazou  <ebotcazou@adacore.com>
 
        PR bootstrap/69513
index 5e7a2edf3b4c5af7473ef7e4ebbe28e6b2f6d5ca..062b8a4d4b8ca177b592d3de119bce729cc295e5 100644 (file)
--- 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;
+               }
            }
        }
     }