------- Comment #2 from cltang at pllab dot cs dot nthu dot edu dot tw 2008-07-05 07:57 ------- Created an attachment (id=15859) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=15859&action=view) Patch for cse.c
I have looked at the debug dumps for the testcase. This seems like a very rare case: 1. -O3 turns on the loop unswitching pass (-funswitch-loops), which transforms the function into two loops guarded by a conditional branch from a header block. 2. During cse2 (the immediately next pass), cse.c:cse_main() transforms that conditional branch into a jump, cutting off the connection to one of the loops. 3. The cut off loop becomes segregated from the other basic blocks, and becomes a circular loop, with a single edge acting as both the entry and latch edge. 4. This cut off loop still contains control flow, and sets CC within. cse.c:cse_condition_reg() calls the recursive cse_cc_succs() to delete redundant CC setters on this circular loop. 5. cse.c:cse_cc_succs() uses the "single predecessor edge" condition as the stopping control flow test, which in this case of a single edge circular loop (a "ring" like control flow structure), fails to properly stop the recursion. cse_cc_succs() then blows up the stack and segfaults. The proposed fix is to record visited basic blocks during the recursive traversal, see the enclosed patch. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36635