https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69175
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bernds at gcc dot gnu.org, | |law at gcc dot gnu.org --- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Segher Boessenkool from comment #7) > I cannot easily reproduce the problem. > > Could you try with r232148 or later? I can reproduce even with that. Either the problem is with NOTE_INSN_DELETED coming before a barrier, or the problem is that merge_if_blocks doesn't handle simple returns correctly. Starting with *.compgotos pass we end up with: (jump_insn 118 99 91 5 (simple_return) -1 (nil) -> simple_return) ;; succ: EXIT [100.0%] ;; lr out 4 [r4] 13 [sp] 14 [lr] ;; live out 4 [r4] 13 [sp] 14 [lr] (note 91 118 92 NOTE_INSN_DELETED) (note 92 91 102 NOTE_INSN_DELETED) (barrier 102 92 24) ;; basic block 6, loop depth 0, count 0, freq 1146, maybe hot which I'm not 100% sure is valid (I'd think barriers should come first). But merge_if_blocks seems to have some code to deal even with that, /* If THEN_BB has no successors, then there's a BARRIER after it. If COMBO_BB has more than one successor (THEN_BB), then that BARRIER is no longer needed, and in fact it is incorrect to leave it in the insn stream. */ if (EDGE_COUNT (then_bb->succs) == 0 && EDGE_COUNT (combo_bb->succs) > 1) { rtx_insn *end = NEXT_INSN (BB_END (then_bb)); while (end && NOTE_P (end) && !NOTE_INSN_BASIC_BLOCK_P (end)) end = NEXT_INSN (end); if (end && BARRIER_P (end)) delete_insn (end); } merge_blocks (combo_bb, then_bb); but that doesn't trigger here, and rtl_merge_blocks only handles a BARRIER coming first: 878 else if (BARRIER_P (NEXT_INSN (a_end))) 879 del_first = NEXT_INSN (a_end); So, the question I have is, do we require BARRIER in between bbs to always come first, or can it be preceeded by notes? Depending on that the bug is either in something the compgotos pass does or uses, or in rtl_merge_blocks.