http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50890
--- Comment #2 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-10-28 12:45:28 UTC --- Bah, probably triggered by that change but reveals some bigger issue with how we keep the mismatched-function-flags (gimple_call_cannot_inline_p and the corresponding edge flag e->call_stmt_cannot_inline_p) up-to-date. In this case the inliner when inlining emit_pattern_after_noloc turns the make_raw () call into a direct call but fails to set this flag, so we inline it during the 2nd early inliner iteration. Setting that flag at a convenient place with + /* Check whether propagating into the function address made the + call direct, and thus possibly non-inlineable. + ??? This asks for a more conservative setting of the non-inlinable + flag, namely true for all indirect calls. But that would require + that we can re-compute the flag conservatively, thus it isn't + ever initialized from something else than return/argument type + checks . */ + callee = gimple_call_fndecl (stmt); + if (callee + && !gimple_check_call_matching_types (stmt, callee)) + gimple_call_set_cannot_inline (stmt, true); during statement folding (CCP can also cause such change when turning an indirect into a direct call) causes us to hit #1 0x00000000012b80e7 in can_inline_edge_p (e=0x7ffff5b286e8, report=true) at /space/rguenther/src/svn/trunk/gcc/ipa-inline.c:339 339 gcc_checking_assert (!e->call_stmt because nobody updated the edge flag ... (and I don't think we should do that from the statement folder). That's during the 2nd iteration of the early inliner. Honza, why do we get away not re-building cgraph edges while iterating? What is supposed to keep the edges up-to-date? I suppose we can adjust the flag when we do /* Technically we ought to recompute inline parameters so the new iteration of early inliner works as expected. We however have values approximately right and thus we only need to update edge info that might be cleared out for newly discovered edges. */ for (edge = node->callees; edge; edge = edge->next_callee) { struct inline_edge_summary *es = inline_edge_summary (edge); es->call_stmt_size = estimate_num_insns (edge->call_stmt, &eni_size_weights); es->call_stmt_time = estimate_num_insns (edge->call_stmt, &eni_time_weights); } Testing a patch.