[libc-commits] [libc] 8cd8127 - [libc] Add multithreading support for exhaustive testing and MPFRUtils.

Tue Ly via libc-commits libc-commits at lists.llvm.org
Thu Jan 13 10:46:30 PST 2022


Author: Tue Ly
Date: 2022-01-13T13:46:14-05:00
New Revision: 8cd81274ff618d9d44d1089d3af0c21a76e719ad

URL: https://github.com/llvm/llvm-project/commit/8cd81274ff618d9d44d1089d3af0c21a76e719ad
DIFF: https://github.com/llvm/llvm-project/commit/8cd81274ff618d9d44d1089d3af0c21a76e719ad.diff

LOG: [libc] Add multithreading support for exhaustive testing and MPFRUtils.

Add threading support for exhaustive testing and MPFRUtils.

Reviewed By: sivachandra

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

Added: 
    libc/test/src/math/exhaustive/exhaustive_test.cpp
    libc/test/src/math/exhaustive/exhaustive_test.h

Modified: 
    libc/cmake/modules/LLVMLibCTestRules.cmake
    libc/test/src/math/exhaustive/CMakeLists.txt
    libc/test/src/math/exhaustive/logf_test.cpp
    libc/utils/MPFRWrapper/MPFRUtils.cpp
    libc/utils/UnitTest/FPMatcher.cpp
    libc/utils/UnitTest/FPMatcher.h

Removed: 
    


################################################################################
diff  --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake
index ba06ccfef536a..285119ff79c0d 100644
--- a/libc/cmake/modules/LLVMLibCTestRules.cmake
+++ b/libc/cmake/modules/LLVMLibCTestRules.cmake
@@ -63,6 +63,7 @@ endfunction(get_object_files_for_test)
 #      HDRS  <list of .h files for the test>
 #      DEPENDS <list of dependencies>
 #      COMPILE_OPTIONS <list of special compile options for this target>
+#      LINK_OPTIONS <list of special linking options for this target>
 #    )
 function(add_libc_unittest target_name)
   if(NOT LLVM_INCLUDE_TESTS)
@@ -71,9 +72,9 @@ function(add_libc_unittest target_name)
 
   cmake_parse_arguments(
     "LIBC_UNITTEST"
-    "" # No optional arguments
+    "NO_RUN_POSTBUILD" # Optional arguments
     "SUITE" # Single value arguments
-    "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi-value arguments
+    "SRCS;HDRS;DEPENDS;COMPILE_OPTIONS;LINK_OPTIONS" # Multi-value arguments
     "NO_LIBC_UNITTEST_TEST_MAIN"
     ${ARGN}
   )
@@ -140,6 +141,12 @@ function(add_libc_unittest target_name)
   endif()
 
   target_link_libraries(${fq_target_name} PRIVATE ${link_object_files})
+  if(LIBC_UNITTEST_LINK_OPTIONS)
+    target_link_options(
+      ${fq_target_name}
+      PRIVATE ${LIBC_UNITTEST_LINK_OPTIONS}
+    )
+  endif()
 
   set_target_properties(${fq_target_name}
     PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
@@ -155,11 +162,14 @@ function(add_libc_unittest target_name)
     target_link_libraries(${fq_target_name} PRIVATE LibcUnitTest LibcUnitTestMain libc_test_utils)
   endif()
 
-  add_custom_command(
-    TARGET ${fq_target_name}
-    POST_BUILD
-    COMMAND $<TARGET_FILE:${fq_target_name}>
-  )
+  if(NOT LIBC_UNITTEST_NO_RUN_POSTBUILD)
+    add_custom_command(
+      TARGET ${fq_target_name}
+      POST_BUILD
+      COMMAND $<TARGET_FILE:${fq_target_name}>
+    )
+  endif()
+
   if(LIBC_UNITTEST_SUITE)
     add_dependencies(
       ${LIBC_UNITTEST_SUITE}

diff  --git a/libc/test/src/math/exhaustive/CMakeLists.txt b/libc/test/src/math/exhaustive/CMakeLists.txt
index 51e659114e1d7..1c1a411160501 100644
--- a/libc/test/src/math/exhaustive/CMakeLists.txt
+++ b/libc/test/src/math/exhaustive/CMakeLists.txt
@@ -1,5 +1,15 @@
 add_libc_exhaustive_testsuite(libc_math_exhaustive_tests)
 
+add_object_library(
+  exhaustive_test
+  HDRS
+    exhaustive_test.h
+  SRCS
+    exhaustive_test.cpp
+  DEPENDS
+    libc.src.__support.CPP.standalone_cpp
+)
+
 add_fp_unittest(
   sqrtf_test
   NEED_MPFR
@@ -54,13 +64,17 @@ add_fp_unittest(
 
 add_fp_unittest(
   logf_test
+  NO_RUN_POSTBUILD
   NEED_MPFR
   SUITE
     libc_math_exhaustive_tests
   SRCS
     logf_test.cpp
   DEPENDS
+    .exhaustive_test
     libc.include.math
     libc.src.math.logf
     libc.src.__support.FPUtil.fputil
+  LINK_OPTIONS
+    -lpthread
 )

diff  --git a/libc/test/src/math/exhaustive/exhaustive_test.cpp b/libc/test/src/math/exhaustive/exhaustive_test.cpp
new file mode 100644
index 0000000000000..fe07467a2ec6b
--- /dev/null
+++ b/libc/test/src/math/exhaustive/exhaustive_test.cpp
@@ -0,0 +1,58 @@
+//===-- Exhaustive test template for math functions -------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <fenv.h>
+#include <functional>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <thread>
+#include <vector>
+
+#include "exhaustive_test.h"
+#include "utils/UnitTest/Test.h"
+
+template <typename T>
+void LlvmLibcExhaustiveTest<T>::test_full_range(T start, T stop, int nthreads,
+                                                mpfr::RoundingMode rounding) {
+  std::vector<std::thread> thread_list(nthreads);
+  T increment = (stop - start - 1) / nthreads + 1;
+  T begin = start;
+  T end = start + increment - 1;
+  for (int i = 0; i < nthreads; ++i) {
+    thread_list.emplace_back([this, begin, end, rounding]() {
+      std::stringstream msg;
+      msg << "-- Testing from " << begin << " to " << end << " [0x" << std::hex
+          << begin << ", 0x" << end << ") ..." << std::endl;
+      std::cout << msg.str();
+      msg.str("");
+
+      check(begin, end, rounding);
+
+      msg << "** Finished testing from " << std::dec << begin << " to " << end
+          << " [0x" << std::hex << begin << ", 0x" << end << ")" << std::endl;
+      std::cout << msg.str();
+    });
+    begin += increment;
+    end += increment;
+    if (end > stop)
+      end = stop;
+  }
+  for (auto &thread : thread_list) {
+    if (thread.joinable()) {
+      thread.join();
+    }
+  }
+}
+
+template void
+LlvmLibcExhaustiveTest<uint32_t>::test_full_range(uint32_t, uint32_t, int,
+                                                  mpfr::RoundingMode);
+template void
+LlvmLibcExhaustiveTest<uint64_t>::test_full_range(uint64_t, uint64_t, int,
+                                                  mpfr::RoundingMode);

diff  --git a/libc/test/src/math/exhaustive/exhaustive_test.h b/libc/test/src/math/exhaustive/exhaustive_test.h
new file mode 100644
index 0000000000000..0782da7a203bd
--- /dev/null
+++ b/libc/test/src/math/exhaustive/exhaustive_test.h
@@ -0,0 +1,26 @@
+//===-- Exhaustive test template for math functions -------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include "utils/UnitTest/Test.h"
+
+// To test exhaustively for inputs in the range [start, stop) in parallel:
+// 1. Inherit from LlvmLibcExhaustiveTest class
+// 2. Overide the test method: void check(T, T, RoundingMode)
+// 4. Call: test_full_range(start, stop, nthreads, rounding)
+namespace mpfr = __llvm_libc::testing::mpfr;
+
+template <typename T>
+struct LlvmLibcExhaustiveTest : public __llvm_libc::testing::Test {
+  // Break [start, stop) into `nthreads` subintervals and apply *check to each
+  // subinterval in parallel.
+  void test_full_range(T start, T stop, int nthreads,
+                       mpfr::RoundingMode rounding);
+
+  virtual void check(T start, T stop, mpfr::RoundingMode rounding);
+};

diff  --git a/libc/test/src/math/exhaustive/logf_test.cpp b/libc/test/src/math/exhaustive/logf_test.cpp
index abed0731d8992..85827a48d0bff 100644
--- a/libc/test/src/math/exhaustive/logf_test.cpp
+++ b/libc/test/src/math/exhaustive/logf_test.cpp
@@ -6,21 +6,46 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "exhaustive_test.h"
 #include "src/__support/FPUtil/FPBits.h"
 #include "src/math/logf.h"
 #include "utils/MPFRWrapper/MPFRUtils.h"
 #include "utils/UnitTest/FPMatcher.h"
-#include "utils/UnitTest/Test.h"
 
 using FPBits = __llvm_libc::fputil::FPBits<float>;
 
 namespace mpfr = __llvm_libc::testing::mpfr;
 
-TEST(LlvmLibcLogfExhaustiveTest, AllValues) {
-  uint32_t bits = 0U;
-  do {
-    FPBits xbits(bits);
-    float x = float(xbits);
-    EXPECT_MPFR_MATCH(mpfr::Operation::Log, x, __llvm_libc::logf(x), 0.5);
-  } while (bits++ < 0x7f7f'ffffU);
+struct LlvmLibcLogfExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> {
+  void check(uint32_t start, uint32_t stop,
+             mpfr::RoundingMode rounding) override {
+    mpfr::ForceRoundingMode r(rounding);
+    uint32_t bits = start;
+    do {
+      FPBits xbits(bits);
+      float x = float(xbits);
+      EXPECT_MPFR_MATCH(mpfr::Operation::Log, x, __llvm_libc::logf(x), 0.5,
+                        rounding);
+    } while (bits++ < stop);
+  }
+};
+
+TEST_F(LlvmLibcLogfExhaustiveTest, RoundNearestTieToEven) {
+  test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16,
+                  mpfr::RoundingMode::Nearest);
+}
+
+TEST_F(LlvmLibcLogfExhaustiveTest, RoundUp) {
+  test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16,
+                  mpfr::RoundingMode::Upward);
+}
+
+TEST_F(LlvmLibcLogfExhaustiveTest, RoundDown) {
+  test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16,
+                  mpfr::RoundingMode::Downward);
+}
+
+TEST_F(LlvmLibcLogfExhaustiveTest, RoundTowardZero) {
+  test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16,
+                  mpfr::RoundingMode::TowardZero);
 }

diff  --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp
index 7bb3a7fc5f598..5339df7a43ac3 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.cpp
+++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp
@@ -16,6 +16,7 @@
 #include <cmath>
 #include <fenv.h>
 #include <memory>
+#include <sstream>
 #include <stdint.h>
 #include <string>
 
@@ -571,6 +572,10 @@ ternary_operation_one_output(Operation op, InputType x, InputType y,
   }
 }
 
+// Remark: For all the explain_*_error functions, we will use std::stringstream
+// to build the complete error messages before sending it to the outstream `OS`
+// once at the end.  This will stop the error messages from interleaving when
+// the tests are running concurrently.
 template <typename T>
 void explain_unary_operation_single_output_error(Operation op, T input,
                                                  T matchValue,
@@ -582,18 +587,20 @@ void explain_unary_operation_single_output_error(Operation op, T input,
   MPFRNumber mpfr_result;
   mpfr_result = unary_operation(op, input, precision, rounding);
   MPFRNumber mpfrMatchValue(matchValue);
-  OS << "Match value not within tolerance value of MPFR result:\n"
+  std::stringstream ss;
+  ss << "Match value not within tolerance value of MPFR result:\n"
      << "  Input decimal: " << mpfrInput.str() << '\n';
-  __llvm_libc::fputil::testing::describeValue("     Input bits: ", input, OS);
-  OS << '\n' << "  Match decimal: " << mpfrMatchValue.str() << '\n';
+  __llvm_libc::fputil::testing::describeValue("     Input bits: ", input, ss);
+  ss << '\n' << "  Match decimal: " << mpfrMatchValue.str() << '\n';
   __llvm_libc::fputil::testing::describeValue("     Match bits: ", matchValue,
-                                              OS);
-  OS << '\n' << "    MPFR result: " << mpfr_result.str() << '\n';
+                                              ss);
+  ss << '\n' << "    MPFR result: " << mpfr_result.str() << '\n';
   __llvm_libc::fputil::testing::describeValue(
-      "   MPFR rounded: ", mpfr_result.as<T>(), OS);
-  OS << '\n';
-  OS << "      ULP error: " << std::to_string(mpfr_result.ulp(matchValue))
+      "   MPFR rounded: ", mpfr_result.as<T>(), ss);
+  ss << '\n';
+  ss << "      ULP error: " << std::to_string(mpfr_result.ulp(matchValue))
      << '\n';
+  OS << ss.str();
 }
 
 template void
@@ -616,31 +623,33 @@ void explain_unary_operation_two_outputs_error(
   int mpfrIntResult;
   MPFRNumber mpfr_result = unary_operation_two_outputs(op, input, mpfrIntResult,
                                                        precision, rounding);
+  std::stringstream ss;
 
   if (mpfrIntResult != libc_result.i) {
-    OS << "MPFR integral result: " << mpfrIntResult << '\n'
+    ss << "MPFR integral result: " << mpfrIntResult << '\n'
        << "Libc integral result: " << libc_result.i << '\n';
   } else {
-    OS << "Integral result from libc matches integral result from MPFR.\n";
+    ss << "Integral result from libc matches integral result from MPFR.\n";
   }
 
   MPFRNumber mpfrMatchValue(libc_result.f);
-  OS << "Libc floating point result is not within tolerance value of the MPFR "
+  ss << "Libc floating point result is not within tolerance value of the MPFR "
      << "result.\n\n";
 
-  OS << "            Input decimal: " << mpfrInput.str() << "\n\n";
+  ss << "            Input decimal: " << mpfrInput.str() << "\n\n";
 
-  OS << "Libc floating point value: " << mpfrMatchValue.str() << '\n';
+  ss << "Libc floating point value: " << mpfrMatchValue.str() << '\n';
   __llvm_libc::fputil::testing::describeValue(
-      " Libc floating point bits: ", libc_result.f, OS);
-  OS << "\n\n";
+      " Libc floating point bits: ", libc_result.f, ss);
+  ss << "\n\n";
 
-  OS << "              MPFR result: " << mpfr_result.str() << '\n';
+  ss << "              MPFR result: " << mpfr_result.str() << '\n';
   __llvm_libc::fputil::testing::describeValue(
-      "             MPFR rounded: ", mpfr_result.as<T>(), OS);
-  OS << '\n'
+      "             MPFR rounded: ", mpfr_result.as<T>(), ss);
+  ss << '\n'
      << "                ULP error: "
      << std::to_string(mpfr_result.ulp(libc_result.f)) << '\n';
+  OS << ss.str();
 }
 
 template void explain_unary_operation_two_outputs_error<float>(
@@ -665,17 +674,19 @@ void explain_binary_operation_two_outputs_error(
   MPFRNumber mpfr_result = binary_operation_two_outputs(
       op, input.x, input.y, mpfrIntResult, precision, rounding);
   MPFRNumber mpfrMatchValue(libc_result.f);
+  std::stringstream ss;
 
-  OS << "Input decimal: x: " << mpfrX.str() << " y: " << mpfrY.str() << '\n'
+  ss << "Input decimal: x: " << mpfrX.str() << " y: " << mpfrY.str() << '\n'
      << "MPFR integral result: " << mpfrIntResult << '\n'
      << "Libc integral result: " << libc_result.i << '\n'
      << "Libc floating point result: " << mpfrMatchValue.str() << '\n'
      << "               MPFR result: " << mpfr_result.str() << '\n';
   __llvm_libc::fputil::testing::describeValue(
-      "Libc floating point result bits: ", libc_result.f, OS);
+      "Libc floating point result bits: ", libc_result.f, ss);
   __llvm_libc::fputil::testing::describeValue(
-      "              MPFR rounded bits: ", mpfr_result.as<T>(), OS);
-  OS << "ULP error: " << std::to_string(mpfr_result.ulp(libc_result.f)) << '\n';
+      "              MPFR rounded bits: ", mpfr_result.as<T>(), ss);
+  ss << "ULP error: " << std::to_string(mpfr_result.ulp(libc_result.f)) << '\n';
+  OS << ss.str();
 }
 
 template void explain_binary_operation_two_outputs_error<float>(
@@ -701,20 +712,22 @@ void explain_binary_operation_one_output_error(
   MPFRNumber mpfr_result =
       binary_operation_one_output(op, input.x, input.y, precision, rounding);
   MPFRNumber mpfrMatchValue(libc_result);
+  std::stringstream ss;
 
-  OS << "Input decimal: x: " << mpfrX.str() << " y: " << mpfrY.str() << '\n';
+  ss << "Input decimal: x: " << mpfrX.str() << " y: " << mpfrY.str() << '\n';
   __llvm_libc::fputil::testing::describeValue("First input bits: ", input.x,
-                                              OS);
+                                              ss);
   __llvm_libc::fputil::testing::describeValue("Second input bits: ", input.y,
-                                              OS);
+                                              ss);
 
-  OS << "Libc result: " << mpfrMatchValue.str() << '\n'
+  ss << "Libc result: " << mpfrMatchValue.str() << '\n'
      << "MPFR result: " << mpfr_result.str() << '\n';
   __llvm_libc::fputil::testing::describeValue(
-      "Libc floating point result bits: ", libc_result, OS);
+      "Libc floating point result bits: ", libc_result, ss);
   __llvm_libc::fputil::testing::describeValue(
-      "              MPFR rounded bits: ", mpfr_result.as<T>(), OS);
-  OS << "ULP error: " << std::to_string(mpfr_result.ulp(libc_result)) << '\n';
+      "              MPFR rounded bits: ", mpfr_result.as<T>(), ss);
+  ss << "ULP error: " << std::to_string(mpfr_result.ulp(libc_result)) << '\n';
+  OS << ss.str();
 }
 
 template void explain_binary_operation_one_output_error<float>(
@@ -741,23 +754,25 @@ void explain_ternary_operation_one_output_error(
   MPFRNumber mpfr_result = ternary_operation_one_output(
       op, input.x, input.y, input.z, precision, rounding);
   MPFRNumber mpfrMatchValue(libc_result);
+  std::stringstream ss;
 
-  OS << "Input decimal: x: " << mpfrX.str() << " y: " << mpfrY.str()
+  ss << "Input decimal: x: " << mpfrX.str() << " y: " << mpfrY.str()
      << " z: " << mpfrZ.str() << '\n';
   __llvm_libc::fputil::testing::describeValue("First input bits: ", input.x,
-                                              OS);
+                                              ss);
   __llvm_libc::fputil::testing::describeValue("Second input bits: ", input.y,
-                                              OS);
+                                              ss);
   __llvm_libc::fputil::testing::describeValue("Third input bits: ", input.z,
-                                              OS);
+                                              ss);
 
-  OS << "Libc result: " << mpfrMatchValue.str() << '\n'
+  ss << "Libc result: " << mpfrMatchValue.str() << '\n'
      << "MPFR result: " << mpfr_result.str() << '\n';
   __llvm_libc::fputil::testing::describeValue(
-      "Libc floating point result bits: ", libc_result, OS);
+      "Libc floating point result bits: ", libc_result, ss);
   __llvm_libc::fputil::testing::describeValue(
-      "              MPFR rounded bits: ", mpfr_result.as<T>(), OS);
-  OS << "ULP error: " << std::to_string(mpfr_result.ulp(libc_result)) << '\n';
+      "              MPFR rounded bits: ", mpfr_result.as<T>(), ss);
+  ss << "ULP error: " << std::to_string(mpfr_result.ulp(libc_result)) << '\n';
+  OS << ss.str();
 }
 
 template void explain_ternary_operation_one_output_error<float>(

diff  --git a/libc/utils/UnitTest/FPMatcher.cpp b/libc/utils/UnitTest/FPMatcher.cpp
index c86473e61a2a8..a5ef268eaba3c 100644
--- a/libc/utils/UnitTest/FPMatcher.cpp
+++ b/libc/utils/UnitTest/FPMatcher.cpp
@@ -10,6 +10,7 @@
 
 #include "src/__support/FPUtil/FPBits.h"
 
+#include <sstream>
 #include <string>
 
 namespace __llvm_libc {
@@ -30,10 +31,9 @@ uintToHex(T X, size_t Length = sizeof(T) * 2) {
   return s;
 }
 
-template <typename ValType>
+template <typename ValType, typename StreamType>
 cpp::EnableIfType<cpp::IsFloatingPointType<ValType>::Value, void>
-describeValue(const char *label, ValType value,
-              testutils::StreamWrapper &stream) {
+describeValue(const char *label, ValType value, StreamType &stream) {
   stream << label;
 
   FPBits<ValType> bits(value);
@@ -49,15 +49,19 @@ describeValue(const char *label, ValType value,
         (fputil::ExponentWidth<ValType>::VALUE - 1) / 4 + 1;
     constexpr int mantissaWidthInHex =
         (fputil::MantissaWidth<ValType>::VALUE - 1) / 4 + 1;
+    constexpr int bitsWidthInHex =
+        sizeof(typename fputil::FPBits<ValType>::UIntType) * 2;
 
-    stream << "Sign: " << (bits.get_sign() ? '1' : '0') << ", "
-           << "Exponent: 0x"
+    stream << "0x"
+           << uintToHex<typename fputil::FPBits<ValType>::UIntType>(
+                  bits.uintval(), bitsWidthInHex)
+           << ", (S | E | M) = (" << (bits.get_sign() ? '1' : '0') << " | 0x"
            << uintToHex<uint16_t>(bits.get_unbiased_exponent(),
                                   exponentWidthInHex)
-           << ", "
-           << "Mantissa: 0x"
+           << " | 0x"
            << uintToHex<typename fputil::FPBits<ValType>::UIntType>(
-                  bits.get_mantissa(), mantissaWidthInHex);
+                  bits.get_mantissa(), mantissaWidthInHex)
+           << ")";
   }
 
   stream << '\n';
@@ -70,6 +74,11 @@ template void describeValue<double>(const char *, double,
 template void describeValue<long double>(const char *, long double,
                                          testutils::StreamWrapper &);
 
+template void describeValue<float>(const char *, float, std::stringstream &);
+template void describeValue<double>(const char *, double, std::stringstream &);
+template void describeValue<long double>(const char *, long double,
+                                         std::stringstream &);
+
 } // namespace testing
 } // namespace fputil
 } // namespace __llvm_libc

diff  --git a/libc/utils/UnitTest/FPMatcher.h b/libc/utils/UnitTest/FPMatcher.h
index 7f1c75d7e108c..a2c204c24f10d 100644
--- a/libc/utils/UnitTest/FPMatcher.h
+++ b/libc/utils/UnitTest/FPMatcher.h
@@ -17,10 +17,9 @@ namespace __llvm_libc {
 namespace fputil {
 namespace testing {
 
-template <typename ValType>
+template <typename ValType, typename StreamType>
 cpp::EnableIfType<cpp::IsFloatingPointType<ValType>::Value, void>
-describeValue(const char *label, ValType value,
-              testutils::StreamWrapper &stream);
+describeValue(const char *label, ValType value, StreamType &stream);
 
 template <typename T, __llvm_libc::testing::TestCondition Condition>
 class FPMatcher : public __llvm_libc::testing::Matcher<T> {


        


More information about the libc-commits mailing list