This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: More fun with aliasing - removing assignments?
- From: Richard Guenther <richard dot guenther at gmail dot com>
- To: Diego Novillo <dnovillo at redhat dot com>
- Cc: gcc-help at gcc dot gnu dot org, gcc at gcc dot gnu dot org, truedfx at gentoo dot org, Ian Lance Taylor <ian at airs dot com>, Richard Henderson <rth at redhat dot com>
- Date: Tue, 2 Aug 2005 14:56:50 +0200
- Subject: Re: More fun with aliasing - removing assignments?
- References: <20050801214735.GA12919@boostbox> <m33bpsq5ve.fsf@gossamer.airs.com> <20050802123253.GB26124@topo.toronto.redhat.com> <84fc9c000508020551459a8a9f@mail.gmail.com>
- Reply-to: Richard Guenther <richard dot guenther at gmail dot com>
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.