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.

Reply via email to