http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52412
Bug #: 52412 Summary: another unnecessary register move on arm Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target AssignedTo: unassig...@gcc.gnu.org ReportedBy: car...@google.com Target: arm-linux-gnueabi Compile following code with options -march=armv7-a -mthumb -Os extern int Table[256]; typedef struct { char* f0; int f1; int f2; char f3[256]; int f4; } S; void t0m(S* s) { int i; char ch = (char)(s->f1); for (i = 0; i < 10 ; i++) s->f4 = Table[s->f4 ^ ch]; s->f3[s->f1] = 1; switch (s->f2) { case 1: *s->f0 = ch; break; case 2: *s->f0 = ch; break; } } ARM gcc 4.7 generates: t0m: ldr r1, [r0, #4] movs r2, #10 push {r4, r5, r6, lr} uxtb r3, r1 ldr r5, .L7 mov r6, r3 // A .L2: ldr r4, [r0, #268] subs r2, r2, #1 eor r4, r6, r4 ldr r4, [r5, r4, lsl #2] str r4, [r0, #268] bne .L2 adds r1, r0, r1 movs r2, #1 strb r2, [r1, #12] ldr r2, [r0, #8] cmp r2, #1 beq .L5 cmp r2, #2 bne .L1 .L5: ldr r2, [r0, #0] strb r3, [r2, #0] .L1: pop {r4, r5, r6, pc} .L8: .align 2 .L7: .word Table Instruction A moves register r3 to r6, but both r3 and r6 are read only in following code, so any one is enough for following usage. Compile it to arm mode instructions has the same problem.