Hi, this patch fixes quite nasty bug in update_indirect_edges_after_inlining that forets to update param_index of indirect edge when the call becomes speculative during inlining.
Bootstrapped/regtested x86_64-linux, comitted. Jakub, do you think you can help with a testcase? I am not quite sure where ubsan correctness testcase belong. Honza PR middle-end/64922 * ipa-prop.c (update_indirect_edges_after_inlining): Correctly update edges that become speculative. Index: ipa-prop.c =================================================================== --- ipa-prop.c (revision 220417) +++ ipa-prop.c (working copy) @@ -3075,6 +3075,7 @@ update_indirect_edges_after_inlining (st struct cgraph_indirect_call_info *ici = ie->indirect_info; struct ipa_jump_func *jfunc; int param_index; + cgraph_node *spec_target = NULL; next_ie = ie->next_callee; @@ -3091,6 +3092,14 @@ update_indirect_edges_after_inlining (st param_index = ici->param_index; jfunc = ipa_get_ith_jump_func (top, param_index); + if (ie->speculative) + { + struct cgraph_edge *de; + struct ipa_ref *ref; + ie->speculative_call_info (de, ie, ref); + spec_target = de->callee; + } + if (!opt_for_fn (node->decl, flag_indirect_inlining)) new_direct_edge = NULL; else if (ici->polymorphic) @@ -3103,11 +3112,13 @@ update_indirect_edges_after_inlining (st new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc, new_root_info); /* If speculation was removed, then we need to do nothing. */ - if (new_direct_edge && new_direct_edge != ie) + if (new_direct_edge && new_direct_edge != ie + && new_direct_edge->callee == spec_target) { new_direct_edge->indirect_inlining_edge = 1; top = IPA_EDGE_REF (cs); res = true; + continue; } else if (new_direct_edge) { @@ -3123,9 +3134,13 @@ update_indirect_edges_after_inlining (st res = true; } top = IPA_EDGE_REF (cs); + /* If speculative edge was introduced we still need to update + call info of the indirect edge. */ + if (!new_direct_edge->speculative) + continue; } - else if (jfunc->type == IPA_JF_PASS_THROUGH - && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) + if (jfunc->type == IPA_JF_PASS_THROUGH + && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) { if ((ici->agg_contents && !ipa_get_jf_pass_through_agg_preserved (jfunc))