[forwarded from http://bugs.debian.org/309210] rechecked with 4.0 CVS 20050816 wrong code for PARI/GP 2.2.10 on x86. The pari source code can be found here: <http://pari.math.u-bordeaux.fr/pub/pari/unstable/pari-2.2.10.alpha.tar.gz> The problem is in the file src/basemath/alglin1.c, function ker0(). The compilation command used was: gcc-4.0 -c -O3 -DGCC_INLINE -Wall -fno-strict-aliasing -fomit-frame-pointer -DBOTH_GNUPLOT_AND_X11 -I. -I../src/headers -o alglin1.o alglin1.i using gcc-4.0 -O2 or gcc-3.4 -O3 generates correct code. The problem can be reproduces running the gp interpreter: 1) download the tarball mentionned in the bug report and untar it 2) do CC=gcc-4.0 ./Configure 3) do make bench One test-case fails (alglin). Alternatively, you can do make gp ./gp matker([1,2;3,4]) *** matker: bug in GP (Segmentation Fault), please report More information about compiler options that fix this problem: <http://pari.math.u-bordeaux.fr/archives/pari-dev-0505/msg00007.html> > Can you make a stand-alone testcase? Not at that time, unfortunately. The bug only occurs inside deeply inlined code.
Created attachment 9526 [details] preprocessed source
We need at least a testcase which links.
testcase at http://people.debian.org/~doko/tmp/tst.tar.bz2
Created attachment 9542 [details] testcase, part1 (948 bytes)
Created attachment 9543 [details] testcase, part2 (3112 bytes) These two files are self-contained tescase for this bug, to compile use this command: gcc bug1.c bug2.c -O3 -fno-strict-aliasing -fomit-frame-pointer -march=i486 Seems that gcse2 miscompiles gauss_pivot_ker() from bug2.c, here is a diff between code generated with -fno-gcse-after-reload and w/o that option: movl $1, 100(%esp) movl $0, 36(%esp) - .p2align 4,,15 -.L23: movl 100(%esp), %edi + movl 100(%esp), %ecx sall $2, %edi pushl $0 pushl $0 pushl $0 - movl 100(%esp), %ecx movl (%ecx,%edi), %ecx pushl %ecx call gauss_get_pivot_max which is clearly wrong.
Single-file testcase, compile with "-march=i486 -O2 -fomit-frame-pointer -fno-strict-aliasing -fgcse-after-reload": bar () { exit (0); } baz (x) { return x; } foo () { abort (); } ker0 (int *x0, int a) { int *x, *c, *d, p, av, i, j, k, r, t, n, m, *dd; n = x0; m = x0 [0]; x = baz (x0); if (a) { if (m) foo (); for (k = 1; k <= n; k ++) ((int **) x) [k] = foo (x [k]); } for (k = 1; k < m; k ++) c [k] = 0; av = k; for (k = 0;; k ++) { j = bar (x [k], 0, 0, 0); if (j > m) { r ++; for (j = 1; j < k; j ++) if (d [j]) ((int **) x) [k] [d [j]] = 0; } else { foo (0, x [j]); for (i = k + 1; i; i ++) ((int *) x) [j] = 0; for (t = 1; m; ) if (j) { p = x [t]; for (i = k + 1; i; i ++) x [t] = foo (x [i], foo (p, x [j])); if (av) foo (k); } } } *dd = r; } int main (void) { int x = 0; ker0 (&x, 0); abort (); }
gcse after reload may move loads from stack around stack pointer changes. here is simple workaround, it is supposed to prevent gcse after reload from touching expressions containing stack pointer at all. Index: cse.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cse.c,v retrieving revision 1.359 diff -u -r1.359 cse.c --- cse.c 29 Jul 2005 05:57:37 -0000 1.359 +++ cse.c 19 Aug 2005 19:33:49 -0000 @@ -2221,6 +2221,14 @@ return 0; } } + else + { + if (x == stack_pointer_rtx) + { + *do_not_record_p = 1; + return 0; + } + } hash += ((unsigned int) REG << 7); hash += (have_reg_qty ? (unsigned) REG_QTY (regno) : regno);
> gcse after reload may move loads from stack around stack pointer changes. here > is simple workaround, it is supposed to prevent gcse after reload from touching > expressions containing stack pointer at all. Off the top of my head, if GCSE-after-reload is designed to remove redundant spills, will it do *anything* with your patch?
Leaving as P2.
This doesn't fail for me with the test case from comment #6... :-(
If nobody is going to fix gcse2, the right thing to do is to not set flag_gcse_after_reload for optimize >= 3 in opts.c: Index: opts.c =================================================================== --- opts.c (revision 108560) +++ opts.c (working copy) @@ -588,7 +588,6 @@ decode_options (unsigned int argc, const { flag_inline_functions = 1; flag_unswitch_loops = 1; - flag_gcse_after_reload = 1; } if (optimize < 2 || optimize_size) Obviously it would be better to just fix the bug, but so far I, for one, can't get a handle on it.
Almost certainly a dup of PR25196
Marking as dup of bug 25196 because that bug contains simpler test case. *** This bug has been marked as a duplicate of 25196 ***
The patch proposed in bug 25196 comment #8 indeed makes the test case from comment #6 in this PR work (at least, it stops it from segfaulting).