From e089e43365f7f2a90979e2316aea25d44823f5a3 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Wed, 7 Oct 2020 14:12:49 +0200 Subject: ipa-prop: Fix multiple-target speculation resolution As the FIXME which this patch removes states, the current code does not work when a call with multiple speculative targets gets resolved through parameter tracking during inlining - it feeds the inliner an edge it has already dealt with. The patch makes the code which should prevent it aware of the possibility that that speculation can have more than one target now. gcc/ChangeLog: 2020-09-30 Martin Jambor PR ipa/96394 * ipa-prop.c (update_indirect_edges_after_inlining): Do not add resolved speculation edges to vector of new direct edges even in presence of multiple speculative direct edges for a single call. gcc/testsuite/ChangeLog: 2020-09-30 Martin Jambor PR ipa/96394 * gcc.dg/tree-prof/pr96394.c: New test. --- gcc/ipa-prop.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'gcc/ipa-prop.c') diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index dec6c73..2d09d91 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -3787,11 +3787,13 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs, param_index = ici->param_index; jfunc = ipa_get_ith_jump_func (top, param_index); - cgraph_node *spec_target = NULL; - /* FIXME: This may need updating for multiple calls. */ + auto_vec spec_targets; if (ie->speculative) - spec_target = ie->first_speculative_call_target ()->callee; + for (cgraph_edge *direct = ie->first_speculative_call_target (); + direct; + direct = direct->next_speculative_call_target ()) + spec_targets.safe_push (direct->callee); if (!opt_for_fn (node->decl, flag_indirect_inlining)) new_direct_edge = NULL; @@ -3814,7 +3816,7 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs, /* If speculation was removed, then we need to do nothing. */ if (new_direct_edge && new_direct_edge != ie - && new_direct_edge->callee == spec_target) + && spec_targets.contains (new_direct_edge->callee)) { new_direct_edge->indirect_inlining_edge = 1; top = IPA_EDGE_REF (cs); -- cgit v1.1