Bug 41431

Summary: Serious bug when comparing doubles in gcc
Product: [Retired] Red Hat Linux Reporter: Need Real Name <sams>
Component: gccAssignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact: David Lawrence <dkl>
Severity: high Docs Contact:
Priority: medium    
Version: 6.1   
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2001-05-20 11:37:10 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
test program for serious bug in comparing doubles none

Description Need Real Name 2001-05-20 11:35:30 UTC
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:

Comment 1 Need Real Name 2001-05-20 11:37:07 UTC
Created attachment 19070 [details]
test program for serious bug in comparing doubles

Comment 2 Jakub Jelinek 2001-05-20 14:55:38 UTC
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.