http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43631
--- Comment #14 from Steven Bosscher <steven at gcc dot gnu.org> 2012-12-07
11:59:15 UTC ---
(In reply to comment #13)
> Please hold on with that, seems BB_END is BARRIER, which is wrong.
> Starting with distilling a testcase...
Perhaps Alex' is right that the real problem is in how BLOCK_FOR_INSN
is handled in add_insn_after and add_insn_before. Jakub, does the
following make sense to you?
Index: emit-rtl.c
===================================================================
--- emit-rtl.c (revision 194229)
+++ emit-rtl.c (working copy)
@@ -3845,19 +3845,25 @@ add_insn_after (rtx insn, rtx after, bas
gcc_assert (stack);
}
- if (!BARRIER_P (after)
- && !BARRIER_P (insn)
- && (bb = BLOCK_FOR_INSN (after)))
+ /* If the new insn is a barrier, bb should be NULL because a barrier
+ is never inside a basic block. Also avoid emitting double barriers. */
+ if (BARRIER_P (insn))
+ gcc_checking_assert (bb == NULL && !BARRIER_P (after));
+ /* Otherwise, try to deduce a basic block from AFTER. */
+ else if (!bb
+ && !BARRIER_P (after)
+ && BLOCK_FOR_INSN (after) != NULL
+ && after != BB_END (BLOCK_FOR_INSN (after)))
+ bb = BLOCK_FOR_INSN (after);
+
+ if (bb)
{
set_block_for_insn (insn, bb);
if (INSN_P (insn))
df_insn_rescan (insn);
- /* Should not happen as first in the BB is always
- either NOTE or LABEL. */
- if (BB_END (bb) == after
- /* Avoid clobbering of structure when creating new BB. */
- && !BARRIER_P (insn)
- && !NOTE_INSN_BASIC_BLOCK_P (insn))
+ /* Move BB_END from AFTER to INSN unless INSN is a note (a note cannot
+ be the end a basic block). */
+ if (BB_END (bb) == after && !NOTE_P (insn))
BB_END (bb) = insn;
}