On Wed, Oct 20, 2010 at 10:29 AM, Albert Cahalan <acaha...@gmail.com> wrote: > On Thu, Sep 30, 2010 at 5:39 AM, Richard Guenther > <richard.guent...@gmail.com> wrote: >> On Thu, Sep 30, 2010 at 9:54 AM, Albert Cahalan <acaha...@gmail.com> wrote: >>> int weird(float *fp){ >>> // access an int as an int (see caller), >>> // so not an aliasing violation >>> return *(int*)fp; >>> } >>> int main(int argc, char *argv[]){ >>> return weird((float*)&argc); >>> } >>> >>> I just tried this code with gcc 4.4.5 on 32-bit powerpc using -O2 -W -Wall. >>> Assembly code for the weird function looks OK, both inlined and not, but >>> that certainly isn't proof that gcc will always tolerate such code. >>> I recall that there were problems handling this type of code. (never mind >>> any non-conformant callers that actually pass a pointer to a float -- not >>> that gcc would be able to see them in separately compiled files) >>> >>> So, is it fixed now? (what gcc version?) If not, is it at least fixed >>> if I change "float" to "void" and/or "unsigned char"? >>> >>> BTW, oddly it looks like gcc tolerates a genuine aliasing violation >>> as well now. (passing the value as a float) Of course, that may just >>> be my luck with the optimizer. >> >> I indeed fixed the above problem at some point (4.1 may be still >> broken, 4.3 should be fixed I think). >> >> We're trying to tolerate genuine alias violations if we can see >> what the user intended (in compiler-speak, when we detect >> a must-alias relationship we do not try to disabiguate using >> type-based alias analysis). That's just being nice to users and >> not breaking their code just because we can. > > I've been trying to come up with an example where either: > > a. gcc gains optimization from type-based alias analysis > b. traditional assumptions result in breakage > > I am no longer able to find either. Is it safe to consider the > type-based aliasing to be essentially disabled now?
int foo (int *i, float *f) { *i = 1; *f = 0; return *i; } is a case for a. We optimize this to return 1. I don't quite understand what you seek for with b, but for example for int foo (void) { int i = 1; *(float *)&i = 0.0; return i; } GCC is allowed to optimize it to return 1, but for example GCC 4.6 will optimize it to return 0 as the user probably expected because when optimizing the load of i we now see a must-alias store to it. Richard.