------- 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

Reply via email to