Date: Tue, 8 Nov 94 03:25:43 JST From: Stephen Turnbull To: cspt AT ludens DOT elte DOT hu Cc: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: 2.4/3-2.4/3!=0 A simple comparison changed the value of a variable (x) when I No floating point operation is "simple." Not even assignment (in an environment of high precision floating point hardware). compiled the program with -O1. When I compiled a program with these With optimization, the program uses common subexpression elimination and does a FPU register to CPU register load for the value of x. This is faster than the memory reference to address &x, thus preferred to the memory reference. The compiler assumes that the value it just stored into that memory location is unchanged. This doesn't mean it stored the same value as the source (can't be---FPU registers are 10 bytes, doubles are only 8 bytes); it means that the result of repeating the store operation would be the same. operations without optimizations (or with optimizations, but declaring all double variables volatile), 1-x was always >=0. When The compiler may not optimize away references to volatile memory locations. The compiler may also not use associativity to change the order of operations if the value of the operation is assigned to a variable, even if that variable is later optimized into nonexistence. I optimized it, there was this bug, which caused the program to terminate with a floating point exception when it tried to calculate sqrt(1-x). I hardly found this bug, because when I compared 1-x to 0, (if(1-x<0) printf("akurvaeletbe\n"); or something like that before sqrt), the program did not hang (the comparison corrected the value of x, so it became 0). So my question is: Is it possible to compile this program with -O1 (and -ffloat-store), but without this bug? If it is, which optimization flag must I switch off after -O1? I forget what GCC calls it; look for "common subexpression" or "very busy expression" in the man page. Switch that one off, it might work.