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.