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