/* { dg-options "-O2 -m32 -march=i386" } /* { dg-do compile } */ typedef struct { void *A; void *B; void *C; unsigned long D; } S;
void foo (S *x) { unsigned long long *c = x->C; unsigned long long *a = x->A; unsigned long long *b = x->B; unsigned long d = x->D; for (; d >= 2; d -= 2) { asm volatile ("" : "=m" (*c) : "m" (*a), "m" (*b) : "eax", "ecx", "edx", "cc"); c++; b++; a++; } if (d > 0) asm volatile ("" : "=m" (*c) : "m" (*a), "m" (*b) : "eax", "ecx", "edx", "cc"); } (distilled from the GIMP) ICEs on HEAD/4.1 when not -fomit-frame-pointer. As the pattern clobbers 3 registers out of 6 available ones, I think it should be theoretically reloadable (just use (%ebx) for one memory, (%esi) for another one and (%edi) for yet another one. But after tree-ssa we end up with: __asm__ __volatile__("":"=m" *(c + D.1386):"m" *(a + D.1386), "m" *(b + D.1386):"cc", "edx", "ecx", "eax"); which is one register too much if a, b, c and D.1386 need each assigned one reg. Reload should try harder in that case though, and just create temporaries, say %ebx = (c + D.1386) %esi = (a + D.1386) %edi = (b + D.1386). -- Summary: reload bailing out even when some regs are still available Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jakub at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25221