🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #808

(none)

#808
From: Bill Bailey
Date: Mon, 20 Nov 1989 03:52
128 lines
3478 bytes
Dear RMS:						11/19/89

I believe I have discovered a bug in cse.c in gcc v.1.36.  I include
below a small code fragment and the assembly generated by gcc both
optimized and not.  The assembly is fine when compiled unoptimized but
incorrect optimized.  I also provide a context diff of a suggested fix.
The fix works for the case below but probably is not comprehensive.

In the distributed version of gcc 1.36, this problem only surfaces when
using gcc as a cross compiler, hosted on sun4 generating target code for
vaxen.  So I built gcc on my sparcstation after 'config.gcc vax'.

More generally, the problem will surface whenever gcc is being used as a 
cross compiler and the host machine's instruction set does not support
shifting by negative amounts but the target instruction set does.  On vaxen,
for example, one does right shifts via:  ashl $-1,r0,r0.

% cat bug.c
foo()
{
  int s;

  s = -8;
  return s / 2;
}
%
% gcc -B./ -v -O -S bug.c
gcc version 1.36
./cpp -v -undef -D__GNUC__ -Dvax -Dunix -D__vax__ -D__unix__ -D__OPTIMIZE__ bug.c /usr/tmp/cca09079.cpp
GNU CPP version 1.36
./cc1 /usr/tmp/cca09079.cpp -quiet -dumpbase bug.c -djs -O -version -o bug.s
GNU C version 1.36 (vax) compiled by CC.
default target switches: -munix
%
% cat bug.s
#NO_APP
gcc_compiled.:
.text
	.align 1
.globl _foo
_foo:
	.word 0x0
	movl $-2147483648,r0       /* NOTE THE INCORRECT IMMEDIATE VALUE */ 
	ret 
%
% gcc -B./ -S bug.c
% cat bug.s

#NO_APP
gcc_compiled.:
.text
	.align 1
.globl _foo
_foo:
	.word 0x0
	subl2 $4,sp
	mcoml $7,-4(fp)
	movl -4(fp),r0
	tstl r0
	jgeq L1
	incl r0
L1:
	ashl $-1,r0,r0
	movl r0,r0
	ret
	ret
%

The reason for the failure is in fold_rtx().  You end up doing:
{
    int a,b,c;
    a = b << c;
}
where c is negative.  Note this violates ansi 'C' section 3.3.7
paragraph 10.  Here is the context diff of a suggested fix:


*** cse.c	Sun Nov 19 18:57:24 1989
--- ../gcc-1.36/cse.c	Fri Sep 15 22:15:22 1989
***************
*** 2357,2377 ****
  	case GTU:
  	  val = ((unsigned) arg0) > ((unsigned) arg1);
  	  break;
  
  	case LSHIFT:
! 	  if (arg1 < 0)
! 	      val = ((unsigned) arg0) >> -arg1;
! 	  else
! 	      val = ((unsigned) arg0) << arg1;
  	  break;
  
  	case ASHIFT:
! 	  if ( arg1 < 0 )
! 	      val = arg0s >> -arg1;
! 	  else
! 	      val = arg0s << arg1;
  	  break;
  
  	case ROTATERT:
  	  arg1 = - arg1;
  	case ROTATE:
--- 2357,2371 ----
  	case GTU:
  	  val = ((unsigned) arg0) > ((unsigned) arg1);
  	  break;
  
  	case LSHIFT:
! 	  val = ((unsigned) arg0) << arg1;
  	  break;
  
  	case ASHIFT:
! 	  val = arg0s << arg1;
  	  break;
  
  	case ROTATERT:
  	  arg1 = - arg1;
  	case ROTATE:


Note there are probably other cases where you shift by negative amounts so
this fix won't be general enough.  In any case, since ansi disallows it, you
should never shift by a negative amount.  Perhaps redefining vax.md would
be a better approach.  

Please let me know what you discover.  I am wbailey@oracle.com
thx
-bill
Technical Details
Message-ID: <8911200352.AA09119@flame.oracle.com>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!ucsd!ucbvax!tut.cis.ohio-state.edu!flame.oracle.com!wbailey

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!ucsd!ucbvax!tut.cis.ohio-state.edu!flame.oracle.com!wbailey
From: wbailey@flame.oracle.com (Bill Bailey)
Newsgroups: gnu.gcc.bug
Subject: (none)
Message-ID: <8911200352.AA09119@flame.oracle.com>
Date: 20 Nov 89 03:52:36 GMT
Sender: daemon@tut.cis.ohio-state.edu
Distribution: gnu
Organization: GNUs Not Usenet
Lines: 128