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