When compiling with optimization, it is possible to assign the value of one
float variable to another, and then have the latter value compare unequal to
the former. Take the following (contrived) testcase:

extern float sqrtf(float);
volatile int foo(int n) {
    float a = sqrtf(n);
    volatile float b = 0;
    int c = 0;
    while (b < a) {
        b = a;
        c++;
    }
    return c;
}
int main() {
    return foo(32)==1 ? 0 : 1;
}

In theory, the loop in foo() should execute once, but when compiled with -O1 or
greater on i386, the loop never terminates. Examination of the generated
assembly shows that "a" is retained on the floating-point stack and never
flushed to memory, so when "b" is reloaded for the comparison, its value is
slightly less than the more-precise "a". (While libm's sqrtf() may also be at
fault for returning a value that was not properly converted to float, the same
problem exists when the test program is compiled with -ffast-math to use the
fsqrt instruction directly: the high-precision result of fsqrt is left on the
stack for the comparison, without being converted to a single-precision value.)


-- 
           Summary: float value not equal to itself after assignment
           Product: gcc
           Version: 4.1.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: gcczilla at achurch dot org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31008

Reply via email to