This maybe papers over PR48271, we're modifying the CFG and yet marking some BBs for cleanup. Well, at least the jump-threading case is supposed to work this way. DOM doesn't deserve too much love, so ...
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2011-03-24 Richard Guenther <rguent...@suse.de> PR tree-optimization/48271 * tree-ssa-dom.c (tree_ssa_dominator_optimize): Only cleanup blocks that still exist. * g++.dg/torture/pr48271.C: New testcase. Index: gcc/tree-ssa-dom.c =================================================================== *** gcc/tree-ssa-dom.c (revision 171387) --- gcc/tree-ssa-dom.c (working copy) *************** tree_ssa_dominator_optimize (void) *** 701,707 **** gimple_stmt_iterator gsi; basic_block bb; FOR_EACH_BB (bb) ! {for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) update_stmt_if_modified (gsi_stmt (gsi)); } } --- 701,708 ---- gimple_stmt_iterator gsi; basic_block bb; FOR_EACH_BB (bb) ! { ! for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) update_stmt_if_modified (gsi_stmt (gsi)); } } *************** tree_ssa_dominator_optimize (void) *** 734,740 **** EXECUTE_IF_SET_IN_BITMAP (need_eh_cleanup, 0, i, bi) { basic_block bb = BASIC_BLOCK (i); ! if (single_succ_p (bb) == 1 && (single_succ_edge (bb)->flags & EDGE_EH) == 0) { bitmap_clear_bit (need_eh_cleanup, i); --- 735,742 ---- EXECUTE_IF_SET_IN_BITMAP (need_eh_cleanup, 0, i, bi) { basic_block bb = BASIC_BLOCK (i); ! if (bb ! && single_succ_p (bb) && (single_succ_edge (bb)->flags & EDGE_EH) == 0) { bitmap_clear_bit (need_eh_cleanup, i); Index: gcc/testsuite/g++.dg/torture/pr48271.C =================================================================== *** gcc/testsuite/g++.dg/torture/pr48271.C (revision 0) --- gcc/testsuite/g++.dg/torture/pr48271.C (revision 0) *************** *** 0 **** --- 1,119 ---- + // { dg-do compile } + // { dg-options "-ftree-vrp -fno-guess-branch-probability -fnon-call-exceptions" } + + void *xalloc (); + void xfree (void *); + void error (); + + static inline void * + MallocT () + { + void *p = xalloc (); + if (!p) + error (); + return p; + } + + + struct ByteBlob + { + int *header; + + ByteBlob(); + + ~ByteBlob () + { + Free (); + } + + int RawFree (int * p) + { + if (!p) + error (); + xfree (p); + } + + int *LengthRef (); + + void Free () + { + if (*header) + RawFree (header); + } + + int Append (int num_ints) + { + if (*header) + MallocT (); + *LengthRef () += num_ints; + } + }; + + struct CBlobT:ByteBlob + { + ~CBlobT () + { + Free (); + } + }; + + template < class T > struct FixedSizeArray + { + int HeaderSize; + T *data; + FixedSizeArray (); + int RefCnt () + { + return *(int *) MallocT (); + } + ~FixedSizeArray () + { + if (RefCnt ()) + for (T * pItem = data + Length (); pItem != data; pItem--) + T (); + } + int Length (); + }; + + class SmallArray + { + typedef FixedSizeArray < int > SubArray; + typedef FixedSizeArray < SubArray > SuperArray; + SuperArray data; + }; + + struct CHashTableT + { + int *m_slots; + ~CHashTableT () + { + delete m_slots; + } + }; + + struct CYapfBaseT + { + int *PfGetSettings (); + SmallArray m_arr; + CHashTableT m_closed; + CYapfBaseT () + { + MallocT (); + } + }; + + struct CYapfCostRailT:CYapfBaseT + { + CBlobT m_sig_look_ahead_costs; + CYapfCostRailT () + { + m_sig_look_ahead_costs.Append (*Yapf ()->PfGetSettings ()); + Yapf ()->PfGetSettings (); + } + CYapfBaseT *Yapf (); + }; + + void stCheckReverseTrain () + { + CYapfCostRailT pf1; + }