Hi,

On Mon, Sep 21 2026, Josef Melcr wrote:
> The ipa-icf pass doesn't differentiate an assume body from a regular
> function.  If an assume body calls a function which gets inlined, a case
> can arise where the assume is equivalent to the function it used to
> call, leading to ipa-icf wanting to merge them together.  While we want
> to merge assumes together, merging them with a non-assume function is
> problematic.  This patch prevents this.
>
> gcc/ChangeLog:
>
>       * ipa-icf.cc (sem_function::get_hash): Hash
>       cgraph_node::assume_function.
>       (sem_function::equals_wpa): Check for assume_function equality.
>       (sem_function::equals_private): Likewise.
>
> Signed-off-by: Josef Melcr <[email protected]>
> ---
>  gcc/ipa-icf.cc | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/gcc/ipa-icf.cc b/gcc/ipa-icf.cc
> index 64cc722bd7a..21db43a99ee 100644
> --- a/gcc/ipa-icf.cc
> +++ b/gcc/ipa-icf.cc
> @@ -295,6 +295,7 @@ sem_function::get_hash (void)
>        hstate.add_flag (DECL_CXX_CONSTRUCTOR_P (decl));
>        hstate.add_flag (DECL_CXX_DESTRUCTOR_P (decl));
>        hstate.add_flag (DECL_STATIC_CHAIN (decl));
> +      hstate.add_flag (dyn_cast<cgraph_node *> (node)->assume_function);

My preference would be to use as_a instead of dyn_cast.  I have just
noticed that dyn_cast is used throughout ipa-icf.cc in places where it
just cannot return nullptr, but it just does not feel right.

>  
>        set_hash (hstate.end ());
>      }
> @@ -538,6 +539,8 @@ sem_function::equals_wpa (sem_item *item,
>        || cnode->must_remain_in_tu_body || cnode2->must_remain_in_tu_body)
>      return return_false_with_msg ("must remain in TU");
>  
> +  if (cnode->assume_function != cnode2->assume_function)
> +    return return_false_with_msg ("assume_function mismatch");
>    if (cnode->thunk != cnode2->thunk)
>      return return_false_with_msg ("thunk mismatch");
>    if (cnode->former_thunk_p () != cnode2->former_thunk_p ())
> @@ -889,7 +892,13 @@ sem_function::equals_private (sem_item *item)
>   if (DECL_STATIC_CHAIN (decl) != DECL_STATIC_CHAIN (m_compared_func->decl))
>      return return_false_with_msg ("static chain mismatch");
>  
> -  if (!dyn_cast <cgraph_node *> (node)->has_gimple_body_p ())
> +  cgraph_node *cnode = dyn_cast<cgraph_node *> (node);
> +  cgraph_node *cnode2 = dyn_cast<cgraph_node *> (m_compared_func->node);

Likewise.

Other than that, this is OK once the assume_function flag is in (you
might even want to squash it into the same commit).

Thanks,

Martin

> +
> +  if (cnode->assume_function != cnode2->assume_function)
> +    return return_false_with_msg ("assume_function mismatch");
> +
> +  if (!cnode->has_gimple_body_p ())
>      return true;
>  
>    /* Fill-up label dictionary.  */
> -- 
> 2.55.0

Reply via email to