[libc] [llvm] [reland][libc][NFC] Use user defined literals to build 128 and 256 bit constants (PR #81998)

via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 16 07:16:58 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Guillaume Chatelet (gchatelet)

<details>
<summary>Changes</summary>

- #<!-- -->81835
- Fix for platforms where uint64_t is not available


---

Patch is 386.24 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/81998.diff


17 Files Affected:

- (modified) libc/src/__support/UInt.h (+20-5) 
- (modified) libc/src/__support/integer_literals.h (+20-19) 
- (modified) libc/src/math/generic/CMakeLists.txt (+24-16) 
- (modified) libc/src/math/generic/exp.cpp (+10-14) 
- (modified) libc/src/math/generic/exp10.cpp (+10-10) 
- (modified) libc/src/math/generic/exp2.cpp (+10-10) 
- (modified) libc/src/math/generic/expm1.cpp (+11-15) 
- (modified) libc/src/math/generic/log.cpp (+634-631) 
- (modified) libc/src/math/generic/log10.cpp (+637-633) 
- (modified) libc/src/math/generic/log1p.cpp (+479-475) 
- (modified) libc/src/math/generic/log2.cpp (+629-626) 
- (modified) libc/test/src/__support/CMakeLists.txt (+3-1) 
- (modified) libc/test/src/__support/FPUtil/fpbits_test.cpp (+21-21) 
- (modified) libc/test/src/__support/integer_to_string_test.cpp (+26-13) 
- (modified) libc/test/src/__support/str_to_long_double_test.cpp (+21-27) 
- (modified) utils/bazel/llvm-project-overlay/libc/BUILD.bazel (+16-8) 
- (modified) utils/bazel/llvm-project-overlay/libc/test/src/__support/BUILD.bazel (+2) 


``````````diff
diff --git a/libc/src/__support/UInt.h b/libc/src/__support/UInt.h
index f2084300d14208..ae1fe7aaa18287 100644
--- a/libc/src/__support/UInt.h
+++ b/libc/src/__support/UInt.h
@@ -867,14 +867,29 @@ struct BigInt {
   LIBC_INLINE const WordType *data() const { return val; }
 };
 
+namespace internal {
+// We default BigInt's WordType to 'uint64_t' or 'uint32_t' depending on type
+// availability.
+template <size_t Bits>
+struct WordTypeSelector : cpp::type_identity<
+#if defined(UINT64_MAX)
+                              uint64_t
+#else
+                              uint32_t
+#endif
+                              > {
+};
+// Except if we request 32 bits explicitly.
+template <> struct WordTypeSelector<32> : cpp::type_identity<uint32_t> {};
+template <size_t Bits>
+using WordTypeSelectorT = typename WordTypeSelector<Bits>::type;
+} // namespace internal
+
 template <size_t Bits>
-using UInt =
-    typename cpp::conditional_t<Bits == 32, BigInt<32, false, uint32_t>,
-                                BigInt<Bits, false, uint64_t>>;
+using UInt = BigInt<Bits, false, internal::WordTypeSelectorT<Bits>>;
 
 template <size_t Bits>
-using Int = typename cpp::conditional_t<Bits == 32, BigInt<32, true, uint32_t>,
-                                        BigInt<Bits, true, uint64_t>>;
+using Int = BigInt<Bits, true, internal::WordTypeSelectorT<Bits>>;
 
 // Provides limits of U/Int<128>.
 template <> class numeric_limits<UInt<128>> {
diff --git a/libc/src/__support/integer_literals.h b/libc/src/__support/integer_literals.h
index c8e965c1a03a05..08bc6973b1582b 100644
--- a/libc/src/__support/integer_literals.h
+++ b/libc/src/__support/integer_literals.h
@@ -22,19 +22,19 @@
 namespace LIBC_NAMESPACE {
 
 LIBC_INLINE constexpr uint8_t operator""_u8(unsigned long long value) {
-  return value;
+  return static_cast<uint8_t>(value);
 }
 
 LIBC_INLINE constexpr uint16_t operator""_u16(unsigned long long value) {
-  return value;
+  return static_cast<uint16_t>(value);
 }
 
 LIBC_INLINE constexpr uint32_t operator""_u32(unsigned long long value) {
-  return value;
+  return static_cast<uint32_t>(value);
 }
 
 LIBC_INLINE constexpr uint64_t operator""_u64(unsigned long long value) {
-  return value;
+  return static_cast<uint64_t>(value);
 }
 
 namespace internal {
@@ -64,6 +64,7 @@ template <typename T, int base> struct DigitBuffer {
                                                                         : 0;
   LIBC_INLINE_VAR static constexpr size_t MAX_DIGITS =
       sizeof(T) * CHAR_BIT / BITS_PER_DIGIT;
+  LIBC_INLINE_VAR static constexpr uint8_t INVALID_DIGIT = 255;
 
   uint8_t digits[MAX_DIGITS] = {};
   size_t size = 0;
@@ -74,7 +75,7 @@ template <typename T, int base> struct DigitBuffer {
   }
 
   // Returns the digit for a particular character.
-  // Returns 255 if the character is invalid.
+  // Returns INVALID_DIGIT if the character is invalid.
   LIBC_INLINE static constexpr uint8_t get_digit_value(const char c) {
     const auto to_lower = [](char c) { return c | 32; };
     const auto is_digit = [](char c) { return c >= '0' && c <= '9'; };
@@ -82,10 +83,10 @@ template <typename T, int base> struct DigitBuffer {
       return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
     };
     if (is_digit(c))
-      return c - '0';
+      return static_cast<uint8_t>(c - '0');
     if (base > 10 && is_alpha(c))
-      return to_lower(c) - 'a' + 10;
-    return 255;
+      return static_cast<uint8_t>(to_lower(c) - 'a' + 10);
+    return INVALID_DIGIT;
   }
 
   // Adds a single character to this buffer.
@@ -93,7 +94,7 @@ template <typename T, int base> struct DigitBuffer {
     if (c == '\'')
       return; // ' is valid but not taken into account.
     const uint8_t value = get_digit_value(c);
-    if (value == 255 || size >= MAX_DIGITS) {
+    if (value == INVALID_DIGIT || size >= MAX_DIGITS) {
       // During constant evaluation `__builtin_unreachable` will halt the
       // compiler as it is not executable. This is preferable over `assert` that
       // will only trigger in debug mode. Also we can't use `static_assert`
@@ -114,32 +115,32 @@ template <typename T> struct Parser {
   }
 };
 
-// Specialization for cpp::BigInt<N, false, uint64_t>.
+// Specialization for cpp::UInt<N>.
 // Because this code runs at compile time we try to make it efficient. For
 // binary and hexadecimal formats we read digits by chunks of 64 bits and
 // produce the BigInt internal representation direcly. For decimal numbers we
 // go the slow path and use slower BigInt arithmetic.
-template <size_t N>
-struct Parser<LIBC_NAMESPACE::cpp::BigInt<N, false, uint64_t>> {
-  using UIntT = cpp::BigInt<N, false, uint64_t>;
+template <size_t N> struct Parser<LIBC_NAMESPACE::cpp::UInt<N>> {
+  using UIntT = cpp::UInt<N>;
   template <int base> static constexpr UIntT parse(const char *str) {
     const DigitBuffer<UIntT, base> buffer(str);
     if constexpr (base == 10) {
       // Slow path, we sum and multiply BigInt for each digit.
       return accumulate<UIntT>(base, buffer.digits, buffer.size);
     } else {
-      // Fast path, we consume blocks of uint64_t and creates the BigInt's
+      // Fast path, we consume blocks of WordType and creates the BigInt's
       // internal representation directly.
-      using U64ArrayT = cpp::array<uint64_t, UIntT::WORD_COUNT>;
-      U64ArrayT array;
+      using WordArrayT = decltype(UIntT::val);
+      using WordType = typename WordArrayT::value_type;
+      WordArrayT array = {};
       size_t size = buffer.size;
       const uint8_t *digit_ptr = buffer.digits + size;
       for (size_t i = 0; i < array.size(); ++i) {
-        constexpr size_t U64_DIGITS = DigitBuffer<uint64_t, base>::MAX_DIGITS;
-        const size_t chunk = size > U64_DIGITS ? U64_DIGITS : size;
+        constexpr size_t DIGITS = DigitBuffer<WordType, base>::MAX_DIGITS;
+        const size_t chunk = size > DIGITS ? DIGITS : size;
         digit_ptr -= chunk;
         size -= chunk;
-        array[i] = accumulate<uint64_t>(base, digit_ptr, chunk);
+        array[i] = accumulate<WordType>(base, digit_ptr, chunk);
       }
       return UIntT(array);
     }
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 259ae1c2793439..07885ae6a3e242 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -622,6 +622,8 @@ add_entrypoint_object(
   DEPENDS
     .common_constants
     .explogxf
+    libc.include.errno
+    libc.include.math
     libc.src.__support.CPP.bit
     libc.src.__support.CPP.optional
     libc.src.__support.FPUtil.dyadic_float
@@ -632,10 +634,9 @@ add_entrypoint_object(
     libc.src.__support.FPUtil.polyeval
     libc.src.__support.FPUtil.rounding_mode
     libc.src.__support.FPUtil.triple_double
+    libc.src.__support.integer_literals
     libc.src.__support.macros.optimization
-    libc.include.errno
     libc.src.errno.errno
-    libc.include.math
   COMPILE_OPTIONS
     -O3
 )
@@ -672,6 +673,8 @@ add_entrypoint_object(
   DEPENDS
     .common_constants
     .explogxf
+    libc.include.errno
+    libc.include.math
     libc.src.__support.CPP.bit
     libc.src.__support.CPP.optional
     libc.src.__support.FPUtil.dyadic_float
@@ -682,10 +685,9 @@ add_entrypoint_object(
     libc.src.__support.FPUtil.polyeval
     libc.src.__support.FPUtil.rounding_mode
     libc.src.__support.FPUtil.triple_double
+    libc.src.__support.integer_literals
     libc.src.__support.macros.optimization
-    libc.include.errno
     libc.src.errno.errno
-    libc.include.math
   COMPILE_OPTIONS
     -O3
 )
@@ -731,6 +733,8 @@ add_entrypoint_object(
   DEPENDS
     .common_constants
     .explogxf
+    libc.include.errno
+    libc.include.math
     libc.src.__support.CPP.bit
     libc.src.__support.CPP.optional
     libc.src.__support.FPUtil.dyadic_float
@@ -741,10 +745,9 @@ add_entrypoint_object(
     libc.src.__support.FPUtil.polyeval
     libc.src.__support.FPUtil.rounding_mode
     libc.src.__support.FPUtil.triple_double
+    libc.src.__support.integer_literals
     libc.src.__support.macros.optimization
-    libc.include.errno
     libc.src.errno.errno
-    libc.include.math
   COMPILE_OPTIONS
     -O3
 )
@@ -791,6 +794,8 @@ add_entrypoint_object(
   DEPENDS
     .common_constants
     .explogxf
+    libc.include.errno
+    libc.include.math
     libc.src.__support.CPP.bit
     libc.src.__support.CPP.optional
     libc.src.__support.FPUtil.dyadic_float
@@ -801,10 +806,9 @@ add_entrypoint_object(
     libc.src.__support.FPUtil.polyeval
     libc.src.__support.FPUtil.rounding_mode
     libc.src.__support.FPUtil.triple_double
+    libc.src.__support.integer_literals
     libc.src.__support.macros.optimization
-    libc.include.errno
     libc.src.errno.errno
-    libc.include.math
   COMPILE_OPTIONS
     -O3
 )
@@ -1074,12 +1078,13 @@ add_entrypoint_object(
   DEPENDS
     .common_constants
     .log_range_reduction
+    libc.src.__support.FPUtil.double_double
+    libc.src.__support.FPUtil.dyadic_float
     libc.src.__support.FPUtil.fenv_impl
     libc.src.__support.FPUtil.fp_bits
     libc.src.__support.FPUtil.multiply_add
     libc.src.__support.FPUtil.polyeval
-    libc.src.__support.FPUtil.double_double
-    libc.src.__support.FPUtil.dyadic_float
+    libc.src.__support.integer_literals
     libc.src.__support.macros.optimization
   COMPILE_OPTIONS
     -O3
@@ -1110,12 +1115,13 @@ add_entrypoint_object(
     ../log1p.h
   DEPENDS
     .common_constants
+    libc.src.__support.FPUtil.double_double
+    libc.src.__support.FPUtil.dyadic_float
     libc.src.__support.FPUtil.fenv_impl
     libc.src.__support.FPUtil.fp_bits
     libc.src.__support.FPUtil.multiply_add
     libc.src.__support.FPUtil.polyeval
-    libc.src.__support.FPUtil.double_double
-    libc.src.__support.FPUtil.dyadic_float
+    libc.src.__support.integer_literals
     libc.src.__support.macros.optimization
   COMPILE_OPTIONS
     -O3
@@ -1148,12 +1154,13 @@ add_entrypoint_object(
   DEPENDS
     .common_constants
     .log_range_reduction
+    libc.src.__support.FPUtil.double_double
+    libc.src.__support.FPUtil.dyadic_float
     libc.src.__support.FPUtil.fenv_impl
     libc.src.__support.FPUtil.fp_bits
     libc.src.__support.FPUtil.multiply_add
     libc.src.__support.FPUtil.polyeval
-    libc.src.__support.FPUtil.double_double
-    libc.src.__support.FPUtil.dyadic_float
+    libc.src.__support.integer_literals
     libc.src.__support.macros.optimization
   COMPILE_OPTIONS
     -O3
@@ -1186,12 +1193,13 @@ add_entrypoint_object(
   DEPENDS
     .common_constants
     .log_range_reduction
+    libc.src.__support.FPUtil.double_double
+    libc.src.__support.FPUtil.dyadic_float
     libc.src.__support.FPUtil.fenv_impl
     libc.src.__support.FPUtil.fp_bits
     libc.src.__support.FPUtil.multiply_add
     libc.src.__support.FPUtil.polyeval
-    libc.src.__support.FPUtil.double_double
-    libc.src.__support.FPUtil.dyadic_float
+    libc.src.__support.integer_literals
     libc.src.__support.macros.optimization
   COMPILE_OPTIONS
     -O3
diff --git a/libc/src/math/generic/exp.cpp b/libc/src/math/generic/exp.cpp
index f23170f8ed4259..42a4491131a04e 100644
--- a/libc/src/math/generic/exp.cpp
+++ b/libc/src/math/generic/exp.cpp
@@ -21,6 +21,7 @@
 #include "src/__support/FPUtil/rounding_mode.h"
 #include "src/__support/FPUtil/triple_double.h"
 #include "src/__support/common.h"
+#include "src/__support/integer_literals.h"
 #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
 
 #include <errno.h>
@@ -31,6 +32,7 @@ using fputil::DoubleDouble;
 using fputil::TripleDouble;
 using Float128 = typename fputil::DyadicFloat<128>;
 using Sign = fputil::Sign;
+using LIBC_NAMESPACE::operator""_u128;
 
 // log2(e)
 constexpr double LOG2_E = 0x1.71547652b82fep+0;
@@ -97,21 +99,15 @@ DoubleDouble poly_approx_dd(const DoubleDouble &dx) {
 // For |dx| < 2^-13 + 2^-30:
 //   | output - exp(dx) | < 2^-126.
 Float128 poly_approx_f128(const Float128 &dx) {
-  using MType = typename Float128::MantissaType;
-
   constexpr Float128 COEFFS_128[]{
-      {Sign::POS, -127, MType({0, 0x8000000000000000})},                  // 1.0
-      {Sign::POS, -127, MType({0, 0x8000000000000000})},                  // 1.0
-      {Sign::POS, -128, MType({0, 0x8000000000000000})},                  // 0.5
-      {Sign::POS, -130, MType({0xaaaaaaaaaaaaaaab, 0xaaaaaaaaaaaaaaaa})}, // 1/6
-      {Sign::POS, -132,
-       MType({0xaaaaaaaaaaaaaaab, 0xaaaaaaaaaaaaaaaa})}, // 1/24
-      {Sign::POS, -134,
-       MType({0x8888888888888889, 0x8888888888888888})}, // 1/120
-      {Sign::POS, -137,
-       MType({0x60b60b60b60b60b6, 0xb60b60b60b60b60b})}, // 1/720
-      {Sign::POS, -140,
-       MType({0x00d00d00d00d00d0, 0xd00d00d00d00d00d})}, // 1/5040
+      {Sign::POS, -127, 0x80000000'00000000'00000000'00000000_u128}, // 1.0
+      {Sign::POS, -127, 0x80000000'00000000'00000000'00000000_u128}, // 1.0
+      {Sign::POS, -128, 0x80000000'00000000'00000000'00000000_u128}, // 0.5
+      {Sign::POS, -130, 0xaaaaaaaa'aaaaaaaa'aaaaaaaa'aaaaaaab_u128}, // 1/6
+      {Sign::POS, -132, 0xaaaaaaaa'aaaaaaaa'aaaaaaaa'aaaaaaab_u128}, // 1/24
+      {Sign::POS, -134, 0x88888888'88888888'88888888'88888889_u128}, // 1/120
+      {Sign::POS, -137, 0xb60b60b6'0b60b60b'60b60b60'b60b60b6_u128}, // 1/720
+      {Sign::POS, -140, 0xd00d00d0'0d00d00d'00d00d00'd00d00d0_u128}, // 1/5040
   };
 
   Float128 p = fputil::polyeval(dx, COEFFS_128[0], COEFFS_128[1], COEFFS_128[2],
diff --git a/libc/src/math/generic/exp10.cpp b/libc/src/math/generic/exp10.cpp
index 6b40f5561845d8..72ece669765688 100644
--- a/libc/src/math/generic/exp10.cpp
+++ b/libc/src/math/generic/exp10.cpp
@@ -21,6 +21,7 @@
 #include "src/__support/FPUtil/rounding_mode.h"
 #include "src/__support/FPUtil/triple_double.h"
 #include "src/__support/common.h"
+#include "src/__support/integer_literals.h"
 #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
 
 #include <errno.h>
@@ -31,6 +32,7 @@ using fputil::DoubleDouble;
 using fputil::TripleDouble;
 using Float128 = typename fputil::DyadicFloat<128>;
 using Sign = fputil::Sign;
+using LIBC_NAMESPACE::operator""_u128;
 
 // log2(10)
 constexpr double LOG2_10 = 0x1.a934f0979a371p+1;
@@ -99,17 +101,15 @@ DoubleDouble poly_approx_dd(const DoubleDouble &dx) {
 // For |dx| < 2^-14:
 //   | output - 10^dx | < 1.5 * 2^-124.
 Float128 poly_approx_f128(const Float128 &dx) {
-  using MType = typename Float128::MantissaType;
-
   constexpr Float128 COEFFS_128[]{
-      {Sign::POS, -127, MType({0, 0x8000000000000000})}, // 1.0
-      {Sign::POS, -126, MType({0xea56d62b82d30a2d, 0x935d8dddaaa8ac16})},
-      {Sign::POS, -126, MType({0x80a99ce75f4d5bdb, 0xa9a92639e753443a})},
-      {Sign::POS, -126, MType({0x6a4f9d7dbf6c9635, 0x82382c8ef1652304})},
-      {Sign::POS, -124, MType({0x345787019216c7af, 0x12bd7609fd98c44c})},
-      {Sign::POS, -127, MType({0xcc41ed7e0d27aee5, 0x450a7ff47535d889})},
-      {Sign::POS, -130, MType({0x8326bb91a6e7601d, 0xd3f6b844702d636b})},
-      {Sign::POS, -130, MType({0xfa7b46df314112a9, 0x45b937f0d05bb1cd})},
+      {Sign::POS, -127, 0x80000000'00000000'00000000'00000000_u128}, // 1.0
+      {Sign::POS, -126, 0x935d8ddd'aaa8ac16'ea56d62b'82d30a2d_u128},
+      {Sign::POS, -126, 0xa9a92639'e753443a'80a99ce7'5f4d5bdb_u128},
+      {Sign::POS, -126, 0x82382c8e'f1652304'6a4f9d7d'bf6c9635_u128},
+      {Sign::POS, -124, 0x12bd7609'fd98c44c'34578701'9216c7af_u128},
+      {Sign::POS, -127, 0x450a7ff4'7535d889'cc41ed7e'0d27aee5_u128},
+      {Sign::POS, -130, 0xd3f6b844'702d636b'8326bb91'a6e7601d_u128},
+      {Sign::POS, -130, 0x45b937f0'd05bb1cd'fa7b46df'314112a9_u128},
   };
 
   Float128 p = fputil::polyeval(dx, COEFFS_128[0], COEFFS_128[1], COEFFS_128[2],
diff --git a/libc/src/math/generic/exp2.cpp b/libc/src/math/generic/exp2.cpp
index 01e66d1ae00f70..83f545eb116bd3 100644
--- a/libc/src/math/generic/exp2.cpp
+++ b/libc/src/math/generic/exp2.cpp
@@ -21,6 +21,7 @@
 #include "src/__support/FPUtil/rounding_mode.h"
 #include "src/__support/FPUtil/triple_double.h"
 #include "src/__support/common.h"
+#include "src/__support/integer_literals.h"
 #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
 
 #include <errno.h>
@@ -31,6 +32,7 @@ using fputil::DoubleDouble;
 using fputil::TripleDouble;
 using Float128 = typename fputil::DyadicFloat<128>;
 using Sign = fputil::Sign;
+using LIBC_NAMESPACE::operator""_u128;
 
 // Error bounds:
 // Errors when using double precision.
@@ -88,17 +90,15 @@ DoubleDouble poly_approx_dd(const DoubleDouble &dx) {
 // For |dx| < 2^-13 + 2^-30:
 //   | output - exp(dx) | < 2^-126.
 Float128 poly_approx_f128(const Float128 &dx) {
-  using MType = typename Float128::MantissaType;
-
   constexpr Float128 COEFFS_128[]{
-      {Sign::POS, -127, MType({0, 0x8000000000000000})}, // 1.0
-      {Sign::POS, -128, MType({0xc9e3b39803f2f6af, 0xb17217f7d1cf79ab})},
-      {Sign::POS, -128, MType({0xde2d60dd9c9a1d9f, 0x3d7f7bff058b1d50})},
-      {Sign::POS, -132, MType({0x9d3b15d9e7fb6897, 0xe35846b82505fc59})},
-      {Sign::POS, -134, MType({0x184462f6bcd2b9e7, 0x9d955b7dd273b94e})},
-      {Sign::POS, -137, MType({0x39ea1bb964c51a89, 0xaec3ff3c53398883})},
-      {Sign::POS, -138, MType({0x842c53418fa8ae61, 0x2861225f345c396a})},
-      {Sign::POS, -144, MType({0x7abeb5abd5ad2079, 0xffe5fe2d109a319d})},
+      {Sign::POS, -127, 0x80000000'00000000'00000000'00000000_u128}, // 1.0
+      {Sign::POS, -128, 0xb17217f7'd1cf79ab'c9e3b398'03f2f6af_u128},
+      {Sign::POS, -128, 0x3d7f7bff'058b1d50'de2d60dd'9c9a1d9f_u128},
+      {Sign::POS, -132, 0xe35846b8'2505fc59'9d3b15d9'e7fb6897_u128},
+      {Sign::POS, -134, 0x9d955b7d'd273b94e'184462f6'bcd2b9e7_u128},
+      {Sign::POS, -137, 0xaec3ff3c'53398883'39ea1bb9'64c51a89_u128},
+      {Sign::POS, -138, 0x2861225f'345c396a'842c5341'8fa8ae61_u128},
+      {Sign::POS, -144, 0xffe5fe2d'109a319d'7abeb5ab'd5ad2079_u128},
   };
 
   Float128 p = fputil::polyeval(dx, COEFFS_128[0], COEFFS_128[1], COEFFS_128[2],
diff --git a/libc/src/math/generic/expm1.cpp b/libc/src/math/generic/expm1.cpp
index c1fb80309d7b46..9f14a8c2068ec1 100644
--- a/libc/src/math/generic/expm1.cpp
+++ b/libc/src/math/generic/expm1.cpp
@@ -22,6 +22,7 @@
 #include "src/__support/FPUtil/rounding_mode.h"
 #include "src/__support/FPUtil/triple_double.h"
 #include "src/__support/common.h"
+#include "src/__support/integer_literals.h"
 #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
 
 #include <errno.h>
@@ -39,6 +40,7 @@ using fputil::DoubleDouble;
 using fputil::TripleDouble;
 using Float128 = typename fputil::DyadicFloat<128>;
 using Sign = fputil::Sign;
+using LIBC_NAMESPACE::operator""_u128;
 
 // log2(e)
 constexpr double LOG2_E = 0x1.71547652b82fep+0;
@@ -107,20 +109,14 @@ DoubleDouble poly_approx_dd(const DoubleDouble &dx) {
 // For |dx| < 2^-13 + 2^-30:
 //   | output - exp(dx) | < 2^-126.
 Float128 poly_approx_f128(const Float128 &dx) {
-  using MType = typename Float128::MantissaType;
-
   constexpr Float128 COEFFS_128[]{
-      {Sign::POS, -127, MType({0, 0x8000000000000000})},                  // 1.0
-      {Sign::POS, -128, MType({0, 0x8000000000000000})},                  // 0.5
-      {Sign::POS, -130, MType({0xaaaaaaaaaaaaaaab, 0xaaaaaaaaaaaaaaaa})}, // 1/6
-      {Sign::POS, -132,
-       MType({0xaaaaaaaaaaaaaaab, 0xaaaaaaaaaaaaaaaa})}, // 1/24
-      {Sign::POS, -134,
-       MType({0x8888888888888889, 0x8888888888888888})}, // 1/120
-      {Sign::POS, -137,
-       MType({0x60b60b60b60b60b6, 0xb60b60b60b60b60b})}, // 1/720
-      {Sign::POS, -140,
-       MType({0x00d00d00d00d00d0, 0xd00d00d00d00d00d})}, // 1/5040
+      {Sign::POS, -127, 0x80000000'00000000'00000000'00000000_u128}, // 1.0
+      {Sign::POS, -128, 0x80000000'00000000'00000000'00000000_u128}, // 0.5
+      {Sign::POS, -130, 0xaaaaaaaa'aaaaaaaa'aaaaaaaa'aaaaaaab_u128}, // 1/6
+      {Sign::POS, -132, 0xaaaaaaaa'aaaaaaaa'aaaaaaaa'aaaaaaab_u128}, // 1/24
+      {Sign::POS, -134, 0x88888888'88888888'88888888'88888889_u128}, // 1/120
+      {Sign::POS, -137, 0xb60b60b6'0b60b60b'60b60b60'b60b60b6_u128}, // 1/720
+      {Sign::POS, -140, 0xd00d00d0'0d00d00d'00d00d00'd00d00d0_u128}, // 1/5040
   };
 
   Float128 p = fputil::polyeval(dx, COEFFS_128[0], COEFFS_128[1], COEFFS_128[2],
@@ -146,7 +142,6 @@ std::ostream &operator<<(std::ostream &OS, const DoubleDouble &r) {
 // TODO(lntue): investigate triple-double precision implementation for this
 // step.
 Float128 expm1_f128...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/81998


More information about the llvm-commits mailing list