From da5239c272ca24d5e7e203d8fbc58f4bc8c0f012 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Fri, 24 Jul 2026 14:20:18 -0400 Subject: [PATCH] Improve performance of widening muls --- include/boost/int128/detail/int128_imp.hpp | 15 ++++++++++++++- include/boost/int128/detail/uint128_imp.hpp | 9 +++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/include/boost/int128/detail/int128_imp.hpp b/include/boost/int128/detail/int128_imp.hpp index 6c821a00..c01ca870 100644 --- a/include/boost/int128/detail/int128_imp.hpp +++ b/include/boost/int128/detail/int128_imp.hpp @@ -2052,12 +2052,20 @@ namespace detail { BOOST_INT128_HOST_DEVICE BOOST_INT128_FORCE_INLINE constexpr int128_t default_mul(const int128_t lhs, const std::uint64_t rhs) noexcept { + #if defined(BOOST_INT128_HAS_INT128) && !defined(__s390__) && !defined(__s390x__) + + return int128_t{static_cast(lhs) * static_cast(rhs)}; + + #else + return low_word_mul(lhs, rhs); + + #endif } BOOST_INT128_HOST_DEVICE BOOST_INT128_FORCE_INLINE constexpr int128_t default_mul(const int128_t lhs, const std::uint32_t rhs) noexcept { - return low_word_mul(lhs, rhs); + return default_mul(lhs, static_cast(rhs)); } #if defined(_M_AMD64) && !defined(__GNUC__) @@ -2131,6 +2139,11 @@ BOOST_INT128_HOST_DEVICE BOOST_INT128_FORCE_INLINE constexpr int128_t default_mu return msvc_amd64_mul(lhs, rhs); } + #elif defined(BOOST_INT128_HAS_INT128) && !defined(__s390__) && !defined(__s390x__) + + // Multiply in the unsigned domain to avoid signed-overflow UB, then reinterpret the bits. + return int128_t{static_cast(lhs) * static_cast(rhs)}; + #else return low_word_mul(lhs, rhs); diff --git a/include/boost/int128/detail/uint128_imp.hpp b/include/boost/int128/detail/uint128_imp.hpp index 2af78cdc..d57c28c2 100644 --- a/include/boost/int128/detail/uint128_imp.hpp +++ b/include/boost/int128/detail/uint128_imp.hpp @@ -1915,6 +1915,10 @@ BOOST_INT128_HOST_DEVICE BOOST_INT128_FORCE_INLINE constexpr uint128_t default_a return res; + #elif (defined(__x86_64__) || (defined(__aarch64__) && !defined(__APPLE__))) && !defined(_MSC_VER) && defined(BOOST_INT128_HAS_INT128) + + return static_cast(static_cast(lhs) + static_cast(rhs)); + #else uint128_t temp {lhs.high + rhs.high, lhs.low + rhs.low}; @@ -2306,6 +2310,11 @@ BOOST_INT128_HOST_DEVICE BOOST_INT128_FORCE_INLINE constexpr uint128_t default_m return msvc_mul(lhs, rhs); } + #elif defined(BOOST_INT128_HAS_INT128) && !defined(__s390__) && !defined(__s390x__) + # define BOOST_INT128_HIDE_MUL + + return static_cast(static_cast(lhs) * static_cast(rhs)); + #endif // We need to hide this if we use a non-const eval method above to avoid a litany of cross-platform warnings