http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54369

Steve Ellcey <sje at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|WAITING                     |NEW

--- Comment #2 from Steve Ellcey <sje at gcc dot gnu.org> 2012-08-31 00:30:01 
UTC ---
I think I see where delete_related_insns is going wrong.  We call it
with a JUMP instruction that we want to remove because we are just
jumping to the next instruction (a label) which we would get to anyway
without the jump, then after delete_related_insns removes the jump it
checks the label it was jumping to, and if it finds no uses it calls
delete_related_insns with that label.  When delete_related_insns
is called with a label, it assumes it can remove all the code after
that label as unreachable.  But the code after the label can be reached
by the default fall-through code sequence.  So after removing a jump and
finding a label with no uses we should call delete_insn with that label,
not delete_related_insns.

So my proposed fix would be:

diff --git a/gcc/jump.c b/gcc/jump.c
index 9721fe1..fa3d65a 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -1207,7 +1207,7 @@ delete_related_insns (rtx insn)
        /* This can delete NEXT or PREV,
           either directly if NEXT is JUMP_LABEL (INSN),
           or indirectly through more levels of jumps.  */
-       delete_related_insns (lab);
+       delete_insn (lab);
       else if (tablejump_p (insn, NULL, &lab_next))
        {
          /* If we're deleting the tablejump, delete the dispatch table.

Reply via email to