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 <[email protected]>
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