<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 - Inconsistent spilling of floating point causes simple floating point comparison to fail in 32 bit"
   href="https://bugs.llvm.org/show_bug.cgi?id=43125">43125</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Inconsistent spilling of floating point causes simple floating point comparison to fail in 32 bit
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </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>LLVM Codegen
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>ldionne@apple.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>In the following code, the assertion fails when compiled for and run in 32 bit
mode:

    $ cat <<EOF | clang++ -xc++ - -m32 -std=c++11 && ./a.out

    #include <cassert>
    #include <cstdint>

    uint_fast32_t min() { return 1; }
    uint_fast32_t max() { return 2147483646; }

    int main() {
        uint_fast32_t x = max() - min();
        double y = 2100000000.0;
        assert((x * y) == (max() - min()) * y);
    }
    EOF

Here, notice that both the right hand side and the left hand side of the
comparison are "the same", the only difference being that in the left hand
side, we cached the value of `max() - min()` into a local variable (x). When
storing both the left hand side and the right hand side into named variables,
the comparison succeeds:

    $ cat <<EOF | clang++ -xc++ - -m32 -std=c++11 && ./a.out

    #include <cassert>
    #include <cstdint>

    uint_fast32_t min() { return 1; }
    uint_fast32_t max() { return 2147483646; }

    int main() {
        uint_fast32_t x = max() - min();
        double y = 2100000000.0;
        double left = x * y;
        double right = (max() - min()) * y;
        assert(left == right);
    }
    EOF

This only reproduces in 32 bit mode. Howard Hinnant hypothesized this was
caused by the compiler storing one in a register and the other one on the
stack, when the register might not be able to hold a true IEEE 64 bit double.

I know comparing floating point values is normally frowned upon, so feel free
to close this as "You shouldn't be doing this". However, since the calculation
is incredibly simple and the difference between the right and the left hand
sides is just "stashing to a variable", I thought this might still be
considered a bug.</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>