[Bug c++/99093] New: [missed optimization] Missed devirtualization involving internal-linkage class type (but only sometimes)
arthur.j.odwyer at gmail dot com
gcc-bugzilla@gcc.gnu.org
Sun Feb 14 01:08:17 GMT 2021
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99093
Bug ID: 99093
Summary: [missed optimization] Missed devirtualization
involving internal-linkage class type (but only
sometimes)
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: arthur.j.odwyer at gmail dot com
Target Milestone: ---
// https://godbolt.org/z/hx7h7v
struct Base {
virtual int f() { return 1; }
};
namespace {
struct Derived1 : public Base {
int f() override { return 2; }
};
struct Derived2 : public Base {};
}
int leaf_class1(Base *p) { return ((Derived1*)p)->f(); }
// devirtualized by GCC, because PrivateDerived is provably a leaf
int leaf_class2(Base *p) { return ((Derived2*)p)->f(); }
// not devirtualized by GCC -- this smells like a missed-optimization bug
====
GCC 4.9 started to be able to devirtualize things in the compiler, based on
translation-unit-wide (but still compiler-time) information. GCC 4.9.0 is able
to devirtualize the call in `leaf_class1`. This is awesome!
However, both GCC 4.9 and GCC trunk fail to apply the exact same optimization
to `leaf_class2`. The only difference between `Derived1` and `Derived2` is that
`Derived1::f` is declared directly in `Derived1` whereas `Derived2::f` is
technically a member of `Base`. That shouldn't matter at all to the
devirtualization logic. But apparently it does.
====
Barely possibly related missed-devirtualization bugs: #47316, #60674, #89924,
#94243.
More information about the Gcc-bugs
mailing list