[llvm-dev] Possible bug in optimizer

Andrea Venturoli via llvm-dev
Sat, 28 Apr 2018 14:32:58 -0000

Hello.

I'm new to this list, but I've been using Clang for a while (and C++ for
many years).

I've encountered a problem when compiling with -O1 on FreeBSD/amd64 11.1
(with bundled Clang, i.e. 4.0.0, as well as with 5.0.1 and 6.0.0 from
ports).
I asked on comp.lang.c++ and the code was also confirmed to misbehave on
Linux, so they suggested I post it here.

What follows is the minimal code which should produce the error; notice
something more convoluted is needed at -O3 (the original software still
crashes, but in this example, probably too much is optimized away).



// ------------ a.cpp ------------------
#include <iostream>
#include <numeric>
#include <limits>
#include <cfenv>

  double f(double A,double B) {
    if (A<B) return std::numeric_limits<double>::max();
    return A-B;
  }

  int main(int , char**) {
    feenableexcept(FE_OVERFLOW); //**** NOTE 1
    double A=f(.0001002773902563,1.);
    std::cout<<A<<std::endl;
    double B;
    if (A==std::numeric_limits<double>::max()) {
//     std::cout<<"Good"<<std::endl; //**** NOTE 2
      B=A;
    } else {
//     std::cout<<"Bad"<<std::endl; //**** NOTE 2
      B=A*2.;
    }
    std::cout<<B<<std::endl;
  }
// ---------------------------------------

The command:
$ clang++ -O1 a.cpp
$ ./a.out
1.79769e+308
Floating point exception (core dumped)



NOTE 1: enabling overflow exceptions on FP math will render the
instruction "B=A*2" illegal.
That instruction shouldn't be executed, if following the proper program
flow; probably the compiler still has the CPU compute this value
speculatively.
NOTE 2: inserting the commented statement makes the program behave
correctly again, evidently avoiding the execution of the second branch.



Please let me know if you think this is a bug in the compiler, if using
feenableexcept along with optimizations is considered bad practive or if
you need further info.

  bye & Thanks
	av.