Hi,

On Mon, Sep 21 2026, Josef Melcr wrote:
> Internal callback edges cause some trouble during ipa-fnsummary summary
> generation.
>
> First one is that fnsummary only looks at regular (i.e. not internal) calls
> and tries to fetch their callgraph edges.  Because internal callback
> edges will be created as a part of ipa-prop, the edge might not always
> exist.  We can anticipate this situation and guard it with an assert to
> make sure it only happens for internal IFN_ASSUME calls.
>
> The second one is the summary itself.  The existing callback edge logic
> assumes the existence of a callback-carrying edge, which the internal
> callback edges lack.  In order to have the correct size and time (both
> being 0) filled, we need to special case this situation as well.
>
> gcc/ChangeLog:
>
>       * ipa-fnsummary.cc (analyze_function_body): Adjust summary
>       generation for internal callback edges.
>
> Signed-off-by: Josef Melcr <[email protected]>
> ---
>  gcc/ipa-fnsummary.cc | 22 +++++++++++++++++++++-
>  1 file changed, 21 insertions(+), 1 deletion(-)
>
> diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc
> index b8571c5b718..423b1c4fdf8 100644
> --- a/gcc/ipa-fnsummary.cc
> +++ b/gcc/ipa-fnsummary.cc
> @@ -90,6 +90,8 @@ along with GCC; see the file COPYING3.  If not see
>  #include "symtab-clones.h"
>  #include "gimple-range.h"
>  #include "tree-dfa.h"
> +#include "attr-callback.h"
> +#include "callback-info.h"
>  
>  /* Summaries.  */
>  fast_function_summary <ipa_fn_summary *, va_gc> *ipa_fn_summaries;
> @@ -3058,9 +3060,18 @@ analyze_function_body (struct cgraph_node *node, bool 
> early)
>           }
>  
>         if (is_gimple_call (stmt)
> -           && !gimple_call_internal_p (stmt))
> +           && (!gimple_call_internal_p (stmt)
> +               || gimple_call_internal_fn (stmt) == IFN_ASSUME))
>           {
>             struct cgraph_edge *edge = node->get_edge (stmt);
> +           if (!edge)
> +             {
> +               /* The edge for .ASSUME outlined bodies is created when
> +                  generating ipa-sra summaries.  Ignore the call statement
> +                  for now.  */

I have issues understanding the comment, why only the statements with an
edge?  Perhaps this is only about those that have not been processed by
IPA-SRA analysis (yet)?

> +               gcc_checking_assert (callback_ifn_assume_call_p (stmt));
> +               continue;

While probably harmless, at least until someone adds something below it,
this continue statement makes me nervous, it skips much more than the if
block.

Can we perhaps change the condition to:

          cgraph_edge *edge;
          if (is_gimple_call (stmt)
              && (!gimple_call_internal_p (stmt)
                  || gimple_call_internal_fn (stmt) == IFN_ASSUME))
              && (edge = node->get_edge (stmt)))

instead?

> +             }
>             ipa_call_summary *es = ipa_call_summaries->get_create (edge);
>  
>             /* Special case: results of BUILT_IN_CONSTANT_P will be always
> @@ -3147,6 +3158,15 @@ analyze_function_body (struct cgraph_node *node, bool 
> early)
>                     es2->call_stmt_time = 0;
>                   }
>               }
> +           /* Internal calls are not in the callgraph, so edges pointing to
> +              .ASSUME bodies are not covered by the above branch, as the
> +              dispatching edge doesn't exist.  */
> +           else if (edge->callback)
> +             {
> +               gcc_checking_assert (edge->callee->assume_function);
> +               es->call_stmt_size = 0;
> +               es->call_stmt_time = 0;
> +             }
>           }

I guess OK with the above changes.

Thanks,

Martin

Reply via email to