mirror of
https://github.com/intel/llvm.git
synced 2026-01-24 08:30:34 +08:00
[libc][NFC] Remove the StreamWrapper class and use the new test logger.
Reviewed By: lntue Differential Revision: https://reviews.llvm.org/D148452
This commit is contained in:
@@ -29,15 +29,18 @@ public:
|
||||
ErrnoSetterMatcher(T ExpectedReturn, int ExpectedErrno)
|
||||
: ExpectedReturn(ExpectedReturn), ExpectedErrno(ExpectedErrno) {}
|
||||
|
||||
void explainError(testutils::StreamWrapper &OS) override {
|
||||
void explainError() override {
|
||||
if (ActualReturn != ExpectedReturn)
|
||||
OS << "Expected return to be " << ExpectedReturn << " but got "
|
||||
<< ActualReturn << ".\nExpecte errno to be " << strerror(ExpectedErrno)
|
||||
<< " but got " << strerror(ActualErrno) << ".\n";
|
||||
__llvm_libc::testing::tlog
|
||||
<< "Expected return to be " << ExpectedReturn << " but got "
|
||||
<< ActualReturn << ".\nExpecte errno to be "
|
||||
<< strerror(ExpectedErrno) << " but got " << strerror(ActualErrno)
|
||||
<< ".\n";
|
||||
else
|
||||
OS << "Correct value " << ExpectedReturn
|
||||
<< " was returned\nBut errno was unexpectely set to "
|
||||
<< strerror(ActualErrno) << ".\n";
|
||||
__llvm_libc::testing::tlog
|
||||
<< "Correct value " << ExpectedReturn
|
||||
<< " was returned\nBut errno was unexpectely set to "
|
||||
<< strerror(ActualErrno) << ".\n";
|
||||
}
|
||||
|
||||
bool match(T Got) {
|
||||
|
||||
@@ -1,20 +1,10 @@
|
||||
add_library(
|
||||
TestLogger
|
||||
TestLogger.cpp
|
||||
TestLogger.h
|
||||
)
|
||||
target_include_directories(TestLogger PUBLIC ${LIBC_SOURCE_DIR})
|
||||
add_dependencies(TestLogger
|
||||
libc.src.__support.CPP.string
|
||||
libc.src.__support.CPP.string_view
|
||||
libc.src.__support.OSUtil.osutil
|
||||
)
|
||||
|
||||
add_library(
|
||||
LibcUnitTest
|
||||
Test.h
|
||||
LibcTest.cpp
|
||||
LibcTest.h
|
||||
TestLogger.cpp
|
||||
TestLogger.h
|
||||
)
|
||||
target_include_directories(LibcUnitTest PUBLIC ${LIBC_SOURCE_DIR})
|
||||
add_dependencies(
|
||||
@@ -22,8 +12,9 @@ add_dependencies(
|
||||
libc.src.__support.CPP.string
|
||||
libc.src.__support.CPP.string_view
|
||||
libc.src.__support.CPP.type_traits
|
||||
libc.src.__support.uint128 TestLogger)
|
||||
target_link_libraries(LibcUnitTest PUBLIC libc_test_utils TestLogger)
|
||||
libc.src.__support.OSUtil.osutil
|
||||
libc.src.__support.uint128)
|
||||
target_link_libraries(LibcUnitTest PUBLIC libc_test_utils)
|
||||
|
||||
add_library(
|
||||
LibcUnitTestMain
|
||||
@@ -39,14 +30,14 @@ add_header_library(
|
||||
HDRS
|
||||
StringUtils.h
|
||||
DEPENDS
|
||||
libc.src.__support.CPP.type_traits
|
||||
libc.src.__support.CPP.string
|
||||
libc.src.__support.CPP.type_traits
|
||||
)
|
||||
|
||||
add_library(
|
||||
LibcFPTestHelpers
|
||||
FPExceptMatcher.cpp
|
||||
FPExceptMatcher.h
|
||||
FPMatcher.cpp
|
||||
FPMatcher.h
|
||||
)
|
||||
target_include_directories(LibcFPTestHelpers PUBLIC ${LIBC_SOURCE_DIR})
|
||||
@@ -57,6 +48,7 @@ add_dependencies(
|
||||
libc.test.UnitTest.string_utils
|
||||
libc.src.__support.FPUtil.fp_bits
|
||||
libc.src.__support.FPUtil.fenv_impl
|
||||
libc.test.UnitTest.string_utils
|
||||
)
|
||||
|
||||
add_library(
|
||||
|
||||
@@ -44,9 +44,10 @@ public:
|
||||
|
||||
bool match(bool unused) { return exceptionRaised; }
|
||||
|
||||
void explainError(testutils::StreamWrapper &stream) override {
|
||||
stream << "A floating point exception should have been raised but it "
|
||||
<< "wasn't\n";
|
||||
void explainError() override {
|
||||
__llvm_libc::testing::tlog
|
||||
<< "A floating point exception should have been raised but it "
|
||||
<< "wasn't\n";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
//===-- TestMatchers.cpp ----------------------------------------*- 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 "FPMatcher.h"
|
||||
|
||||
#include "src/__support/FPUtil/FPBits.h"
|
||||
|
||||
#include "test/UnitTest/StringUtils.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace __llvm_libc {
|
||||
namespace fputil {
|
||||
namespace testing {
|
||||
|
||||
template <typename ValType, typename StreamType>
|
||||
cpp::enable_if_t<cpp::is_floating_point_v<ValType>, void>
|
||||
describeValue(const char *label, ValType value, StreamType &stream) {
|
||||
stream << label;
|
||||
|
||||
FPBits<ValType> bits(value);
|
||||
if (bits.is_nan()) {
|
||||
stream << "(NaN)";
|
||||
} else if (bits.is_inf()) {
|
||||
if (bits.get_sign())
|
||||
stream << "(-Infinity)";
|
||||
else
|
||||
stream << "(+Infinity)";
|
||||
} else {
|
||||
constexpr int exponentWidthInHex =
|
||||
(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 << "0x"
|
||||
<< int_to_hex<typename fputil::FPBits<ValType>::UIntType>(
|
||||
bits.uintval(), bitsWidthInHex)
|
||||
<< ", (S | E | M) = (" << (bits.get_sign() ? '1' : '0') << " | 0x"
|
||||
<< int_to_hex<uint16_t>(bits.get_unbiased_exponent(),
|
||||
exponentWidthInHex)
|
||||
<< " | 0x"
|
||||
<< int_to_hex<typename fputil::FPBits<ValType>::UIntType>(
|
||||
bits.get_mantissa(), mantissaWidthInHex)
|
||||
<< ")";
|
||||
}
|
||||
|
||||
stream << '\n';
|
||||
}
|
||||
|
||||
template void describeValue<float>(const char *, float,
|
||||
testutils::StreamWrapper &);
|
||||
template void describeValue<double>(const char *, double,
|
||||
testutils::StreamWrapper &);
|
||||
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
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "src/__support/FPUtil/FEnvImpl.h"
|
||||
#include "src/__support/FPUtil/FPBits.h"
|
||||
#include "test/UnitTest/StringUtils.h"
|
||||
#include "test/UnitTest/Test.h"
|
||||
#include "utils/testutils/RoundingModeUtils.h"
|
||||
|
||||
@@ -20,9 +21,42 @@ namespace __llvm_libc {
|
||||
namespace fputil {
|
||||
namespace testing {
|
||||
|
||||
template <typename ValType, typename StreamType>
|
||||
template <typename ValType>
|
||||
cpp::enable_if_t<cpp::is_floating_point_v<ValType>, void>
|
||||
describeValue(const char *label, ValType value, StreamType &stream);
|
||||
describeValue(const char *label, ValType value) {
|
||||
__llvm_libc::testing::tlog << label;
|
||||
|
||||
FPBits<ValType> bits(value);
|
||||
if (bits.is_nan()) {
|
||||
__llvm_libc::testing::tlog << "(NaN)";
|
||||
} else if (bits.is_inf()) {
|
||||
if (bits.get_sign())
|
||||
__llvm_libc::testing::tlog << "(-Infinity)";
|
||||
else
|
||||
__llvm_libc::testing::tlog << "(+Infinity)";
|
||||
} else {
|
||||
constexpr int exponentWidthInHex =
|
||||
(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;
|
||||
|
||||
__llvm_libc::testing::tlog
|
||||
<< "0x"
|
||||
<< int_to_hex<typename fputil::FPBits<ValType>::UIntType>(
|
||||
bits.uintval(), bitsWidthInHex)
|
||||
<< ", (S | E | M) = (" << (bits.get_sign() ? '1' : '0') << " | 0x"
|
||||
<< int_to_hex<uint16_t>(bits.get_unbiased_exponent(),
|
||||
exponentWidthInHex)
|
||||
<< " | 0x"
|
||||
<< int_to_hex<typename fputil::FPBits<ValType>::UIntType>(
|
||||
bits.get_mantissa(), mantissaWidthInHex)
|
||||
<< ")";
|
||||
}
|
||||
|
||||
__llvm_libc::testing::tlog << '\n';
|
||||
}
|
||||
|
||||
template <typename T, __llvm_libc::testing::TestCondition Condition>
|
||||
class FPMatcher : public __llvm_libc::testing::Matcher<T> {
|
||||
@@ -52,9 +86,9 @@ public:
|
||||
(actualBits.uintval() != expectedBits.uintval());
|
||||
}
|
||||
|
||||
void explainError(testutils::StreamWrapper &stream) override {
|
||||
describeValue("Expected floating point value: ", expected, stream);
|
||||
describeValue(" Actual floating point value: ", actual, stream);
|
||||
void explainError() override {
|
||||
describeValue("Expected floating point value: ", expected);
|
||||
describeValue(" Actual floating point value: ", actual);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -321,8 +321,7 @@ bool Test::testMatch(bool MatchResult, MatcherBase &Matcher, const char *LHSStr,
|
||||
if (!Matcher.is_silent()) {
|
||||
tlog << File << ":" << Line << ": FAILURE\n"
|
||||
<< "Failed to match " << LHSStr << " against " << RHSStr << ".\n";
|
||||
testutils::StreamWrapper OutsWrapper = testutils::outs();
|
||||
Matcher.explainError(OutsWrapper);
|
||||
Matcher.explainError();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
#include "src/__support/CPP/string.h"
|
||||
#include "src/__support/CPP/string_view.h"
|
||||
#include "src/__support/CPP/type_traits.h"
|
||||
#include "test/UnitTest/TestLogger.h"
|
||||
#include "utils/testutils/ExecuteFunction.h"
|
||||
#include "utils/testutils/StreamWrapper.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
namespace testing {
|
||||
@@ -51,9 +51,7 @@ bool test(RunContext *Ctx, TestCondition Cond, ValType LHS, ValType RHS,
|
||||
|
||||
struct MatcherBase {
|
||||
virtual ~MatcherBase() {}
|
||||
virtual void explainError(testutils::StreamWrapper &OS) {
|
||||
OS << "unknown error\n";
|
||||
}
|
||||
virtual void explainError() { tlog << "unknown error\n"; }
|
||||
// Override and return true to skip `explainError` step.
|
||||
virtual bool is_silent() const { return false; }
|
||||
};
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
|
||||
#include "MemoryMatcher.h"
|
||||
|
||||
#include "test/UnitTest/Test.h"
|
||||
|
||||
using __llvm_libc::testing::tlog;
|
||||
|
||||
namespace __llvm_libc {
|
||||
namespace memory {
|
||||
namespace testing {
|
||||
@@ -32,42 +36,42 @@ bool MemoryMatcher::match(MemoryView actualValue) {
|
||||
return equals(expected, actual, mismatch_size, mismatch_index);
|
||||
}
|
||||
|
||||
void display(testutils::StreamWrapper &Stream, char C) {
|
||||
const auto print = [&Stream](unsigned char I) {
|
||||
Stream << static_cast<char>(I < 10 ? '0' + I : 'A' + I - 10);
|
||||
static void display(char C) {
|
||||
const auto print = [](unsigned char I) {
|
||||
tlog << static_cast<char>(I < 10 ? '0' + I : 'A' + I - 10);
|
||||
};
|
||||
print(static_cast<unsigned char>(C) / 16);
|
||||
print(static_cast<unsigned char>(C) & 15);
|
||||
}
|
||||
|
||||
void display(testutils::StreamWrapper &Stream, MemoryView View) {
|
||||
static void display(MemoryView View) {
|
||||
for (auto C : View) {
|
||||
Stream << ' ';
|
||||
display(Stream, C);
|
||||
tlog << ' ';
|
||||
display(C);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryMatcher::explainError(testutils::StreamWrapper &Stream) {
|
||||
void MemoryMatcher::explainError() {
|
||||
if (mismatch_size) {
|
||||
Stream << "Size mismatch :";
|
||||
Stream << "expected : ";
|
||||
Stream << expected.size();
|
||||
Stream << '\n';
|
||||
Stream << "actual : ";
|
||||
Stream << actual.size();
|
||||
Stream << '\n';
|
||||
tlog << "Size mismatch :";
|
||||
tlog << "expected : ";
|
||||
tlog << expected.size();
|
||||
tlog << '\n';
|
||||
tlog << "actual : ";
|
||||
tlog << actual.size();
|
||||
tlog << '\n';
|
||||
} else {
|
||||
Stream << "Mismatch at position : ";
|
||||
Stream << mismatch_index;
|
||||
Stream << " / ";
|
||||
Stream << expected.size();
|
||||
Stream << "\n";
|
||||
Stream << "expected :";
|
||||
display(Stream, expected);
|
||||
Stream << '\n';
|
||||
Stream << "actual :";
|
||||
display(Stream, actual);
|
||||
Stream << '\n';
|
||||
tlog << "Mismatch at position : ";
|
||||
tlog << mismatch_index;
|
||||
tlog << " / ";
|
||||
tlog << expected.size();
|
||||
tlog << "\n";
|
||||
tlog << "expected :";
|
||||
display(expected);
|
||||
tlog << '\n';
|
||||
tlog << "actual :";
|
||||
display(actual);
|
||||
tlog << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
|
||||
bool match(MemoryView actualValue);
|
||||
|
||||
void explainError(testutils::StreamWrapper &stream) override;
|
||||
void explainError() override;
|
||||
};
|
||||
|
||||
} // namespace __llvm_libc::memory::testing
|
||||
|
||||
@@ -12,9 +12,12 @@
|
||||
#include "src/stdio/printf_core/core_structs.h"
|
||||
|
||||
#include "test/UnitTest/StringUtils.h"
|
||||
#include "test/UnitTest/Test.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
using __llvm_libc::testing::tlog;
|
||||
|
||||
namespace __llvm_libc {
|
||||
namespace printf_core {
|
||||
namespace testing {
|
||||
@@ -29,30 +32,30 @@ namespace {
|
||||
#define IF_FLAG_SHOW_FLAG(flag_name) \
|
||||
do { \
|
||||
if ((form.flags & FormatFlags::flag_name) == FormatFlags::flag_name) \
|
||||
stream << "\n\t\t" << #flag_name; \
|
||||
tlog << "\n\t\t" << #flag_name; \
|
||||
} while (false)
|
||||
#define CASE_LM(lm) \
|
||||
case (LengthModifier::lm): \
|
||||
stream << #lm; \
|
||||
tlog << #lm; \
|
||||
break
|
||||
|
||||
void display(testutils::StreamWrapper &stream, FormatSection form) {
|
||||
stream << "Raw String (len " << form.raw_string.size() << "): \"";
|
||||
static void display(FormatSection form) {
|
||||
tlog << "Raw String (len " << form.raw_string.size() << "): \"";
|
||||
for (size_t i = 0; i < form.raw_string.size(); ++i) {
|
||||
stream << form.raw_string[i];
|
||||
tlog << form.raw_string[i];
|
||||
}
|
||||
stream << "\"";
|
||||
tlog << "\"";
|
||||
if (form.has_conv) {
|
||||
stream << "\n\tHas Conv\n\tFlags:";
|
||||
tlog << "\n\tHas Conv\n\tFlags:";
|
||||
IF_FLAG_SHOW_FLAG(LEFT_JUSTIFIED);
|
||||
IF_FLAG_SHOW_FLAG(FORCE_SIGN);
|
||||
IF_FLAG_SHOW_FLAG(SPACE_PREFIX);
|
||||
IF_FLAG_SHOW_FLAG(ALTERNATE_FORM);
|
||||
IF_FLAG_SHOW_FLAG(LEADING_ZEROES);
|
||||
stream << "\n";
|
||||
stream << "\tmin width: " << form.min_width << "\n";
|
||||
stream << "\tprecision: " << form.precision << "\n";
|
||||
stream << "\tlength modifier: ";
|
||||
tlog << "\n";
|
||||
tlog << "\tmin width: " << form.min_width << "\n";
|
||||
tlog << "\tprecision: " << form.precision << "\n";
|
||||
tlog << "\tlength modifier: ";
|
||||
switch (form.length_modifier) {
|
||||
CASE_LM(none);
|
||||
CASE_LM(l);
|
||||
@@ -64,29 +67,29 @@ void display(testutils::StreamWrapper &stream, FormatSection form) {
|
||||
CASE_LM(t);
|
||||
CASE_LM(L);
|
||||
}
|
||||
stream << "\n";
|
||||
stream << "\tconversion name: " << form.conv_name << "\n";
|
||||
tlog << "\n";
|
||||
tlog << "\tconversion name: " << form.conv_name << "\n";
|
||||
if (form.conv_name == 'p' || form.conv_name == 'n' || form.conv_name == 's')
|
||||
stream << "\tpointer value: "
|
||||
<< int_to_hex<uintptr_t>(
|
||||
reinterpret_cast<uintptr_t>(form.conv_val_ptr))
|
||||
<< "\n";
|
||||
tlog << "\tpointer value: "
|
||||
<< int_to_hex<uintptr_t>(
|
||||
reinterpret_cast<uintptr_t>(form.conv_val_ptr))
|
||||
<< "\n";
|
||||
else if (form.conv_name != '%')
|
||||
stream << "\tvalue: "
|
||||
<< int_to_hex<fputil::FPBits<long double>::UIntType>(
|
||||
form.conv_val_raw)
|
||||
<< "\n";
|
||||
tlog << "\tvalue: "
|
||||
<< int_to_hex<fputil::FPBits<long double>::UIntType>(
|
||||
form.conv_val_raw)
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
void FormatSectionMatcher::explainError(testutils::StreamWrapper &stream) {
|
||||
stream << "expected format section: ";
|
||||
display(stream, expected);
|
||||
stream << '\n';
|
||||
stream << "actual format section : ";
|
||||
display(stream, actual);
|
||||
stream << '\n';
|
||||
void FormatSectionMatcher::explainError() {
|
||||
tlog << "expected format section: ";
|
||||
display(expected);
|
||||
tlog << '\n';
|
||||
tlog << "actual format section : ";
|
||||
display(actual);
|
||||
tlog << '\n';
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
|
||||
bool match(FormatSection actualValue);
|
||||
|
||||
void explainError(testutils::StreamWrapper &stream) override;
|
||||
void explainError() override;
|
||||
};
|
||||
|
||||
} // namespace testing
|
||||
|
||||
@@ -12,9 +12,12 @@
|
||||
#include "src/stdio/scanf_core/core_structs.h"
|
||||
|
||||
#include "test/UnitTest/StringUtils.h"
|
||||
#include "test/UnitTest/Test.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
using __llvm_libc::testing::tlog;
|
||||
|
||||
namespace __llvm_libc {
|
||||
namespace scanf_core {
|
||||
namespace testing {
|
||||
@@ -29,26 +32,26 @@ namespace {
|
||||
#define IF_FLAG_SHOW_FLAG(flag_name) \
|
||||
do { \
|
||||
if ((form.flags & FormatFlags::flag_name) == FormatFlags::flag_name) \
|
||||
stream << "\n\t\t" << #flag_name; \
|
||||
tlog << "\n\t\t" << #flag_name; \
|
||||
} while (false)
|
||||
#define CASE_LM(lm) \
|
||||
case (LengthModifier::lm): \
|
||||
stream << #lm; \
|
||||
tlog << #lm; \
|
||||
break
|
||||
|
||||
void display(testutils::StreamWrapper &stream, FormatSection form) {
|
||||
stream << "Raw String (len " << form.raw_string.size() << "): \"";
|
||||
void display(FormatSection form) {
|
||||
tlog << "Raw String (len " << form.raw_string.size() << "): \"";
|
||||
for (size_t i = 0; i < form.raw_string.size(); ++i) {
|
||||
stream << form.raw_string[i];
|
||||
tlog << form.raw_string[i];
|
||||
}
|
||||
stream << "\"";
|
||||
tlog << "\"";
|
||||
if (form.has_conv) {
|
||||
stream << "\n\tHas Conv\n\tFlags:";
|
||||
tlog << "\n\tHas Conv\n\tFlags:";
|
||||
IF_FLAG_SHOW_FLAG(NO_WRITE);
|
||||
IF_FLAG_SHOW_FLAG(ALLOCATE);
|
||||
stream << "\n";
|
||||
stream << "\tmax width: " << form.max_width << "\n";
|
||||
stream << "\tlength modifier: ";
|
||||
tlog << "\n";
|
||||
tlog << "\tmax width: " << form.max_width << "\n";
|
||||
tlog << "\tlength modifier: ";
|
||||
switch (form.length_modifier) {
|
||||
CASE_LM(NONE);
|
||||
CASE_LM(l);
|
||||
@@ -60,38 +63,38 @@ void display(testutils::StreamWrapper &stream, FormatSection form) {
|
||||
CASE_LM(t);
|
||||
CASE_LM(L);
|
||||
}
|
||||
stream << "\n";
|
||||
tlog << "\n";
|
||||
// If the pointer is used (NO_WRITE is not set and the conversion isn't %).
|
||||
if (((form.flags & FormatFlags::NO_WRITE) == 0) &&
|
||||
(form.conv_name != '%')) {
|
||||
stream << "\tpointer value: "
|
||||
<< int_to_hex<uintptr_t>(
|
||||
reinterpret_cast<uintptr_t>(form.output_ptr))
|
||||
<< "\n";
|
||||
tlog << "\tpointer value: "
|
||||
<< int_to_hex<uintptr_t>(
|
||||
reinterpret_cast<uintptr_t>(form.output_ptr))
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
stream << "\tconversion name: " << form.conv_name << "\n";
|
||||
tlog << "\tconversion name: " << form.conv_name << "\n";
|
||||
|
||||
if (form.conv_name == '[') {
|
||||
stream << "\t\t";
|
||||
tlog << "\t\t";
|
||||
for (size_t i = 0; i < 256 /* char max */; ++i) {
|
||||
if (form.scan_set.test(i)) {
|
||||
stream << static_cast<char>(i);
|
||||
tlog << static_cast<char>(i);
|
||||
}
|
||||
}
|
||||
stream << "\n\t]\n";
|
||||
tlog << "\n\t]\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
void FormatSectionMatcher::explainError(testutils::StreamWrapper &stream) {
|
||||
stream << "expected format section: ";
|
||||
display(stream, expected);
|
||||
stream << '\n';
|
||||
stream << "actual format section : ";
|
||||
display(stream, actual);
|
||||
stream << '\n';
|
||||
void FormatSectionMatcher::explainError() {
|
||||
tlog << "expected format section: ";
|
||||
display(expected);
|
||||
tlog << '\n';
|
||||
tlog << "actual format section : ";
|
||||
display(actual);
|
||||
tlog << '\n';
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
|
||||
bool match(FormatSection actualValue);
|
||||
|
||||
void explainError(testutils::StreamWrapper &stream) override;
|
||||
void explainError() override;
|
||||
};
|
||||
|
||||
} // namespace testing
|
||||
|
||||
@@ -9,24 +9,26 @@
|
||||
#ifndef LLVM_LIBC_UTILS_UNITTEST_SIMPLE_STRING_CONV_H
|
||||
#define LLVM_LIBC_UTILS_UNITTEST_SIMPLE_STRING_CONV_H
|
||||
|
||||
#include "src/__support/CPP/string.h"
|
||||
#include "src/__support/CPP/type_traits.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
// Return the first N hex digits of an integer as a string in upper case.
|
||||
template <typename T>
|
||||
cpp::enable_if_t<cpp::is_integral_v<T>, std::string>
|
||||
int_to_hex(T X, size_t Length = sizeof(T) * 2) {
|
||||
std::string s(Length, '0');
|
||||
cpp::enable_if_t<cpp::is_integral_v<T>, cpp::string>
|
||||
int_to_hex(T value, size_t length = sizeof(T) * 2) {
|
||||
cpp::string s(length, '0');
|
||||
|
||||
for (auto it = s.rbegin(), end = s.rend(); it != end; ++it, X >>= 4) {
|
||||
unsigned char Mod = static_cast<unsigned char>(X) & 15;
|
||||
*it = (Mod < 10 ? '0' + Mod : 'a' + Mod - 10);
|
||||
constexpr char HEXADECIMALS[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
for (size_t i = 0; i < length; i += 2, value >>= 8) {
|
||||
unsigned char mod = static_cast<unsigned char>(value) & 0xFF;
|
||||
s[length - i] = HEXADECIMALS[mod & 0x0F];
|
||||
s[length - (i + 1)] = HEXADECIMALS[mod & 0x0F];
|
||||
}
|
||||
|
||||
return s;
|
||||
return "0x" + s;
|
||||
}
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include "test/UnitTest/TestLogger.h"
|
||||
#include "src/__support/CPP/string.h"
|
||||
#include "src/__support/CPP/string_view.h"
|
||||
#include "src/__support/OSUtil/io.h" //write_to_stderr
|
||||
#include "src/__support/OSUtil/io.h" // write_to_stderr
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace __llvm_libc {
|
||||
namespace testing {
|
||||
@@ -23,11 +25,21 @@ template <> TestLogger &TestLogger::operator<< <const char *>(const char *str) {
|
||||
return *this << cpp::string_view(str);
|
||||
}
|
||||
|
||||
// char* specialization
|
||||
template <> TestLogger &TestLogger::operator<< <char *>(char *str) {
|
||||
return *this << cpp::string_view(str);
|
||||
}
|
||||
|
||||
// char specialization
|
||||
template <> TestLogger &TestLogger::operator<<(char ch) {
|
||||
return *this << cpp::string_view(&ch, 1);
|
||||
}
|
||||
|
||||
// void * specialization
|
||||
template <> TestLogger &TestLogger::operator<<(void *addr) {
|
||||
return *this << "0x" << cpp::to_string(reinterpret_cast<uintptr_t>(addr));
|
||||
}
|
||||
|
||||
template <typename T> TestLogger &TestLogger::operator<<(T t) {
|
||||
return *this << cpp::to_string(t);
|
||||
}
|
||||
|
||||
@@ -12,14 +12,12 @@
|
||||
#include "test/UnitTest/FPMatcher.h"
|
||||
#include "test/UnitTest/Test.h"
|
||||
#include "utils/MPFRWrapper/MPFRUtils.h"
|
||||
#include "utils/testutils/StreamWrapper.h"
|
||||
#include <math.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace mpfr = __llvm_libc::testing::mpfr;
|
||||
auto outs = __llvm_libc::testutils::outs();
|
||||
|
||||
DECLARE_SPECIAL_CONSTANTS(double)
|
||||
|
||||
@@ -104,23 +102,16 @@ TEST(LlvmLibcLog10Test, InDoubleRange) {
|
||||
}
|
||||
}
|
||||
}
|
||||
outs << " Log10 failed: " << fails << "/" << count << "/" << cc
|
||||
<< " tests.\n";
|
||||
outs << " Max ULPs is at most: " << tol << ".\n";
|
||||
if (fails) {
|
||||
EXPECT_MPFR_MATCH(mpfr::Operation::Log10, mx, mr, 0.5, rounding_mode);
|
||||
}
|
||||
};
|
||||
|
||||
outs << " Test Rounding To Nearest...\n";
|
||||
test(mpfr::RoundingMode::Nearest);
|
||||
|
||||
outs << " Test Rounding Downward...\n";
|
||||
test(mpfr::RoundingMode::Downward);
|
||||
|
||||
outs << " Test Rounding Upward...\n";
|
||||
test(mpfr::RoundingMode::Upward);
|
||||
|
||||
outs << " Test Rounding Toward Zero...\n";
|
||||
test(mpfr::RoundingMode::TowardZero);
|
||||
}
|
||||
|
||||
@@ -37,24 +37,23 @@ public:
|
||||
actual.tm_isdst == expected.tm_isdst);
|
||||
}
|
||||
|
||||
void describeValue(const char *label, ::tm value,
|
||||
__llvm_libc::testutils::StreamWrapper &stream) {
|
||||
stream << label;
|
||||
stream << " sec: " << value.tm_sec;
|
||||
stream << " min: " << value.tm_min;
|
||||
stream << " hour: " << value.tm_hour;
|
||||
stream << " mday: " << value.tm_mday;
|
||||
stream << " mon: " << value.tm_mon;
|
||||
stream << " year: " << value.tm_year;
|
||||
stream << " wday: " << value.tm_wday;
|
||||
stream << " yday: " << value.tm_yday;
|
||||
stream << " isdst: " << value.tm_isdst;
|
||||
stream << '\n';
|
||||
void describeValue(const char *label, ::tm value) {
|
||||
__llvm_libc::testing::tlog << label;
|
||||
__llvm_libc::testing::tlog << " sec: " << value.tm_sec;
|
||||
__llvm_libc::testing::tlog << " min: " << value.tm_min;
|
||||
__llvm_libc::testing::tlog << " hour: " << value.tm_hour;
|
||||
__llvm_libc::testing::tlog << " mday: " << value.tm_mday;
|
||||
__llvm_libc::testing::tlog << " mon: " << value.tm_mon;
|
||||
__llvm_libc::testing::tlog << " year: " << value.tm_year;
|
||||
__llvm_libc::testing::tlog << " wday: " << value.tm_wday;
|
||||
__llvm_libc::testing::tlog << " yday: " << value.tm_yday;
|
||||
__llvm_libc::testing::tlog << " isdst: " << value.tm_isdst;
|
||||
__llvm_libc::testing::tlog << '\n';
|
||||
}
|
||||
|
||||
void explainError(__llvm_libc::testutils::StreamWrapper &stream) override {
|
||||
describeValue("Expected tm_struct value: ", expected, stream);
|
||||
describeValue(" Actual tm_struct value: ", actual, stream);
|
||||
void explainError() override {
|
||||
describeValue("Expected tm_struct value: ", expected);
|
||||
describeValue(" Actual tm_struct value: ", actual);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "MPFRUtils.h"
|
||||
|
||||
#include "src/__support/CPP/string.h"
|
||||
#include "src/__support/CPP/string_view.h"
|
||||
#include "src/__support/FPUtil/FPBits.h"
|
||||
#include "src/__support/FPUtil/PlatformDefs.h"
|
||||
@@ -16,9 +17,7 @@
|
||||
#include <cmath>
|
||||
#include <fenv.h>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef CUSTOM_MPFR_INCLUDER
|
||||
// Some downstream repos are monoliths carrying MPFR sources in their third
|
||||
@@ -417,7 +416,7 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string str() const {
|
||||
cpp::string str() const {
|
||||
// 200 bytes should be more than sufficient to hold a 100-digit number
|
||||
// plus additional bytes for the decimal point, '-' sign etc.
|
||||
constexpr size_t printBufSize = 200;
|
||||
@@ -430,7 +429,7 @@ public:
|
||||
view.remove_prefix(1);
|
||||
while (!view.empty() && view.back() == whitespace)
|
||||
view.remove_suffix(1);
|
||||
return std::string(view.data());
|
||||
return cpp::string(view.data());
|
||||
}
|
||||
|
||||
// These functions are useful for debugging.
|
||||
@@ -463,15 +462,16 @@ public:
|
||||
// of N between this number and [input].
|
||||
// 4. A values of +0.0 and -0.0 are treated as equal.
|
||||
template <typename T>
|
||||
cpp::enable_if_t<cpp::is_floating_point_v<T>, double> ulp(T input) {
|
||||
cpp::enable_if_t<cpp::is_floating_point_v<T>, MPFRNumber>
|
||||
ulp_as_mpfr_number(T input) {
|
||||
T thisAsT = as<T>();
|
||||
if (thisAsT == input)
|
||||
return T(0.0);
|
||||
return MPFRNumber(0.0);
|
||||
|
||||
if (is_nan()) {
|
||||
if (fputil::FPBits<T>(input).is_nan())
|
||||
return T(0.0);
|
||||
return T(fputil::FPBits<T>::inf());
|
||||
return MPFRNumber(0.0);
|
||||
return MPFRNumber(static_cast<T>(fputil::FPBits<T>::inf()));
|
||||
}
|
||||
|
||||
int thisExponent = fputil::FPBits<T>(thisAsT).get_exponent();
|
||||
@@ -489,7 +489,7 @@ public:
|
||||
mpfr_mul_2si(inputMPFR.value, inputMPFR.value,
|
||||
-thisExponent + int(fputil::MantissaWidth<T>::VALUE),
|
||||
MPFR_RNDN);
|
||||
return inputMPFR.as<double>();
|
||||
return inputMPFR;
|
||||
}
|
||||
|
||||
// If the control reaches here, it means that this number and input are
|
||||
@@ -524,7 +524,20 @@ public:
|
||||
MPFR_RNDN);
|
||||
|
||||
mpfr_add(minMPFR.value, minMPFR.value, maxMPFR.value, MPFR_RNDN);
|
||||
return minMPFR.as<double>();
|
||||
return minMPFR;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
cpp::enable_if_t<cpp::is_floating_point_v<T>, cpp::string>
|
||||
ulp_as_string(T input) {
|
||||
MPFRNumber num = ulp_as_mpfr_number(input);
|
||||
return num.str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
cpp::enable_if_t<cpp::is_floating_point_v<T>, double> ulp(T input) {
|
||||
MPFRNumber num = ulp_as_mpfr_number(input);
|
||||
return num.as<double>();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -682,93 +695,84 @@ template <typename T>
|
||||
void explain_unary_operation_single_output_error(Operation op, T input,
|
||||
T matchValue,
|
||||
double ulp_tolerance,
|
||||
RoundingMode rounding,
|
||||
testutils::StreamWrapper &OS) {
|
||||
RoundingMode rounding) {
|
||||
unsigned int precision = get_precision<T>(ulp_tolerance);
|
||||
MPFRNumber mpfrInput(input, precision);
|
||||
MPFRNumber mpfr_result;
|
||||
mpfr_result = unary_operation(op, input, precision, rounding);
|
||||
MPFRNumber mpfrMatchValue(matchValue);
|
||||
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, ss);
|
||||
ss << '\n' << " Match decimal: " << mpfrMatchValue.str() << '\n';
|
||||
__llvm_libc::fputil::testing::describeValue(" Match bits: ", matchValue,
|
||||
ss);
|
||||
ss << '\n' << " MPFR result: " << mpfr_result.str() << '\n';
|
||||
__llvm_libc::fputil::testing::describeValue(
|
||||
" MPFR rounded: ", mpfr_result.as<T>(), ss);
|
||||
ss << '\n';
|
||||
ss << " ULP error: " << std::to_string(mpfr_result.ulp(matchValue))
|
||||
<< '\n';
|
||||
OS << ss.str();
|
||||
tlog << "Match value not within tolerance value of MPFR result:\n"
|
||||
<< " Input decimal: " << mpfrInput.str() << '\n';
|
||||
__llvm_libc::fputil::testing::describeValue(" Input bits: ", input);
|
||||
tlog << '\n' << " Match decimal: " << mpfrMatchValue.str() << '\n';
|
||||
__llvm_libc::fputil::testing::describeValue(" Match bits: ", matchValue);
|
||||
tlog << '\n' << " MPFR result: " << mpfr_result.str() << '\n';
|
||||
__llvm_libc::fputil::testing::describeValue(" MPFR rounded: ",
|
||||
mpfr_result.as<T>());
|
||||
tlog << '\n';
|
||||
tlog << " ULP error: "
|
||||
<< mpfr_result.ulp_as_mpfr_number(matchValue).str() << '\n';
|
||||
}
|
||||
|
||||
template void
|
||||
explain_unary_operation_single_output_error<float>(Operation op, float, float,
|
||||
double, RoundingMode,
|
||||
testutils::StreamWrapper &);
|
||||
template void explain_unary_operation_single_output_error<float>(Operation op,
|
||||
float, float,
|
||||
double,
|
||||
RoundingMode);
|
||||
template void explain_unary_operation_single_output_error<double>(
|
||||
Operation op, double, double, double, RoundingMode,
|
||||
testutils::StreamWrapper &);
|
||||
Operation op, double, double, double, RoundingMode);
|
||||
template void explain_unary_operation_single_output_error<long double>(
|
||||
Operation op, long double, long double, double, RoundingMode,
|
||||
testutils::StreamWrapper &);
|
||||
Operation op, long double, long double, double, RoundingMode);
|
||||
|
||||
template <typename T>
|
||||
void explain_unary_operation_two_outputs_error(
|
||||
Operation op, T input, const BinaryOutput<T> &libc_result,
|
||||
double ulp_tolerance, RoundingMode rounding, testutils::StreamWrapper &OS) {
|
||||
double ulp_tolerance, RoundingMode rounding) {
|
||||
unsigned int precision = get_precision<T>(ulp_tolerance);
|
||||
MPFRNumber mpfrInput(input, precision);
|
||||
int mpfrIntResult;
|
||||
MPFRNumber mpfr_result = unary_operation_two_outputs(op, input, mpfrIntResult,
|
||||
precision, rounding);
|
||||
std::stringstream ss;
|
||||
|
||||
if (mpfrIntResult != libc_result.i) {
|
||||
ss << "MPFR integral result: " << mpfrIntResult << '\n'
|
||||
<< "Libc integral result: " << libc_result.i << '\n';
|
||||
tlog << "MPFR integral result: " << mpfrIntResult << '\n'
|
||||
<< "Libc integral result: " << libc_result.i << '\n';
|
||||
} else {
|
||||
ss << "Integral result from libc matches integral result from MPFR.\n";
|
||||
tlog << "Integral result from libc matches integral result from MPFR.\n";
|
||||
}
|
||||
|
||||
MPFRNumber mpfrMatchValue(libc_result.f);
|
||||
ss << "Libc floating point result is not within tolerance value of the MPFR "
|
||||
<< "result.\n\n";
|
||||
tlog
|
||||
<< "Libc floating point result is not within tolerance value of the MPFR "
|
||||
<< "result.\n\n";
|
||||
|
||||
ss << " Input decimal: " << mpfrInput.str() << "\n\n";
|
||||
tlog << " Input decimal: " << mpfrInput.str() << "\n\n";
|
||||
|
||||
ss << "Libc floating point value: " << mpfrMatchValue.str() << '\n';
|
||||
__llvm_libc::fputil::testing::describeValue(
|
||||
" Libc floating point bits: ", libc_result.f, ss);
|
||||
ss << "\n\n";
|
||||
tlog << "Libc floating point value: " << mpfrMatchValue.str() << '\n';
|
||||
__llvm_libc::fputil::testing::describeValue(" Libc floating point bits: ",
|
||||
libc_result.f);
|
||||
tlog << "\n\n";
|
||||
|
||||
ss << " MPFR result: " << mpfr_result.str() << '\n';
|
||||
__llvm_libc::fputil::testing::describeValue(
|
||||
" MPFR rounded: ", mpfr_result.as<T>(), ss);
|
||||
ss << '\n'
|
||||
<< " ULP error: "
|
||||
<< std::to_string(mpfr_result.ulp(libc_result.f)) << '\n';
|
||||
OS << ss.str();
|
||||
tlog << " MPFR result: " << mpfr_result.str() << '\n';
|
||||
__llvm_libc::fputil::testing::describeValue(" MPFR rounded: ",
|
||||
mpfr_result.as<T>());
|
||||
tlog << '\n'
|
||||
<< " ULP error: "
|
||||
<< mpfr_result.ulp_as_mpfr_number(libc_result.f).str() << '\n';
|
||||
}
|
||||
|
||||
template void explain_unary_operation_two_outputs_error<float>(
|
||||
Operation, float, const BinaryOutput<float> &, double, RoundingMode,
|
||||
testutils::StreamWrapper &);
|
||||
Operation, float, const BinaryOutput<float> &, double, RoundingMode);
|
||||
template void explain_unary_operation_two_outputs_error<double>(
|
||||
Operation, double, const BinaryOutput<double> &, double, RoundingMode,
|
||||
testutils::StreamWrapper &);
|
||||
Operation, double, const BinaryOutput<double> &, double, RoundingMode);
|
||||
template void explain_unary_operation_two_outputs_error<long double>(
|
||||
Operation, long double, const BinaryOutput<long double> &, double,
|
||||
RoundingMode, testutils::StreamWrapper &);
|
||||
RoundingMode);
|
||||
|
||||
template <typename T>
|
||||
void explain_binary_operation_two_outputs_error(
|
||||
Operation op, const BinaryInput<T> &input,
|
||||
const BinaryOutput<T> &libc_result, double ulp_tolerance,
|
||||
RoundingMode rounding, testutils::StreamWrapper &OS) {
|
||||
RoundingMode rounding) {
|
||||
unsigned int precision = get_precision<T>(ulp_tolerance);
|
||||
MPFRNumber mpfrX(input.x, precision);
|
||||
MPFRNumber mpfrY(input.y, precision);
|
||||
@@ -776,36 +780,36 @@ 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;
|
||||
|
||||
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';
|
||||
tlog << "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, ss);
|
||||
"Libc floating point result bits: ", libc_result.f);
|
||||
__llvm_libc::fputil::testing::describeValue(
|
||||
" MPFR rounded bits: ", mpfr_result.as<T>(), ss);
|
||||
ss << "ULP error: " << std::to_string(mpfr_result.ulp(libc_result.f)) << '\n';
|
||||
OS << ss.str();
|
||||
" MPFR rounded bits: ", mpfr_result.as<T>());
|
||||
tlog << "ULP error: " << mpfr_result.ulp_as_mpfr_number(libc_result.f).str()
|
||||
<< '\n';
|
||||
}
|
||||
|
||||
template void explain_binary_operation_two_outputs_error<float>(
|
||||
Operation, const BinaryInput<float> &, const BinaryOutput<float> &, double,
|
||||
RoundingMode, testutils::StreamWrapper &);
|
||||
RoundingMode);
|
||||
template void explain_binary_operation_two_outputs_error<double>(
|
||||
Operation, const BinaryInput<double> &, const BinaryOutput<double> &,
|
||||
double, RoundingMode, testutils::StreamWrapper &);
|
||||
double, RoundingMode);
|
||||
template void explain_binary_operation_two_outputs_error<long double>(
|
||||
Operation, const BinaryInput<long double> &,
|
||||
const BinaryOutput<long double> &, double, RoundingMode,
|
||||
testutils::StreamWrapper &);
|
||||
const BinaryOutput<long double> &, double, RoundingMode);
|
||||
|
||||
template <typename T>
|
||||
void explain_binary_operation_one_output_error(
|
||||
Operation op, const BinaryInput<T> &input, T libc_result,
|
||||
double ulp_tolerance, RoundingMode rounding, testutils::StreamWrapper &OS) {
|
||||
void explain_binary_operation_one_output_error(Operation op,
|
||||
const BinaryInput<T> &input,
|
||||
T libc_result,
|
||||
double ulp_tolerance,
|
||||
RoundingMode rounding) {
|
||||
unsigned int precision = get_precision<T>(ulp_tolerance);
|
||||
MPFRNumber mpfrX(input.x, precision);
|
||||
MPFRNumber mpfrY(input.y, precision);
|
||||
@@ -814,38 +818,35 @@ 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;
|
||||
|
||||
ss << "Input decimal: x: " << mpfrX.str() << " y: " << mpfrY.str() << '\n';
|
||||
__llvm_libc::fputil::testing::describeValue("First input bits: ", input.x,
|
||||
ss);
|
||||
__llvm_libc::fputil::testing::describeValue("Second input bits: ", input.y,
|
||||
ss);
|
||||
tlog << "Input decimal: x: " << mpfrX.str() << " y: " << mpfrY.str() << '\n';
|
||||
__llvm_libc::fputil::testing::describeValue("First input bits: ", input.x);
|
||||
__llvm_libc::fputil::testing::describeValue("Second input bits: ", input.y);
|
||||
|
||||
ss << "Libc result: " << mpfrMatchValue.str() << '\n'
|
||||
<< "MPFR result: " << mpfr_result.str() << '\n';
|
||||
tlog << "Libc result: " << mpfrMatchValue.str() << '\n'
|
||||
<< "MPFR result: " << mpfr_result.str() << '\n';
|
||||
__llvm_libc::fputil::testing::describeValue(
|
||||
"Libc floating point result bits: ", libc_result, ss);
|
||||
"Libc floating point result bits: ", libc_result);
|
||||
__llvm_libc::fputil::testing::describeValue(
|
||||
" MPFR rounded bits: ", mpfr_result.as<T>(), ss);
|
||||
ss << "ULP error: " << std::to_string(mpfr_result.ulp(libc_result)) << '\n';
|
||||
OS << ss.str();
|
||||
" MPFR rounded bits: ", mpfr_result.as<T>());
|
||||
tlog << "ULP error: " << mpfr_result.ulp_as_mpfr_number(libc_result).str()
|
||||
<< '\n';
|
||||
}
|
||||
|
||||
template void explain_binary_operation_one_output_error<float>(
|
||||
Operation, const BinaryInput<float> &, float, double, RoundingMode,
|
||||
testutils::StreamWrapper &);
|
||||
Operation, const BinaryInput<float> &, float, double, RoundingMode);
|
||||
template void explain_binary_operation_one_output_error<double>(
|
||||
Operation, const BinaryInput<double> &, double, double, RoundingMode,
|
||||
testutils::StreamWrapper &);
|
||||
Operation, const BinaryInput<double> &, double, double, RoundingMode);
|
||||
template void explain_binary_operation_one_output_error<long double>(
|
||||
Operation, const BinaryInput<long double> &, long double, double,
|
||||
RoundingMode, testutils::StreamWrapper &);
|
||||
RoundingMode);
|
||||
|
||||
template <typename T>
|
||||
void explain_ternary_operation_one_output_error(
|
||||
Operation op, const TernaryInput<T> &input, T libc_result,
|
||||
double ulp_tolerance, RoundingMode rounding, testutils::StreamWrapper &OS) {
|
||||
void explain_ternary_operation_one_output_error(Operation op,
|
||||
const TernaryInput<T> &input,
|
||||
T libc_result,
|
||||
double ulp_tolerance,
|
||||
RoundingMode rounding) {
|
||||
unsigned int precision = get_precision<T>(ulp_tolerance);
|
||||
MPFRNumber mpfrX(input.x, precision);
|
||||
MPFRNumber mpfrY(input.y, precision);
|
||||
@@ -856,36 +857,30 @@ 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;
|
||||
|
||||
ss << "Input decimal: x: " << mpfrX.str() << " y: " << mpfrY.str()
|
||||
<< " z: " << mpfrZ.str() << '\n';
|
||||
__llvm_libc::fputil::testing::describeValue("First input bits: ", input.x,
|
||||
ss);
|
||||
__llvm_libc::fputil::testing::describeValue("Second input bits: ", input.y,
|
||||
ss);
|
||||
__llvm_libc::fputil::testing::describeValue("Third input bits: ", input.z,
|
||||
ss);
|
||||
tlog << "Input decimal: x: " << mpfrX.str() << " y: " << mpfrY.str()
|
||||
<< " z: " << mpfrZ.str() << '\n';
|
||||
__llvm_libc::fputil::testing::describeValue("First input bits: ", input.x);
|
||||
__llvm_libc::fputil::testing::describeValue("Second input bits: ", input.y);
|
||||
__llvm_libc::fputil::testing::describeValue("Third input bits: ", input.z);
|
||||
|
||||
ss << "Libc result: " << mpfrMatchValue.str() << '\n'
|
||||
<< "MPFR result: " << mpfr_result.str() << '\n';
|
||||
tlog << "Libc result: " << mpfrMatchValue.str() << '\n'
|
||||
<< "MPFR result: " << mpfr_result.str() << '\n';
|
||||
__llvm_libc::fputil::testing::describeValue(
|
||||
"Libc floating point result bits: ", libc_result, ss);
|
||||
"Libc floating point result bits: ", libc_result);
|
||||
__llvm_libc::fputil::testing::describeValue(
|
||||
" MPFR rounded bits: ", mpfr_result.as<T>(), ss);
|
||||
ss << "ULP error: " << std::to_string(mpfr_result.ulp(libc_result)) << '\n';
|
||||
OS << ss.str();
|
||||
" MPFR rounded bits: ", mpfr_result.as<T>());
|
||||
tlog << "ULP error: " << mpfr_result.ulp_as_mpfr_number(libc_result).str()
|
||||
<< '\n';
|
||||
}
|
||||
|
||||
template void explain_ternary_operation_one_output_error<float>(
|
||||
Operation, const TernaryInput<float> &, float, double, RoundingMode,
|
||||
testutils::StreamWrapper &);
|
||||
Operation, const TernaryInput<float> &, float, double, RoundingMode);
|
||||
template void explain_ternary_operation_one_output_error<double>(
|
||||
Operation, const TernaryInput<double> &, double, double, RoundingMode,
|
||||
testutils::StreamWrapper &);
|
||||
Operation, const TernaryInput<double> &, double, double, RoundingMode);
|
||||
template void explain_ternary_operation_one_output_error<long double>(
|
||||
Operation, const TernaryInput<long double> &, long double, double,
|
||||
RoundingMode, testutils::StreamWrapper &);
|
||||
RoundingMode);
|
||||
|
||||
template <typename T>
|
||||
bool compare_unary_operation_single_output(Operation op, T input, T libc_result,
|
||||
|
||||
@@ -156,27 +156,30 @@ template <typename T>
|
||||
void explain_unary_operation_single_output_error(Operation op, T input,
|
||||
T match_value,
|
||||
double ulp_tolerance,
|
||||
RoundingMode rounding,
|
||||
testutils::StreamWrapper &OS);
|
||||
RoundingMode rounding);
|
||||
template <typename T>
|
||||
void explain_unary_operation_two_outputs_error(
|
||||
Operation op, T input, const BinaryOutput<T> &match_value,
|
||||
double ulp_tolerance, RoundingMode rounding, testutils::StreamWrapper &OS);
|
||||
double ulp_tolerance, RoundingMode rounding);
|
||||
template <typename T>
|
||||
void explain_binary_operation_two_outputs_error(
|
||||
Operation op, const BinaryInput<T> &input,
|
||||
const BinaryOutput<T> &match_value, double ulp_tolerance,
|
||||
RoundingMode rounding, testutils::StreamWrapper &OS);
|
||||
RoundingMode rounding);
|
||||
|
||||
template <typename T>
|
||||
void explain_binary_operation_one_output_error(
|
||||
Operation op, const BinaryInput<T> &input, T match_value,
|
||||
double ulp_tolerance, RoundingMode rounding, testutils::StreamWrapper &OS);
|
||||
void explain_binary_operation_one_output_error(Operation op,
|
||||
const BinaryInput<T> &input,
|
||||
T match_value,
|
||||
double ulp_tolerance,
|
||||
RoundingMode rounding);
|
||||
|
||||
template <typename T>
|
||||
void explain_ternary_operation_one_output_error(
|
||||
Operation op, const TernaryInput<T> &input, T match_value,
|
||||
double ulp_tolerance, RoundingMode rounding, testutils::StreamWrapper &OS);
|
||||
void explain_ternary_operation_one_output_error(Operation op,
|
||||
const TernaryInput<T> &input,
|
||||
T match_value,
|
||||
double ulp_tolerance,
|
||||
RoundingMode rounding);
|
||||
|
||||
template <Operation op, bool silent, typename InputType, typename OutputType>
|
||||
class MPFRMatcher : public testing::Matcher<OutputType> {
|
||||
@@ -196,8 +199,8 @@ public:
|
||||
|
||||
// This method is marked with NOLINT because it the name `explainError`
|
||||
// does not confirm to the coding style.
|
||||
void explainError(testutils::StreamWrapper &OS) override { // NOLINT
|
||||
explain_error(input, match_value, OS);
|
||||
void explainError() override { // NOLINT
|
||||
explain_error(input, match_value);
|
||||
}
|
||||
|
||||
// Whether the `explainError` step is skipped or not.
|
||||
@@ -230,38 +233,30 @@ private:
|
||||
rounding);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void explain_error(T in, T out, testutils::StreamWrapper &OS) {
|
||||
template <typename T> void explain_error(T in, T out) {
|
||||
explain_unary_operation_single_output_error(op, in, out, ulp_tolerance,
|
||||
rounding, OS);
|
||||
rounding);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void explain_error(T in, const BinaryOutput<T> &out,
|
||||
testutils::StreamWrapper &OS) {
|
||||
template <typename T> void explain_error(T in, const BinaryOutput<T> &out) {
|
||||
explain_unary_operation_two_outputs_error(op, in, out, ulp_tolerance,
|
||||
rounding, OS);
|
||||
rounding);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void explain_error(const BinaryInput<T> &in, const BinaryOutput<T> &out,
|
||||
testutils::StreamWrapper &OS) {
|
||||
void explain_error(const BinaryInput<T> &in, const BinaryOutput<T> &out) {
|
||||
explain_binary_operation_two_outputs_error(op, in, out, ulp_tolerance,
|
||||
rounding, OS);
|
||||
rounding);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void explain_error(const BinaryInput<T> &in, T out,
|
||||
testutils::StreamWrapper &OS) {
|
||||
template <typename T> void explain_error(const BinaryInput<T> &in, T out) {
|
||||
explain_binary_operation_one_output_error(op, in, out, ulp_tolerance,
|
||||
rounding, OS);
|
||||
rounding);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void explain_error(const TernaryInput<T> &in, T out,
|
||||
testutils::StreamWrapper &OS) {
|
||||
template <typename T> void explain_error(const TernaryInput<T> &in, T out) {
|
||||
explain_ternary_operation_one_output_error(op, in, out, ulp_tolerance,
|
||||
rounding, OS);
|
||||
rounding);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ endif()
|
||||
|
||||
add_library(
|
||||
libc_test_utils
|
||||
StreamWrapper.cpp
|
||||
StreamWrapper.h
|
||||
${EFFile}
|
||||
ExecuteFunction.h
|
||||
${FDReaderFile}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
//===-- StreamWrapper.cpp -------------------------------------------------===//
|
||||
//
|
||||
// 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 "StreamWrapper.h"
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace __llvm_libc {
|
||||
namespace testutils {
|
||||
|
||||
StreamWrapper outs() { return {std::addressof(std::cout)}; }
|
||||
|
||||
template <typename T> StreamWrapper &StreamWrapper::operator<<(T t) {
|
||||
assert(os);
|
||||
std::ostream &Stream = *reinterpret_cast<std::ostream *>(os);
|
||||
Stream << t;
|
||||
Stream.flush();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template StreamWrapper &StreamWrapper::operator<<<void *>(void *t);
|
||||
template StreamWrapper &StreamWrapper::operator<<<const char *>(const char *t);
|
||||
template StreamWrapper &StreamWrapper::operator<<<char *>(char *t);
|
||||
template StreamWrapper &StreamWrapper::operator<<<char>(char t);
|
||||
template StreamWrapper &StreamWrapper::operator<<<short>(short t);
|
||||
template StreamWrapper &StreamWrapper::operator<<<int>(int t);
|
||||
template StreamWrapper &StreamWrapper::operator<<<long>(long t);
|
||||
template StreamWrapper &StreamWrapper::operator<<<long long>(long long t);
|
||||
template StreamWrapper &
|
||||
StreamWrapper::operator<<<unsigned char>(unsigned char t);
|
||||
template StreamWrapper &
|
||||
StreamWrapper::operator<<<unsigned short>(unsigned short t);
|
||||
template StreamWrapper &StreamWrapper::operator<<<unsigned int>(unsigned int t);
|
||||
template StreamWrapper &
|
||||
StreamWrapper::operator<<<unsigned long>(unsigned long t);
|
||||
template StreamWrapper &
|
||||
StreamWrapper::operator<<<unsigned long long>(unsigned long long t);
|
||||
template StreamWrapper &StreamWrapper::operator<<<bool>(bool t);
|
||||
template StreamWrapper &StreamWrapper::operator<<<std::string>(std::string t);
|
||||
template StreamWrapper &StreamWrapper::operator<<<float>(float t);
|
||||
template StreamWrapper &StreamWrapper::operator<<<double>(double t);
|
||||
|
||||
OutputFileStream::OutputFileStream(const char *FN)
|
||||
: StreamWrapper(new std::ofstream(FN)) {}
|
||||
|
||||
OutputFileStream::~OutputFileStream() {
|
||||
delete reinterpret_cast<std::ofstream *>(os);
|
||||
}
|
||||
|
||||
} // namespace testutils
|
||||
} // namespace __llvm_libc
|
||||
@@ -1,39 +0,0 @@
|
||||
//===-- StreamWrapper.h -----------------------------------------*- 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_UTILS_TESTUTILS_STREAMWRAPPER_H
|
||||
#define LLVM_LIBC_UTILS_TESTUTILS_STREAMWRAPPER_H
|
||||
|
||||
namespace __llvm_libc {
|
||||
namespace testutils {
|
||||
|
||||
// StreamWrapper is necessary because llvm/Support/raw_ostream.h includes
|
||||
// standard headers so we must provide streams through indirection to not
|
||||
// expose the system libc headers.
|
||||
class StreamWrapper {
|
||||
protected:
|
||||
void *os;
|
||||
|
||||
public:
|
||||
StreamWrapper(void *OS) : os(OS) {}
|
||||
|
||||
template <typename T> StreamWrapper &operator<<(T t);
|
||||
};
|
||||
|
||||
StreamWrapper outs();
|
||||
|
||||
class OutputFileStream : public StreamWrapper {
|
||||
public:
|
||||
explicit OutputFileStream(const char *FN);
|
||||
~OutputFileStream();
|
||||
};
|
||||
|
||||
} // namespace testutils
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_UTILS_TESTUTILS_STREAMWRAPPER_H
|
||||
@@ -50,7 +50,6 @@ cc_library(
|
||||
name = "fp_test_helpers",
|
||||
srcs = [
|
||||
"FPExceptMatcher.cpp",
|
||||
"FPMatcher.cpp",
|
||||
],
|
||||
hdrs = [
|
||||
"FPExceptMatcher.h",
|
||||
|
||||
@@ -12,13 +12,11 @@ cc_library(
|
||||
"ExecuteFunctionUnix.cpp",
|
||||
"FDReaderUnix.cpp",
|
||||
"RoundingModeUtils.cpp",
|
||||
"StreamWrapper.cpp",
|
||||
],
|
||||
hdrs = [
|
||||
"ExecuteFunction.h",
|
||||
"FDReader.h",
|
||||
"RoundingModeUtils.h",
|
||||
"StreamWrapper.h",
|
||||
],
|
||||
deps = [
|
||||
"//libc:libc_root",
|
||||
|
||||
Reference in New Issue
Block a user