http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61032

            Bug ID: 61032
           Summary: rs6000 code gen suffers from lack of address_cost
           Product: gcc
           Version: 4.10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: amodra at gmail dot com

-mcmodel=medium introduced a code model where addresses typically need two
instructions.  As illustrated in the following, the fact that rs6000 lacks an
address_cost function to say that UNSPEC_TOCREL addresses are more costly than
say, register indirect, sees fwprop making poor decisions.

struct fourlongs {
  long l[4];
} x, y;

void f1(void)
{
  void *a = &x;
  void *b = &y;
  __builtin_memcpy (a, b, sizeof(x));
}

/* -O2 -S -fvisibility-hidden
.L.f1:
        addis 7,2,y@toc@ha
        addis 8,2,y+8@toc@ha
        addis 6,2,x@toc@ha
        addis 10,2,y+16@toc@ha
        ld 7,y@toc@l(7)
        ld 8,y+8@toc@l(8)
        addis 9,2,y+24@toc@ha
        ld 10,y+16@toc@l(10)
        ld 9,y+24@toc@l(9)
        std 7,x@toc@l(6)
        addis 7,2,x+8@toc@ha
        std 8,x+8@toc@l(7)
        addis 8,2,x+16@toc@ha
        std 10,x+16@toc@l(8)
        addis 10,2,x+24@toc@ha
        std 9,x+24@toc@l(10)
        blr
*/

void f2(void)
{
  void *a = &x;
  void *b = &y;
  __asm__ ("" : "+r" (a));
  __asm__ ("" : "+r" (b));
  __builtin_memcpy (a, b, sizeof(x));
}

/* -O2 -S -fvisibility-hidden
   fewer dependent address calcs, mem loads earlier and back-to-back, smaller
code
.L.f2:
        addis 9,2,y@toc@ha
        addi 9,9,y@toc@l
        ld 6,0(9)
        ld 7,8(9)
        ld 8,16(9)
        ld 10,24(9)
        addis 9,2,x@toc@ha
        addi 9,9,x@toc@l
        std 6,0(9)
        std 7,8(9)
        std 8,16(9)
        std 10,24(9)
        blr
*/

Reply via email to