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