GCC Bugzilla – Bug 23453
[4.0/4.1/4.2 regression] miscompilation of PARI/GP on x86 with gcse after reload
Last modified: 2005-12-20 16:11:31 UTC
[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:
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
One test-case fails (alglin).
Alternatively, you can do
*** matker: bug in GP (Segmentation Fault), please report
More information about compiler options that fix this problem:
> Can you make a stand-alone testcase?
Not at that time, unfortunately. The bug only occurs inside deeply inlined
Created attachment 9526 [details]
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
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
movl 100(%esp), %edi
+ movl 100(%esp), %ecx
sall $2, %edi
- movl 100(%esp), %ecx
movl (%ecx,%edi), %ecx
which is clearly wrong.
Single-file testcase, compile with "-march=i486 -O2 -fomit-frame-pointer
ker0 (int *x0, int a)
int *x, *c, *d, p, av, i, j, k, r, t, n, m, *dd;
n = x0;
m = x0 ;
x = baz (x0);
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)
for (j = 1; j < k; j ++)
if (d [j])
((int **) x) [k] [d [j]] = 0;
foo (0, x [j]);
for (i = k + 1; i; i ++)
((int *) x) [j] = 0;
for (t = 1; m; )
p = x [t];
for (i = k + 1; i; i ++)
x [t] = foo (x [i], foo (p, x [j]));
*dd = r;
int main (void)
int x = 0;
ker0 (&x, 0);
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.
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 @@
+ 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:
--- 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).