/* { 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

Reply via email to