This moves queueing calls to MODIFIED_NORETURN_CALLS from gimple_set_modified to update_stmt_operands. The former is called when we remove stmts and thus the call may reference freed SSA names which doesn't make gimple_call_noreturn_p happy (and in fact we have a kludge to avoid ICEing here). At the latter point we are sure the stmt is still meaningful, so that's a much better point to queue it. We are also sure we'll call update_stmt eventually on all modified stmts which makes this movement safe as well.
Bootstrapped on x86_64-unknown-linux-gnu, regtests in progress. Will commit if that succeeds. Richard. 2011-04-08 Richard Guenther <rguent...@suse.de> * gimple.c (gimple_set_modified): Do not queue calls to MODIFIED_NORETURN_CALLS here ... * tree-ssa-operands.c (update_stmt_operands): ... but here. Index: gcc/gimple.c =================================================================== *** gcc/gimple.c (revision 172170) --- gcc/gimple.c (working copy) *************** void *** 2252,2266 **** gimple_set_modified (gimple s, bool modifiedp) { if (gimple_has_ops (s)) ! { ! s->gsbase.modified = (unsigned) modifiedp; ! ! if (modifiedp ! && cfun->gimple_df ! && is_gimple_call (s) ! && gimple_call_noreturn_p (s)) ! VEC_safe_push (gimple, gc, MODIFIED_NORETURN_CALLS (cfun), s); ! } } --- 2252,2258 ---- gimple_set_modified (gimple s, bool modifiedp) { if (gimple_has_ops (s)) ! s->gsbase.modified = (unsigned) modifiedp; } Index: gcc/tree-ssa-operands.c =================================================================== *** gcc/tree-ssa-operands.c (revision 172170) --- gcc/tree-ssa-operands.c (working copy) *************** update_stmt_operands (gimple stmt) *** 1134,1139 **** --- 1134,1145 ---- timevar_push (TV_TREE_OPS); + /* If the stmt is a noreturn call queue it to be processed by + split_bbs_on_noreturn_calls during cfg cleanup. */ + if (is_gimple_call (stmt) + && gimple_call_noreturn_p (stmt)) + VEC_safe_push (gimple, gc, MODIFIED_NORETURN_CALLS (cfun), stmt); + gcc_assert (gimple_modified_p (stmt)); build_ssa_operands (stmt); gimple_set_modified (stmt, false);