Bug 7967 - optimization produces wrong code (ARM)
Summary: optimization produces wrong code (ARM)
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 3.2
: P2 critical
Target Milestone: ---
Assignee: Richard Earnshaw
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2002-09-18 05:36 UTC by jeroen.dobbelaere
Modified: 2003-07-25 17:33 UTC (History)
1 user (show)

See Also:
Host: armv5l-unknown-linux-gnu
Target:
Build: armv5l-unknown-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description jeroen.dobbelaere 2002-09-18 05:36:02 UTC
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;
}
Comment 1 jeroen.dobbelaere 2002-09-18 05:36:02 UTC
Fix:
disable optimizations
Comment 2 Richard Earnshaw 2002-09-18 08:22:39 UTC
Responsible-Changed-From-To: unassigned->rearnsha
Responsible-Changed-Why: .
Comment 3 Richard Earnshaw 2002-09-18 08:22:39 UTC
State-Changed-From-To: open->closed
State-Changed-Why: Fixed with the patch referenced.
Comment 4 Richard Earnshaw 2002-09-18 14:01:59 UTC
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
 

Comment 5 Richard Earnshaw 2002-09-18 14:05:39 UTC
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