https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122956
--- Comment #14 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
This is interesting that GPT can do something here. The analysis is not quite
correct. we support multi-target speculation since 2020
(r:f1ba88b1b20cb579b3b7ce6ce65470205742be7e) and resolve_speculation is
documented as resolving only one of multiple speculative targets:
/* Speculative call EDGE turned out to be direct call to CALLEE_DECL. Remove
the speculative call sequence and return edge representing the call, the
original EDGE can be removed and deallocated. Return the edge that now
represents the call.
For "speculative" indirect call that contains multiple "speculative"
targets (i.e. edge->indirect_info->num_speculative_call_targets > 1),
decrease the count and only remove current direct edge.
If no speculative direct call left to the speculative indirect call, remove
the speculative of both the indirect call and corresponding direct edge.
It is up to caller to iteratively resolve each "speculative" direct call and
redirect the call as appropriate. */
cgraph_edge *
cgraph_edge::resolve_speculation (cgraph_edge *edge, tree callee_decl)
Perhaps we want to have resolve_all_speculations to avoid the need to loop in
each use. I have a talk tomorrow, after that I will try to get correct LLVM
version.
Since failure is in ipa-inline I suspect it is
cgraph_update_edges_for_call_stmt_node which does not seem to iterate:
/* If call was devirtualized during cloning, mark edge
as resolved. */
if (e->speculative)
{
if (new_stmt && is_gimple_call (new_stmt))
{
tree decl = gimple_call_fndecl (new_stmt);
if (decl)
e = cgraph_edge::resolve_speculation (e, decl);
}
else
e = cgraph_edge::resolve_speculation (e, NULL);
}