This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Strange (wrong?) aliasing outcome
- From: Michael Veksler <VEKSLER at il dot ibm dot com>
- To: Andrew Haley <aph at redhat dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: Mon, 25 Oct 2004 12:50:03 +0200
- Subject: Re: Strange (wrong?) aliasing outcome
struct A { int v0 ; int v1; } ;
struct B { int v[2]; };
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;
}
I see, when 'f()' is static it gets inlined. Due to type differences
'pb' is marked unread, and so it is eliminated. As a result 'a'
is kept intact with its original value.
I don't understand why when 'f' is not inlined, the (expensive)
division is not moved to the beginning of the function. It seems
beneficial (from perfromance POV) to move long latency operations
as early as possible.
Is this a missed optimization opportunity?
Andrew Haley
<aph@redhat.com>
To
25/10/2004 12:29 Michael Veksler/Haifa/IBM@IBMIL
cc
gcc@gcc.gnu.org
Subject
Strange (wrong?) aliasing outcome
Michael Veksler writes:
> I am playing around with examples that show user code bugs related to
> aliasing rules. Aliasing rules do not explain the following result
> $ ./a.out
> 3 - this should be 1
>
> Now, this is strange. It would seem that 0 is more likely outcome.
The result of the division is unused, because it is not written to any
object that is type compatible with an object that is later read. So,
dead code elimination removes the division altogether.
> 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?
Whyever not? After the divsion has been removed you have
struct A a = {3, 4};
printf("%d - the coder thinks it should give 1\n", a.v0);
which is 3.
Andrew.