From Bugzilla Helper: User-Agent: Mozilla/4.72 [en] (X11; U; Linux 2.2.12-20 i686; Nav) Description of problem: When I compile the simple C-program below under RedHat 6.2 (egcs-2.91.66) or RedHat 7.0 (gcc-2.96) I get the following problem: > gcc -O3 testc.c -lm -o testc > ./testc 1: x1!=x2 1: x1!=x2 -0.227202 -0.227202 0.000000e+00 If a comparison of variables is made, as the first operation, the values are not loaded into the varibles before comparison. If I compile without the -O3 flag, the problem disappears. On an alpha-architecture (gcc 2.8.1) the problem is not present. test program: #include <stdio.h> #include <math.h> #include <stdlib.h> int main(){ double x1; double x2; x1 = cos(1.7); x2 = cos(1.7); if(x1!=x2) printf("1: x1!=x2\n"); if(x1!=x2) printf("2: x1!=x2\n"); if(x1!=x2) printf("3: x1!=x2\n"); x1 = cos(1.8); x2 = cos(1.8); if(x1!=x2) printf("1: x1!=x2 %f %f %e\n", x1, x2, x1-x2); if(x1!=x2) printf("2: x1!=x2 %f %f %e\n", x1, x2, x1-x2); if(x1!=x2) printf("3: x1!=x2 %f %f %e\n", x1, x2, x1-x2); exit(0); } How reproducible: Always Steps to Reproduce: 1. gcc -O3 testc.c -lm -o testc 2. ./testc 3. Actual Results: When compiled with optimization O1, O2, O3, ... the test program fails to compare two double the first time they are used. When compiled with O0, the program works without problem. Additional info:
Created attachment 19070 [details] test program for serious bug in comparing doubles
This is not a bug. The Intel IA32 FPU architecture is so braindamaged that if floating point code generated for this architecture is to run sufficiently fast, there is no other way. You can use the -ffloat-store switch to force all floating point variables into memory, where at the cost of slowing things down these will compare equal. The issue is that IA32 computes all floating point stuff in IEEE 854 extended double precision (IA32 long double) and the values are rounded on storing into memory only. On sane architectures, there are separate instructions to do single precision, double precision and on some arches either extended double precision or quad precision arithmetics, so rounding is done to the right precision after every single operation.