http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53695
--- Comment #4 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-06-27 10:32:53 UTC --- I am testing Index: gcc/cfgloop.c =================================================================== *** gcc/cfgloop.c (revision 188987) --- gcc/cfgloop.c (working copy) *************** init_loops_structure (struct loops *loop *** 365,370 **** --- 365,406 ---- loops->tree_root = root; } + /* Return true if there is a path from FROM to the dominated TO where no + edge on that path contains FLAGS. */ + + static bool + path_without_edge_flags (basic_block from, basic_block to, int flags) + { + do + { + /* At least one such path to the immediate dominator. */ + if (single_pred_p (to)) + { + edge e = single_pred_edge (to); + if (e->flags & flags) + return false; + to = e->src; + } + else + { + basic_block dom = get_immediate_dominator (CDI_DOMINATORS, to); + edge_iterator ei; + edge e; + + FOR_EACH_EDGE(e, ei, to->preds) + if (!(e->flags & flags) + && (e->src == dom + || path_without_edge_flags (dom, e->src, flags))) + break; + + to = dom; + } + } + while (to != from); + + return true; + } + /* Find all the natural loops in the function and save in LOOPS structure and recalculate loop_depth information in basic block structures. Return the number of natural loops found. */ *************** flow_loops_find (struct loops *loops) *** 422,430 **** 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 ! && dominated_by_p (CDI_DOMINATORS, latch, header)) { /* Shared headers should be eliminated by now. */ SET_BIT (headers, header->index); --- 458,470 ---- 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 there is no regular path from the header to the ! latch do not consider this latch (not worth the ! problems). */ if (latch != ENTRY_BLOCK_PTR ! && dominated_by_p (CDI_DOMINATORS, latch, header) ! && path_without_edge_flags (header, latch, EDGE_COMPLEX)) { /* Shared headers should be eliminated by now. */ SET_BIT (headers, header->index);