[Bug rtl-optimization/54369] Delayed-branch pass in reorg.c removes too many instructions
sje at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Aug 31 00:31:00 GMT 2012
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.
More information about the Gcc-bugs
mailing list