Message ID | ri6o7xsena9.fsf@suse.cz |
---|---|
State | New, archived |
Headers |
Return-Path: <gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a98:d5ce:0:b0:178:cc93:bf7d with SMTP id g14csp450869eik; Wed, 13 Jul 2022 14:06:08 -0700 (PDT) X-Google-Smtp-Source: AGRyM1tg+X8tjYeUoB8ofho1ZB4IrSOjexlxHnLAuatXHeI28TxapijXWB+wRBrrcb+aSmZB7NGx X-Received: by 2002:a17:906:84f7:b0:72b:47ba:33b6 with SMTP id zp23-20020a17090684f700b0072b47ba33b6mr5079935ejb.699.1657746368425; Wed, 13 Jul 2022 14:06:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657746368; cv=none; d=google.com; s=arc-20160816; b=truQM2HiKwPPTH3E/iHSejlNxP/Izu2do+huQYNSNqy1puTHOsf2hOSro5ESaE4crR SlFb9dCu8jtHyjN4ElGk7vz7jbmM/0t2LZmCK1fEoo8KIN4rlGV+yhEd5qgbiwEXXTVO vNoNRgpw2Th5vlEGMY8uVnxC84cDYmL3LeQdwYa+icQijkk9BpgshGMrNZHcsRr/Qn4p x7c/9swUwAR2v0Bw+IcU2OSH1E3UPZJ6ON+CTMX/MiqZ4DHCttHfkrVEyuKotACPS6Xv iZz4B8wPz1G4eFr1AsSi1FoXDXOOgwl62KYrgWM1UJHyigC38Waz7HW5KtY1DOVsZVJC VUWw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:mime-version:message-id:date :user-agent:subject:to:from:dkim-signature:dkim-signature :dmarc-filter:delivered-to; bh=jXDzfiR1Ml+PCi0zhSd2yR5r9Sc7G0+980qMMFnKwas=; b=KU8kTbFSM1N1yiyM82rxE25UQ7tjawjgM4hs4CimMnL1/yFBWO6FRZIaiD8uLnFSgR 5VpEFjfckgkTK6OzCBj2PLHj4EcnNHnbh30QlZ8W9/uh0iWczJztrP4+Ob+3yLIbUabH 0ynp4DHuUHcRfvPRQe8kY6YUhUxJXldU9E2vfHL3jndyYXIaUZZCXAfiqOFS2YbrLG0Z 29EK3vd+HQQzRaJ3OjZeUNTGVp3DKLErYQi3CzHnBuiqjU9eDWz6fFr8i8KDQET9xIAd +k2qUfG9+WOVse+MTcvlkHeiLvAKXHAQkga4FB+S4wKU2jf0hUR1tT+Pvu7lpm4dUucz N5kw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@suse.cz header.s=susede2_rsa header.b=ITzk4KIL; dkim=neutral (no key) header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id g27-20020a1709063b1b00b00706fe017e89si2075505ejf.880.2022.07.13.14.06.08 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Jul 2022 14:06:08 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@suse.cz header.s=susede2_rsa header.b=ITzk4KIL; dkim=neutral (no key) header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 17A3E385627D for <ouuuleilei@gmail.com>; Wed, 13 Jul 2022 21:06:03 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by sourceware.org (Postfix) with ESMTPS id 517BE3858D1E for <gcc-patches@gcc.gnu.org>; Wed, 13 Jul 2022 21:05:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 517BE3858D1E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.cz Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.cz Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out1.suse.de (Postfix) with ESMTP id 067C234401 for <gcc-patches@gcc.gnu.org>; Wed, 13 Jul 2022 21:05:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1657746338; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type; bh=jXDzfiR1Ml+PCi0zhSd2yR5r9Sc7G0+980qMMFnKwas=; b=ITzk4KILzMPiKFlcSNbLTtsyNz+qSPKGHvpUQu6xEW2pl3gdLVBzIq0oBuV8mN8IgJFq4q uB4WJJ7J4SaFC7qbUIuBJ9dSMnJx9AT1HwY2Fm1E92dnlJWw8gUfiqsDwlPvDCbs9HXFF6 FR29b6BO5oilRbtBaWAMICtQnYAOru4= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1657746338; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type; bh=jXDzfiR1Ml+PCi0zhSd2yR5r9Sc7G0+980qMMFnKwas=; b=efFf3pktzE11u0f5406f+PhxFfbyO06TzFpsGDcFsWrvcKWDscuTc/6QilS6pD4KvGw4V5 ZXGWiOxVCAmFkADg== Received: from suse.cz (unknown [10.100.200.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by relay2.suse.de (Postfix) with ESMTPS id D72A32C141; Wed, 13 Jul 2022 21:05:37 +0000 (UTC) From: Martin Jambor <mjambor@suse.cz> To: GCC Patches <gcc-patches@gcc.gnu.org> Subject: [PATCH] ipa-cp: Fix assert triggering with -fno-toplevel-reorder (PR 106260) User-Agent: Notmuch/0.35 (https://notmuchmail.org) Emacs/28.1 (x86_64-suse-linux-gnu) Date: Wed, 13 Jul 2022 23:05:34 +0200 Message-ID: <ri6o7xsena9.fsf@suse.cz> MIME-Version: 1.0 Content-Type: text/plain X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list <gcc-patches.gcc.gnu.org> List-Unsubscribe: <https://gcc.gnu.org/mailman/options/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe> List-Archive: <https://gcc.gnu.org/pipermail/gcc-patches/> List-Post: <mailto:gcc-patches@gcc.gnu.org> List-Help: <mailto:gcc-patches-request@gcc.gnu.org?subject=help> List-Subscribe: <https://gcc.gnu.org/mailman/listinfo/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> Cc: Jan Hubicka <jh@suse.cz> Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" <gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org> X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1738273055732596874?= X-GMAIL-MSGID: =?utf-8?q?1738273055732596874?= |
Series |
ipa-cp: Fix assert triggering with -fno-toplevel-reorder (PR 106260)
|
|
Commit Message
Martin Jambor
July 13, 2022, 9:05 p.m. UTC
Hi, with -fno-toplevel-reorder (and -fwhole-program), there apparently can be local functions without any callers. This is something that IPA-CP does not like because its propagation verifier checks that local functions do not end up with TOP in their lattices. Therefore there is an assert checking that all call-less unreachable functions have been removed, which triggers in PR 106260 with these two options. This patch detects the situation and marks the lattices as variable, thus avoiding both the assert trigger and the verification failure. Bootstrapped and tested on x86_64-linux. OK for master and then all active release branches? Thanks, Martin gcc/ChangeLog: 2022-07-13 Martin Jambor <mjambor@suse.cz> PR ipa/106260 * ipa-cp.cc (initialize_node_lattices): Replace assert that there are callers with handling that situation when -fno-toplevel_reorder. gcc/testsuite/ChangeLog: 2022-07-13 Martin Jambor <mjambor@suse.cz> PR ipa/106260 * g++.dg/ipa/pr106260.C: New test. --- gcc/ipa-cp.cc | 6 ++- gcc/testsuite/g++.dg/ipa/pr106260.C | 64 +++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/ipa/pr106260.C
Comments
On Wed, Jul 13, 2022 at 11:06 PM Martin Jambor <mjambor@suse.cz> wrote: > > Hi, > > with -fno-toplevel-reorder (and -fwhole-program), there apparently can > be local functions without any callers. Did you check why? Can't we fix that? > This is something that IPA-CP > does not like because its propagation verifier checks that local > functions do not end up with TOP in their lattices. Therefore there > is an assert checking that all call-less unreachable functions have > been removed, which triggers in PR 106260 with these two options. > > This patch detects the situation and marks the lattices as variable, > thus avoiding both the assert trigger and the verification failure. > > Bootstrapped and tested on x86_64-linux. OK for master and then all > active release branches? > > Thanks, > > Martin > > > gcc/ChangeLog: > > 2022-07-13 Martin Jambor <mjambor@suse.cz> > > PR ipa/106260 > * ipa-cp.cc (initialize_node_lattices): Replace assert that there are > callers with handling that situation when -fno-toplevel_reorder. > > gcc/testsuite/ChangeLog: > > 2022-07-13 Martin Jambor <mjambor@suse.cz> > > PR ipa/106260 > * g++.dg/ipa/pr106260.C: New test. > --- > gcc/ipa-cp.cc | 6 ++- > gcc/testsuite/g++.dg/ipa/pr106260.C | 64 +++++++++++++++++++++++++++++ > 2 files changed, 69 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/ipa/pr106260.C > > diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc > index 543a9334e2c..f699a8dadc0 100644 > --- a/gcc/ipa-cp.cc > +++ b/gcc/ipa-cp.cc > @@ -1286,10 +1286,14 @@ initialize_node_lattices (struct cgraph_node *node) > int caller_count = 0; > node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count, > true); > - gcc_checking_assert (caller_count > 0); > if (caller_count == 1) > node->call_for_symbol_thunks_and_aliases (set_single_call_flag, > NULL, true); > + else if (caller_count == 0) > + { > + gcc_checking_assert (!opt_for_fn (node->decl, flag_toplevel_reorder)); > + variable = true; > + } > } > else > { > diff --git a/gcc/testsuite/g++.dg/ipa/pr106260.C b/gcc/testsuite/g++.dg/ipa/pr106260.C > new file mode 100644 > index 00000000000..bd3b6e0af79 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/ipa/pr106260.C > @@ -0,0 +1,64 @@ > +// { dg-do compile } > +// { dg-options "-O2 -std=gnu++14 -fwhole-program -fno-unit-at-a-time" } > + > +struct A; > +template <class T> > +struct Q { Q (T); }; > +template<typename T, class D> > +struct U { > + ~U () { m1 (nullptr); } > + D m2 (); > + T *u; > + void m1 (T *) { m2 () (u); } > +}; > +struct F { F (int *); }; > +template <class, class T = F> > +using W = Q<T>; > +int a, b; > +void fn1 (void *); > +template <class T> > +void > +fn2 (T *x) > +{ > + if (x) > + x->~T(); > + fn1 (x); > +} > +template <typename T> > +struct C { > + void operator() (T *x) { fn2 (x); } > +}; > +struct D; > +template <typename T, typename D = C<T> > > +using V = U<T, D>; > +struct A { > + A (int *); > +}; > +struct S; > +struct G { > + V<S> m3 (); > +}; > +struct S { > + int e; > + virtual ~S () {} > +}; > +template<typename T> > +struct H { > + H (int, T x, int) : h(x) {} > + G g; > + void m4 () { g.m3 (); } > + T h; > +}; > +struct I { > + I(A, W<D>); > +}; > +void > +test () > +{ > + A c (&b); > + W<D> d (&b); > + I e (c, d); > + H<I> f (0, e, a); > + f.m4 (); > +} > + > -- > 2.36.1 >
Hi, On Thu, Jul 14 2022, Richard Biener wrote: > On Wed, Jul 13, 2022 at 11:06 PM Martin Jambor <mjambor@suse.cz> wrote: >> >> Hi, >> >> with -fno-toplevel-reorder (and -fwhole-program), there apparently can >> be local functions without any callers. > > Did you check why? Can't we fix that? no, I have not checked much. Our manual description of -fno-toplevel-reorder says that: "When this option is used, unreferenced static variables are not removed." In the beginning, static (because of -fwhole-program) variables _ZTV1S and __gxx_personality_v0 do refer to the destructor in question, my hypothesis is that the dead function removal code somehow has to be careful in case these have been already output, even when these two variables are no longer in the symbol table when IPA-CP runs. But I did not look deeper, hoping that Honza would correct me if I am totally off. Perhaps the bug is that the function should not be local even with -fwhole-program. The semantics of this combination of options is a bit unclear to me. Martin > >> This is something that IPA-CP >> does not like because its propagation verifier checks that local >> functions do not end up with TOP in their lattices. Therefore there >> is an assert checking that all call-less unreachable functions have >> been removed, which triggers in PR 106260 with these two options. >> >> This patch detects the situation and marks the lattices as variable, >> thus avoiding both the assert trigger and the verification failure. >> >> Bootstrapped and tested on x86_64-linux. OK for master and then all >> active release branches? >> >> Thanks, >> >> Martin >> >> >> gcc/ChangeLog: >> >> 2022-07-13 Martin Jambor <mjambor@suse.cz> >> >> PR ipa/106260 >> * ipa-cp.cc (initialize_node_lattices): Replace assert that there are >> callers with handling that situation when -fno-toplevel_reorder. >> >> gcc/testsuite/ChangeLog: >> >> 2022-07-13 Martin Jambor <mjambor@suse.cz> >> >> PR ipa/106260 >> * g++.dg/ipa/pr106260.C: New test. >> --- >> gcc/ipa-cp.cc | 6 ++- >> gcc/testsuite/g++.dg/ipa/pr106260.C | 64 +++++++++++++++++++++++++++++ >> 2 files changed, 69 insertions(+), 1 deletion(-) >> create mode 100644 gcc/testsuite/g++.dg/ipa/pr106260.C >> >> diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc >> index 543a9334e2c..f699a8dadc0 100644 >> --- a/gcc/ipa-cp.cc >> +++ b/gcc/ipa-cp.cc >> @@ -1286,10 +1286,14 @@ initialize_node_lattices (struct cgraph_node *node) >> int caller_count = 0; >> node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count, >> true); >> - gcc_checking_assert (caller_count > 0); >> if (caller_count == 1) >> node->call_for_symbol_thunks_and_aliases (set_single_call_flag, >> NULL, true); >> + else if (caller_count == 0) >> + { >> + gcc_checking_assert (!opt_for_fn (node->decl, flag_toplevel_reorder)); >> + variable = true; >> + } >> } >> else >> { >> diff --git a/gcc/testsuite/g++.dg/ipa/pr106260.C b/gcc/testsuite/g++.dg/ipa/pr106260.C >> new file mode 100644 >> index 00000000000..bd3b6e0af79 >> --- /dev/null >> +++ b/gcc/testsuite/g++.dg/ipa/pr106260.C >> @@ -0,0 +1,64 @@ >> +// { dg-do compile } >> +// { dg-options "-O2 -std=gnu++14 -fwhole-program -fno-unit-at-a-time" } >> + >> +struct A; >> +template <class T> >> +struct Q { Q (T); }; >> +template<typename T, class D> >> +struct U { >> + ~U () { m1 (nullptr); } >> + D m2 (); >> + T *u; >> + void m1 (T *) { m2 () (u); } >> +}; >> +struct F { F (int *); }; >> +template <class, class T = F> >> +using W = Q<T>; >> +int a, b; >> +void fn1 (void *); >> +template <class T> >> +void >> +fn2 (T *x) >> +{ >> + if (x) >> + x->~T(); >> + fn1 (x); >> +} >> +template <typename T> >> +struct C { >> + void operator() (T *x) { fn2 (x); } >> +}; >> +struct D; >> +template <typename T, typename D = C<T> > >> +using V = U<T, D>; >> +struct A { >> + A (int *); >> +}; >> +struct S; >> +struct G { >> + V<S> m3 (); >> +}; >> +struct S { >> + int e; >> + virtual ~S () {} >> +}; >> +template<typename T> >> +struct H { >> + H (int, T x, int) : h(x) {} >> + G g; >> + void m4 () { g.m3 (); } >> + T h; >> +}; >> +struct I { >> + I(A, W<D>); >> +}; >> +void >> +test () >> +{ >> + A c (&b); >> + W<D> d (&b); >> + I e (c, d); >> + H<I> f (0, e, a); >> + f.m4 (); >> +} >> + >> -- >> 2.36.1 >>
> Hi, > > with -fno-toplevel-reorder (and -fwhole-program), there apparently can > be local functions without any callers. This is something that IPA-CP If there is possibility to trigger a local function without callers, I think one can also make two local functions calling each other but with no other callers. So I think you need to wait until dataflow solution stabilizes and then then find such isolated cases and do something sensible (as of not crashing since the code is dead anyway). -fno-toplevel-reorder was kind of meant to get close to what -fno-unit-at-a-time did to make legacy code (kernel) happy. Without unit-at-a-time we did not remove local functions unless we decided to inline them since they were output before we had chance to realize that they were unused. Since we document that only about static variables, perhaps we could simply start removing functions to avoid these side cases? Honza > does not like because its propagation verifier checks that local > functions do not end up with TOP in their lattices. Therefore there > is an assert checking that all call-less unreachable functions have > been removed, which triggers in PR 106260 with these two options. > > This patch detects the situation and marks the lattices as variable, > thus avoiding both the assert trigger and the verification failure. > > Bootstrapped and tested on x86_64-linux. OK for master and then all > active release branches? > > Thanks, > > Martin > > > gcc/ChangeLog: > > 2022-07-13 Martin Jambor <mjambor@suse.cz> > > PR ipa/106260 > * ipa-cp.cc (initialize_node_lattices): Replace assert that there are > callers with handling that situation when -fno-toplevel_reorder. > > gcc/testsuite/ChangeLog: > > 2022-07-13 Martin Jambor <mjambor@suse.cz> > > PR ipa/106260 > * g++.dg/ipa/pr106260.C: New test. > --- > gcc/ipa-cp.cc | 6 ++- > gcc/testsuite/g++.dg/ipa/pr106260.C | 64 +++++++++++++++++++++++++++++ > 2 files changed, 69 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/ipa/pr106260.C > > diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc > index 543a9334e2c..f699a8dadc0 100644 > --- a/gcc/ipa-cp.cc > +++ b/gcc/ipa-cp.cc > @@ -1286,10 +1286,14 @@ initialize_node_lattices (struct cgraph_node *node) > int caller_count = 0; > node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count, > true); > - gcc_checking_assert (caller_count > 0); > if (caller_count == 1) > node->call_for_symbol_thunks_and_aliases (set_single_call_flag, > NULL, true); > + else if (caller_count == 0) > + { > + gcc_checking_assert (!opt_for_fn (node->decl, flag_toplevel_reorder)); > + variable = true; > + } > } > else > { > diff --git a/gcc/testsuite/g++.dg/ipa/pr106260.C b/gcc/testsuite/g++.dg/ipa/pr106260.C > new file mode 100644 > index 00000000000..bd3b6e0af79 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/ipa/pr106260.C > @@ -0,0 +1,64 @@ > +// { dg-do compile } > +// { dg-options "-O2 -std=gnu++14 -fwhole-program -fno-unit-at-a-time" } > + > +struct A; > +template <class T> > +struct Q { Q (T); }; > +template<typename T, class D> > +struct U { > + ~U () { m1 (nullptr); } > + D m2 (); > + T *u; > + void m1 (T *) { m2 () (u); } > +}; > +struct F { F (int *); }; > +template <class, class T = F> > +using W = Q<T>; > +int a, b; > +void fn1 (void *); > +template <class T> > +void > +fn2 (T *x) > +{ > + if (x) > + x->~T(); > + fn1 (x); > +} > +template <typename T> > +struct C { > + void operator() (T *x) { fn2 (x); } > +}; > +struct D; > +template <typename T, typename D = C<T> > > +using V = U<T, D>; > +struct A { > + A (int *); > +}; > +struct S; > +struct G { > + V<S> m3 (); > +}; > +struct S { > + int e; > + virtual ~S () {} > +}; > +template<typename T> > +struct H { > + H (int, T x, int) : h(x) {} > + G g; > + void m4 () { g.m3 (); } > + T h; > +}; > +struct I { > + I(A, W<D>); > +}; > +void > +test () > +{ > + A c (&b); > + W<D> d (&b); > + I e (c, d); > + H<I> f (0, e, a); > + f.m4 (); > +} > + > -- > 2.36.1 >
Hi, On Mon, Jul 18 2022, Jan Hubicka wrote: >> Hi, >> >> with -fno-toplevel-reorder (and -fwhole-program), there apparently can >> be local functions without any callers. This is something that IPA-CP > > If there is possibility to trigger a local function without callers, I > think one can also make two local functions calling each other but with > no other callers. I am not sure I understand. The above can happen only with -fno-toplevel-reorder, right? > > So I think you need to wait until dataflow solution stabilizes and > then then find such isolated cases and do something sensible (as of > not crashing since the code is dead anyway). After dataflow stabilizes, it crashes only because a verifier does not like the result. Perhaps the solution is simply not verify nodes built with -fno-toplevel-reorder? But the assert was useful in the past in the general case so I'd like to keep it. I can now see that the proposed patch could also pessimize the lattices of functions that the dead functions call a bit, although arguably it might be the right thing to do, since we cannot say anything about these calls. But I do not care much. > > -fno-toplevel-reorder was kind of meant to get close to what -fno-unit-at-a-time > did to make legacy code (kernel) happy. Without unit-at-a-time we did > not remove local functions unless we decided to inline them since they > were output before we had chance to realize that they were unused. I understand that it is legacy stuff but actually I wonder what the option means for IPA in general. Is IPA run after we might have output something already? (If not then why do we see any differences? If yes, can all IPA optimizations work, especially with -fwhole-program?) > > Since we document that only about static variables, perhaps we could > simply start removing functions to avoid these side cases? Well, the funny thing is that we eventually do remove the function, just at IPA-CP stage it is there and not even local yet (I have not noticed this last week). Removing it earlier would definitely make life simpler for me :-) Anyway, I'm happy to work in whichever direction you prefer, just now I am not sure which one it is. Thanks, Martin > >> does not like because its propagation verifier checks that local >> functions do not end up with TOP in their lattices. Therefore there >> is an assert checking that all call-less unreachable functions have >> been removed, which triggers in PR 106260 with these two options. >> >> This patch detects the situation and marks the lattices as variable, >> thus avoiding both the assert trigger and the verification failure. >> >> Bootstrapped and tested on x86_64-linux. OK for master and then all >> active release branches? >> >> Thanks, >> >> Martin >> >> >> gcc/ChangeLog: >> >> 2022-07-13 Martin Jambor <mjambor@suse.cz> >> >> PR ipa/106260 >> * ipa-cp.cc (initialize_node_lattices): Replace assert that there are >> callers with handling that situation when -fno-toplevel_reorder. >>
diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc index 543a9334e2c..f699a8dadc0 100644 --- a/gcc/ipa-cp.cc +++ b/gcc/ipa-cp.cc @@ -1286,10 +1286,14 @@ initialize_node_lattices (struct cgraph_node *node) int caller_count = 0; node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count, true); - gcc_checking_assert (caller_count > 0); if (caller_count == 1) node->call_for_symbol_thunks_and_aliases (set_single_call_flag, NULL, true); + else if (caller_count == 0) + { + gcc_checking_assert (!opt_for_fn (node->decl, flag_toplevel_reorder)); + variable = true; + } } else { diff --git a/gcc/testsuite/g++.dg/ipa/pr106260.C b/gcc/testsuite/g++.dg/ipa/pr106260.C new file mode 100644 index 00000000000..bd3b6e0af79 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr106260.C @@ -0,0 +1,64 @@ +// { dg-do compile } +// { dg-options "-O2 -std=gnu++14 -fwhole-program -fno-unit-at-a-time" } + +struct A; +template <class T> +struct Q { Q (T); }; +template<typename T, class D> +struct U { + ~U () { m1 (nullptr); } + D m2 (); + T *u; + void m1 (T *) { m2 () (u); } +}; +struct F { F (int *); }; +template <class, class T = F> +using W = Q<T>; +int a, b; +void fn1 (void *); +template <class T> +void +fn2 (T *x) +{ + if (x) + x->~T(); + fn1 (x); +} +template <typename T> +struct C { + void operator() (T *x) { fn2 (x); } +}; +struct D; +template <typename T, typename D = C<T> > +using V = U<T, D>; +struct A { + A (int *); +}; +struct S; +struct G { + V<S> m3 (); +}; +struct S { + int e; + virtual ~S () {} +}; +template<typename T> +struct H { + H (int, T x, int) : h(x) {} + G g; + void m4 () { g.m3 (); } + T h; +}; +struct I { + I(A, W<D>); +}; +void +test () +{ + A c (&b); + W<D> d (&b); + I e (c, d); + H<I> f (0, e, a); + f.m4 (); +} +