Compiling following peace of code for an ARM processor (with optimization), produces wrong code. This is true with gcc-3.0.4 and gcc-3.2 The file in the 'HowToRepeat' section produces : root:~# gcc -O1 -v test.c Reading specs from /usr/local/gcc-3.2/lib/gcc-lib/armv5l-unknown-linux-gnu/3.2/specs Configured with: ../gcc-3.2/configure --prefix=/usr/local/gcc-3.2 --with-cpu=xscale --enable-languages=c,c++ Thread model: posix gcc version 3.2 /usr/local/gcc-3.2/lib/gcc-lib/armv5l-unknown-linux-gnu/3.2/cc1 -lang-c -v -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=0 -D__GXX_ABI_VERSION=102 -Dunix -D__gnu_linux__ -Dlinux -D__ELF__ -D__unix__ -D__gnu_linux__ -D__linux__ -D__ELF__ -D__unix -D__linux -Asystem=unix -Asystem=posix -D__OPTIMIZE__ -D__STDC_HOSTED__=1 -Acpu=arm -Amachine=arm -D__ARM_ARCH_5TE__ -D__XSCALE__ -D__APCS_32__ -D__ARMEL__ -D__arm__ test.c -quiet -dumpbase test.c -O1 -version -o /tmp/cce7i9ST.s GNU CPP version 3.2 (cpplib) (ARM GNU/Linux with ELF) GNU C version 3.2 (armv5l-unknown-linux-gnu) compiled by GNU C version 3.0.4. ignoring nonexistent directory "/usr/local/gcc-3.2/armv5l-unknown-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/local/include /usr/local/gcc-3.2/include /usr/local/gcc-3.2/lib/gcc-lib/armv5l-unknown-linux-gnu/3.2/include /usr/include End of search list. as -o /tmp/cccJot3S.o /tmp/cce7i9ST.s /usr/local/gcc-3.2/lib/gcc-lib/armv5l-unknown-linux-gnu/3.2/collect2 -dynamic-linker /lib/ld-linux.so.2 -X -m armelf_linux -p /usr/lib/crt1.o /usr/lib/crti.o /usr/local/gcc-3.2/lib/gcc-lib/armv5l-unknown-linux-gnu/3.2/crtbegin.o -L/usr/local/gcc-3.2/lib/gcc-lib/armv5l-unknown-linux-gnu/3.2 -L/usr/local/gcc-3.2/lib/gcc-lib/armv5l-unknown-linux-gnu/3.2/../../.. /tmp/cccJot3S.o -lgcc -lgcc_eh -lc -lgcc -lgcc_eh /usr/local/gcc-3.2/lib/gcc-lib/armv5l-unknown-linux-gnu/3.2/crtend.o /usr/lib/crtn.o root:~# ./a.out expect 0 : 0 expect 1 : 1 expect 2 : 2 expect 3 : 3 root:~# gcc -O2 test.c root:~# ./a.out expect 0 : 0 expect 1 : 3 expect 2 : 0 expect 3 : 3 The problem appears to be a mixup of the condition codes set by a 'tst' and an 'ands', as the .s from the 'bar' function indicates : bar: @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. cmp r0, #1 @ lr needed for prologue mov r0, #0 bxne lr tst r2, #3 **** Set CC ands r0, r1, #3 **** Overrule CC movne r0, #1 orrne r0, r0, #2 **** should use CC set by 'tst' bx lr .Lfe2: .size bar,.Lfe2-bar .ident "GCC: (GNU) 3.2" Release: gcc-3.2 Environment: Linux xingu-07 2.4.16-rmk1-xng1 #38 Mon Jul 8 16:09:28 CEST 2002 armv5l unknown host: armv5l-unknown-linux-gnu build: armv5l-unknown-linux-gnu How-To-Repeat: /* reproduce with : */ /* gcc -O2 test.c */ #include <stdio.h> int bar(int s,int motion_x, int motion_y); int main(int argc, char* argv[]) { printf("expect %d : %d\n", 0, bar(1,0,0)); printf("expect %d : %d\n", 1, bar(1,1,0)); printf("expect %d : %d\n", 2, bar(1,0,1)); printf("expect %d : %d\n", 3, bar(1,1,1)); } int bar(int s,int motion_x, int motion_y) { int dxy; dxy = 0; if (s == 1) { if ((motion_x & 3) != 0) { dxy |= 1; } if ((motion_y & 3) != 0) { dxy |= 2; } } else { } return dxy; }
Fix: disable optimizations
Responsible-Changed-From-To: unassigned->rearnsha Responsible-Changed-Why: .
State-Changed-From-To: open->closed State-Changed-Why: Fixed with the patch referenced.
From: rearnsha@gcc.gnu.org To: gcc-gnats@gcc.gnu.org Cc: Subject: optimization/7967 Date: 18 Sep 2002 14:01:59 -0000 CVSROOT: /cvs/gcc Module name: egcs Changes by: rearnsha@gcc.gnu.org 2002-09-18 07:01:58 Modified files: gcc : ChangeLog gcc/config/arm : arm.md Log message: PR optimization/7967 * arm.md (ne_zeroextractsi): Add clobber of the condition code register. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/egcs/gcc/ChangeLog.diff?cvsroot=gcc&r1=1.15466&r2=1.15467 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/egcs/gcc/config/arm/arm.md.diff?cvsroot=gcc&r1=1.109&r2=1.110
From: rearnsha@gcc.gnu.org To: gcc-gnats@gcc.gnu.org Cc: Subject: optimization/7967 Date: 18 Sep 2002 14:05:39 -0000 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_2-branch Changes by: rearnsha@gcc.gnu.org 2002-09-18 07:05:39 Modified files: gcc : ChangeLog gcc/config/arm : arm.md Log message: PR optimization/7967 * arm.md (ne_zeroextractsi): Add clobber of the condition code register. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.13152.2.657.2.51&r2=1.13152.2.657.2.52 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/arm/arm.md.diff?cvsroot=gcc&only_with_tag=gcc-3_2-branch&r1=1.89.2.6&r2=1.89.2.6.2.1