This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug regression/39839] New: [4.3/4.4/4.5 regression] loop invariant motion causes stack spill


The following code:
struct S
{
  int count;
  char *addr;
};

void func(const char*, const char*, int, const char*);

void test(struct S *p)
{
  int off = p->count;
  while (p->count >= 0)
    {
      const char *s = "xyz";
      if (*p->addr) s = "pqr";
      func("abcde", p->addr + off, off, s);
      p->count--;
    }
}

is compiled by GCC 4.2.1 to 64 bytes, and by GCC 4.4.0 to 76 bytes. Bisection
shows that size is increased several times:
123918 -> 123919: 64 -> 72
124041 -> 124042: 72 -> 76
I already filed a bug for 123919
(http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39837), so let's take a look at
http://gcc.gnu.org/viewcvs?view=rev&revision=124042

GCC rev124041 (with -march=armv5te -mthumb -mthumb-interwork -fpic -Os)
test:
        push    {r4, r5, r6, r7, lr}
        ldr     r3, .L9
        ldr     r2, .L9+4
.LPIC0:
        add     r3, pc
        add     r7, r3, r2
        ldr     r2, .L9+8
        ldr     r5, [r0]
        sub     sp, sp, #4
        mov     r4, r0
        add     r6, r3, r2
        b       .L2
.L3:
        ldr     r0, [r4, #4]
        ldrb    r3, [r0]
        cmp     r3, #0
        beq     .L4
        mov     r2, r6
        b       .L6
.L4:
        mov     r2, r7
.L6:
        add     r0, r0, r5
        lsl     r1, r5, #1
        bl      func
        ldr     r3, [r4]
        sub     r3, r3, #1
        str     r3, [r4]
.L2:
        ldr     r3, [r4]
        cmp     r3, #0
        bge     .L3
        add     sp, sp, #4
        @ sp needed for prologue
        pop     {r4, r5, r6, r7, pc}
.L10:

GCC rev124042:
test:
        push    {r4, r5, r6, r7, lr}
        ldr     r3, .L9
        ldr     r2, .L9+4
.LPIC0:
        add     r3, pc
        add     r2, r3, r2
        sub     sp, sp, #12
        ldr     r5, [r0]
        str     r2, [sp, #4]
        ldr     r2, .L9+8
        mov     r4, r0
        lsl     r6, r5, #1
        add     r7, r3, r2
        b       .L2
.L3:
        ldr     r0, [r4, #4]
        ldrb    r3, [r0]
        cmp     r3, #0
        beq     .L4
        mov     r2, r7
        b       .L6
.L4:
        ldr     r2, [sp, #4]
.L6:
        add     r0, r0, r5
        mov     r1, r6
        bl      func
        ldr     r3, [r4]
        sub     r3, r3, #1
        str     r3, [r4]
.L2:
        ldr     r3, [r4]
        cmp     r3, #0
        bge     .L3
        add     sp, sp, #12
        @ sp needed for prologue
        pop     {r4, r5, r6, r7, pc}

The first different dump is 090t.lim, which moves (off << 1) out of the loop.
But this extra variable causes extra stack spill, so it actually a loss, not a
win. Any ideas about what to tweak?


-- 
           Summary: [4.3/4.4/4.5 regression] loop invariant motion causes
                    stack spill
           Product: gcc
           Version: 4.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: regression
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: alexvod at google dot com
 GCC build triplet: x86_64-unknown-linux-gnu
  GCC host triplet: x86_64-unknown-linux-gnu
GCC target triplet: arm-eabi


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]