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: unassig...@gcc.gnu.org ReportedBy: mi...@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)