Hi, During testing the approved-for-commit middle-end patch for bug 43864 on ARM, I ran into a gcc.dg/torture/pr46068.c ICE.
The following assert in haifa-sched.c:check_cfg triggered: ... else if (any_condjump_p (head)) gcc_assert (/* Usual case. */ (EDGE_COUNT (bb->succs) > 1 && !BARRIER_P (NEXT_INSN (head))) /* Or jump to the next instruction. */ || (EDGE_COUNT (bb->succs) == 1 && (BB_HEAD (EDGE_I (bb->succs, 0)->dest) == JUMP_LABEL (head)))); ... It triggered on this rtl, a conditional return followed by a barrier: ... (jump_insn 44 43 93 7 (set (pc) (if_then_else (ne (reg:CC 24 cc) (const_int 0 [0])) (return) (pc))) gcc/testsuite/gcc.dg/builtin-unreachable-4.c:13 249 {*cond_return} (expr_list:REG_DEAD (reg:CC 24 cc) (expr_list:REG_BR_PROB (const_int 9996 [0x270c]) (nil))) -> return) (barrier 93 44 92) ... Although this insn sequence is non-optimal (the conditional return can be optimized to an unconditional one, given that it's followed by a barrier), it's not incorrect. The patch fixes this ICE by removing the check for the 'EDGE_COUNT (bb->succs) == 1' case. Bootstrapped and reg-tested on x86_64 and build and reg-tested on arm. OK for trunk? Thanks, - Tom 2011-09-05 Tom de Vries <t...@codesourcery.com> * haifa-sched.c (check_cfg): Remove restriction on conditional jump if the containing block has only 1 outgoing edge.
Index: gcc/haifa-sched.c =================================================================== --- gcc/haifa-sched.c (revision 178145) +++ gcc/haifa-sched.c (working copy) @@ -6065,13 +6065,12 @@ check_cfg (rtx head, rtx tail) gcc_assert (EDGE_COUNT (bb->succs) == 1 && BARRIER_P (NEXT_INSN (head))); else if (any_condjump_p (head)) - gcc_assert (/* Usual case. */ - (EDGE_COUNT (bb->succs) > 1 - && !BARRIER_P (NEXT_INSN (head))) - /* Or jump to the next instruction. */ - || (EDGE_COUNT (bb->succs) == 1 - && (BB_HEAD (EDGE_I (bb->succs, 0)->dest) - == JUMP_LABEL (head)))); + gcc_assert (/* Weird case, like jump to the next insn + or use of __builtin_unreachable (). */ + EDGE_COUNT (bb->succs) == 1 + /* Normal case, one path falls through. */ + || !BARRIER_P (NEXT_INSN (head))); + } if (BB_END (bb) == head) {