This is the mail archive of the gcc-bugs@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]

[Bug inline-asm/64119] asm triggers local register variable data corruption


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64119

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Adam Warner from comment #3)
> Seriously Andrew? Here's an opportunity to reconsider your closing of the
> bug report.
Did you read the documentation I pointed out?  Because it is obvious you did
not.


> 
> //asm triggers local register variable data corruption
> #include <stdio.h>
> 
> __attribute__((noinline)) void fn(int inputa, int inputb, int inputc) {
>   register int a asm ("rax");
>   register int b asm ("rbx");
>   register int c asm ("rcx");
> 
>   a = inputa; b = inputb; c = inputc;
>   printf("The values of a, b and c are %d, %d and %d respectively\n", a, b,
> c);
> 
>   a = inputa; b = inputb; c = inputc;
>   printf("The values of a, b and c are %d, %d and %d respectively\n", a, b,
> c);
> 
>   a = inputa; b = inputb; c = inputc;
>   asm volatile ("mov %0, %0; mov %1, %1; mov %2, %2" : "+r" (a), "+r" (b),
> "+r" (c));
>   printf("The values of a, b and c are %d, %d and %d respectively\n", a, b,
> c);
> 
>   a = inputa; b = inputb; c = inputc;
>   printf("The values of a, b and c are %d, %d and %d respectively\n", a, b,
> c);
> }
> 
> int main(void) {
>   fn(1, 2, 3);
>   return 0;
> }
> 
> $ clang-3.6 -O3 gcc-asm-reg-var-data-corruption_b.c && ./a.out 
> The values of a, b and c are 1, 2 and 3 respectively
> The values of a, b and c are 1, 2 and 3 respectively
> The values of a, b and c are 1, 2 and 3 respectively
> The values of a, b and c are 1, 2 and 3 respectively
> 
> $ gcc-4.9 -O3 gcc-asm-reg-var-data-corruption_b.c && ./a.out 
> The values of a, b and c are 1, 2 and 3 respectively
> The values of a, b and c are 1, 2 and 3 respectively
> The values of a, b and c are 53, 2 and 39 respectively
> The values of a, b and c are 1, 2 and 3 respectively



What GCC is optimizing it to:
#include <stdio.h>

__attribute__((noinline)) void fn(int inputa, int inputb, int inputc) {
  register int a asm ("rax");
  register int b asm ("rbx");
  register int c asm ("rcx");

  a = inputa; b = inputb; c = inputc;
  printf("The values of a, b and c are %d, %d and %d respectively\n", a, b, c);

  printf("The values of a, b and c are %d, %d and %d respectively\n", inputa,
inputb, inputc);

  asm volatile ("mov %0, %0; mov %1, %1; mov %2, %2" : "+r" (a), "+r" (b), "+r"
(c));
  printf("The values of a, b and c are %d, %d and %d respectively\n", a, b, c);

  printf("The values of a, b and c are %d, %d and %d respectively\n", inputa,
inputb, inputc);
}

Aka it is treating the local register variables as normal variables except for
inline-asm.

> 
> Do you claim that one may not assign values to explicit register variables?
> (which clearly appears to be happening when a, b and c are again set to a =
> inputa; b = inputb; c = inputc; as evidenced by the output of the fourth
> printf statement)

No you can assign them, except they got optimized like normal variables in most
cases that means the assignments might be optimized away if there is already an
assignment.

> 
> GCC is ignoring the variable assignments in the presence of a harmless asm
> statement.

No it is not see above on how GCC optimizes it and read the documentation again
about what is going on.

> 
> At this stage I cannot accept your justification for the compiler output.
> What is your computational model?

It is standard C one.
...
clang output which is not useful this for discussion because this is about the
documentation of GCC and use in GCC
....


> 
> I've only used features supported by both gcc and clang. clang's output is
> sensible and fits my mental model of the C virtual machine. gcc's output is
> really surprising and I've had a lot of experience manipulating gcc via
> inline asm. Are you sure gcc's output is justified?

Yes re-read the documentation.  I explicitly put it here for you to understand
what GCC is doing.
I will again copy and paste the most important part of the documentation for
you to understand what is going on here:
 References to local register variables may be deleted or moved or simplified.

--- CUT ---
They are being moved and simplified to only assigned before the first printf. 
If you don't like that then create a new local register variable each time and
GCC won't optimize them away.


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