This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/50890] [4.7 Regression] ICE in fold_convert_loc, at fold-const.c:1894
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 28 Oct 2011 12:45:28 +0000
- Subject: [Bug middle-end/50890] [4.7 Regression] ICE in fold_convert_loc, at fold-const.c:1894
- Auto-submitted: auto-generated
- References: <bug-50890-4@http.gcc.gnu.org/bugzilla/>
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.