Hi, On Mon, Jan 16 2023, Martin Liška wrote: > On 1/14/23 22:36, Jan Hubicka wrote: >>> Noticed during building of libbackend.a with the LTO partial linking. >>> >>> The function release_body is called even if clone_of is a clone >>> of a another function and thus it shares tree declaration. We should >>> preserve it in that situation. >>> >>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. >>> >>> Ready to be installed? >>> Thanks, >>> Martin >>> >>> PR ipa/107944 >>> >>> gcc/ChangeLog: >>> >>> * cgraph.cc (cgraph_node::remove): Do not release body >>> if a node is clone of another node. >>> --- >>> gcc/cgraph.cc | 2 +- >>> 1 file changed, 1 insertion(+), 1 deletion(-) >>> >>> diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc >>> index f15cb47c8b8..2e7d77ffd6c 100644 >>> --- a/gcc/cgraph.cc >>> +++ b/gcc/cgraph.cc >>> @@ -1893,7 +1893,7 @@ cgraph_node::remove (void) >>> else if (clone_of) >>> { >>> clone_of->clones = next_sibling_clone; >>> - if (!clone_of->analyzed && !clone_of->clones && !clones) >>> + if (!clone_of->analyzed && !clone_of->clones && !clones && >>> !clone_of->clone_of) >>> clone_of->release_body (); >> >> It is interesting that the problem reproduced only after almost 20 >> years. But I suppose it is because we materialize clones in parituclar >> order. > > Well, it started with r13-48-g27ee75dbe81bb7 where Martin add a new code > that calls the release_body function. So it's pretty new. > >> >> I think there are two ways to fix it. Either declare release_body to be >> applicable only to the master clone and avoid calling it here (as you >> do) or make release_body do nothing when called on a clone. >> I guess it makes sense to keep your approach but please add sanity check >> to release_body that clone_of == NULL with a comment. > > I do support Martin's enhanced version of the patch. >
I take that as an approval, so I am about to commit the following after re-testing it on trunk. Afterwards I'll backport it to the affected release branches too. Thanks, Martin The code removing function bodies when the last call graph clone of a node is removed is too aggressive when there are nodes up the clone_of chain which still need them. Fixed by expanding the check. gcc/ChangeLog: 2023-01-18 Martin Jambor <mjam...@suse.cz> PR ipa/107944 * cgraph.cc (cgraph_node::remove): Check whether nodes up the lcone_of chain also do not need the body. --- gcc/cgraph.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc index 5e60c2b73db..5f72ace9b57 100644 --- a/gcc/cgraph.cc +++ b/gcc/cgraph.cc @@ -1893,8 +1893,18 @@ cgraph_node::remove (void) else if (clone_of) { clone_of->clones = next_sibling_clone; - if (!clone_of->analyzed && !clone_of->clones && !clones) - clone_of->release_body (); + if (!clones) + { + bool need_body = false; + for (cgraph_node *n = clone_of; n; n = n->clone_of) + if (n->analyzed || n->clones) + { + need_body = true; + break; + } + if (!need_body) + clone_of->release_body (); + } } if (next_sibling_clone) next_sibling_clone->prev_sibling_clone = prev_sibling_clone; -- 2.39.0