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.