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.

Reply via email to