https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98078

--- Comment #3 from Martin Jambor <jamborm at gcc dot gnu.org> ---
Here is what happens.  An IPA-CP clone for a particular
devirtualziation context is created but all devirtualziations based on
it are speculative.  Then the clone is inlined at one of its call
sites and the devirtualization turns out to be exactly right.  The
following goes on in cgraph_edge::set_call_stmt which gets a direct
call as the statement.

We end up in the update_speculative condition, which calls itself on
all the corresponding speculative edges.  First at the direct, which
then is removed and inserted into the call hash.  Then at the
indirect, which is not removed from the has because it is not the one
in there.  At this point, we figure out we have a direct call
statement at our hands and so we call make_direct at the edge, which
in turn simply resolves the speculation and returns the direct
branch, which we store to e.

And then we try to add e to call_site_hash, which is already there and
the assert condition does not take that possibility into account.

  (gdb) p/r *slot
  $42 = (cgraph_edge *) 0x7ffff74d6478
  (gdb) p/r e
  $43 = (cgraph_edge *) 0x7ffff74d6478


So the simplest fix is probably just adding
  if (*slot == e)
    return;
before the assert.

Reply via email to