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.

Reply via email to