Improve code generated for a switch statement
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Linaro GCC |
Confirmed
|
Low
|
Unassigned |
Bug Description
Consider:
unsigned int
f (unsigned int a)
{
switch (a)
{
case 32:
case 13:
case 10:
case 9:
return 0;
default:
return a;
}
}
"arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb O2 -S kazu.c" generates
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
which is equivalent to:
a -= 9;
if (a > 23)
return a;
if (0x800013 & (1 << a))
return 0;
return a;
We can improve this sequence by shifting the magic constant to left
and test the sign bit like so:
a -= 9;
if (a > 23)
return a;
if (((signed int) 0xc8000100 << a) < 0)
return 0;
return a;
The assembly would be:
sub r3, r0, #9
cmp r3, #23
bhi .L2
movw r2, #:lower16:
movt r2, #:upper16:
lsls r2, r2, r3
it mi
movmi r0, #0
.L2:
bx lr
Note that the "and" and "cmp r3,#0" have disappeared.
[CodeSourcery Tracker ID #7899]
tags: | added: speed task |
Changed in gcc-linaro: | |
status: | New → Triaged |
importance: | Undecided → Low |
Changed in gcc-linaro: | |
status: | Triaged → Won't Fix |
Changed in gcc-linaro: | |
status: | Won't Fix → Confirmed |