https://gcc.gnu.org/g:79a1f1b686b94bf492f16d52b434324c8e3dd0ff
commit r17-5627-g79a1f1b686b94bf492f16d52b434324c8e3dd0ff Author: Josef Melcr <[email protected]> Date: Tue Sep 15 12:46:44 2026 +0200 ipa: Adjust jump function computations for callback edges The jump function logic for regular callback edges does not apply to internal callback edges, as it relies on the existence of a callback-carrying edge for the remapping. In order to make ipa-cp act on assume bodies, we need to remap the arguments before the analysis is done. This patch adds the remapping logic and also adds an early return to ipa_polymorphic_call_context::get_dynamic_type, which tries to get the called function from the call statement with gimple_call_fn. This of course doesn't work for internal calls. gcc/ChangeLog: * ipa-polymorphic-call.cc (ipa_polymorphic_call_context::get_dynamic_type): Exclude IFN_ASSUME internal calls. * ipa-prop.cc (ipa_compute_jump_functions_for_edge): Remap arguments for callback edges. Signed-off-by: Josef Melcr <[email protected]> Diff: --- gcc/ipa-polymorphic-call.cc | 8 ++++++++ gcc/ipa-prop.cc | 15 +++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/gcc/ipa-polymorphic-call.cc b/gcc/ipa-polymorphic-call.cc index addb52561c70..3f2d413a73ac 100644 --- a/gcc/ipa-polymorphic-call.cc +++ b/gcc/ipa-polymorphic-call.cc @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "backend.h" #include "rtl.h" +#include "tree-core.h" #include "tree.h" #include "gimple.h" #include "tree-pass.h" @@ -41,6 +42,8 @@ along with GCC; see the file COPYING3. If not see #include "alloc-pool.h" #include "symbol-summary.h" #include "symtab-thunks.h" +#include "attr-callback.h" +#include "callback-info.h" /* Return true when TYPE contains an polymorphic type and thus is interesting for devirtualization machinery. */ @@ -1584,6 +1587,11 @@ ipa_polymorphic_call_context::get_dynamic_type (tree instance, if (!instance) return false; + /* Bail to avoid segfaults for IFN_ASSUME internal calls. They are not + polymorphic anyway. */ + if (is_gimple_call (call) && gimple_call_internal_p (call, IFN_ASSUME)) + return false; + if (otr_type) otr_type = TYPE_MAIN_VARIANT (otr_type); diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index b4f08fb23de5..54c40691932b 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -2492,7 +2492,8 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, ipa_node_params *info = ipa_node_params_sum->get (cs->caller); ipa_edge_args *args = ipa_edge_args_sum->get_create (cs); gcall *call = cs->call_stmt; - int n, arg_num = gimple_call_num_args (call); + callback_info *ci = callback_info_sum->get (cs); + int n, arg_num = callback_call_num_args_summary (call, ci); bool useful_context = false; if (arg_num == 0 || args->jump_functions) @@ -2508,7 +2509,17 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, for (n = 0; n < arg_num; n++) { struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n); - tree arg = gimple_call_arg (call, n); + tree arg; + if (cs->callback) + { + gcc_assert (cs->callee->assume_function); + int remapped_idx = ci->arg_mapping[n]; + if (remapped_idx == ARG_MAPPING_UNKNOWN_IDX) + continue; + arg = gimple_call_arg (call, remapped_idx); + } + else + arg = gimple_call_arg (call, n); tree param_type = ipa_get_callee_param_type (cs, n); if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg))) {
