The following snipped when compiled with -O0 generates a program that quickly finishes (correct behavior). But when compiled with any optimizations (-O1, -O2 or -O3) generates a program that never finishes. Variations on the code, (such as the comment line) geneate valid program with either level of optimization. Checked in 4.1.1 too (i386) and the bug is there too. Checked in 4.1.2 on x86_64 and the bug is NOT there. -- star of file aa.cpp struct A { unsigned int e; }; A a = {1}; double f[] = {0.0461109, 0.285433}; int main(void) { for (bool bEncore = true; bEncore; ) { bEncore = false; double p = 0.422244 * f[a.e]; // double p = 0.422244 * f[1]; if (f[0] < p) { f[0] = p; bEncore = true; } } return 0; } -- end of file aa.cpp g++ -O3 aa.cpp ./a.out --> goes into infinite loop
Created attachment 14280 [details] source file and the result of 'gcc -v -save-temps -O3 aa.cpp 2>stderr'
I think you should read http://www.validlab.com/goldberg/paper.pdf . I think what is happening is on x86, there is extra precision so really you are running into bug 323. Can you try to add -ffloat-store?
For once a real floating point bug. In this code double p = 0.422244 * f[a.e]; if (f[0] < p) with a.e=1, f[1]=0.285433, we should calculate p=0.285433. Since f[0]=0.0461109, we shouldn't enter the if-clause, but we do when optimization is on. Since the numbers aren't even close, this isn't due to excess precision or any other floating point instability but a real bug. Funny enough, this was already broken in 2.95, 3.2.3 and 3.3.6 but then worked in 3.4.6 and 4.0.x only to be broken again in 4.1.2. W.
(In reply to comment #3) > For once a real floating point bug. In this code > double p = 0.422244 * f[a.e]; > if (f[0] < p) > > with a.e=1, f[1]=0.285433, we should calculate p=0.285433. Since > f[0]=0.0461109, we shouldn't enter the if-clause, but we do when Sorry, but this isn't quite accurate; the math is off, and the code _should_ enter the if branch the first time around, just not the second time around.
*** This bug has been marked as a duplicate of 323 ***