[Bug target/51001] New: redundant address re-computations on ARM

mikpe at it dot uu.se gcc-bugzilla@gcc.gnu.org
Sun Nov 6 20:51:00 GMT 2011


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51001

             Bug #: 51001
           Summary: redundant address re-computations on ARM
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: mikpe@it.uu.se


This test case is based on the one in PR50448, but slightly modified since the
original was too easy for ARM:

> cat test.c
typedef struct
{
    unsigned char a,b,c,d;
} SPI_t;

#if 1
#define SPIE (*(SPI_t volatile*) 0xDAC0)
#else
extern volatile SPI_t SPIE;
#endif

void foo (void)
{
    SPIE.d = 0xAA;
    while (!(SPIE.c & 0x80));

    SPIE.d = 0xBB;
    while (!(SPIE.c & 0x80));
}
> gcc/xgcc -Bgcc/ -Os -S test.c ; cat test.s
...
        .type   foo, %function
foo:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        mov     r3, #53248
        mvn     r2, #85
        strb    r2, [r3, #2755]
        mov     r2, r3
.L2:

@@ At this point r2 == r3 so in the next instruction we could
@@ have used r3 instead of r2, and deleted the mov to r2 above.

        ldrb    r1, [r2, #2754] @ zero_extendqisi2

@@ At this point r3 still contains 53248 from above, so the
@@ following mov is redundant.

        mov     r3, #53248
        tst     r1, #128
        beq     .L2
        mvn     r2, #68
        strb    r2, [r3, #2755]
.L3:
        ldrb    r2, [r3, #2754] @ zero_extendqisi2
        tst     r2, #128
        beq     .L3
        bx      lr
        .size   foo, .-foo
        .ident  "GCC: (GNU) 4.7.0 20111105 (experimental)"
        .section        .note.GNU-stack,"",%progbits

Making the variable not have a known address shows similar poor code:

> sed 's/#if 1/#if 0/g' < test.c > test2.c
> gcc/xgcc -Bgcc/ -Os -S test2.c ; cat test2.s
...
        .type   foo, %function
foo:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        ldr     r3, .L6
        mvn     r2, #85
        strb    r2, [r3, #3]
        mov     r2, r3
.L2:

@@ Here r2 == r3 so we could have used r3 instead and
@@ deleted the mov to r2 above.

        ldrb    r1, [r2, #2]    @ zero_extendqisi2

@@ The following ldr is redundant as r3 already contains that value.

        ldr     r3, .L6
        tst     r1, #128
        beq     .L2
        mvn     r2, #68
        strb    r2, [r3, #3]
.L3:
        ldrb    r2, [r3, #2]    @ zero_extendqisi2
        tst     r2, #128
        beq     .L3
        bx      lr
.L7:
        .align  2
.L6:
        .word   SPIE
        .size   foo, .-foo
        .ident  "GCC: (GNU) 4.7.0 20111105 (experimental)"
        .section        .note.GNU-stack,"",%progbits

Compiling test2.c with -O2 not -Os shows a partial improvement:

> gcc/xgcc -Bgcc/ -O2 -S test2.c ; cat test2.s
...
        .type   foo, %function
foo:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        ldr     r3, .L7
        mvn     r2, #85
        strb    r2, [r3, #3]
.L2:
        ldrb    r2, [r3, #2]    @ zero_extendqisi2

@@ We got rid of the redundant ldr in this loop.

        tst     r2, #128
        beq     .L2

@@ But instead we got a new redundant ldr between the loops.
@@ The address loaded into r3 above is still available here,
@@ so the following ldr should be deleted and the strb two
@@ instructions below should use r3 as base register.

        ldr     r2, .L7
        mvn     r1, #68
        strb    r1, [r2, #3]
.L3:
        ldrb    r2, [r3, #2]    @ zero_extendqisi2
        tst     r2, #128
        beq     .L3
        bx      lr
.L8:
        .align  2
.L7:
        .word   SPIE
        .size   foo, .-foo
        .ident  "GCC: (GNU) 4.7.0 20111105 (experimental)"
        .section        .note.GNU-stack,"",%progbits

Configuration:
> gcc/xgcc -v
Using built-in specs.
COLLECT_GCC=/mnt/scratch/objdir47/gcc/xgcc
Target: armv5tel-brewer-linux-gnueabi
Configured with: /mnt/scratch/gcc-4.7-20111105/configure
--prefix=/mnt/scratch/install47 --enable-bootstrap --enable-shared
--enable-threads=posix --enable-checking=release --with-system-zlib
--enable-__cxa_atexit --disable-libunwind-exceptions
--enable-languages=c,c++,fortran,ada --enable-java-awt=gtk --disable-dssi
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre
--enable-libgcj-multifile --disable-java-maintainer-mode
--with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib
--disable-sjlj-exceptions --with-arch=armv5te --with-tune=xscale
--build=armv5tel-brewer-linux-gnueabi
--with-gmp=/home/mikpe/pkgs/linux-armv5l/gmp-5.0.2
--with-mpfr=/home/mikpe/pkgs/linux-armv5l/mpfr-3.0.1
--with-mpc=/home/mikpe/pkgs/linux-armv5l/mpc-0.9 --disable-plugin --disable-lto
--disable-libmudflap --disable-build-poststage1-with-cxx
Thread model: posix
gcc version 4.7.0 20111105 (experimental) (GCC)



More information about the Gcc-bugs mailing list