Path: 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 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