For the following code:
extern void func();
extern char outbuf[];
extern int outcnt;
extern int bool_var;
void test ()
{
char flags;
flags = 0;
outcnt = 0;
if (outcnt == 1) func ();
if (outcnt == 1) func ();
if (outcnt == 1) func ();
if (bool_var) flags = 2;
outbuf[outcnt] = flags;
if (outcnt == 1) func ();
}
I found that GCC 4.4.0 generates the following code:
.code 16
.file "outcnt.c"
.text
.align 2
.global test
.code 16
.thumb_func
.type test, %function
test:
push {r4, lr}
ldr r3, .L7
mov r2, #0
str r2, [r3]
ldr r3, .L7+4
mov r2, #2
ldr r3, [r3]
cmp r3, #0
bne .L3
mov r2, #0
.L3:
ldr r3, .L7
ldr r1, .L7+8
ldr r3, [r3]
strb r2, [r1, r3]
cmp r3, #1
bne .L5
bl func
.L5:
@ sp needed for prologue
pop {r4, pc}
.L8:
.align 2
.L7:
.word outcnt
.word bool_var
.word outbuf
.size test, .-test
.ident "GCC: (GNU) 4.4.0"
, while GCC 4.2.1 generates the following code:
.code 16
.file "outcnt.c"
.text
.align 2
.global test
.code 16
.thumb_func
.type test, %function
test:
push {lr}
ldr r2, .L6
mov r3, #0
str r3, [r2]
ldr r3, .L6+4
ldr r3, [r3]
cmp r3, #0
beq .L2
mov r2, #2
b .L4
.L2:
mov r2, #0
.L4:
ldr r3, .L6+8
@ sp needed for prologue
strb r2, [r3]
pop {pc}
.L7:
.align 2
.L6:
.word outcnt
.word bool_var
.word outbuf
.size test, .-test
.ident "GCC: (GNU) 4.2.1"
The code snippet has a lot of dead code that is not completely eliminated by
gcc 4.4.0 (but correctly eliminated by gcc 4.2.1).
Because outcnt == 0, all lines 'if (outcnt == 1)' can be eliminated. Because
outbuf and outcnt are global external symbols of different types, they can not
be aliased, so the last statement can be also eliminated.
gcc 4.2.1 output is 40 bytes, gcc 4.4.0 output is 52 bytes. It also inserts 'bl
func'.
This code snippet was extracted from gzip benchmark, but got changed quite a
bit.
--
Summary: Regression on dead-code-elimination: GCC 4.2.1 generates
better code than 4.4.0
Product: gcc
Version: 4.4.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: sliao at google dot com
GCC build triplet: i686-linux
GCC host triplet: i686-linux
GCC target triplet: arm-eabi
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42494