https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123386

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
This is related to the last asm goto:
  __asm__ goto ("" : : : : d);
d:;
which has just one edge:
(code_label 18 17 19 6 9 (nil) [1 uses])
(note 19 18 20 6 [bb 6] NOTE_INSN_BASIC_BLOCK)
(jump_insn 20 19 24 6 (parallel [
            (asm_operands/v ("") ("") 0 []
                 []
                 [
                    (label_ref:DI 24)
                ] pr123386.c:20)
            (clobber (reg:CC 17 flags))
        ]) "pr123386.c":20:3 -1
     (nil)
 -> 24)

0x7fffe960c938 = {<edge 0x7fffe99f9c78 (6 -> 7)>}

(code_label 24 20 25 7 8 ("d") [3 uses])
During the separate shrink wrapping commit_one_edge_insertion is called on the
3->7 edge, trying to insert there:
(insn/f 58 0 59 (set (reg:DI 3 bx)
        (mem/c:DI (plus:DI (reg/f:DI 7 sp)
                (const_int 8 [0x8])) [3  S8 A8])) -1
     (expr_list:REG_CFA_RESTORE (reg:DI 3 bx)
        (nil)))

(insn/f 59 58 0 (set (reg:DI 42 r14)
        (mem/c:DI (plus:DI (reg/f:DI 7 sp)
                (const_int 16 [0x10])) [3  S8 A8])) -1
     (expr_list:REG_CFA_RESTORE (reg:DI 42 r14)
        (nil)))
This leads to:
#5  0x00000000006f7c07 in force_nonfallthru_and_redirect (e=<edge
0x7fffe99f9c78 (6 -> 7)>, target=<basic_block 0x7fffe99fe660 (7)>,
jump_label=0x0) at ../../gcc/cfgrtl.cc:1672
#6  0x00000000006f7ee5 in rtl_force_nonfallthru (e=<edge 0x7fffe99f9c78 (6 ->
7)>) at ../../gcc/cfgrtl.cc:1743
#7  0x00000000006e1abc in force_nonfallthru (e=<edge 0x7fffe99f9c78 (6 -> 7)>)
at ../../gcc/cfghooks.cc:1090
#8  0x00000000006f823a in rtl_split_edge (edge_in=<edge 0x7fffe99f9d90 (3 ->
7)>) at ../../gcc/cfgrtl.cc:1873
#9  0x00000000006e0d7d in split_edge (e=<edge 0x7fffe99f9d90 (3 -> 7)>) at
../../gcc/cfghooks.cc:700
#10 0x00000000006f8959 in commit_one_edge_insertion (e=<edge 0x7fffe99f9d90 (3
-> 7)>) at ../../gcc/cfgrtl.cc:2090
This is because of:
  /* We are going to place the new block in front of edge destination.
     Avoid existence of fallthru predecessors.  */
  if ((edge_in->flags & EDGE_FALLTHRU) == 0)
    {
      edge e = find_fallthru_edge (edge_in->dest->preds);

      if (e)
        force_nonfallthru (e);
    }
Now, force_nonfallthru_and_redirect has code to deal with asm goto, but guess
I'll need to go over all possible cases, including what should be done for
e->dest == target cases, what should be done if it is different and in each
cases consider both the e->dest being fallthru edge with 0 or 1+ labels
pointing to the same result or when it is some other edge with just some labels
pointing to e->dest.

Reply via email to