3 Replies Latest reply on Jan 31, 2008 3:15 PM by mickpont

    IEEE violation with optimization:  gcc 3.4 on X86_64

    kumnav
      double-precision NaN less-than FiniteValue returns TRUE with gcc -O, -O2, and higher on X86_64

      I see a problem with ACML if it is being built with GCC 3.4. The following demonstrates how NaN is mistreated when optimization, even -O let alone -O2, is enabled. In the following, when optimization is not enabled, the output is correctly "nan" since IEEE standards dictate that (x > max) must return FALSE when x=NAN and (x < min) must return FALSE when x=NAN. Therefore, f(x) must return x when x=NAN. This does not happen, for some reason the (x < min) branch is taken and -1 is returned. Will ACML be built with GCC 4.x? I'm not sure how I can trust double-precision arithmetic otherwise.

      gcc-3.4 Output without optimization: "nan" (correct)
      gcc-3.4 Output with optimization: "-1" (wrong)

      gcc-4.x Output always: "nan" (correct)

      Source:

      #include <iostream>
      #include <stdint.h>
      #include <math.h>


      double f(double x)
      {
      static const double max = 1;
      static const double min = -1;
      if(x > max) {
      return max;
      } else if(x < min) {
      return min;
      } else {
      return x;
      }
      }

      int main(int argc, char** argv)
      {
      double x = 0;
      double y = 0;
      x /= y;
      std::cerr << f(x) << std::endl;
      return 0;
      }
        • IEEE violation with optimization:  gcc 3.4 on X86_64
          kumnav
          Just to clarify, GCC 3.4 only seems to have the NAN arithmetic comparison bug when compiling for 64-bit mode on X86_64 _and_ using an optimization flag (-O, -O2, or -O3).
          • IEEE violation with optimization:  gcc 3.4 on X86_64
            chipf
            We did not build ACML with GCC 3.4.

            We currently build with GCC 4.1.2 and GCC 4.2.0 (for the OpenMP version), so this issue should not be a problem.
            • IEEE violation with optimization:  gcc 3.4 on X86_64
              mickpont
              High level languages like Fortran do not necessarily handle comparisons involving NaNs in the way that you suggest, irrespective
              of what the IEEE 754 arithmetic standard says. That standard (section 5.7) says that NaNs compare as "unordered" with all other numbers,
              including other NaNs. The standard also recommends using a function isnan() to detect whether a value is a NaN. In my experience,
              a Fortran comparison involving a NaN can go any which way, and the same comparison written in two parts of the same routine
              might go two different ways.

              Even if the high level language handled NaNs in the way you would like, I'm not sure it would help much.
              LAPACK, BLAS and other routines are not generally designed to expect NaNs. So, however NaN's are handled,
              the results you get from a routine call might not be what you expect if you supply input data (e.g. a matrix element) containing a NaN.
              You might or might not get a NaN returned in your results.