fast-math, clang-6+ and floating point exceptions

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

fast-math, clang-6+ and floating point exceptions

Nathan Ridge via cfe-dev
I'm working on scientific code, that  explicitly catches and crashes
on floating point exceptions (I've seen several such projects in the
past in the scientific domain do this). *Everything* is compiled with
-ffast-math and -O3. However, we've got this code in a module:

    float w = std::log(x);
    if (x > 3) {
        w -= std::log(w);
    }

Godbolt: https://godbolt.org/z/yvGqjl

Basically, if I'm reading the assembly output properly, it looks like
clang > 6 optimizes this into assuming that the second log is almost
always run (not unreasonably), always calls log twice, and eliminates
the branch. However, in our code, the second log causes an FPE which
jumps to a crash handler.

My questions are:
- Am I correct in my interpretation of what's going on here?
- Is this a reasonable thing for clang to do - it's not implied by any
of the cases on
https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math ,
although to be fair that does say it's a non-inclusive list. GCC
_doesn't_ seem to make this transform, though obviously that doesn't
mean that it's a bad one
- Can I prevent this from happening, even with -ffast-math enabled?
- Is this sort of configuration sensible or insane?

Thanks,

Nick
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: fast-math, clang-6+ and floating point exceptions

Nathan Ridge via cfe-dev


> -----Original Message-----
> From: cfe-dev [mailto:[hidden email]] On Behalf Of
> Nicholas Devenish via cfe-dev
> Sent: Tuesday, July 30, 2019 6:28 PM
> To: [hidden email]
> Subject: [cfe-dev] fast-math, clang-6+ and floating point exceptions
>
> I'm working on scientific code, that  explicitly catches and crashes
> on floating point exceptions (I've seen several such projects in the
> past in the scientific domain do this). *Everything* is compiled with
> -ffast-math and -O3. However, we've got this code in a module:
>
>     float w = std::log(x);
>     if (x > 3) {
>         w -= std::log(w);
>     }
>
> Godbolt: https://godbolt.org/z/yvGqjl
>
> Basically, if I'm reading the assembly output properly, it looks like
> clang > 6 optimizes this into assuming that the second log is almost
> always run (not unreasonably), always calls log twice, and eliminates
> the branch. However, in our code, the second log causes an FPE which
> jumps to a crash handler.
>
> My questions are:
> - Am I correct in my interpretation of what's going on here?
> - Is this a reasonable thing for clang to do - it's not implied by any
> of the cases on
> https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math ,
> although to be fair that does say it's a non-inclusive list. GCC
> _doesn't_ seem to make this transform, though obviously that doesn't
> mean that it's a bad one

I'm far from an expert, but we've run into this kind of thing, and
basically (a) LLVM assumes there are no exceptions, (b) it is willing
to speculate FP operations sometimes; this combo can go boom.

> - Can I prevent this from happening, even with -ffast-math enabled?

We do the equivalent of `-mllvm -speculate-one-expensive-inst=false`
and it helps.

> - Is this sort of configuration sensible or insane?

In the golden land of perfect understanding of FP exceptions, it would
be controllable in a more complete and principled way.  LLVM is a long
way off from that.
--paulr

>
> Thanks,
>
> Nick
> _______________________________________________
> cfe-dev mailing list
> [hidden email]
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: fast-math, clang-6+ and floating point exceptions

Nathan Ridge via cfe-dev
On Wed, Jul 31, 2019 at 2:07 PM <[hidden email]> wrote:
> > - Can I prevent this from happening, even with -ffast-math enabled?
>
> We do the equivalent of `-mllvm -speculate-one-expensive-inst=false`
> and it helps.

Someone has put a noop redundant function call in the middle and that
tricks the optimizer into not doing this transform, but it's not
exactly an elegant or obvious solution.

I was also surprised to see that /both directions/ of __builtin_expect
caused it to not apply the transform - even though I'd naively expect
the "True" case to result in exactly the same optimization
assumptions.

> > - Is this sort of configuration sensible or insane?
>
> In the golden land of perfect understanding of FP exceptions, it would
> be controllable in a more complete and principled way.  LLVM is a long
> way off from that.

Was more asking about, this approach of catching/crashing on all FPE's
- I've seen it before but not completely understood (or believed) the
reasons why.

Nick
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: fast-math, clang-6+ and floating point exceptions

Nathan Ridge via cfe-dev

On 7/31/19 11:04 AM, Nicholas Devenish via cfe-dev wrote:

> On Wed, Jul 31, 2019 at 2:07 PM <[hidden email]> wrote:
>>> - Can I prevent this from happening, even with -ffast-math enabled?
>> We do the equivalent of `-mllvm -speculate-one-expensive-inst=false`
>> and it helps.
> Someone has put a noop redundant function call in the middle and that
> tricks the optimizer into not doing this transform, but it's not
> exactly an elegant or obvious solution.
>
> I was also surprised to see that /both directions/ of __builtin_expect
> caused it to not apply the transform - even though I'd naively expect
> the "True" case to result in exactly the same optimization
> assumptions.
>
>>> - Is this sort of configuration sensible or insane?
>> In the golden land of perfect understanding of FP exceptions, it would
>> be controllable in a more complete and principled way.  LLVM is a long
>> way off from that.


We're not that far off. There's an active effort in this area and it's
pretty far along (see, e.g.,
http://llvm.org/docs/LangRef.html#constrained-floating-point-intrinsics).


> Was more asking about, this approach of catching/crashing on all FPE's
> - I've seen it before but not completely understood (or believed) the
> reasons why.


The primary use case I've seen is that you don't want you application,
which is supposed to be performing some numerical simulation, to run for
an extended period of time simply computing NaNs. And, moreover, if
something does go around and you generate a NaN, you want to know
exactly where that happened. LLVM doesn't really support this yet, but I
think that it's a perfectly-reasonable use case.

  -Hal


>
> Nick
> _______________________________________________
> cfe-dev mailing list
> [hidden email]
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

--
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev