[llvm-bugs] [Bug 49325] New: changing the floating point environment interacts badly with interprocedural optimizations

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Feb 22 20:28:04 PST 2021


https://bugs.llvm.org/show_bug.cgi?id=49325

            Bug ID: 49325
           Summary: changing the floating point environment interacts
                    badly with interprocedural optimizations
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Interprocedural Optimizations
          Assignee: unassignedbugs at nondot.org
          Reporter: richard-llvm at metafoo.co.uk
                CC: llvm-bugs at lists.llvm.org

Testcase:

https://godbolt.org/z/E8Kje7

This example is miscompiled by reordering the call to f(j, a) between two
fesetround calls. There are at least two different bugs here (for the testcase
with inlining disabled and the testcase with inlining enabled):

1) With inlining disabled, the call to function f is reordered past a call to
function fesetround. 'f' is attributed as 'readnone' (plus 'willreturn
nounwind'), so this transform superficially appears correct, but is not: we
can't reorder a function that reads the FP environment past a function that
changes the FP environment (at least, not within a 'strictfp' function). It's
not clear to me whether it's wrong to mark 'f' as 'readnone', or whether we
should track the FP environment separately from reads of memory, but I suspect
the latter might be a better choice.

2) With inlining enabled, the inliner adds an 'fadd' instruction to 'g'. That's
wrong: 'fadd' can be freely reordered past function calls, but we certainly
don't want to allow 'fadd' to be reordered past a call to 'fesetround'. I think
the right approach here is that the inliner should produce constrained FP
intrinsic calls (assuming the default rounding mode) when inlining into a
'strictfp' function.

As a complementary problem to (2), we also have:

3) Inlining a constrained FP intrinsic call into a non-'strictfp' function
should convert the constrained FP intrinsic call into an unconstrained
instruction. This is important because we need to emit the libc++ wrapper
functions around C math functions as 'strictfp', and don't want that to be a
pessimization.

Right now:

#include <cmath>
#pragma STDC FENV_ACCESS ON
float f() { return std::rint(10.5); }

... produces wrong results with Clang+libc++ (and also with Clang+libstdc++),
because std::rint is built with FENV_ACCESS OFF, so its call to rint is treated
as unconstrained. We could fix that by using FENV_ACCESS ON in libc++'s
<math.h> wrapper, but that will pessimize all FENV_ACCESS OFF calls unless the
inliner is able to undo that when inlining into non-strictfp functions.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210223/265b7fe9/attachment.html>


More information about the llvm-bugs mailing list