Hi! The RTL verification in rtl_verify_edges as well as various other routines in cfgrtl.c etc. require that any_uncondjump_p jumps never have fallthru edges - even if their destination is right after them, there still needs to be barrier in between them and code_label after that. rtl_tidy_fallthru_edge can violate this. If if (JUMP_P (q) && onlyjump_p (q) && (any_uncondjump_p (q) || single_succ_p (b))) it will delete also the JUMP_INSN and everything is fine, but if any_uncondjump_p (q) is true, but onlyjump_p (q) is false, we can't remove the jump (as is the case of the split_stack_call_<mode> insn), but still remove the barrier and make the edge EDGE_FALLTHRU, which then violates the verification, or with --enable-checking=rtl, ICEs later in fixup_reorder_chain.
The following patch avoids doing that, if it is any_uncondjump_p that can't have fallthru edges, either we manage to remove the jump, or we don't tidy anything. Bootstrapped/regtested on x86_64-linux, i686-linux and bootstrapped on s390x-linux (regtests there still ongoing). Ok for trunk if the regtests pass there? 2017-01-12 Jakub Jelinek <ja...@redhat.com> PR bootstrap/79069 * cfgrtl.c (rtl_tidy_fallthru_edge): For any_uncondjump_p that can't be removed due to side-effects, don't remove following barrier nor turn the successor edge into fallthru edge. --- gcc/cfgrtl.c.jj 2017-01-01 12:45:35.000000000 +0100 +++ gcc/cfgrtl.c 2017-01-12 13:24:48.414579702 +0100 @@ -1794,6 +1794,10 @@ rtl_tidy_fallthru_edge (edge e) q = PREV_INSN (q); } + /* Unconditional jumps with side-effects (i.e. which we can't just delete + together with the barrier) should never have a fallthru edge. */ + else if (JUMP_P (q) && any_uncondjump_p (q)) + return; /* Selectively unlink the sequence. */ if (q != PREV_INSN (BB_HEAD (c))) Jakub