Compile the following code with options -march=armv7-a -mthumb -Os

struct A
{
  int f0,f1,f2,f3,f4,f5;
};

void func(const struct A* p)
{
  printf("%d %d %d %d %d %d %d",
         p->f0, p->f1, p->f2, p->f3, p->f4,
         (p->f2 == 0) ? 0 : p->f2 * 100 / (p->f1 + p->f2 + p->f3), p->f5);
}

GCC generates:

func:
        push    {r4, r5, r6, r7, lr}
        ldr     r4, [r0, #8]
        mov     r5, r0
        ldr     r2, [r0, #0]
        ldr     r6, [r0, #4]
        sub     sp, sp, #28
        ldr     r7, [r0, #12]
        ldr     r3, [r0, #16]
        mov     r0, r4
        cbz     r4, .L2
        adds    r1, r7, r6
        movs    r0, #100
        adds    r1, r1, r4
        muls    r0, r4, r0
        str     r2, [sp, #20]    // A
        str     r3, [sp, #16]    // B
        bl      __aeabi_idiv
        ldr     r2, [sp, #20]    // C
        ldr     r3, [sp, #16]    // D
.L2:
        str     r3, [sp, #4]
        mov     r1, r2
        ldr     r3, [r5, #20]
        mov     r2, r6
        str     r0, [sp, #8]
        ldr     r0, .L4
        str     r3, [sp, #12]
        mov     r3, r4
        str     r7, [sp, #0]
        bl      printf
        add     sp, sp, #28
        pop     {r4, r5, r6, r7, pc}
.L5:
        .align  2
.L4:
        .word   .LC0
        .size   func, .-func
        .section        .rodata.str1.1,"aMS",%progbits,1
.LC0:
        .ascii  "%d %d %d %d %d %d %d\000"

Instructions AB spills register r2 and r3 to stack. Instructions CD reloads r2
and r3 from stack. Register r2 contains p->f0, r3 contains p->f4. After
function call to __aeabi_idiv, pointer p is still in register r5. So we can
directly reload r2 and r3 through register r5, avoiding spill them to stack.


-- 
           Summary: unnecessary register spill
           Product: gcc
           Version: 4.5.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: carrot at google dot com
 GCC build triplet: i686-linux
  GCC host triplet: i686-linux
GCC target triplet: arm-eabi


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

Reply via email to