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

Reply via email to