http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45791
--- Comment #9 from Jan Hubicka <hubicka at gcc dot gnu.org> 2010-12-14 23:15:16 UTC --- OK, main() code seems to optimize out that is an imrovement. Is it optimized away with your patch pre-IPA too? Derived() is also devirtualizable: Derived::Derived() (struct Derived * const this) { int (*__vtbl_ptr_type) (void) * D.2237; int (*__vtbl_ptr_type) (void) D.2236; struct Base * D.2215; <bb 2>: D.2215_2 = &this_1(D)->D.2115; D.2215_2->_vptr.Base = &_ZTV4Base[2]; this_1(D)->D.2115._vptr.Base = &_ZTV7Derived[2]; D.2215_3 = &this_1(D)->D.2115; D.2237_9 = D.2215_3->_vptr.Base; D.2236_10 = MEM[(int (*__vtbl_ptr_type) (void) *)D.2237_9 + 16B]; OBJ_TYPE_REF(D.2236_10;D.2215_3->2) (D.2215_3); We fail to devirtualize pre-IPA. After IPA we compile into: <bb 2>: MEM[(struct Base *)this_1(D)]._vptr.Base = &_ZTV4Base[2]; this_1(D)->D.2115._vptr.Base = &_ZTV7Derived[2]; D.2215_3 = &this_1(D)->D.2115; D.2236_10 = (int (*__vtbl_ptr_type) (void)) f; a type mismatch?