Bug 18548 - [4.0 Regression] Miscompiles code generated by Gambit-C Scheme->C compiler
Summary: [4.0 Regression] Miscompiles code generated by Gambit-C Scheme->C compiler
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.0.0
: P2 normal
Target Milestone: 4.0.0
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2004-11-18 18:53 UTC by lucier
Modified: 2004-12-18 15:28 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 3.4.4
Known to fail: 4.0.0
Last reconfirmed: 2004-12-18 00:02:55


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description lucier 2004-11-18 18:53:18 UTC
 
Comment 1 lucier 2004-11-18 19:04:47 UTC
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))
Comment 2 Serge Belyshev 2004-12-16 14:12:20 UTC
Failing with just '-O1' and -fno-tree-dominator-opts is a workaround.
Comment 3 Serge Belyshev 2004-12-17 23:28:04 UTC
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.
Comment 4 Andrew Pinski 2004-12-17 23:50:25 UTC
(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;
}
Comment 5 Andrew Pinski 2004-12-18 00:02:54 UTC
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.
Comment 6 Giovanni Bajo 2004-12-18 00:33:05 UTC
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.
Comment 7 Andrew Pinski 2004-12-18 00:38:49 UTC
(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 ();
}
Comment 8 Steven Bosscher 2004-12-18 13:54:47 UTC
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 :-) 
 
Comment 9 Steven Bosscher 2004-12-18 14:03:11 UTC
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. 
 
Comment 10 GCC Commits 2004-12-18 14:38:52 UTC
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

Comment 11 roger 2004-12-18 14:50:31 UTC
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.
Comment 12 Steven Bosscher 2004-12-18 15:07:54 UTC
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? 
Comment 13 Steven Bosscher 2004-12-18 15:08:28 UTC
Waiting for Brad to check if there are more problems. 
 
Comment 14 Steven Bosscher 2004-12-18 15:08:52 UTC
May or may not look at any remaining issues... 
Comment 15 Serge Belyshev 2004-12-18 15:28:11 UTC
Original testcase now fixed.
Comment 16 lucier 2004-12-18 20:23:04 UTC
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