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: [email protected]
ReportedBy: [email protected]
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.