On 8/2/05, Diego Novillo <dnovillo@xxxxxxxxxx> wrote: > On Mon, Aug 01, 2005 at 10:12:37PM -0700, Ian Lance Taylor wrote: > > Harald van D??k <truedfx@xxxxxxxxxx> 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. Richard.