Compiling the attached source on i386 with: > gcc -O3 -fomit-frame-pointer -fno-pic -S asm-spills.i produces: .text .align 4,0x90 .globl _get_cabac_noinline _get_cabac_noinline: subl $76, %esp movl %esi, 64(%esp) movl %edi, 68(%esp) movl %ebp, 72(%esp) movl %ebx, 60(%esp) movl 80(%esp), %esi movl 84(%esp), %edi movl (%esi), %edx movl 4(%esi), %ebx movl %edx, 28(%esp) # unused spill movl %edx, %ebp # pointless move # 24 "../strange-spills.i" 1 #%eax %bp %ebx 16(%esi) %edx (%edi) # 0 "" 2 movl %ebp, (%esi) movl %ebx, 4(%esi) andl $1, %eax movl 60(%esp), %ebx movl %eax, 44(%esp) #unused spill movl 64(%esp), %esi movl 68(%esp), %edi movl 72(%esp), %ebp addl $76, %esp ret .subsections_via_symbols
which has several unnecessary stack spills. Reading through RTL dumps: - everything is fine before asmcons - asmcons inserts copies of c->low/range after they're loaded. There's no point to this, since the original is never used later, but I guess there isn't a problem as long as it's cleaned up. - Somehow, the RA gets confused by the asmcons copy and the later one to copy the return value into eax. Instead of assigning both sides of the copy to the same register (which is obviously possible), or even using mov, it spills and reloads them into different registers. - Later passes optimize away the reloads but keep the stores. This isn't a regression (gcc 3.4 isn't much better) and still happens in the IRA branch. For some reason, changing "=&q"(tmp) to "=&d" improves IRA but not trunk. This is about the same source as http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36539. -- Summary: x86 asm "+r" operands cause unnecessary spills/copies Product: gcc Version: 4.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: astrange at ithinksw dot com GCC target triplet: i?86-*-* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36661