On Fri, Jan 15, 2016 at 12:01 PM, Jan Hubicka <hubi...@ucw.cz> wrote: > Hi, > this patch avoid ipa-icf to take away body of a virtual function which is a > subject > of later devirtualization.
But isn't can_remove_if_no_direct_alls_p () supposed to return false then? (depending on cgraph state) Richard. > Bootstrapped/regtested x86_64-linux, comitted. > > Honza > > PR ipa/68148 > * ipa-icf.c (sem_function::merge): Virtual functions may become > reachable even if they address is not taken and there are no > idrect calls. > * testsuite/g++.dg/ipa/devirt-49.C: New testcase. > > Index: ipa-icf.c > =================================================================== > --- ipa-icf.c (revision 232407) > +++ ipa-icf.c (working copy) > @@ -1305,6 +1305,7 @@ sem_function::merge (sem_item *alias_ite > > /* If all callers was redirected, do not produce wrapper. */ > if (alias->can_remove_if_no_direct_calls_p () > + && !DECL_VIRTUAL_P (alias->decl) > && !alias->has_aliases_p ()) > { > create_wrapper = false; > Index: testsuite/g++.dg/ipa/devirt-49.C > =================================================================== > --- testsuite/g++.dg/ipa/devirt-49.C (revision 0) > +++ testsuite/g++.dg/ipa/devirt-49.C (revision 0) > @@ -0,0 +1,20 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-ipa-devirt" } */ > +struct Interface { > + virtual ~Interface() {} > + virtual void virtualFunc() = 0; > + virtual void virtualFunc2() = 0; > +}; > + > +struct Concrete : Interface { > + int counter_; > + Concrete() : counter_(0) {} > + void virtualFunc() { counter_++; } > + void virtualFunc2() { counter_++; } > +}; > + > +void test(Interface &c) { > + c.virtualFunc(); > + c.virtualFunc2(); > +} > +/* { dg-final { scan-ipa-dump "2 speculatively devirtualized" "devirt" } } > */