Improve code generated for a switch statement (part 2)
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Linaro GCC |
Triaged
|
Low
|
Unassigned |
Bug Description
Consider:
char
f (char *p)
{
switch (*p)
{
case 32:
case 13:
case 10:
case 9:
return 0;
default:
return *p;
}
}
"gcc -O2 -S test.c" generates
ldrb r0, [r0, #0] @ zero_extendqisi2
sub r3, r0, #9
uxtb r2, r3
cmp r2, #23
bhi .L2
sxtb r3, r3
movs r1, #1
lsls r2, r1, r3
movw r1, #:lower16:8388627
movt r1, #:upper16:8388627
and r3, r2, r1
cmp r3, #0
it ne
movne r0, #0
.L2:
bx lr
Note the three extensions -- ldrb, uxtb, and sxtb. We can optimize this sequence and remove uxtb and sxtb like so:
ldrb r0, [r0, #0] @ zero_extendqisi2
sub r3, r0, #9
cmp r3, #23
bhi .L2
movs r1, #1
lsls r2, r1, r3
movw r1, #:lower16:8388627
movt r1, #:upper16:8388627
and r3, r2, r1
cmp r3, #0
it ne
movne r0, #0
.L2:
bx lr
These extensions come from the fact that emit_case_bit_tests tries to do comparisons in the index type, which is char in this case. If we do the comparisons in "int" or "unsigned int", we don't have do extend as many times.
See LP:645267 for a closely related optimization opportunity.
[CodeSourcery Tracker ID #7900]
tags: | added: speed task |
Changed in gcc-linaro: | |
status: | New → Triaged |
importance: | Undecided → Low |