http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46479
Summary: [4.4/4.5/4.6 Regression] "+m" (*regs) : "a" (regs) doesn't use (%eax) for the MEM Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end AssignedTo: unassig...@gcc.gnu.org ReportedBy: ja...@gcc.gnu.org /* { dg-do compile { target { { i686-*-* x86_64-*-* } && ilp32 } } } */ /* { dg-options "-Os -fno-omit-frame-pointer" } */ struct S { long c[64]; }; int foo (struct S *regs) { int rc; asm volatile ("" : "=a" (rc), "+m" (*regs) : "a" (regs) : "ebx", "ecx", "edx", "esi", "edi", "memory"); return rc; } doesn't compile any longer, starting with 4.4. Even with smaller register pressure GCC before IRA used to reuse the register holding the address, wasting another one is unnecessary. If there is just "m" (*regs) as input operand even with IRA the eax register is used as the address for the memory operand. I guess what is confusing IRA here is that the MEM appears as output operand and the asm clobbers the %eax register (as it sets it to something else) and so thinks it must give the output operand an address that is still valid at the end of the inline asm rather than just start. But for memory addresses that is not true, unless there is an earlyclobber - it is enough if the address of the output MEM is valid at the beginning of the inline asm. I'd say this is an important bug, not because in this very high register pressure asm we fail to compile it, but because int bar (struct S *regs) { int rc; asm volatile ("" : "=a" (rc), "+m" (*regs) : "a" (regs)); return rc; } is quite common, the "+m" there is just to tell GCC what side-effects it has, is never used in the asm and it is desirable that it doesn't introduce runtime overhead.