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

Reply via email to