This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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.




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]