[Bug middle-end/50890] [4.7 Regression] ICE in fold_convert_loc, at fold-const.c:1894
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Oct 28 12:45:00 GMT 2011
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.
More information about the Gcc-bugs
mailing list