[Boost-bugs] [Boost C++ Libraries] #13503: Boost.Multiprecision generates incorrect code

Subject: [Boost-bugs] [Boost C++ Libraries] #13503: Boost.Multiprecision generates incorrect code
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2018-03-29 21:05:08


#13503: Boost.Multiprecision generates incorrect code
----------------------------------------+----------------------------
 Reporter: Sam Lunt <samuel.j.lunt@…> | Owner: John Maddock
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: multiprecision
  Version: Boost 1.64.0 | Severity: Problem
 Keywords: |
----------------------------------------+----------------------------
 Comparing two identical functions, one using
 `boost::multiprecision::uint128_t` and the other using GCC/Clang builtin
 `unsigned __int128`:

 {{{
 auto foo(std::uint64_t lhs, std::uint64_t rhs) -> std::uint64_t
 {
     boost::multiprecision::uint128_t a(lhs);
     a *= rhs;
     return static_cast<std::uint64_t>(a >> 64)
          + static_cast<std::uint64_t>(a);
 }

 auto bar(std::uint64_t lhs, std::uint64_t rhs) -> std::uint64_t
 {
     unsingned __int128 a(lhs);
     a *= rhs;
     return static_cast<std::uint64_t>(a >> 64)
          + static_cast<std::uint64_t>(a);
 }
 }}}

 Comparing the outputs of each function, they return different results for
 `(-1ULL, -1ULL)`, `(-1ULL, 2)`, `(-1ULL, 3)`, and presumably others.
 (`foo` returns `18446744073709551613`, `0`, and `1`, respectively).

 Comparing the results to Python's big int type (the builtin `int`), it
 seems that the `foo` results are not correct and the `bar` results are
 (this can also be confirmed by hand). This is also confirmed by looking at
 the disassembly for the each function:

 {{{
 0000000000000000 <foo(unsigned long, unsigned long)>:
    0: 48 89 f0 mov %rsi,%rax
    3: 48 f7 e7 mul %rdi
    6: 48 83 f8 ff cmp $0xffffffffffffffff,%rax
    a: 48 89 d1 mov %rdx,%rcx
    d: 48 83 d9 00 sbb $0x0,%rcx
   11: 48 c7 c1 ff ff ff ff mov $0xffffffffffffffff,%rcx
   18: 48 0f 43 c1 cmovae %rcx,%rax
   1c: 48 01 d0 add %rdx,%rax
   1f: c3 retq

 0000000000000020 <bar(unsigned long, unsigned long)>:
   20: 48 89 f0 mov %rsi,%rax
   23: 48 f7 e7 mul %rdi
   26: 48 01 d0 add %rdx,%rax
   29: c3 retq
 }}}

 These results were consistent when compiling with clang++ (5.0.0) and g++
 (6.3.1) and when compiling with optimization enabled and disabled.

-- 
Ticket URL: <https://svn.boost.org/trac10/ticket/13503>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2018-03-29 21:11:43 UTC