[libc-commits] [libc] 37458f6 - [libc][math] Move str method from FPBits class to testing utils.

Tue Ly via libc-commits libc-commits at lists.llvm.org
Fri Jun 9 23:51:13 PDT 2023


Author: Tue Ly
Date: 2023-06-10T02:50:58-04:00
New Revision: 37458f66935e1809b4c18a0fee55783ed9e808bb

URL: https://github.com/llvm/llvm-project/commit/37458f66935e1809b4c18a0fee55783ed9e808bb
DIFF: https://github.com/llvm/llvm-project/commit/37458f66935e1809b4c18a0fee55783ed9e808bb.diff

LOG: [libc][math] Move str method from FPBits class to testing utils.

str method of FPBits class is only used for pretty printing its objects
in tests.  It brings cpp::string dependency to FPBits class, which is not ideal
for embedded use case.  We move str method to a free function in test utils and
remove this dependency of FPBits class.

Reviewed By: sivachandra

Differential Revision: https://reviews.llvm.org/D152607

Added: 
    libc/src/__support/FPUtil/fpbits_str.h

Modified: 
    libc/src/__support/FPUtil/CMakeLists.txt
    libc/src/__support/FPUtil/FPBits.h
    libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
    libc/test/UnitTest/CMakeLists.txt
    libc/test/UnitTest/ErrnoSetterMatcher.h
    libc/test/UnitTest/FPMatcher.h
    libc/test/src/__support/FPUtil/CMakeLists.txt
    libc/test/src/__support/FPUtil/fpbits_test.cpp
    libc/utils/MPFRWrapper/CMakeLists.txt
    libc/utils/MPFRWrapper/MPFRUtils.cpp
    utils/bazel/llvm-project-overlay/libc/BUILD.bazel
    utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel
    utils/bazel/llvm-project-overlay/libc/utils/MPFRWrapper/BUILD.bazel

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index 4452655d5708a..b772b9d47ceec 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -36,13 +36,25 @@ add_header_library(
     .platform_defs
     .float_properties
     libc.src.__support.builtin_wrappers
-    libc.src.__support.integer_to_string
     libc.src.__support.CPP.bit
-    libc.src.__support.CPP.string
     libc.src.__support.CPP.type_traits
     libc.src.__support.common
 )
 
+add_header_library(
+  fpbits_str
+  HDRS
+    fpbits_str.h
+  DEPENDS
+    .float_properties
+    .fp_bits
+    libc.src.__support.CPP.bit
+    libc.src.__support.CPP.type_traits
+    libc.src.__support.macros.attributes
+    libc.src.__support.common
+    libc.src.__support.integer_to_string
+)
+
 add_header_library(
   nearest_integer_operations
   HDRS

diff  --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index ddeb7c0f97ed2..49285527305ab 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -12,11 +12,9 @@
 #include "PlatformDefs.h"
 
 #include "src/__support/CPP/bit.h"
-#include "src/__support/CPP/string.h"
 #include "src/__support/CPP/type_traits.h"
 #include "src/__support/builtin_wrappers.h"
 #include "src/__support/common.h"
-#include "src/__support/integer_to_string.h"
 
 #include "FloatProperties.h"
 #include <stdint.h>
@@ -215,47 +213,6 @@ template <typename T> struct FPBits {
     result.set_mantissa(mantissa);
     return result;
   }
-
-  // Converts the bits to a string in the following format:
-  //    "0x<NNN...N> = S: N, E: 0xNNNN, M:0xNNN...N"
-  // 1. N is a hexadecimal digit.
-  // 2. The hexadecimal number on the LHS is the raw numerical representation
-  //    of the bits.
-  // 3. The exponent is always 16 bits wide irrespective of the type of the
-  //    floating encoding.
-  LIBC_INLINE cpp::string str() const {
-    if (is_nan())
-      return "(NaN)";
-    if (is_inf())
-      return get_sign() ? "(-Infinity)" : "(+Infinity)";
-
-    auto zerofill = [](char *arr, size_t n) {
-      for (size_t i = 0; i < n; ++i)
-        arr[i] = '0';
-    };
-
-    cpp::string s("0x");
-    char bitsbuf[IntegerToString::hex_bufsize<UIntType>()];
-    zerofill(bitsbuf, sizeof(bitsbuf));
-    IntegerToString::hex(bits, bitsbuf, false);
-    s += cpp::string(bitsbuf, sizeof(bitsbuf));
-
-    s += " = (";
-    s += cpp::string("S: ") + (get_sign() ? "1" : "0");
-
-    char expbuf[IntegerToString::hex_bufsize<uint16_t>()];
-    zerofill(expbuf, sizeof(expbuf));
-    IntegerToString::hex(get_unbiased_exponent(), expbuf, false);
-    s += cpp::string(", E: 0x") + cpp::string(expbuf, sizeof(expbuf));
-
-    char mantbuf[IntegerToString::hex_bufsize<UIntType>()] = {'0'};
-    zerofill(mantbuf, sizeof(mantbuf));
-    IntegerToString::hex(get_mantissa(), mantbuf, false);
-    s += cpp::string(", M: 0x") + cpp::string(mantbuf, sizeof(mantbuf));
-
-    s += ")";
-    return s;
-  }
 };
 
 } // namespace fputil

diff  --git a/libc/src/__support/FPUtil/fpbits_str.h b/libc/src/__support/FPUtil/fpbits_str.h
new file mode 100644
index 0000000000000..475b582d05082
--- /dev/null
+++ b/libc/src/__support/FPUtil/fpbits_str.h
@@ -0,0 +1,71 @@
+//===------ Pretty print function for FPBits --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SUPPORT_FPUTIL_FP_BITS_STR_H
+#define LLVM_LIBC_SRC_SUPPORT_FPUTIL_FP_BITS_STR_H
+
+#include "src/__support/CPP/string.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/FloatProperties.h"
+#include "src/__support/integer_to_string.h"
+#include "src/__support/macros/attributes.h"
+
+namespace __llvm_libc {
+
+// Converts the bits to a string in the following format:
+//    "0x<NNN...N> = S: N, E: 0xNNNN, M:0xNNN...N"
+// 1. N is a hexadecimal digit.
+// 2. The hexadecimal number on the LHS is the raw numerical representation
+//    of the bits.
+// 3. The exponent is always 16 bits wide irrespective of the type of the
+//    floating encoding.
+template <typename T> LIBC_INLINE cpp::string str(fputil::FPBits<T> x) {
+  using UIntType = typename fputil::FPBits<T>::UIntType;
+
+  if (x.is_nan())
+    return "(NaN)";
+  if (x.is_inf())
+    return x.get_sign() ? "(-Infinity)" : "(+Infinity)";
+
+  auto zerofill = [](char *arr, size_t n) {
+    for (size_t i = 0; i < n; ++i)
+      arr[i] = '0';
+  };
+
+  cpp::string s("0x");
+  char bitsbuf[IntegerToString::hex_bufsize<UIntType>()];
+  zerofill(bitsbuf, sizeof(bitsbuf));
+  IntegerToString::hex(x.bits, bitsbuf, false);
+  s += cpp::string(bitsbuf, sizeof(bitsbuf));
+
+  s += " = (";
+  s += cpp::string("S: ") + (x.get_sign() ? "1" : "0");
+
+  char expbuf[IntegerToString::hex_bufsize<uint16_t>()];
+  zerofill(expbuf, sizeof(expbuf));
+  IntegerToString::hex(x.get_unbiased_exponent(), expbuf, false);
+  s += cpp::string(", E: 0x") + cpp::string(expbuf, sizeof(expbuf));
+
+  if constexpr (cpp::is_same_v<T, long double> &&
+                fputil::FloatProperties<long double>::MANTISSA_WIDTH == 63) {
+    s += cpp::string(", I: ") + (x.get_implicit_bit() ? "1" : "0");
+  }
+
+  char mantbuf[IntegerToString::hex_bufsize<UIntType>()] = {'0'};
+  zerofill(mantbuf, sizeof(mantbuf));
+  IntegerToString::hex(x.get_mantissa(), mantbuf, false);
+  s += cpp::string(", M: 0x") + cpp::string(mantbuf, sizeof(mantbuf));
+
+  s += ")";
+  return s;
+}
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_SUPPORT_FPUTIL_FP_BITS_STR_H

diff  --git a/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h b/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
index 1ef588fba54ac..ba2fddb2a6fed 100644
--- a/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
+++ b/libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
@@ -10,10 +10,8 @@
 #define LLVM_LIBC_SRC_SUPPORT_FPUTIL_X86_64_LONG_DOUBLE_BITS_H
 
 #include "src/__support/CPP/bit.h"
-#include "src/__support/CPP/string.h"
 #include "src/__support/UInt128.h"
 #include "src/__support/common.h"
-#include "src/__support/integer_to_string.h"
 #include "src/__support/macros/properties/architectures.h"
 
 #if !defined(LIBC_TARGET_ARCH_IS_X86)
@@ -209,50 +207,6 @@ template <> struct FPBits<long double> {
     result.set_mantissa(mantissa);
     return result;
   }
-
-  // Converts the bits to a string in the following format:
-  //    "0x<NNN...N> = S: N, E: 0xNNNN, I: N, M:0xNNN...N"
-  // 1. N is a hexadecimal digit.
-  // 2. "I" denotes the implicit bit.
-  // 3. The hexadecimal number on the LHS is the raw numerical representation
-  //    of the bits.
-  // 4. The exponent is always 16 bits wide irrespective of the type of the
-  //    floating encoding.
-  LIBC_INLINE cpp::string str() const {
-    if (is_nan())
-      return "(NaN)";
-    if (is_inf())
-      return get_sign() ? "(-Infinity)" : "(+Infinity)";
-
-    auto zerofill = [](char *arr, size_t n) {
-      for (size_t i = 0; i < n; ++i)
-        arr[i] = '0';
-    };
-
-    cpp::string s("0x");
-    char bitsbuf[IntegerToString::hex_bufsize<UIntType>()] = {'0'};
-    zerofill(bitsbuf, sizeof(bitsbuf));
-    IntegerToString::hex(bits, bitsbuf, false);
-    s += cpp::string(bitsbuf, sizeof(bitsbuf));
-
-    s += " = (";
-    s += cpp::string("S: ") + (get_sign() ? "1" : "0");
-
-    char expbuf[IntegerToString::hex_bufsize<uint16_t>()] = {'0'};
-    zerofill(expbuf, sizeof(expbuf));
-    IntegerToString::hex(get_unbiased_exponent(), expbuf, false);
-    s += cpp::string(", E: 0x") + cpp::string(expbuf, sizeof(expbuf));
-
-    s += cpp::string(", I: ") + (get_implicit_bit() ? "1" : "0");
-
-    char mantbuf[IntegerToString::hex_bufsize<UIntType>()] = {'0'};
-    zerofill(mantbuf, sizeof(mantbuf));
-    IntegerToString::hex(get_mantissa(), mantbuf, false);
-    s += cpp::string(", M: 0x") + cpp::string(mantbuf, sizeof(mantbuf));
-
-    s += ")";
-    return s;
-  }
 };
 
 static_assert(

diff  --git a/libc/test/UnitTest/CMakeLists.txt b/libc/test/UnitTest/CMakeLists.txt
index 014e366b80264..ec8182d88165a 100644
--- a/libc/test/UnitTest/CMakeLists.txt
+++ b/libc/test/UnitTest/CMakeLists.txt
@@ -108,8 +108,8 @@ add_unittest_framework_library(
     LibcTest
     libc.test.UnitTest.string_utils
     libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.fpbits_str
     libc.src.__support.FPUtil.fenv_impl
-    libc.test.UnitTest.string_utils
 )
 
 add_unittest_framework_library(

diff  --git a/libc/test/UnitTest/ErrnoSetterMatcher.h b/libc/test/UnitTest/ErrnoSetterMatcher.h
index 370e8117b82ce..a93d194e13d72 100644
--- a/libc/test/UnitTest/ErrnoSetterMatcher.h
+++ b/libc/test/UnitTest/ErrnoSetterMatcher.h
@@ -10,6 +10,7 @@
 #define LLVM_LIBC_TEST_ERRNOSETTERMATCHER_H
 
 #include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/fpbits_str.h"
 #include "src/__support/StringUtil/error_to_string.h"
 #include "src/__support/macros/properties/architectures.h"
 #include "src/errno/libc_errno.h"
@@ -46,10 +47,10 @@ template <typename T> class ErrnoSetterMatcher : public Matcher<T> {
       if constexpr (cpp::is_floating_point_v<T>) {
         __llvm_libc::testing::tlog
             << "Expected return value to be: "
-            << __llvm_libc::fputil::FPBits<T>(ExpectedReturn).str() << '\n';
+            << str(__llvm_libc::fputil::FPBits<T>(ExpectedReturn)) << '\n';
         __llvm_libc::testing::tlog
             << "                    But got: "
-            << __llvm_libc::fputil::FPBits<T>(ActualReturn).str() << '\n';
+            << str(__llvm_libc::fputil::FPBits<T>(ActualReturn)) << '\n';
       } else {
         __llvm_libc::testing::tlog << "Expected return value to be "
                                    << ExpectedReturn << " but got "

diff  --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h
index ae50d50cdb15d..f5294203c39fc 100644
--- a/libc/test/UnitTest/FPMatcher.h
+++ b/libc/test/UnitTest/FPMatcher.h
@@ -11,6 +11,7 @@
 
 #include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/fpbits_str.h"
 #include "test/UnitTest/RoundingModeUtils.h"
 #include "test/UnitTest/StringUtils.h"
 #include "test/UnitTest/Test.h"
@@ -24,7 +25,7 @@ template <typename T, TestCond Condition> class FPMatcher : public Matcher<T> {
   static_assert(cpp::is_floating_point_v<T>,
                 "FPMatcher can only be used with floating point values.");
   static_assert(Condition == TestCond::EQ || Condition == TestCond::NE,
-                "Unsupported FPMathcer test condition.");
+                "Unsupported FPMatcher test condition.");
 
   T expected;
   T actual;
@@ -48,8 +49,8 @@ template <typename T, TestCond Condition> class FPMatcher : public Matcher<T> {
 
   void explainError() override {
     tlog << "Expected floating point value: "
-         << fputil::FPBits<T>(expected).str() << '\n';
-    tlog << "Actual floating point value: " << fputil::FPBits<T>(actual).str()
+         << str(fputil::FPBits<T>(expected)) << '\n';
+    tlog << "Actual floating point value: " << str(fputil::FPBits<T>(actual))
          << '\n';
   }
 };

diff  --git a/libc/test/src/__support/FPUtil/CMakeLists.txt b/libc/test/src/__support/FPUtil/CMakeLists.txt
index f421e7c584bfc..a28c89a87bbbf 100644
--- a/libc/test/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/test/src/__support/FPUtil/CMakeLists.txt
@@ -19,4 +19,5 @@ add_libc_test(
     fpbits_test.cpp
   DEPENDS
     libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.fpbits_str
 )

diff  --git a/libc/test/src/__support/FPUtil/fpbits_test.cpp b/libc/test/src/__support/FPUtil/fpbits_test.cpp
index a678c1591f2b5..f910eb1d87637 100644
--- a/libc/test/src/__support/FPUtil/fpbits_test.cpp
+++ b/libc/test/src/__support/FPUtil/fpbits_test.cpp
@@ -7,22 +7,25 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/fpbits_str.h"
 #include "test/UnitTest/Test.h"
 
 using __llvm_libc::fputil::FPBits;
 
 TEST(LlvmLibcFPBitsTest, FloatType) {
-  EXPECT_STREQ(FPBits<float>::inf().str().c_str(), "(+Infinity)");
-  EXPECT_STREQ(FPBits<float>::neg_inf().str().c_str(), "(-Infinity)");
-  EXPECT_STREQ(FPBits<float>(FPBits<float>::build_nan(1)).str().c_str(),
-               "(NaN)");
+  EXPECT_STREQ(__llvm_libc::str(FPBits<float>::inf()).c_str(), "(+Infinity)");
+  EXPECT_STREQ(__llvm_libc::str(FPBits<float>::neg_inf()).c_str(),
+               "(-Infinity)");
+  EXPECT_STREQ(
+      __llvm_libc::str(FPBits<float>(FPBits<float>::build_nan(1))).c_str(),
+      "(NaN)");
 
   FPBits<float> zero(0.0f);
   EXPECT_EQ(zero.get_sign(), false);
   EXPECT_EQ(zero.get_unbiased_exponent(), static_cast<uint16_t>(0));
   EXPECT_EQ(zero.get_mantissa(), static_cast<uint32_t>(0));
   EXPECT_EQ(zero.uintval(), static_cast<uint32_t>(0x00000000));
-  EXPECT_STREQ(zero.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(zero).c_str(),
                "0x00000000 = (S: 0, E: 0x0000, M: 0x00000000)");
 
   FPBits<float> negzero(-0.0f);
@@ -30,7 +33,7 @@ TEST(LlvmLibcFPBitsTest, FloatType) {
   EXPECT_EQ(negzero.get_unbiased_exponent(), static_cast<uint16_t>(0));
   EXPECT_EQ(negzero.get_mantissa(), static_cast<uint32_t>(0));
   EXPECT_EQ(negzero.uintval(), static_cast<uint32_t>(0x80000000));
-  EXPECT_STREQ(negzero.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(negzero).c_str(),
                "0x80000000 = (S: 1, E: 0x0000, M: 0x00000000)");
 
   FPBits<float> one(1.0f);
@@ -38,7 +41,7 @@ TEST(LlvmLibcFPBitsTest, FloatType) {
   EXPECT_EQ(one.get_unbiased_exponent(), static_cast<uint16_t>(0x7F));
   EXPECT_EQ(one.get_mantissa(), static_cast<uint32_t>(0));
   EXPECT_EQ(one.uintval(), static_cast<uint32_t>(0x3F800000));
-  EXPECT_STREQ(one.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(one).c_str(),
                "0x3F800000 = (S: 0, E: 0x007F, M: 0x00000000)");
 
   FPBits<float> negone(-1.0f);
@@ -46,7 +49,7 @@ TEST(LlvmLibcFPBitsTest, FloatType) {
   EXPECT_EQ(negone.get_unbiased_exponent(), static_cast<uint16_t>(0x7F));
   EXPECT_EQ(negone.get_mantissa(), static_cast<uint32_t>(0));
   EXPECT_EQ(negone.uintval(), static_cast<uint32_t>(0xBF800000));
-  EXPECT_STREQ(negone.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(negone).c_str(),
                "0xBF800000 = (S: 1, E: 0x007F, M: 0x00000000)");
 
   FPBits<float> num(1.125f);
@@ -54,7 +57,7 @@ TEST(LlvmLibcFPBitsTest, FloatType) {
   EXPECT_EQ(num.get_unbiased_exponent(), static_cast<uint16_t>(0x7F));
   EXPECT_EQ(num.get_mantissa(), static_cast<uint32_t>(0x00100000));
   EXPECT_EQ(num.uintval(), static_cast<uint32_t>(0x3F900000));
-  EXPECT_STREQ(num.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(num).c_str(),
                "0x3F900000 = (S: 0, E: 0x007F, M: 0x00100000)");
 
   FPBits<float> negnum(-1.125f);
@@ -62,22 +65,24 @@ TEST(LlvmLibcFPBitsTest, FloatType) {
   EXPECT_EQ(negnum.get_unbiased_exponent(), static_cast<uint16_t>(0x7F));
   EXPECT_EQ(negnum.get_mantissa(), static_cast<uint32_t>(0x00100000));
   EXPECT_EQ(negnum.uintval(), static_cast<uint32_t>(0xBF900000));
-  EXPECT_STREQ(negnum.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(negnum).c_str(),
                "0xBF900000 = (S: 1, E: 0x007F, M: 0x00100000)");
 }
 
 TEST(LlvmLibcFPBitsTest, DoubleType) {
-  EXPECT_STREQ(FPBits<double>::inf().str().c_str(), "(+Infinity)");
-  EXPECT_STREQ(FPBits<double>::neg_inf().str().c_str(), "(-Infinity)");
-  EXPECT_STREQ(FPBits<double>(FPBits<double>::build_nan(1)).str().c_str(),
-               "(NaN)");
+  EXPECT_STREQ(__llvm_libc::str(FPBits<double>::inf()).c_str(), "(+Infinity)");
+  EXPECT_STREQ(__llvm_libc::str(FPBits<double>::neg_inf()).c_str(),
+               "(-Infinity)");
+  EXPECT_STREQ(
+      __llvm_libc::str(FPBits<double>(FPBits<double>::build_nan(1))).c_str(),
+      "(NaN)");
 
   FPBits<double> zero(0.0);
   EXPECT_EQ(zero.get_sign(), false);
   EXPECT_EQ(zero.get_unbiased_exponent(), static_cast<uint16_t>(0x0000));
   EXPECT_EQ(zero.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
   EXPECT_EQ(zero.uintval(), static_cast<uint64_t>(0x0000000000000000));
-  EXPECT_STREQ(zero.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(zero).c_str(),
                "0x0000000000000000 = (S: 0, E: 0x0000, M: 0x0000000000000000)");
 
   FPBits<double> negzero(-0.0);
@@ -85,7 +90,7 @@ TEST(LlvmLibcFPBitsTest, DoubleType) {
   EXPECT_EQ(negzero.get_unbiased_exponent(), static_cast<uint16_t>(0x0000));
   EXPECT_EQ(negzero.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
   EXPECT_EQ(negzero.uintval(), static_cast<uint64_t>(0x8000000000000000));
-  EXPECT_STREQ(negzero.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(negzero).c_str(),
                "0x8000000000000000 = (S: 1, E: 0x0000, M: 0x0000000000000000)");
 
   FPBits<double> one(1.0);
@@ -93,7 +98,7 @@ TEST(LlvmLibcFPBitsTest, DoubleType) {
   EXPECT_EQ(one.get_unbiased_exponent(), static_cast<uint16_t>(0x03FF));
   EXPECT_EQ(one.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
   EXPECT_EQ(one.uintval(), static_cast<uint64_t>(0x3FF0000000000000));
-  EXPECT_STREQ(one.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(one).c_str(),
                "0x3FF0000000000000 = (S: 0, E: 0x03FF, M: 0x0000000000000000)");
 
   FPBits<double> negone(-1.0);
@@ -101,7 +106,7 @@ TEST(LlvmLibcFPBitsTest, DoubleType) {
   EXPECT_EQ(negone.get_unbiased_exponent(), static_cast<uint16_t>(0x03FF));
   EXPECT_EQ(negone.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
   EXPECT_EQ(negone.uintval(), static_cast<uint64_t>(0xBFF0000000000000));
-  EXPECT_STREQ(negone.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(negone).c_str(),
                "0xBFF0000000000000 = (S: 1, E: 0x03FF, M: 0x0000000000000000)");
 
   FPBits<double> num(1.125);
@@ -109,7 +114,7 @@ TEST(LlvmLibcFPBitsTest, DoubleType) {
   EXPECT_EQ(num.get_unbiased_exponent(), static_cast<uint16_t>(0x03FF));
   EXPECT_EQ(num.get_mantissa(), static_cast<uint64_t>(0x0002000000000000));
   EXPECT_EQ(num.uintval(), static_cast<uint64_t>(0x3FF2000000000000));
-  EXPECT_STREQ(num.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(num).c_str(),
                "0x3FF2000000000000 = (S: 0, E: 0x03FF, M: 0x0002000000000000)");
 
   FPBits<double> negnum(-1.125);
@@ -117,7 +122,7 @@ TEST(LlvmLibcFPBitsTest, DoubleType) {
   EXPECT_EQ(negnum.get_unbiased_exponent(), static_cast<uint16_t>(0x03FF));
   EXPECT_EQ(negnum.get_mantissa(), static_cast<uint64_t>(0x0002000000000000));
   EXPECT_EQ(negnum.uintval(), static_cast<uint64_t>(0xBFF2000000000000));
-  EXPECT_STREQ(negnum.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(negnum).c_str(),
                "0xBFF2000000000000 = (S: 1, E: 0x03FF, M: 0x0002000000000000)");
 }
 
@@ -126,10 +131,13 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
   if constexpr (sizeof(long double) == sizeof(double))
     return; // The tests for the "double" type cover for this case.
 
-  EXPECT_STREQ(FPBits<long double>::inf().str().c_str(), "(+Infinity)");
-  EXPECT_STREQ(FPBits<long double>::neg_inf().str().c_str(), "(-Infinity)");
+  EXPECT_STREQ(__llvm_libc::str(FPBits<long double>::inf()).c_str(),
+               "(+Infinity)");
+  EXPECT_STREQ(__llvm_libc::str(FPBits<long double>::neg_inf()).c_str(),
+               "(-Infinity)");
   EXPECT_STREQ(
-      FPBits<long double>(FPBits<long double>::build_nan(1)).str().c_str(),
+      __llvm_libc::str(FPBits<long double>(FPBits<long double>::build_nan(1)))
+          .c_str(),
       "(NaN)");
 
   FPBits<long double> zero(0.0l);
@@ -139,7 +147,7 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
                                      << 64);
   EXPECT_EQ(zero.uintval(), static_cast<UInt128>(0x0000000000000000) << 64);
   EXPECT_STREQ(
-      zero.str().c_str(),
+      __llvm_libc::str(zero).c_str(),
       "0x00000000000000000000000000000000 = "
       "(S: 0, E: 0x0000, I: 0, M: 0x00000000000000000000000000000000)");
 
@@ -150,7 +158,7 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
                                         << 64);
   EXPECT_EQ(negzero.uintval(), static_cast<UInt128>(0x1) << 79);
   EXPECT_STREQ(
-      negzero.str().c_str(),
+      __llvm_libc::str(negzero).c_str(),
       "0x00000000000080000000000000000000 = "
       "(S: 1, E: 0x0000, I: 0, M: 0x00000000000000000000000000000000)");
 
@@ -160,7 +168,7 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
   EXPECT_EQ(one.get_mantissa(), static_cast<UInt128>(0x0000000000000000) << 64);
   EXPECT_EQ(one.uintval(), static_cast<UInt128>(0x3FFF8) << 60);
   EXPECT_STREQ(
-      one.str().c_str(),
+      __llvm_libc::str(one).c_str(),
       "0x0000000000003FFF8000000000000000 = "
       "(S: 0, E: 0x3FFF, I: 1, M: 0x00000000000000000000000000000000)");
 
@@ -171,7 +179,7 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
                                        << 64);
   EXPECT_EQ(negone.uintval(), static_cast<UInt128>(0xBFFF8) << 60);
   EXPECT_STREQ(
-      negone.str().c_str(),
+      __llvm_libc::str(negone).c_str(),
       "0x000000000000BFFF8000000000000000 = "
       "(S: 1, E: 0x3FFF, I: 1, M: 0x00000000000000000000000000000000)");
 
@@ -181,7 +189,7 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
   EXPECT_EQ(num.get_mantissa(), static_cast<UInt128>(0x1) << 60);
   EXPECT_EQ(num.uintval(), static_cast<UInt128>(0x3FFF9) << 60);
   EXPECT_STREQ(
-      num.str().c_str(),
+      __llvm_libc::str(num).c_str(),
       "0x0000000000003FFF9000000000000000 = "
       "(S: 0, E: 0x3FFF, I: 1, M: 0x00000000000000001000000000000000)");
 
@@ -191,7 +199,7 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
   EXPECT_EQ(negnum.get_mantissa(), static_cast<UInt128>(0x1) << 60);
   EXPECT_EQ(negnum.uintval(), static_cast<UInt128>(0xBFFF9) << 60);
   EXPECT_STREQ(
-      negnum.str().c_str(),
+      __llvm_libc::str(negnum).c_str(),
       "0x000000000000BFFF9000000000000000 = "
       "(S: 1, E: 0x3FFF, I: 1, M: 0x00000000000000001000000000000000)");
 }
@@ -200,10 +208,13 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) {
 #if defined(LONG_DOUBLE_IS_DOUBLE)
   return; // The tests for the "double" type cover for this case.
 #else
-  EXPECT_STREQ(FPBits<long double>::inf().str().c_str(), "(+Infinity)");
-  EXPECT_STREQ(FPBits<long double>::neg_inf().str().c_str(), "(-Infinity)");
+  EXPECT_STREQ(__llvm_libc::str(FPBits<long double>::inf()).c_str(),
+               "(+Infinity)");
+  EXPECT_STREQ(__llvm_libc::str(FPBits<long double>::neg_inf()).c_str(),
+               "(-Infinity)");
   EXPECT_STREQ(
-      FPBits<long double>(FPBits<long double>::build_nan(1)).str().c_str(),
+      __llvm_libc::str(FPBits<long double>(FPBits<long double>::build_nan(1)))
+          .c_str(),
       "(NaN)");
 
   FPBits<long double> zero(0.0l);
@@ -212,7 +223,7 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) {
   EXPECT_EQ(zero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
                                      << 64);
   EXPECT_EQ(zero.uintval(), static_cast<UInt128>(0x0000000000000000) << 64);
-  EXPECT_STREQ(zero.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(zero).c_str(),
                "0x00000000000000000000000000000000 = "
                "(S: 0, E: 0x0000, M: 0x00000000000000000000000000000000)");
 
@@ -222,7 +233,7 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) {
   EXPECT_EQ(negzero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
                                         << 64);
   EXPECT_EQ(negzero.uintval(), static_cast<UInt128>(0x1) << 127);
-  EXPECT_STREQ(negzero.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(negzero).c_str(),
                "0x80000000000000000000000000000000 = "
                "(S: 1, E: 0x0000, M: 0x00000000000000000000000000000000)");
 
@@ -231,7 +242,7 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) {
   EXPECT_EQ(one.get_unbiased_exponent(), static_cast<uint16_t>(0x3FFF));
   EXPECT_EQ(one.get_mantissa(), static_cast<UInt128>(0x0000000000000000) << 64);
   EXPECT_EQ(one.uintval(), static_cast<UInt128>(0x3FFF) << 112);
-  EXPECT_STREQ(one.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(one).c_str(),
                "0x3FFF0000000000000000000000000000 = "
                "(S: 0, E: 0x3FFF, M: 0x00000000000000000000000000000000)");
 
@@ -241,7 +252,7 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) {
   EXPECT_EQ(negone.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
                                        << 64);
   EXPECT_EQ(negone.uintval(), static_cast<UInt128>(0xBFFF) << 112);
-  EXPECT_STREQ(negone.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(negone).c_str(),
                "0xBFFF0000000000000000000000000000 = "
                "(S: 1, E: 0x3FFF, M: 0x00000000000000000000000000000000)");
 
@@ -250,7 +261,7 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) {
   EXPECT_EQ(num.get_unbiased_exponent(), static_cast<uint16_t>(0x3FFF));
   EXPECT_EQ(num.get_mantissa(), static_cast<UInt128>(0x2) << 108);
   EXPECT_EQ(num.uintval(), static_cast<UInt128>(0x3FFF2) << 108);
-  EXPECT_STREQ(num.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(num).c_str(),
                "0x3FFF2000000000000000000000000000 = "
                "(S: 0, E: 0x3FFF, M: 0x00002000000000000000000000000000)");
 
@@ -259,7 +270,7 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) {
   EXPECT_EQ(negnum.get_unbiased_exponent(), static_cast<uint16_t>(0x3FFF));
   EXPECT_EQ(negnum.get_mantissa(), static_cast<UInt128>(0x2) << 108);
   EXPECT_EQ(negnum.uintval(), static_cast<UInt128>(0xBFFF2) << 108);
-  EXPECT_STREQ(negnum.str().c_str(),
+  EXPECT_STREQ(__llvm_libc::str(negnum).c_str(),
                "0xBFFF2000000000000000000000000000 = "
                "(S: 1, E: 0x3FFF, M: 0x00002000000000000000000000000000)");
 #endif

diff  --git a/libc/utils/MPFRWrapper/CMakeLists.txt b/libc/utils/MPFRWrapper/CMakeLists.txt
index e863867126131..0c9328acfb8db 100644
--- a/libc/utils/MPFRWrapper/CMakeLists.txt
+++ b/libc/utils/MPFRWrapper/CMakeLists.txt
@@ -12,6 +12,7 @@ if(LIBC_TESTS_CAN_USE_MPFR)
     libc.src.__support.CPP.string_view 
     libc.src.__support.CPP.type_traits 
     libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.fpbits_str
     libc.src.__support.FPUtil.platform_defs
     LibcTest.unit
   )

diff  --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp
index d92510f2e51ce..a45474ee8dd32 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.cpp
+++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp
@@ -12,6 +12,7 @@
 #include "src/__support/CPP/string_view.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/PlatformDefs.h"
+#include "src/__support/FPUtil/fpbits_str.h"
 #include "test/UnitTest/FPMatcher.h"
 
 #include <cmath>
@@ -694,11 +695,11 @@ void explain_unary_operation_single_output_error(Operation op, T input,
   MPFRNumber mpfrMatchValue(matchValue);
   tlog << "Match value not within tolerance value of MPFR result:\n"
        << "  Input decimal: " << mpfrInput.str() << '\n';
-  tlog << "     Input bits: " << FPBits<T>(input).str() << '\n';
+  tlog << "     Input bits: " << str(FPBits<T>(input)) << '\n';
   tlog << '\n' << "  Match decimal: " << mpfrMatchValue.str() << '\n';
-  tlog << "     Match bits: " << FPBits<T>(matchValue).str() << '\n';
+  tlog << "     Match bits: " << str(FPBits<T>(matchValue)) << '\n';
   tlog << '\n' << "    MPFR result: " << mpfr_result.str() << '\n';
-  tlog << "   MPFR rounded: " << FPBits<T>(mpfr_result.as<T>()).str() << '\n';
+  tlog << "   MPFR rounded: " << str(FPBits<T>(mpfr_result.as<T>())) << '\n';
   tlog << '\n';
   tlog << "      ULP error: "
        << mpfr_result.ulp_as_mpfr_number(matchValue).str() << '\n';
@@ -738,12 +739,12 @@ void explain_unary_operation_two_outputs_error(
   tlog << "            Input decimal: " << mpfrInput.str() << "\n\n";
 
   tlog << "Libc floating point value: " << mpfrMatchValue.str() << '\n';
-  tlog << " Libc floating point bits: " << FPBits<T>(libc_result.f).str()
+  tlog << " Libc floating point bits: " << str(FPBits<T>(libc_result.f))
        << '\n';
   tlog << "\n\n";
 
   tlog << "              MPFR result: " << mpfr_result.str() << '\n';
-  tlog << "             MPFR rounded: " << FPBits<T>(mpfr_result.as<T>()).str()
+  tlog << "             MPFR rounded: " << str(FPBits<T>(mpfr_result.as<T>()))
        << '\n';
   tlog << '\n'
        << "                ULP error: "
@@ -776,10 +777,10 @@ void explain_binary_operation_two_outputs_error(
        << "Libc integral result: " << libc_result.i << '\n'
        << "Libc floating point result: " << mpfrMatchValue.str() << '\n'
        << "               MPFR result: " << mpfr_result.str() << '\n';
-  tlog << "Libc floating point result bits: " << FPBits<T>(libc_result.f).str()
+  tlog << "Libc floating point result bits: " << str(FPBits<T>(libc_result.f))
        << '\n';
   tlog << "              MPFR rounded bits: "
-       << FPBits<T>(mpfr_result.as<T>()).str() << '\n';
+       << str(FPBits<T>(mpfr_result.as<T>())) << '\n';
   tlog << "ULP error: " << mpfr_result.ulp_as_mpfr_number(libc_result.f).str()
        << '\n';
 }
@@ -810,15 +811,15 @@ void explain_binary_operation_one_output_error(Operation op,
   MPFRNumber mpfrMatchValue(libc_result);
 
   tlog << "Input decimal: x: " << mpfrX.str() << " y: " << mpfrY.str() << '\n';
-  tlog << "First input bits: " << FPBits<T>(input.x).str() << '\n';
-  tlog << "Second input bits: " << FPBits<T>(input.y).str() << '\n';
+  tlog << "First input bits: " << str(FPBits<T>(input.x)) << '\n';
+  tlog << "Second input bits: " << str(FPBits<T>(input.y)) << '\n';
 
   tlog << "Libc result: " << mpfrMatchValue.str() << '\n'
        << "MPFR result: " << mpfr_result.str() << '\n';
-  tlog << "Libc floating point result bits: " << FPBits<T>(libc_result).str()
+  tlog << "Libc floating point result bits: " << str(FPBits<T>(libc_result))
        << '\n';
   tlog << "              MPFR rounded bits: "
-       << FPBits<T>(mpfr_result.as<T>()).str() << '\n';
+       << str(FPBits<T>(mpfr_result.as<T>())) << '\n';
   tlog << "ULP error: " << mpfr_result.ulp_as_mpfr_number(libc_result).str()
        << '\n';
 }
@@ -850,16 +851,16 @@ void explain_ternary_operation_one_output_error(Operation op,
 
   tlog << "Input decimal: x: " << mpfrX.str() << " y: " << mpfrY.str()
        << " z: " << mpfrZ.str() << '\n';
-  tlog << " First input bits: " << FPBits<T>(input.x).str() << '\n';
-  tlog << "Second input bits: " << FPBits<T>(input.y).str() << '\n';
-  tlog << " Third input bits: " << FPBits<T>(input.z).str() << '\n';
+  tlog << " First input bits: " << str(FPBits<T>(input.x)) << '\n';
+  tlog << "Second input bits: " << str(FPBits<T>(input.y)) << '\n';
+  tlog << " Third input bits: " << str(FPBits<T>(input.z)) << '\n';
 
   tlog << "Libc result: " << mpfrMatchValue.str() << '\n'
        << "MPFR result: " << mpfr_result.str() << '\n';
-  tlog << "Libc floating point result bits: " << FPBits<T>(libc_result).str()
+  tlog << "Libc floating point result bits: " << str(FPBits<T>(libc_result))
        << '\n';
   tlog << "              MPFR rounded bits: "
-       << FPBits<T>(mpfr_result.as<T>()).str() << '\n';
+       << str(FPBits<T>(mpfr_result.as<T>())) << '\n';
   tlog << "ULP error: " << mpfr_result.ulp_as_mpfr_number(libc_result).str()
        << '\n';
 }

diff  --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 914838cf88f24..f62e5393c6eaa 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -569,9 +569,23 @@ libc_support_library(
         ":__support_builtin_wrappers",
         ":__support_common",
         ":__support_cpp_bit",
+        ":__support_cpp_type_traits",
+        ":__support_fputil_float_properties",
+        ":__support_fputil_platform_defs",
+        ":__support_uint128",
+        ":libc_root",
+    ],
+)
+
+libc_support_library(
+    name = "__support_fputil_fpbits_str",
+    hdrs = ["src/__support/FPUtil/fpbits_str.h"],
+    deps = [
+        ":__support_common",
         ":__support_cpp_string",
         ":__support_cpp_type_traits",
         ":__support_fputil_float_properties",
+        ":__support_fputil_fp_bits",
         ":__support_fputil_platform_defs",
         ":__support_integer_to_string",
         ":__support_uint128",

diff  --git a/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel
index 49ab0aec7e921..afff7db4b3885 100644
--- a/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel
@@ -45,6 +45,7 @@ cc_library(
         "//libc:__support_cpp_string_view",
         "//libc:__support_cpp_type_traits",
         "//libc:__support_fputil_fp_bits",
+        "//libc:__support_fputil_fpbits_str",
         "//libc:__support_macros_properties_architectures",
         "//libc:__support_stringutil",
         "//libc:__support_uint128",
@@ -74,6 +75,7 @@ cc_library(
         "//libc:__support_cpp_type_traits",
         "//libc:__support_fputil_fenv_impl",
         "//libc:__support_fputil_fp_bits",
+        "//libc:__support_fputil_fpbits_str",
         "//libc:libc_root",
     ],
 )

diff  --git a/utils/bazel/llvm-project-overlay/libc/utils/MPFRWrapper/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/utils/MPFRWrapper/BUILD.bazel
index 441bb047782b1..5b228a2b5313a 100644
--- a/utils/bazel/llvm-project-overlay/libc/utils/MPFRWrapper/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/utils/MPFRWrapper/BUILD.bazel
@@ -43,6 +43,7 @@ cc_library(
         "//libc:__support_cpp_string_view",
         "//libc:__support_cpp_type_traits",
         "//libc:__support_fputil_fp_bits",
+        "//libc:__support_fputil_fpbits_str",
         "//libc:__support_fputil_platform_defs",
         "//libc:libc_root",
         "//libc/test/UnitTest:LibcUnitTest",


        


More information about the libc-commits mailing list