https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118896
Mikael Morin <mikael at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Component|tree-optimization |fortran --- Comment #6 from Mikael Morin <mikael at gcc dot gnu.org> --- I've had a look at this again. The dse2 removal: @@ -487,9 +140,6 @@ <bb 4> [local count: 1073312328]: afab._vptr = &__vtab_foo2_mod_Foo2; - _17 = MEM[(struct __class_foo2_mod_Foo2_t &)&a.3]._data; - *_17.foo.i = 2; - *_17.j = 3; a.3 ={v} {CLOBBER(eos)}; _13 = MEM[(struct foo *)_7].i; if (_13 != 2) seems to be valid because the surrounding code making the stores to i and j useful has been removed. I think the problem is more in dse1: @@ -146,13 +165,8 @@ <bb 4> : afab._vptr = &__vtab_foo2_mod_Foo2; - class.1._vptr = &__vtab_foo2_mod_Foo2; - af2.foo.i = 2; - af2.j = 3; class.1 ={v} {CLOBBER(eos)}; - class.2._vptr = &__vtab_foo2_mod_Foo2; class.2 ={v} {CLOBBER(eos)}; - a.3 = afab; doit2 (&a.3); a.3 ={v} {CLOBBER(eos)}; _16 = afab._data; where the a.3 = afab initialization should stay there. The detailed dump gives a hint: ipa-modref: call to doit2/10 does not use ref: a.3 alias sets: 4->4 Deleted dead store: a.3 = afab; so basically an alias set problem, most probably type-related. Here is how I understand it. We have two types foo and foo2, foo2 inheriting foo. Associated with the types there are two polymorphism wrappers, __class_foo_mod_Foo_t and __class_foo2_mod_Foo2_t respectively. Associated with each type there is a procedure, respectively doit and doit2. The doit2 procedure applies on variables of type foo2, so it expects a __class_foo2_mod_Foo2_t argument. The doit2 procedure can be called polymorphically, that is by calling object._vptr.doit (object). The code doing the polymorphic call, which only knows the parent type, calls the function as if it was a call to doit, so with an object of type __class_foo_mod_Foo_t. The optimizers are able to simplify object._vptr.doit to a direct call to doit2. The dse optimizer, knowing that doing2 only cares about things coming from a __class_foo2_mod_Foo2_t, happily remove initialization of the object passed as argument, which has type __class_foo_mod_Foo_t. doit2 is inlined. The remaining code from the inlined function, writing through uninitialized pointers, is removed. I don't know how it should be fixed, the doit2 argument should be a __class_foo2_mod_Foo2_t, and the polymorphic call should pass a __class_foo_mod_Foo_t as argument, so I don't see how it could work. Changing back to fortran, I'm pretty confident this is a frontend bug.