http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47855
Summary: missed cbnz optimization
Product: gcc
Version: 4.6.0
Status: UNCONFIRMED
Severity: enhancement
Priority: P3
Component: target
AssignedTo: [email protected]
ReportedBy: [email protected]
Target: arm-linux-androideabi
Created attachment 23440
--> http://gcc.gnu.org/bugzilla/attachment.cgi?id=23440
testcase
Compile the attached source code with options -march=armv7-a -mthumb -Os, GCC
4.6 generates
pnm_gethdr:
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 0, uses_anonymous_args = 0
push {r0, r1, r2, r4, r5, lr}
mov r5, r0
mov r4, r1
bl foo2
cmp r0, #0 // A
bne .L13 // B
adds r1, r4, #4
mov r0, r5
bl foo3
cmp r0, #0 // C
bne .L13 // D
add r1, r4, #8
mov r0, r5
bl foo1
cbnz r0, .L13 // E
ldr r0, [r4, #0]
bl pnm_type
cmp r0, #2
beq .L3
mov r0, r5
add r1, sp, #4
bl pnm_getsintstr
cbz r0, .L4
b .L13
.L3:
movs r3, #1
str r3, [sp, #4]
.L4:
ldr r3, [sp, #4]
cmp r3, #0
bge .L5
negs r3, r3
str r3, [r4, #16]
movs r3, #1
b .L14
.L5:
str r3, [r4, #16]
movs r3, #0
.L14:
strb r3, [r4, #20]
ldr r0, [r4, #0]
bl pnm_type
cmp r0, #0
beq .L8
blt .L7
cmp r0, #2
bgt .L7
movs r3, #1
movs r0, #0
str r3, [r4, #12]
b .L2
.L8:
movs r3, #3
str r3, [r4, #12]
b .L2
.L7:
bl abort
.L13:
mov r0, #-1
.L2:
pop {r1, r2, r3, r4, r5, pc}
The branch distance of cbz/cbnz is 126 bytes. The size of the whole function is
124 bytes. So instructions AB and CD can be replaced by
cbnz r0, .L13
same as instruction E.