This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: More fun with aliasing - removing assignments?


On 8/2/05, Richard Guenther <richard.guenther@gmail.com> wrote:
> On 8/2/05, Diego Novillo <dnovillo@redhat.com> wrote:
> > On Mon, Aug 01, 2005 at 10:12:37PM -0700, Ian Lance Taylor wrote:
> > > Harald van D??k <truedfx@gentoo.org> writes:
> > >
> > > > I finally managed to track down the problem I've been having to this
> > > > short code:
> > > >
> > > >     typedef struct {
> > > >         unsigned car;
> > > >         unsigned cdr;
> > > >     } cons;
> > > >
> > > >     void nconc (unsigned x, unsigned y) {
> > > >         unsigned *ptr = &x;
> > > >         while(!(*ptr & 3))
> > > >             ptr = &((cons *)(*ptr))->cdr;
> > > >         *ptr = y;
> > > >     }
> > > >
> > > > With gcc 4.0-20050728 on i686-pc-linux-gnu, compiling this with -O2
> > > > appears to remove the assignment to *ptr. (I didn't prepare an example
> > > > program, but it's verifiable with objdump.) Obviously, this code is
> > > > non-portable, but still, I don't see why this can happen. Would anyone
> > > > be kind enough to explain this to me? It works as expected with -O2
> > > > -fno-strict-aliasing.
> > >
> > > Well, I'd say it's a bug.  It works in 4.1.  The final assignment gets
> > > removed by tree-ssa-dce.c because it looks like a useless store.  This
> > > is because alias analysis thinks it knows what is going on, when it
> > > clearly does not.
> > >
> > Are you sure?  I am not a language lawyer, but my understanding
> > is that you cannot legally make pointer 'p' point outside of
> > 'x' using pointer arithmetic.  Since 'x' is a PARM_DECL passed by
> > value, the last assignment is a dead store.
> 
> p is not made to point 'outside' of x, but x is treated as a pointer, cast
> to a struct pointer and then dereferenced.  Only if the loop entry condition
> is false we end up storing into x (but only to x, not to memory beyond x),
> and this store is of course dead.

Oh, and a workaround and slight correction would be to write

    void nconc (unsigned x, unsigned y) {
         unsigned *ptr = &((cons *)x)->cdr;
         while(!(*ptr & 3))
             ptr = &((cons *)(*ptr))->cdr;
         *ptr = y;
     }

which makes aliasing see that the store is not dead and in fact it never will
be to the argument area.

Richard.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]