On Mon, May 17, 2021 at 9:32 AM Uecker, Martin
<martin.uec...@med.uni-goettingen.de> wrote:
>
>
>
> Am Montag, den 17.05.2021, 09:08 +0200 schrieb Richard Biener:
> > On Sun, May 16, 2021 at 8:57 AM Uecker, Martin
> > <martin.uec...@med.uni-goettingen.de> wrote:
> > >
> > >
> > > Hi Richard,
> > >
> > > I noticed that GCC 11 has different behavior in the following
> > > example relative to 10.2 with -O2. I wonder whether this
> > > is an intentional change and if yes, what are the rules?
> >
> > Yes, this is a fix for the long-standing PR57359 where we
> > failed to preserve the order of stores when applying store-motion.
> >
> > The basic rule is that stores may not be re-ordered based on
> > TBAA since a store changes the dynamic type of a memory
> > location.  That notably happens for C/C++ programs re-using
> > allocated storage and for C++ programs using placement
> > new.
> >
> > It looked like a not so important bug since all other compilers
> > fall into the same trap, nevertheless they are all wrong in
> > doing so (and so was GCC).  All work fine at -O0 of course.
> >
> > Richard.
>
> This is excellent news! We were already thinking about
> how one could change the effective type rules in C, but
> it is not clear how this could have been done.

Yes, indeed.  It also turned out the solution found for GCC
has zero performance impact in practice.  The idea is simply
to re-do dependent stores in program order on each loop exit.
Without this "trick" fixing the bug has severe impact on SPEC
(fixing as in disabling the invalid store-motion optimizations).

Richard.

> Best,
> Martin
>
>
>
> > > Thanks!
> > > Martin
> > >
> > > https://godbolt.org/z/57res7ax1
> > >
> > > #include <stdio.h>
> > > #include <stdlib.h>
> > >
> > >
> > > __attribute__((__noinline__, __weak__))
> > > void f(long unk, void *pa, void *pa2, void *pb, long *x) {
> > >   for (long i = 0; i < unk; ++i) {
> > >     int oldy = *(int *)pa;
> > >     *(float *)pb = 42;
> > >     *(int *)pa2 = oldy ^ x[i];
> > >   }
> > > }
> > >
> > > int main(void) {
> > >   void *p = malloc(sizeof(int));
> > >   *(int *)p = 13;
> > >   f(1, p, p, p, (long []){ 0 });
> > >   printf("*pa(%d)\n", *(int *)p);
> > > }

Reply via email to