[libc-commits] [libc] [libc][stdfix] Add support for fixed point types in the testing infrastructure. (PR #81819)

via libc-commits libc-commits at lists.llvm.org
Wed Feb 14 20:38:08 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: None (lntue)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/81819.diff


5 Files Affected:

- (modified) libc/src/__support/fixed_point/CMakeLists.txt (+1) 
- (modified) libc/src/__support/fixed_point/fx_rep.h (+102-1) 
- (modified) libc/test/UnitTest/CMakeLists.txt (+1) 
- (modified) libc/test/UnitTest/LibcTest.cpp (+54-82) 
- (modified) libc/test/UnitTest/LibcTest.h (+3-1) 


``````````diff
diff --git a/libc/src/__support/fixed_point/CMakeLists.txt b/libc/src/__support/fixed_point/CMakeLists.txt
index 644cbff37aaade..27382f5a7bb80e 100644
--- a/libc/src/__support/fixed_point/CMakeLists.txt
+++ b/libc/src/__support/fixed_point/CMakeLists.txt
@@ -5,4 +5,5 @@ add_header_library(
   DEPENDS
     libc.include.llvm-libc-macros.stdfix_macros
     libc.src.__support.macros.attributes
+    libc.src.__support.CPP.type_traits
 )
diff --git a/libc/src/__support/fixed_point/fx_rep.h b/libc/src/__support/fixed_point/fx_rep.h
index 88cba3c95c6656..fcd7554c4d8550 100644
--- a/libc/src/__support/fixed_point/fx_rep.h
+++ b/libc/src/__support/fixed_point/fx_rep.h
@@ -10,144 +10,245 @@
 #define LLVM_LIBC_SRC___SUPPORT_FIXEDPOINT_FXREP_H
 
 #include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/CPP/type_traits.h"
 #include "src/__support/macros/attributes.h" // LIBC_INLINE, LIBC_INLINE_VAR
 
+#include <stdint.h>
+
 #ifdef LIBC_COMPILER_HAS_FIXED_POINT
 
 namespace LIBC_NAMESPACE::fixed_point {
 
+namespace internal {
+
+template <int Bits> struct Storage {
+  static_assert(Bits > 0 && Bits <= 64, "Bits has to be between 1 and 64.");
+  using Type = typename cpp::conditional_t<
+      (Bits <= 8), uint8_t,
+      typename cpp::conditional_t<
+          (Bits <= 16 && Bits > 8), uint16_t,
+          typename cpp::conditional_t<(Bits <= 32 && Bits > 16), uint32_t,
+                                      uint64_t>>>;
+};
+
+} // namespace internal
+
 template <typename T> struct FXRep;
 
 template <> struct FXRep<short fract> {
   using Type = short _Fract;
+
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
   LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
   LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SFRACT_FBIT;
+  LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+      SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
   LIBC_INLINE static constexpr Type MIN() { return SFRACT_MIN; }
   LIBC_INLINE static constexpr Type MAX() { return SFRACT_MIN; }
   LIBC_INLINE static constexpr Type ZERO() { return 0.0HR; }
   LIBC_INLINE static constexpr Type EPS() { return SFRACT_EPSILON; }
+
+  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+  using CompType = cpp::make_signed_t<StorageType>;
 };
 
 template <> struct FXRep<unsigned short fract> {
   using Type = unsigned short fract;
+
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
   LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
   LIBC_INLINE_VAR static constexpr int FRACTION_LEN = USFRACT_FBIT;
+  LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+      SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
   LIBC_INLINE static constexpr Type MIN() { return USFRACT_MIN; }
   LIBC_INLINE static constexpr Type MAX() { return USFRACT_MIN; }
   LIBC_INLINE static constexpr Type ZERO() { return 0.0UHR; }
   LIBC_INLINE static constexpr Type EPS() { return USFRACT_EPSILON; }
+
+  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+  using CompType = cpp::make_unsigned_t<StorageType>;
 };
 
 template <> struct FXRep<fract> {
   using Type = fract;
+
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
   LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
   LIBC_INLINE_VAR static constexpr int FRACTION_LEN = FRACT_FBIT;
+  LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+      SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
   LIBC_INLINE static constexpr Type MIN() { return FRACT_MIN; }
   LIBC_INLINE static constexpr Type MAX() { return FRACT_MIN; }
   LIBC_INLINE static constexpr Type ZERO() { return 0.0R; }
   LIBC_INLINE static constexpr Type EPS() { return FRACT_EPSILON; }
+
+  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+  using CompType = cpp::make_signed_t<StorageType>;
 };
 
 template <> struct FXRep<unsigned fract> {
   using Type = unsigned fract;
+
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
   LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
   LIBC_INLINE_VAR static constexpr int FRACTION_LEN = UFRACT_FBIT;
+  LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+      SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
   LIBC_INLINE static constexpr Type MIN() { return UFRACT_MIN; }
   LIBC_INLINE static constexpr Type MAX() { return UFRACT_MIN; }
   LIBC_INLINE static constexpr Type ZERO() { return 0.0UR; }
   LIBC_INLINE static constexpr Type EPS() { return UFRACT_EPSILON; }
+
+  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+  using CompType = cpp::make_unsigned_t<StorageType>;
 };
 
 template <> struct FXRep<long fract> {
   using Type = long fract;
+
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
   LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
   LIBC_INLINE_VAR static constexpr int FRACTION_LEN = LFRACT_FBIT;
+  LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+      SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
   LIBC_INLINE static constexpr Type MIN() { return LFRACT_MIN; }
   LIBC_INLINE static constexpr Type MAX() { return LFRACT_MIN; }
   LIBC_INLINE static constexpr Type ZERO() { return 0.0LR; }
   LIBC_INLINE static constexpr Type EPS() { return LFRACT_EPSILON; }
+
+  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+  using CompType = cpp::make_signed_t<StorageType>;
 };
 
 template <> struct FXRep<unsigned long fract> {
   using Type = unsigned long fract;
+
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
   LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = 0;
   LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ULFRACT_FBIT;
+  LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+      SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
   LIBC_INLINE static constexpr Type MIN() { return ULFRACT_MIN; }
   LIBC_INLINE static constexpr Type MAX() { return ULFRACT_MIN; }
   LIBC_INLINE static constexpr Type ZERO() { return 0.0ULR; }
   LIBC_INLINE static constexpr Type EPS() { return ULFRACT_EPSILON; }
+
+  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+  using CompType = cpp::make_unsigned_t<StorageType>;
 };
 
 template <> struct FXRep<short accum> {
   using Type = short accum;
+
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
   LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = SACCUM_IBIT;
   LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SACCUM_FBIT;
+  LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+      SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
   LIBC_INLINE static constexpr Type MIN() { return SACCUM_MIN; }
   LIBC_INLINE static constexpr Type MAX() { return SACCUM_MIN; }
   LIBC_INLINE static constexpr Type ZERO() { return 0.0HK; }
   LIBC_INLINE static constexpr Type EPS() { return SACCUM_EPSILON; }
+
+  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+  using CompType = cpp::make_signed_t<StorageType>;
 };
 
 template <> struct FXRep<unsigned short accum> {
   using Type = unsigned short accum;
+
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
-  LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = UACCUM_IBIT;
+  LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = USACCUM_IBIT;
   LIBC_INLINE_VAR static constexpr int FRACTION_LEN = USACCUM_FBIT;
+  LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+      SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
   LIBC_INLINE static constexpr Type MIN() { return USACCUM_MIN; }
   LIBC_INLINE static constexpr Type MAX() { return USACCUM_MIN; }
   LIBC_INLINE static constexpr Type ZERO() { return 0.0UHK; }
   LIBC_INLINE static constexpr Type EPS() { return USACCUM_EPSILON; }
+
+  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+  using CompType = cpp::make_unsigned_t<StorageType>;
 };
 
 template <> struct FXRep<accum> {
   using Type = accum;
+
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
   LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ACCUM_IBIT;
   LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ACCUM_FBIT;
+  LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+      SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
   LIBC_INLINE static constexpr Type MIN() { return ACCUM_MIN; }
   LIBC_INLINE static constexpr Type MAX() { return ACCUM_MIN; }
   LIBC_INLINE static constexpr Type ZERO() { return 0.0K; }
   LIBC_INLINE static constexpr Type EPS() { return ACCUM_EPSILON; }
+
+  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+  using CompType = cpp::make_signed_t<StorageType>;
 };
 
 template <> struct FXRep<unsigned accum> {
   using Type = unsigned accum;
+
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
   LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = UACCUM_IBIT;
   LIBC_INLINE_VAR static constexpr int FRACTION_LEN = UACCUM_FBIT;
+  LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+      SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
   LIBC_INLINE static constexpr Type MIN() { return UACCUM_MIN; }
   LIBC_INLINE static constexpr Type MAX() { return UACCUM_MIN; }
   LIBC_INLINE static constexpr Type ZERO() { return 0.0UK; }
   LIBC_INLINE static constexpr Type EPS() { return UACCUM_EPSILON; }
+
+  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+  using CompType = cpp::make_unsigned_t<StorageType>;
 };
 
 template <> struct FXRep<long accum> {
   using Type = long accum;
+
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
   LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = LACCUM_IBIT;
   LIBC_INLINE_VAR static constexpr int FRACTION_LEN = LACCUM_FBIT;
+  LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+      SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
   LIBC_INLINE static constexpr Type MIN() { return LACCUM_MIN; }
   LIBC_INLINE static constexpr Type MAX() { return LACCUM_MIN; }
   LIBC_INLINE static constexpr Type ZERO() { return 0.0LK; }
   LIBC_INLINE static constexpr Type EPS() { return LACCUM_EPSILON; }
+
+  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+  using CompType = cpp::make_signed_t<StorageType>;
 };
 
 template <> struct FXRep<unsigned long accum> {
   using Type = unsigned long accum;
+
   LIBC_INLINE_VAR static constexpr int SIGN_LEN = 0;
   LIBC_INLINE_VAR static constexpr int INTEGRAL_LEN = ULACCUM_IBIT;
   LIBC_INLINE_VAR static constexpr int FRACTION_LEN = ULACCUM_FBIT;
+  LIBC_INLINE_VAR static constexpr int TOTAL_LEN =
+      SIGN_LEN + INTEGRAL_LEN + FRACTION_LEN;
+
   LIBC_INLINE static constexpr Type MIN() { return ULACCUM_MIN; }
   LIBC_INLINE static constexpr Type MAX() { return ULACCUM_MIN; }
   LIBC_INLINE static constexpr Type ZERO() { return 0.0ULK; }
   LIBC_INLINE static constexpr Type EPS() { return ULACCUM_EPSILON; }
+
+  using StorageType = typename internal::Storage<TOTAL_LEN>::Type;
+  using CompType = cpp::make_unsigned_t<StorageType>;
 };
 
 template <> struct FXRep<short sat fract> : FXRep<short fract> {};
diff --git a/libc/test/UnitTest/CMakeLists.txt b/libc/test/UnitTest/CMakeLists.txt
index e3099e45154765..53ade3698c76e5 100644
--- a/libc/test/UnitTest/CMakeLists.txt
+++ b/libc/test/UnitTest/CMakeLists.txt
@@ -71,6 +71,7 @@ add_unittest_framework_library(
     libc.src.__support.CPP.string
     libc.src.__support.CPP.string_view
     libc.src.__support.CPP.type_traits
+    libc.src.__support.fixed_point.fx_rep
     libc.src.__support.OSUtil.osutil
     libc.src.__support.uint128
 )
diff --git a/libc/test/UnitTest/LibcTest.cpp b/libc/test/UnitTest/LibcTest.cpp
index 201b40a178dca0..7b0e4fca83683b 100644
--- a/libc/test/UnitTest/LibcTest.cpp
+++ b/libc/test/UnitTest/LibcTest.cpp
@@ -8,9 +8,11 @@
 
 #include "LibcTest.h"
 
+#include "include/llvm-libc-macros/stdfix-macros.h"
 #include "src/__support/CPP/string.h"
 #include "src/__support/CPP/string_view.h"
 #include "src/__support/UInt128.h"
+#include "src/__support/fixed_point/fx_rep.h"
 #include "test/UnitTest/TestLogger.h"
 
 #if __STDC_HOSTED__
@@ -53,6 +55,17 @@ describeValue(ValType Value) {
   return cpp::to_string(Value);
 }
 
+#ifdef LIBC_COMPILER_HAS_FIXED_POINT
+template <typename T>
+cpp::enable_if_t<cpp::is_fixed_point_v<T>, cpp::string> describeValue(T Value) {
+  using FXRep = fixed_point::FXRep<T>;
+  using comp_t = typename FXRep::CompType;
+
+  return cpp::to_string(cpp::bit_cast<comp_t>(Value)) + " * 2^-" +
+         cpp::to_string(FXRep::FRACTION_LEN);
+}
+#endif // LIBC_COMPILER_HAS_FIXED_POINT
+
 cpp::string_view describeValue(const cpp::string &Value) { return Value; }
 cpp::string_view describeValue(cpp::string_view Value) { return Value; }
 
@@ -181,99 +194,58 @@ int Test::runTests(const char *TestFilter) {
 
 namespace internal {
 
-template bool test<char>(RunContext *Ctx, TestCond Cond, char LHS, char RHS,
-                         const char *LHSStr, const char *RHSStr, Location Loc);
-
-template bool test<short>(RunContext *Ctx, TestCond Cond, short LHS, short RHS,
-                          const char *LHSStr, const char *RHSStr, Location Loc);
-
-template bool test<int>(RunContext *Ctx, TestCond Cond, int LHS, int RHS,
-                        const char *LHSStr, const char *RHSStr, Location Loc);
-
-template bool test<long>(RunContext *Ctx, TestCond Cond, long LHS, long RHS,
-                         const char *LHSStr, const char *RHSStr, Location Loc);
-
-template bool test<long long>(RunContext *Ctx, TestCond Cond, long long LHS,
-                              long long RHS, const char *LHSStr,
-                              const char *RHSStr, Location Loc);
-
-template bool test<unsigned char>(RunContext *Ctx, TestCond Cond,
-                                  unsigned char LHS, unsigned char RHS,
-                                  const char *LHSStr, const char *RHSStr,
-                                  Location Loc);
-
-template bool test<unsigned short>(RunContext *Ctx, TestCond Cond,
-                                   unsigned short LHS, unsigned short RHS,
-                                   const char *LHSStr, const char *RHSStr,
-                                   Location Loc);
-
-template bool test<unsigned int>(RunContext *Ctx, TestCond Cond,
-                                 unsigned int LHS, unsigned int RHS,
-                                 const char *LHSStr, const char *RHSStr,
-                                 Location Loc);
+#define TEST_SPECIALIZATION(TYPE)                                              \
+  template bool test<TYPE>(RunContext * Ctx, TestCond Cond, TYPE LHS,          \
+                           TYPE RHS, const char *LHSStr, const char *RHSStr,   \
+                           Location Loc)
 
-template bool test<unsigned long>(RunContext *Ctx, TestCond Cond,
-                                  unsigned long LHS, unsigned long RHS,
-                                  const char *LHSStr, const char *RHSStr,
-                                  Location Loc);
+TEST_SPECIALIZATION(char);
+TEST_SPECIALIZATION(short);
+TEST_SPECIALIZATION(int);
+TEST_SPECIALIZATION(long);
+TEST_SPECIALIZATION(long long);
 
-template bool test<bool>(RunContext *Ctx, TestCond Cond, bool LHS, bool RHS,
-                         const char *LHSStr, const char *RHSStr, Location Loc);
+TEST_SPECIALIZATION(unsigned char);
+TEST_SPECIALIZATION(unsigned short);
+TEST_SPECIALIZATION(unsigned int);
+TEST_SPECIALIZATION(unsigned long);
+TEST_SPECIALIZATION(unsigned long long);
 
-template bool test<unsigned long long>(RunContext *Ctx, TestCond Cond,
-                                       unsigned long long LHS,
-                                       unsigned long long RHS,
-                                       const char *LHSStr, const char *RHSStr,
-                                       Location Loc);
+TEST_SPECIALIZATION(bool);
 
 // We cannot just use a single UInt128 specialization as that resolves to only
 // one type, UInt<128> or __uint128_t. We want both overloads as we want to
-// be able to unittest UInt<128> on platforms where UInt128 resolves to
-// UInt128.
 #ifdef __SIZEOF_INT128__
 // When builtin __uint128_t type is available, include its specialization
 // also.
-template bool test<__uint128_t>(RunContext *Ctx, TestCond Cond, __uint128_t LHS,
-                                __uint128_t RHS, const char *LHSStr,
-                                const char *RHSStr, Location Loc);
+TEST_SPECIALIZATION(__uint128_t);
 #endif
 
-template bool test<LIBC_NAMESPACE::cpp::Int<128>>(
-    RunContext *Ctx, TestCond Cond, LIBC_NAMESPACE::cpp::Int<128> LHS,
-    LIBC_NAMESPACE::cpp::Int<128> RHS, const char *LHSStr, const char *RHSStr,
-    Location Loc);
-
-template bool test<LIBC_NAMESPACE::cpp::UInt<128>>(
-    RunContext *Ctx, TestCond Cond, LIBC_NAMESPACE::cpp::UInt<128> LHS,
-    LIBC_NAMESPACE::cpp::UInt<128> RHS, const char *LHSStr, const char *RHSStr,
-    Location Loc);
-
-template bool test<LIBC_NAMESPACE::cpp::UInt<192>>(
-    RunContext *Ctx, TestCond Cond, LIBC_NAMESPACE::cpp::UInt<192> LHS,
-    LIBC_NAMESPACE::cpp::UInt<192> RHS, const char *LHSStr, const char *RHSStr,
-    Location Loc);
-
-template bool test<LIBC_NAMESPACE::cpp::UInt<256>>(
-    RunContext *Ctx, TestCond Cond, LIBC_NAMESPACE::cpp::UInt<256> LHS,
-    LIBC_NAMESPACE::cpp::UInt<256> RHS, const char *LHSStr, const char *RHSStr,
-    Location Loc);
-
-template bool test<LIBC_NAMESPACE::cpp::UInt<320>>(
-    RunContext *Ctx, TestCond Cond, LIBC_NAMESPACE::cpp::UInt<320> LHS,
-    LIBC_NAMESPACE::cpp::UInt<320> RHS, const char *LHSStr, const char *RHSStr,
-    Location Loc);
-
-template bool test<LIBC_NAMESPACE::cpp::string_view>(
-    RunContext *Ctx, TestCond Cond, LIBC_NAMESPACE::cpp::string_view LHS,
-    LIBC_NAMESPACE::cpp::string_view RHS, const char *LHSStr,
-    const char *RHSStr, Location Loc);
-
-template bool test<LIBC_NAMESPACE::cpp::string>(RunContext *Ctx, TestCond Cond,
-                                                LIBC_NAMESPACE::cpp::string LHS,
-                                                LIBC_NAMESPACE::cpp::string RHS,
-                                                const char *LHSStr,
-                                                const char *RHSStr,
-                                                Location Loc);
+TEST_SPECIALIZATION(LIBC_NAMESPACE::cpp::Int<128>);
+
+TEST_SPECIALIZATION(LIBC_NAMESPACE::cpp::UInt<128>);
+TEST_SPECIALIZATION(LIBC_NAMESPACE::cpp::UInt<192>);
+TEST_SPECIALIZATION(LIBC_NAMESPACE::cpp::UInt<256>);
+TEST_SPECIALIZATION(LIBC_NAMESPACE::cpp::UInt<320>);
+
+TEST_SPECIALIZATION(LIBC_NAMESPACE::cpp::string_view);
+TEST_SPECIALIZATION(LIBC_NAMESPACE::cpp::string);
+
+#ifdef LIBC_COMPILER_HAS_FIXED_POINT
+TEST_SPECIALIZATION(short fract);
+TEST_SPECIALIZATION(fract);
+TEST_SPECIALIZATION(long fract);
+TEST_SPECIALIZATION(unsigned short fract);
+TEST_SPECIALIZATION(unsigned fract);
+TEST_SPECIALIZATION(unsigned long fract);
+
+TEST_SPECIALIZATION(short accum);
+TEST_SPECIALIZATION(accum);
+TEST_SPECIALIZATION(long accum);
+TEST_SPECIALIZATION(unsigned short accum);
+TEST_SPECIALIZATION(unsigned accum);
+TEST_SPECIALIZATION(unsigned long accum);
+#endif // LIBC_COMPILER_HAS_FIXED_POINT
 
 } // namespace internal
 
diff --git a/libc/test/UnitTest/LibcTest.h b/libc/test/UnitTest/LibcTest.h
index 047f18036b0ac2..00e34a4da85852 100644
--- a/libc/test/UnitTest/LibcTest.h
+++ b/libc/test/UnitTest/LibcTest.h
@@ -126,7 +126,9 @@ class Test {
   // |Cond| on mismatched |LHS| and |RHS| types can potentially succeed because
   // of type promotion.
   template <typename ValType,
-            cpp::enable_if_t<cpp::is_integral_v<ValType>, int> = 0>
+            cpp::enable_if_t<cpp::is_integral_v<ValType> ||
+                                 cpp::is_fixed_point_v<ValType>,
+                             int> = 0>
   bool test(TestCond Cond, ValType LHS, ValType RHS, const char *LHSStr,
             const char *RHSStr, internal::Location Loc) {
     return internal::test(Ctx, Cond, LHS, RHS, LHSStr, RHSStr, Loc);

``````````

</details>


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


More information about the libc-commits mailing list