https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64119
Bug ID: 64119 Summary: asm triggers local register variable data corruption Product: gcc Version: unknown Status: UNCONFIRMED Severity: major Priority: P3 Component: inline-asm Assignee: unassigned at gcc dot gnu.org Reporter: adam at consulting dot net.nz //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 ("" : "+r" (a), "+r" (b), "+r" (c)); 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; } $ gcc-4.9 -O0 gcc-asm-reg-var-data-corruption.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 $ gcc-4.9 -O1 gcc-asm-reg-var-data-corruption.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 $ clang-3.6 -O0 gcc-asm-reg-var-data-corruption.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 $ clang-3.6 -O1 gcc-asm-reg-var-data-corruption.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 I think it's unfortunate that gcc allows library routines to clobber local register variables (does clang save/restore values between library calls?) Note: This code restores the variable values after each library call. The asm statement should be harmless. At input it says: make sure rax, rbx and rcx hold the values of a, b and c respectively. Since the inline assembly is empty the asm output trivially satisfies the same constraint. I upped the severity because I don't consider data corruption "normal" and this kind of data corruption is difficult to isolate.