<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - changing the floating point environment interacts badly with interprocedural optimizations"
   href="https://bugs.llvm.org/show_bug.cgi?id=49325">49325</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>changing the floating point environment interacts badly with interprocedural optimizations
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Interprocedural Optimizations
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>richard-llvm@metafoo.co.uk
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Testcase:

<a href="https://godbolt.org/z/E8Kje7">https://godbolt.org/z/E8Kje7</a>

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.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>