[llvm-bugs] [Bug 43125] New: Inconsistent spilling of floating point causes simple floating point comparison to fail in 32 bit

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Aug 27 09:03:53 PDT 2019


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

            Bug ID: 43125
           Summary: Inconsistent spilling of floating point causes simple
                    floating point comparison to fail in 32 bit
           Product: clang
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: LLVM Codegen
          Assignee: unassignedclangbugs at nondot.org
          Reporter: ldionne at apple.com
                CC: llvm-bugs at lists.llvm.org, neeilans at live.com,
                    richard-llvm at metafoo.co.uk

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.

-- 
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/20190827/7d630854/attachment.html>


More information about the llvm-bugs mailing list