[llvm-dev] LLVM v3.9.0 and math built-ins

Mehdi Amini via llvm-dev
Fri, 16 Sep 2016 20:15:39 -0000

> On Sep 16, 2016, at 1:30 AM, Martin J. O'Riordan via llvm-dev
<llvm-dev at lists.llvm.org> wrote:
>
> A little while ago I asked a question on CFE-Dev about a change in the
behaviour of programs using the ISO C math functions, although that question
should have been put to LLVM-Dev.  But I got excellent clarification of the
problem anyway.  However, since then I have been trying to adapt our out-of-tree
implementation to get the previous behaviour.  The problem is that something
like:
>
> #include <math.h>
>
> extern double foo(double);
>
> int useMathName() {
>   if ((exp(1.0) < 2.71) || (exp(1.0) > 2.72))
>     return -1;
>   return 0;
> }
>
> int useOtherName() {
>   if ((foo(1.0) < 2.71) || (foo(1.0) > 2.72))
>     return -1;
>   return 0;
> }
>
> With v3.8.0 the compiler elided both the calls to ‘exp’ and the tests, so
the function ‘useMathName’ reduced to simply:
>
> return 0;
>
> But this was not correct as it ignored the possibility that the math
functions could have the side-effect of changing ‘errno’, and this was fixed in
v3.9.0, and the calls are no longer elided, though using the “as-if” rule, the
tests are still eliminated and ‘useMathName’ becomes:
>
> (void)exp(1.0);
> (void)exp(1.0);


It is not clear to me: isn’t the spec saying that errno shall be set on
underflow and overflow. The constant folding should be able to detect this and
fold if it does not happen?

Also, because we don’t really model errno, we don’t constant fold these call
anymore :(


> return 0;
>
> So I changed our implementation so that ‘-fno-math-errno’ is the default
for the tool-chain, and the ‘-fmath-errno’ option is not passed on to the CC1
phase.  I expected that this would allow the compiler to elide the calls, but it
is not doing so.  I don’t want to use ‘-ffast-math’ as this has lots of FP
issues, and I don’t want to make it the default.
>
> Any idea why the math functions are not elided?  I am using ‘-O3’ and
implying ‘-fno-math-errno’.  I have verified that our Toolchain implements
‘IsMathErrnoDefault’ and returns ‘false’, and that the option ‘-fmath-errno’ is
not being passed to the CC1 stage.  Since our math function implementation does
not in fact change ‘errno’, it is very desirable that this elision occurs in an
FP safe way.

You can check that clang when emitting the IR is adding the attribute
"readnone” on the declaration of exp(). If it does not then it assumes
errno.

As a starting point, have you tried to pass -fno-math-errno?

—
Mehdi

-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20160916/3e4524c9/attachment.html>