$ cat > testcase.c register int r asm("esi"); void foo(void) { if (r) __asm__("sar\t%0" : "+r" (r)); __asm__("sar\t%0" : "+r" (r)); } ^D $ gcc -O2 -S testcase.c $ cat testcase.s [...] foo: .LFB0: xorl %eax, %eax testl %esi, %esi je .L2 #APP # 6 "testcase.c" 1 sar %esi # 0 "" 2 #NO_APP movl %esi, %eax .L2: movl %eax, %esi #APP # 8 "testcase.c" 1 sar %esi # 0 "" 2 #NO_APP ret [...]
Why do you think it is wrong? If %esi is non-zero upon entry, then it is just moved to %eax and back, so it isn't changed, if it was zero upon entry, then 0 is loaded into it. The reason for the extra code is that pre attempts to optimize it (register vars are not SSA vars), so we get at *.optimized: int prephitmp.4; int r.0; <bb 2>: r.0_1 = r; if (r.0_1 != 0) goto <bb 3>; else goto <bb 4>; <bb 3>: __asm__("sar %0" : "=r" r : "0" r.0_1); prephitmp.4_2 = r; <bb 4>: # prephitmp.4_8 = PHI <0(2), prephitmp.4_2(3)> __asm__("sar %0" : "=r" r : "0" prephitmp.4_8); and RTL optimizations aren't able to undo that. I doubt anything can be done about this easily, with -fno-tree-pre you get your expected output.
Ah, yes; changed the summary.
4.4 branch is being closed, moving to 4.5.4 target.
(In reply to comment #1) > and RTL optimizations aren't able to undo that. I doubt anything can > be done about this easily. Perhaps tree-ssa-uncprop should handle this. FWIW, I've always thought that constant propagation into PHI arguments was a mistake...
GCC 4.6.4 has been released and the branch has been closed.
I can't reproduce the bug with GCC 4.7.3 and 4.8.1.
Apparently fixed (probably by IRA).