Sorry for hitting return in the summary field ... This is a catch-all bug report for miscompilations of machine-generated code that is generated by the Gambit-C Scheme->C compiler. Giovanni Bajo suggested that I at least document the problem with proper preprocessed files, etc. All 34 megabytes of the files are at http://www.math.purdue.edu/~lucier/GNATS/GNATS-16/gambit-test.tgz They were generated and the bug was verified with the following commands: [lucier@cohomology gambc40b11]$ env CC='gcc -g -save-temps' ./configure --enable-single-host [lucier@cohomology gambc40b11]$ gcc -v Reading specs from /home/lucier/local/bin/../lib/gcc/i686-pc-linux-gnu/4.0.0/specs Configured with: ../configure --prefix=/home/lucier/local/ --enable-languages=c --enable-checking=no Thread model: posix gcc version 4.0.0 20041118 (experimental) [lucier@cohomology gambc40b11]$ make <stuff removed> [lucier@cohomology gambc40b11]$ cd bench [lucier@cohomology bench]$ ./bench -c no gambit fib Testing fib under Gambit-C Compiling... ./bench: line 518: 25754 Segmentation fault LD_LIBRARY_PATH=../../../lib GAMBCDIR=../../../lib ../../../gsc/gsc -:=../../.. $1.scm gcc: fib.c: No such file or directory gcc: fib_.c: No such file or directory Command exited with non-zero status 1 0.00user 0.00system 0:00.01elapsed 0%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (153major+23minor)pagefaults 0swaps ls: fib: No such file or directory Running... time: cannot run ./fib: No such file or directory Command exited with non-zero status 127 0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (24major+8minor)pagefaults 0swaps [lucier@cohomology bench]$ cd sys/gambit [lucier@cohomology gambit]$ ls fib.scm [lucier@cohomology gambit]$ env GAMBCDIR=../../../lib ../../../gsc/gsc -:=../../.. fib.scm Segmentation fault [lucier@cohomology gambit]$ env GAMBCDIR=../../../lib gdb ../../../gsc/gsc GNU gdb 6.3 Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) run -:=../../.. fib.scm Starting program: /home/lucier/programs/gambc40b11/gsc/gsc -:=../../.. fib.scm Program received signal SIGSEGV, Segmentation fault. 0x0815741b in ___H__20___front (___ps=0x8495ce0) at _front.c:7075 7075 ___SET_R2(___FIXMAX(___R3,___R2))
Failing with just '-O1' and -fno-tree-dominator-opts is a workaround.
We expanding this: ___r2.303 = MAX_EXPR <___r3.316, *((int *) ___r2.303 + 1B)>; into this: (insn 12778 12777 12779 1127 (set (reg/v:SI 1280 [ ___r2.303 ]) (reg/v:SI 1273 [ ___r3.316 ])) -1 (nil) (nil)) (insn 12779 12778 12780 1127 (set (reg:CCGC 17 flags) (compare:CCGC (reg/v:SI 1280 [ ___r2.303 ]) (mem:SI (plus:SI (reg/v:SI 1280 [ ___r2.303 ]) (const_int 1 [0x1])) [0 S4 A32]))) -1 (nil) (nil)) ... which is wrong. So the problem is with expander, unless i am mistaken.
(In reply to comment #3) > We expanding this: Yes it is, here is an small example of where we produce wrong code, I have to think of a full working testcase which we can run: int *fff; int f(int a, int b) { int crcc = b; int d = *((int*)(a+1)); int i; a = d >= b? d:b; for(i=0;i<a;i++) fff[i] = a; }
Here is at least a testcase for the MAX_EXPR problem: Compile with -O0, works, compiling with -O2 -fno-tree-lrs does not. long fff[10]; long f(long a, long b) { long crcc = b; long d = *((int*)(a+1)); int i; a = d >= b? d:b; for(i=0;i<10;i++) fff[i] = a; } int main(void) { int i; long a = 10; f((long)(&a)-1,0); for(i = 0;i<10;i++) if (fff[i]!=10) abort (); } -fno-tree-lrs is needed so we don't split the live range of a which we need to do so we hit the bug.
Andrew, your testcase is invalid. You cannot access a variable of long type through a pointer to int. I know the original code disables strict aliasing, but I did not test if your testcase also aborts with -fno-strict-aliasing.
(In reply to comment #6) > Andrew, your testcase is invalid. You cannot access a variable of long type > through a pointer to int. I know the original code disables strict aliasing, > but I did not test if your testcase also aborts with -fno-strict-aliasing. Oops, here is one which is just changes the cast to long* instead of int*, it is still broken at -O1 -fno-tree-lrs also: long fff[10]; long f(long a, long b) { long crcc = b; long d = *((long*)(a+1)); int i; a = d >= b? d:b; for(i=0;i<10;i++) fff[i] = a; } int main(void) { int i; long a = 10; f((long)(&a)-1,0); for(i = 0;i<10;i++) if (fff[i]!=10) abort (); }
Here's the RTL we generate for this on AMD64: ;; a = MAX_EXPR <b, *(long int *) (a + 1)> (insn 19 17 20 (set (reg/v:DI 66 [ a ]) (reg/v:DI 67 [ b ])) -1 (nil) (nil)) (insn 20 19 21 (set (reg:CCGC 17 flags) (compare:CCGC (reg/v:DI 66 [ a ]) (mem:DI (plus:DI (reg/v:DI 66 [ a ]) (const_int 1 [0x1])) [0 S8 A64]))) -1 (nil) (nil)) (jump_insn 21 20 22 (set (pc) (if_then_else (ge (reg:CCGC 17 flags) (const_int 0 [0x0])) (label_ref 23) (pc))) -1 (nil) (nil)) (insn 22 21 23 (set (reg/v:DI 66 [ a ]) (mem:DI (plus:DI (reg/v:DI 66 [ a ]) (const_int 1 [0x1])) [0 S8 A64])) -1 (nil) (nil)) (code_label 23 22 0 2 "" [0 uses]) Note that this is pretty dreadful with the common subexpression and all. And indeed, it is also buggy :-)
Right... so this is miscompiled: ;; a = MAX_EXPR <b, *(long int *) (a + 1)> but this is not: ;; a = MAX_EXPR <*(long int *) (a + 1), b> Tricky to have a stable test case for this. I suppose we should just force both options of the MAX_EXPR into a reg.
Subject: Bug 18548 CVSROOT: /cvs/gcc Module name: gcc Changes by: sayle@gcc.gnu.org 2004-12-18 14:38:44 Modified files: gcc : ChangeLog expr.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.dg: max-1.c Log message: PR middle-end/18548 * expr.c (expand_expr_real_1) <MAX_EXPR>: Ensure that target, op0 and op1 are all registers (or constants) before expanding the RTL comparison sequence [to avoid reg_overlap_mentioned (target, op1)]. * gcc.dg/max-1.c: New test case. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.6873&r2=2.6874 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/expr.c.diff?cvsroot=gcc&r1=1.760&r2=1.761 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.4780&r2=1.4781 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/max-1.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
My apologies to Steven. I've only just noticed that between me agreeing to investigate the problem on IRC and preparing a patch last night, and committing the fix this morning, that you'd/he'd assigned this PR to himself. Please forgive me, next time I should re-check the PR in bugzilla after comparing the regression test output, and before posting/committing a patch.
Roger, this was a "catch-all bug reports", there may still be other problems open. Brad, can you try and see if you have any more problems?
Waiting for Brad to check if there are more problems.
May or may not look at any remaining issues...
Original testcase now fixed.
Subject: Re: [4.0 Regression] Miscompiles code generated by Gambit-C Scheme->C compiler I can find no other problems at the moment. Thank you all for investigating and fixing this. Brad