https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84872
--- Comment #2 from Andrey Belevantsev <abel at gcc dot gnu.org> --- Nothing to do with sel-sched as is :) We're just asking to make loop preheaders that will be fallthrough blocks. The loop has blocks 5 and 6 (6->5 is a loop latch), and the pred block is block 7 but there's block 4 between 7 and 5 like this: (note 52 53 24 7 [bb 7] NOTE_INSN_BASIC_BLOCK) <...> (jump_insn/j 25 24 38 7 (set (pc) (if_then_else (le (reg:CCNO 17 flags) (const_int 0 [0])) (label_ref:DI 18) (pc))) "../prs/pr84872.c":13 682 {*jcc} (expr_list:REG_DEAD (reg:CCNO 17 flags) (nil)) -> 18) (note 38 25 48 4 [bb 4] NOTE_INSN_BASIC_BLOCK) (jump_insn 48 38 49 4 (set (pc) (label_ref 22)) -1 (nil) -> 22) (barrier 49 48 18) (code_label 18 49 16 5 3 (nil) [2 uses]) (note 16 18 17 5 [bb 5] NOTE_INSN_BASIC_BLOCK) <...> The create_preheader code asks to split the 7->5 edge and we happily make block 9: (note 52 53 24 7 [bb 7] NOTE_INSN_BASIC_BLOCK) <...> (jump_insn/j 25 24 38 7 (set (pc) (if_then_else (le (reg:CCNO 17 flags) (const_int 0 [0])) (label_ref:DI 18) (pc))) "../prs/pr84872.c":13 682 {*jcc} (expr_list:REG_DEAD (reg:CCNO 17 flags) (nil)) -> 18) (note 38 25 48 4 [bb 4] NOTE_INSN_BASIC_BLOCK) (jump_insn 48 38 49 4 (set (pc) (label_ref 22)) -1 (nil) -> 22) (barrier 49 48 60) (note 60 49 18 9 [bb 9] NOTE_INSN_BASIC_BLOCK) (code_label 18 60 16 5 3 (nil) [2 uses]) (note 16 18 17 5 [bb 5] NOTE_INSN_BASIC_BLOCK) But then we hit the "can't allow a region crossing edge to be fallthrough" conditional in rtl_split_edge, the edge is forced to be nonfallthru and the create_preheader assert fires. The below of course "fixes" it so we need to do something with the bb partitioning rules or something. Any pass that will ask for fallthrough preheaders after bb reordering between partitions has been completed will blow up. diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index fd095ac59ed..ed6b0c11802 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1901,7 +1901,7 @@ rtl_split_edge (edge edge_in) /* Can't allow a region crossing edge to be fallthrough. */ if (BB_PARTITION (bb) != BB_PARTITION (edge_in->dest) - && edge_in->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)) + && edge_in->dest != EXIT_BLOCK_PTR_FOR_FN (cfun) && false) { new_bb = force_nonfallthru (single_succ_edge (bb)); gcc_assert (!new_bb);