https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92346
--- Comment #2 from wierton <141242068 at smail dot nju.edu.cn> --- (In reply to Andrew Pinski from comment #1) > This code is clearly undefined. > > First you say eax is in eax and then then you say the register gets > clobbered by the inline-asm (and is set by the inline-asm). > But you only set the lower bits of the eax to be 1 in the inline-asm. > > In the -O0 case, what is happening is eax is both the output register and > the clobbered. > In the -O2 case, the eax is not used as the output register but rather a > different one as eax would conflict with the clobber register. > > You can see that effect by outputing %0 and %1 in the inline-asm template. > > Basically the inline-asm is broken and is not expected to work the way you > expected it to work. I feel so sorry for my previous manner of speaking, finding a bug in big project such as gcc makes me a little excited. I simplified the code as following: ``` #include <stdio.h> int set_eax(int val) { return val; } int main() { int ax, tmp; register int eax asm("eax") = set_eax(0x23232323); asm volatile("movl $1, %%eax\n" ::: "eax"); printf("%08x\n", eax); return 0; } ``` This code can reproduce the phenomenon and there are no output constraints. I do understand that the declaration %eax in eax is conflict with the inline assembly clobber list, but in compiler such as clang, this dependency will be detected and clang will extraly generate a move instruction to save the eax and the resume it. I think gcc is a mostly widely used compiler, we as users expect this compiler becomes better and better, and this feature will help improve the usability, so I post it here. Very sorry for previous post. The binary code generated by clang: ``` 8048451: 89 45 f0 mov %eax,-0x10(%ebp) // save eax 8048454: b8 01 00 00 00 mov $0x1,%eax // inline assembly 8048459: 8d 05 00 85 04 08 lea 0x8048500,%eax 804845f: 8b 4d f0 mov -0x10(%ebp),%ecx // restore the value to ecx 8048462: 89 04 24 mov %eax,(%esp) 8048465: 89 4c 24 04 mov %ecx,0x4(%esp) 8048469: e8 52 fe ff ff call 80482c0 <printf@plt> ```