------- Comment #2 from hubicka at gcc dot gnu dot org 2010-09-17 01:05 -------
OK, problem is that we both devirtualize and clone the destination function.
Then when producing clone, we run into:
cgraph_update_edges_for_call_stmt_node (struct cgraph_node *node,
gimple old_stmt, tree old_call, gimple
new_stmt)
{
tree new_call = (is_gimple_call (new_stmt)) ? gimple_call_fndecl (new_stmt) :
0;
/* We are seeing indirect calls, then there is nothing to update. */
if (!new_call && !old_call)
return;
/* See if we turned indirect call into direct call or folded call to one
builtin
into different bultin. */
if (old_call != new_call)
{
struct cgraph_edge *e = cgraph_edge (node, old_stmt);
struct cgraph_edge *ne = NULL;
gcov_type count;
int frequency;
int loop_nest;
if (e)
{
/* See if the edge is already there and has the correct callee. It
might be so because of indirect inlining has already updated
it. */
if (new_call && e->callee && e->callee->decl == new_call)
return;
/* Otherwise remove edge and create new one; we can't simply redirect
since function has changed, so inline plan and other information
attached to edge is invalid. */
and kill the inline plan. This code is intended to handle bulitins, I guess
we will need to look out if the decl can be redirected to decl in the function.
Honza
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45621