i686 (PentiumPro) Optimizer Bug
Robert Lipe
robertl@dgii.com
Mon Nov 16 10:00:00 GMT 1998
I was unable to duplicate this problem with either 1.0.2 (as shipped
with redhad 5.1) or with a Linux snapshot of egcs-2.92.21.
Interestingly, on 1.1.1, this example emits an opcode the OpenServer
assembler cannot grok. It seems to choke on:
/usr/tmp/cc2QneXL.s:35:unknown instruction: fcmove
/usr/tmp/cc2QneXL.s:58:unknown instruction: fcmove
On the trunk, it seems to print the expected results (with no fcmove)
on all of Linux, UDK, and OpenServer.
So apparently, this particular opcode/optimization isn't covered by the
testsuite.
RJL
Gerhard Heinzel wrote:
> Dear gcc maintainers,
>
> I believe I have found a bug in the PentiumPro optimizer of
>
> gcc version egcs-2.91.57 19980901 (egcs-1.1 release)
>
> built for i686-pc-linux-gnulibc1 without any options or modifications.
>
> The program below should multipliy a matrix with its inverse and compare
> elementwise the result to the unity matrix, recording the maximum absolute
> difference between the expected result and the unity matrix.
>
> I have simplified the program as much as possible, using unity matrices as
> operands. The result should be 0.
>
> Here is the program:
>
> #include <stdio.h>
> #include <math.h>
> #define SIZE 10
>
> int
> main (void)
> {
> int i, j, k;
> double a[SIZE * SIZE], ainv[SIZE * SIZE];
> double diff, sum, soll, maxd;
>
> /* matrix addressing : a(i,j) = a[n*i+j] */
>
> /* Normally here 'a' is a double matrix and 'ainv' its inverse */
> /* For testing, set 'a' and 'ainv' as unity matrices */
> for (i = 0; i < SIZE; i++)
> for (j = 0; j < SIZE; j++)
> a[i * SIZE + j] = ainv[i * SIZE + j] = ((i == j) ? 1 : 0);
>
> /* compute the product a*ainv element by element and compare to
> unity matrix */
>
> maxd = 0; /* maximum of difference */
> for (i = 0; i < SIZE; i++)
> for (j = 0; j < SIZE; j++)
> /* compute element (i,j) of product */
> {
> /*1*/ sum = 0;
> /*2*/ soll = ((i == j) ? 1 : 0); /* this should be the result */
> for (k = 0; k < SIZE; k++)
> sum += a[i * SIZE + k] * ainv[k * SIZE + j];
> diff = fabs (sum - soll); /* measure difference */
> if (diff > maxd) /* record maximum difference */
> maxd = diff;
> }
> printf ("maxd=%g \n", maxd);
> return 0;
> }
>
> If I compile it with
>
> gcc -g -O -march=i686 err.c -o err /* BUG */
>
> I get the wrong result
>
> maxd=NaN
>
> The bug appears only with the combination of '-O' and '-march=i686'.
> The following produce correct results:
>
> gcc -g -O3 -march=i586 err.c -o err /* NO BUG */
> gcc -g -march=i686 err.c -o err /* NO BUG */
>
> Furthermore, the bug disappears if the lines marked /*1*/ and /*2*/
> in the source are interchanged.
>
> Here is some information on the CPU:
>
> cat /proc/cpuinfo
> processor : 0
> cpu : 686
> model : Pentium Pro
> vendor_id : GenuineIntel
> stepping : 9
> fdiv_bug : no
> hlt_bug : no
> f00f_bug : no
> fpu : yes
> fpu_exception : yes
> cpuid : yes
> wp : yes
> flags : fpu vme de pse tsc msr pae mce cx8 11 mtrr pge mca cmov
> bogomips : 199.07
>
> Since I regularily compile programs for lengthy numerical mathematics for
> our GNU/Linux PentiumPro machines I would be very pleased to learn that I
> can continue to optimize for that machine.
>
> With best greetings
>
> Gerhard Heinzel
>
> =====================================================================
> Gerhard Heinzel E-mail: ghh@mpq.mpg.de
> Max-Planck-Institut fuer Quantenoptik Phone: +49(89)32905-268/252
> Hans-Kopfermann-Str. 1 Phone (30m Lab): +49(89)3299-3282
> D-85748 Garching Fax: +49(89)32905-200
> Germany http://www.geo600.uni-hannover.de
> =====================================================================
>
More information about the Gcc-bugs
mailing list