This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Strange (wrong?) aliasing outcome
- From: Michael Veksler <VEKSLER at il dot ibm dot com>
- To: gcc at gcc dot gnu dot org
- Date: Sun, 24 Oct 2004 13:35:11 +0200
- Subject: Strange (wrong?) aliasing outcome
I am playing around with examples that show user code bugs related to
aliasing rules. Aliasing rules do not explain the following result
[gcc-4.0-20041017]. Is it a bug in one of the optimizers?
$ cat t.c
include <stdio.h>
struct A { int v0 ; int v1; } ;
struct B { int v[2]; };
static void f(struct A* pa, struct B* pb)
{
pb->v[1]= pa->v0;
pb->v[0]= pa->v0 / pa->v1; /* '/' is expected to be moved up */
}
int main()
{
struct A a = {3, 4};
f(&a, (struct B*)&a);
printf("%d - the coder thinks it should give 1\n", a.v0);
return 0;
}
$ /home/veksler/gcc-4.0-20041017/bin/gcc -O2 -Wall t.c
t.c: In function 'main':
t.c:15: warning: de-referencing type-punned pointer will break
strict-aliasing rules
This warning was expected - the code is buggy.
$ ./a.out
3 - this should be 1
Now, this is strange. It would seem that 0 is more likely outcome. Because
'/' is
expensive, it should move to the beginning of the function - this way we
should get 0 (like we get with IBM's Visual Age 5.0 - AKA xlC-5).
After some analysis, I found out that f() got inlined, and
main contains
movl $3, %edx
So, as it seems, gcc wrongly (?) transforms f() into "3". Is this correct
behavior? I thought that possible results should include possible
interleaving of memory access, and only them. These seems to
be no interleaving to justify the result 3.
$ /home/veksler/gcc-4.0-20041017/bin/gcc -v
Reading specs from
/home/veksler/gcc-4.0-20041017/lib/gcc/i686-pc-linux-gnu/4.0.0/specs
Configured with: ../gcc-4.0-20041017.src/configure
--prefix=/home/veksler/gcc-4.0-20041017 --enable-languages=c++
--enable-__cxa_atexit
Thread model: posix
gcc version 4.0.0 20041017 (experimental)