[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