http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53933
Bug #: 53933 Summary: Register choosing error when inline assembly used at inline function Classification: Unclassified Product: gcc Version: 4.6.4 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: nicejae...@gmail.com Created attachment 27778 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=27778 gcc -v verbose output and itermediate(*.i) file 1) the system type: arm cortex-a8 / linux-montavista 2) the options given when GCC was configured/built: -O3 3) the complete command line that triggers the bug: execute w/ no param 4) the compiler output (error messages, warnings, etc.): attached It seems GCC picks wrong registers when inline assembly is used at inline function. Below clip_int32 function is in-lined at main function by -O3 option, and GCC picked same register 'movlt ip, ip' (it should have picked different register as instructed 'movlt %0, %2 ') *code int clip_int32(int a, int amin, int amax) { #if 1 asm volatile ( "mov %0, %1 \n\t" "cmp %1, %2 \n\t" "movlt %0, %2 \n\t" "cmp %1, %3 \n\t" "movgt %0, %3 \n\t" : "=r"(a) : "r"(a), "r"(amin), "r"(amax) //: "r0", "r1", "r2" ); return a; #endif #else if (a < amin) return amin; else if (a > amax) return amax; else return a; #endif } int main() { int ret[4]; ret[0] = clip_int32( -5, -1, 1 ); ret[1] = clip_int32( -5, -1, 1 ); ret[2] = clip_int32( -5, -1, 1 ); ret[3] = clip_int32( -5, -1, 1 ); printf("%d %d %d %d\n", ret[0], ret[1], ret[2], ret[3]); return 0; } *disassembled executable 000082c8 <main>: 82c8: e52de004 push {lr} ; (str lr, [sp, #-4]!) 82cc: e3e00004 mvn r0, #4 82d0: e24dd00c sub sp, sp, #12 82d4: e3e0c000 mvn ip, #0 82d8: e3a0e001 mov lr, #1 82dc: e1a01000 mov r1, r0 82e0: e150000c cmp r0, ip 82e4: b1a0100c movlt r1, ip 82e8: e150000e cmp r0, lr 82ec: c1a0100e movgt r1, lr 82f0: e1a02000 mov r2, r0 82f4: e150000c cmp r0, ip 82f8: b1a0200c movlt r2, ip 82fc: e150000e cmp r0, lr 8300: c1a0200e movgt r2, lr 8304: e1a03000 mov r3, r0 8308: e150000c cmp r0, ip 830c: b1a0300c movlt r3, ip 8310: e150000e cmp r0, lr 8314: c1a0300e movgt r3, lr 8318: e1a0c000 mov ip, r0 831c: e150000c cmp r0, ip 8320: b1a0c00c movlt ip, ip (these register should not be the same!) 8324: e150000e cmp r0, lr 8328: c1a0c00e movgt ip, lr 832c: e3080480 movw r0, #33920 ; 0x8480 8330: e58dc000 str ip, [sp] 8334: e3400000 movt r0, #0 8338: ebffffd6 bl 8298 <_init+0x20> 833c: e3a00000 mov r0, #0 8340: e28dd00c add sp, sp, #12 8344: e8bd8000 pop {pc} the result was -1, -1, -1, -1(wrong) for -O3 option, and -1, -1, -1, -5(correct) for -O1 option.