This patch extends verify_loop_structure by checking that header's are really its own headers (this proved as useful in PR56181). The bulk of the code is taken from flow_loops_find.
Bootstrapped on x86_64 linux. The only fallout now is (for C/C++): FAIL: gcc.dg/torture/pr54458.c -O3 -fomit-frame-pointer (internal compiler error) FAIL: gcc.dg/torture/pr54458.c -O3 -fomit-frame-pointer (test for excess errors) FAIL: gcc.dg/torture/pr54458.c -O3 -fomit-frame-pointer -funroll-loops (internal compiler error) FAIL: gcc.dg/torture/pr54458.c -O3 -fomit-frame-pointer -funroll-loops (test for excess errors) FAIL: gcc.dg/torture/pr54458.c -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (internal compiler error) FAIL: gcc.dg/torture/pr54458.c -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (test for excess errors) FAIL: gcc.dg/torture/pr54458.c -O3 -g (internal compiler error) FAIL: gcc.dg/torture/pr54458.c -O3 -g (test for excess errors) which is only because -O3 means -funswitch-loops as well. What happens here is quite interesting situation, we have three analogical loops which look like below. BB7 is marked as IRREDUCIBLE_LOOP. | +---------------+ | | | | | +---+-+-+ | | 6 | | +---+---+ | | ---| | | -----/ | | +-----/-+ | | | 7 | | | +-------+ | | / \ | | / \ | | +------+ +------+ | | | 9 | | 8 | | | +--+---+ +---+--+ | | | | | | | +-------+ | +-------+ | | 10 | | +---+---+ | | +-------+ Thus, we basically have two headers in a loop. So, shall I skip the BB_IRREDUCIBLE_LOOP blocks? (Although this leads to another crash: we get into the same situation in another pass, just the BB isn't marked as BB_IRREDUCIBLE_LOOP, so we don't skip it. Perhaps this could be sorted out by just calling mark_irreducible_loops somewhere.) Comments? 2013-02-06 Marek Polacek <pola...@redhat.com> * cfgloop.c (verify_loop_structure): Check that header BBs are really its own headers. --- gcc/cfgloop.c.mp 2013-02-06 12:08:01.536918761 +0100 +++ gcc/cfgloop.c 2013-02-06 18:32:59.957027313 +0100 @@ -1316,6 +1316,41 @@ verify_loop_structure (void) else verify_dominators (CDI_DOMINATORS); + /* Check the loop headers. */ + FOR_EACH_BB (bb) + { + edge_iterator ei; + + /* If we have an abnormal predecessor, do not consider the + loop (not worth the problems). */ + if (bb_has_abnormal_pred (bb)) + continue; + + if (bb->loop_father == current_loops->tree_root) + continue; + + FOR_EACH_EDGE (e, ei, bb->preds) + { + basic_block latch = e->src; + + gcc_assert (!(e->flags & EDGE_ABNORMAL)); + + /* Look for back edges where a predecessor is dominated + by this block. A natural loop has a single entry + node (header) that dominates all the nodes in the + loop. It also has single back edge to the header + from a latch node. */ + if (latch != ENTRY_BLOCK_PTR + && bb != latch + && dominated_by_p (CDI_DOMINATORS, latch, bb)) + if (bb->loop_father->header != bb) + { + error ("header %d is not its own header", bb->index); + err = 1; + } + } + } + /* Check sizes. */ sizes = XCNEWVEC (unsigned, num); sizes[0] = 2; Marek