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