[Bug ipa/80899] [6/7/8 Regression] Devirtualization causes incorrect code generation with placement new in some cases

2018-02-28 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80899

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org

--- Comment #7 from Jakub Jelinek  ---
Having placement new represented in the IL is something I've suggested several
times (e.g. to be able to be more aggressive on TBAA in loops which don't
contain any placement new), but Richard didn't like that.

[Bug ipa/80899] [6/7/8 Regression] Devirtualization causes incorrect code generation with placement new in some cases

2018-02-04 Thread hubicka at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80899

--- Comment #6 from Jan Hubicka  ---
The problem here is that after gimplification we make no distinction between
original pointer and pointer returned by placement new.  If one can placement
new different type to object into arbitrary field of structure, probably one
can do it also for automatic and static variables. So we would need to
anticipate dynamic type changes absolutely everywhere. This would more or less
disable nonspeculative devirtualization completely because in most cases there
is some function call between constructor and use of values which prevents us
from proving that the value did not change.

What we could do is to keep new operations represented in gimple form until
later stages of compilation (remove them soonish after IPA is done). So having
osmething like

 new_ptr = __builtin_placement_new (oldptr)

which would also hold type of the allocated value (not sure how to do that
without having declaration of biultin_placement_new for every type but even
that would work well for me). This would be useful information because devirt
machinery then could expect that the dynamic type did not change for all
polymorphic types and subtypes.

Would that make sense to you? Probably something for next stage1 though.

[Bug ipa/80899] [6/7/8 Regression] Devirtualization causes incorrect code generation with placement new in some cases

2018-02-01 Thread jason at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80899

Jason Merrill  changed:

   What|Removed |Added

 CC||jason at gcc dot gnu.org

--- Comment #5 from Jason Merrill  ---
(In reply to Jan Hubicka from comment #4)
> Is this valid C++? bar.mem is non-POD and is already constructed and it
> seems fishy to placement new it to something different.

It's very fishy; the code should use aligned_storage rather a different
non-trivial type.  My old proposed resolution for wg21.link/cwg1116 would have
clarified that this is undefined, and might still happen to resolve
wg21.link/cwg1027 , but it hasn't been accepted yet.

On the other hand, it is careful to use the pointer returned from placement new
rather than a pointer derived from mem, and it seems like we ought to use the
information from placement new to guide devirtualization.

So...sketchy code in a volatile area of semantics, but it seems like we could
get it right without breaking important optimizations.

[Bug ipa/80899] [6/7/8 Regression] Devirtualization causes incorrect code generation with placement new in some cases

2018-01-30 Thread hubicka at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80899

Jan Hubicka  changed:

   What|Removed |Added

 CC||jason at redhat dot com

--- Comment #4 from Jan Hubicka  ---
Is this valid C++? bar.mem is non-POD and is already constructed and it seems
fishy to placement new it to something different.
Devirtualization machinery does not consider that substructure of polymorphic
type may be replaced by arbitrary other type via placement new.

The testcase works on mainline. On GCC 7 we get:
  MEM[(struct foo *)].D.6234._vptr.base = [(void *)&_ZTV3fooIxE + 16B];   
  MEM[(struct foo *)].D.6370._vptr.base = [(void *)&_ZTV3fooIiE + 16B];   
  b.val =
  _8 = MEM[(struct base * *) + 8B];   
  _10 = _8->_vptr.base; 
  _11 = *_10;   
  OBJ_TYPE_REF(_11;(struct base)_8->0) (_8);
in a.C.036t.ealias and incorrect devirtualization happens in fre1 just after:
int main() ()
{
  struct bar b;

   [100.00%]:
  MEM[(struct foo *)].D.6234._vptr.base = [(void *)&_ZTV3fooIxE + 16B];
  MEM[(struct foo *)].D.6370._vptr.base = [(void *)&_ZTV3fooIiE + 16B];
  b.val = 
  foo::f ();

}
because of:
  Targets of polymorphic call of type 0:struct base token 0 
Outer type:struct foo offset 0  
This is a complete list.
   void foo::f() [with T = long long int]/73 

a.C:15:28: note: converting indirect call to function void foo::f() [with T
= long long int]

On mainline we get in the same context:
   Type inheritance inconsistent devirtualization of OBJ_TYPE_REF(f;>0)
();
 to OBJ_TYPE_REF(f;>0)   
  Removed EH side-effects.  

So the devirt machinery is says wrong answer, but FRE got smarter and
determines the correct destination with priority.

[Bug ipa/80899] [6/7/8 Regression] Devirtualization causes incorrect code generation with placement new in some cases

2017-11-20 Thread hubicka at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80899

Jan Hubicka  changed:

   What|Removed |Added

 Status|SUSPENDED   |ASSIGNED

--- Comment #3 from Jan Hubicka  ---
Looks like I set it to suspended instead of assigned and ignored ever since :(