https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70526

--- Comment #20 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Jan de Mooij from comment #17)
> Thank you for looking into this again.
> 
> I don't understand comment 16 though:
> 
> > _BUT_ here we access D.3125 both as Register (the store)
> > and as its declared type TypedOrValueRegister (the load).
> 
> So D.3125 is a TypedOrValueRegister right? TypedOrValueRegister is defined as
> 
> class TypedOrValueRegister
> {
>     MIRType type_;
>     AlignedStorage2<Register> typed;
> ...
> 
> So IIUC it's wrong to store to |typed| in the constructor, by doing this:
> 
> *typed.addr() = reg;
> 
> Why is that? Any suggestions on how to fix this on our end?

No, it's valid to do that.  What is not valid is to copy TypedOrValueRegister
with a plain assignment (well, or the C++ FE is implementing that wrongly).

In C language terms the analogy is when you write

struct X { int type; char c[16]; };

float foo ()
{
 struct X x;
 x.type = 1;
 *(float *)x.c = 1.0;
 struct X y = x;
 return *(float *)y.c;
}

then the aggregate copy y = x is not using an effective type that aliases
with the float store/load and thus it can be re-ordered with both the store
and the load.

I'd have to dive deep into the C++ standard to find the equivalent wording
about how TBAA applies to class types (and the C++ notion of the type
in effect when writing an aggregate assignment or a copy via a return 
by value or passing a parameter by value).  It might be that the C++ standard
writes the copying is done member-wise with accesses that have the member
type as effective type for TBAA which would mean the C++ FE has to implement
aggregate assignment differently.  Note this applies to PODs mostly as
non-PODs would invoke the copy constructor (where then the question is on
the constraints of the default implementation done by GCC again).

I'm going to backport the original fix and I think the new issue warrants
a separate bug as it only affects GCC 6.

Reply via email to