[llvm-dev] Possible bug in optimizer

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[llvm-dev] Possible bug in optimizer

Adam Nemet via llvm-dev
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.
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Possible bug in optimizer

Adam Nemet via llvm-dev
Hi Andrea,

On 28 April 2018 at 15:32, Andrea Venturoli via llvm-dev
<[hidden email]> wrote:
>    feenableexcept(FE_OVERFLOW); //**** NOTE 1

There are two problems here. One with the code and one with Clang.

First, in order to use these floating-point environment functions, the
C (and C++) language requires you to use "#pragma stdc fenv_access
on". Without that, the compiler is free to assume that exceptions
aren't possible and the default rounding mode prevails regardless of
the calls you make. And Clang does.

Unfortunately, the other half is the Clang bug: it doesn't actually
support that #pragma yet. It'll warn (yay!?) but won't actually make
your code work.

One final silver lining is that there's actually a reasonably active
effort to start supporting the pragma going on now. We've got most of
a plan, bits are implemented, and people are working on it. Now that
you know to search for the keyword "fenv_access" you should be able to
find lots more discussion on these lists. Though probably not a
committed timeline, I'm afraid.

Cheers.

Tim.
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev