[libc-commits] [libc] [libc][math] Add MPFR tests for fmul (PR #96413)
Job Henandez Lara via libc-commits
libc-commits at lists.llvm.org
Sat Jun 22 17:55:15 PDT 2024
https://github.com/Jobhdez updated https://github.com/llvm/llvm-project/pull/96413
>From ec2d4df1b600801a77b662b947d5c8326fbe86aa Mon Sep 17 00:00:00 2001
From: Job Hernandez <hj93 at protonmail.com>
Date: Fri, 21 Jun 2024 11:21:09 -0700
Subject: [PATCH 1/7] add mpfr tests
---
libc/test/src/math/CMakeLists.txt | 12 +++++
libc/test/src/math/FMulTest.h | 73 ++++++++++++++++++++++++++++
libc/test/src/math/fmul_test.cpp | 13 +++++
libc/test/src/math/smoke/FMulTest.h | 47 +++++++++++++++++-
libc/utils/MPFRWrapper/MPFRUtils.cpp | 8 +++
libc/utils/MPFRWrapper/MPFRUtils.h | 1 +
6 files changed, 153 insertions(+), 1 deletion(-)
create mode 100644 libc/test/src/math/FMulTest.h
create mode 100644 libc/test/src/math/fmul_test.cpp
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index bb364c3f0a175..6e6da9f0cef14 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -1729,6 +1729,18 @@ add_fp_unittest(
libc.src.__support.FPUtil.fp_bits
)
+add_fp_unittest(
+ fmul_test
+ NEED_MPFR
+ SUITE
+ libc-math-unittests
+ SRCS
+ fmul_test.cpp
+ HDRS
+ FMulTest.h
+ DEPENDS
+ libc.src.math.fmul
+)
add_fp_unittest(
asinhf_test
NEED_MPFR
diff --git a/libc/test/src/math/FMulTest.h b/libc/test/src/math/FMulTest.h
new file mode 100644
index 0000000000000..0f5dc2e40de10
--- /dev/null
+++ b/libc/test/src/math/FMulTest.h
@@ -0,0 +1,73 @@
+//===-- Utility class to test fmul[f|l] ---------------------*- 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_TEST_SRC_MATH_FMULTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_FMULTEST_H
+
+#include "test/UnitTest/FEnvSafeTest.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+template <typename T, typename R>
+class FmulMPFRTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*FMulFunc)(R, R);
+
+ void testFMulMPFR(FMulFunc func) {
+ constexpr int N = 10;
+ mpfr::BinaryInput<T> INPUTS[N] = {
+ {3.0, 5.0}, {0x1.0p1, 0x1.0p-131}, {0x1.0p2, 0x1.0p-129},
+ {1.0,1.0}, {-0.0, -0.0}, {-0.0, 0.0}, {0.0, -0.0},
+ {0x1.0p100, 0x1.0p100},
+ {1.0, 1.0 + 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150},
+ {1.0, 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150}
+ };
+
+ for (int i = 0; i < N; ++i) {
+ T x = INPUTS[i].x;
+ T y = INPUTS[i].y;
+ ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fmul, INPUTS[i], func(x,y), 0.5);
+ }
+ }
+
+ void testSpecialInputsMPFR(FMulFunc func) {
+ constexpr int N = 27;
+ mpfr::BinaryInput<T> INPUTS[N] = {
+ {inf, 0x1.0p-129}, {0x1.0p-129, inf}, {inf, 2.0}, {3.0, inf}, {0.0, 0.0},
+ {neg_inf, aNaN}, {aNaN, neg_inf}, {neg_inf, neg_inf},
+ {0.0, neg_inf}, {neg_inf, 0.0},
+ {neg_inf, 1.0}, {1.0, neg_inf},
+ {neg_inf, 0x1.0p-129}, {0x1.0p-129, neg_inf},
+ {0.0, 0x1.0p-129}, {inf, 0.0}, {0.0, inf},
+ {0.0, aNaN}, {2.0, aNaN}, {0x1.0p-129, aNaN}, {inf, aNaN}, {aNaN, aNaN},
+ {0.0, sNaN}, {2.0, sNaN}, {0x1.0p-129, sNaN}, {inf, sNaN}, {sNaN, sNaN}
+ };
+
+
+ for (int i = 0; i < N; ++i) {
+ T x = INPUTS[i].x;
+ T y = INPUTS[i].y;
+ ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fmul, INPUTS[i], func(x, y), 0.5);
+ }
+}
+
+};
+
+#define LIST_FMUL_MPFR_TESTS(T, R, func) \
+ using LlvmLibcFmulTest = FmulMPFRTest<T, R>; \
+ TEST_F(LlvmLibcFmulTest, MulMpfr) { testFMulMPFR(&func); } \
+ TEST_F(LlvmLibcFmulTest, NanInfMpfr) { testSpecialInputsMPFR(&func); }
+
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_FMULTEST_H
diff --git a/libc/test/src/math/fmul_test.cpp b/libc/test/src/math/fmul_test.cpp
new file mode 100644
index 0000000000000..16eaa1a818daf
--- /dev/null
+++ b/libc/test/src/math/fmul_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fmul-------------------------------------------------===//
+//
+// 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 "FMulTest.h"
+
+#include "src/math/fmul.h"
+
+LIST_FMUL_MPFR_TESTS(float, double, LIBC_NAMESPACE::fmul)
diff --git a/libc/test/src/math/smoke/FMulTest.h b/libc/test/src/math/smoke/FMulTest.h
index 33fb82c8d2da1..40d4b4d930326 100644
--- a/libc/test/src/math/smoke/FMulTest.h
+++ b/libc/test/src/math/smoke/FMulTest.h
@@ -12,6 +12,9 @@
#include "test/UnitTest/FEnvSafeTest.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
template <typename T, typename R>
class FmulTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
@@ -94,11 +97,53 @@ class FmulTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(inf, sNaN));
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(sNaN, sNaN));
}
+
+ void testMPFR(FMulFunc func) {
+ constexpr int N = 10;
+ mpfr::BinaryInput<T> INPUTS[N] = {
+ {3.0, 5.0}, {0x1.0p1, 0x1.0p-131}, {0x1.0p2, 0x1.0p-129},
+ {1.0,1.0}, {-0.0, -0.0}, {-0.0, 0.0}, {0.0, -0.0},
+ {0x1.0p100, 0x1.0p100},
+ {1.0, 1.0 + 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150},
+ {1.0, 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150}
+ };
+
+ for (int i = 0; i < N; ++i) {
+ T x = INPUTS[i].x;
+ T y = INPUTS[i].y;
+ ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fmul, INPUTS[i], LIBC_NAMESPACE::fmul(x,y), 0.5);
+ }
+ }
+
+ void testSpecialInputsMPFR(FMulFunc func) {
+ constexpr int N = 27;
+ mpfr::BinaryInput<T> INPUTS[N] = {
+ {inf, 0x1.0p-129}, {0x1.0p-129, inf}, {inf, 2.0}, {3.0, inf}, {0.0, 0.0},
+ {neg_inf, aNaN}, {aNaN, neg_inf}, {neg_inf, neg_inf},
+ {0.0, neg_inf}, {neg_inf, 0.0},
+ {neg_inf, 1.0}, {1.0, neg_inf},
+ {neg_inf, 0x1.0p-129}, {0x1.0p-129, neg_inf},
+ {0.0, 0x1.0p-129}, {inf, 0.0}, {0.0, inf},
+ {0.0, aNaN}, {2.0, aNaN}, {0x1.0p-129, aNaN}, {inf, aNaN}, {aNaN, aNaN},
+ {0.0, sNaN}, {2.0, sNaN}, {0x1.0p-129, sNaN}, {inf, sNaN}, {sNaN, sNaN}
+ };
+
+
+ for (int i = 0; i < N; ++i) {
+ T x = INPUTS[i].x;
+ T y = INPUTS[i].y;
+ ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fmul, INPUTS[i], LIBC_NAMESPACE::fmul(x, y), 0.5);
+ }
+}
+
};
#define LIST_FMUL_TESTS(T, R, func) \
using LlvmLibcFmulTest = FmulTest<T, R>; \
TEST_F(LlvmLibcFmulTest, Mul) { testMul(&func); } \
- TEST_F(LlvmLibcFmulTest, NaNInf) { testSpecialInputs(&func); }
+ TEST_F(LlvmLibcFmulTest, NaNInf) { testSpecialInputs(&func); } \
+ TEST_F(LlvmLibcFmulTest, MulMpfr) { testMPFR(&func); } \
+ TEST_F(LlvmLibcFmulTest, NanInfMpfr) { testSpecialInputsMPFR(&func); }
+
#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMULTEST_H
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp
index 2eac4dd8e199d..5aa37c035b32f 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.cpp
+++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp
@@ -467,6 +467,12 @@ class MPFRNumber {
return result;
}
+ MPFRNumber fmul(const MPFRNumber &b) {
+ MPFRNumber result(*this);
+ mpfr_mul(result.value, value, b.value, mpfr_rounding);
+ return result;
+ }
+
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.
@@ -714,6 +720,8 @@ binary_operation_one_output(Operation op, InputType x, InputType y,
return inputX.hypot(inputY);
case Operation::Pow:
return inputX.pow(inputY);
+ case Operation::Fmul:
+ return inputX.fmul(inputY);
default:
__builtin_unreachable();
}
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.h b/libc/utils/MPFRWrapper/MPFRUtils.h
index 0b4f42a72ec81..8e9a770834df9 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.h
+++ b/libc/utils/MPFRWrapper/MPFRUtils.h
@@ -41,6 +41,7 @@ enum class Operation : int {
Exp10,
Expm1,
Floor,
+ Fmul,
Log,
Log2,
Log10,
>From f228088b075d0b10536f1be97bf9552d1d966589 Mon Sep 17 00:00:00 2001
From: Job Hernandez <hj93 at protonmail.com>
Date: Fri, 21 Jun 2024 20:22:57 -0700
Subject: [PATCH 2/7] update
---
libc/utils/MPFRWrapper/MPFRUtils.cpp | 8 ++++----
libc/utils/MPFRWrapper/MPFRUtils.h | 14 +++++++-------
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp
index 5aa37c035b32f..18d0d7a853029 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.cpp
+++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp
@@ -893,10 +893,10 @@ template void explain_binary_operation_two_outputs_error<long double>(
Operation, const BinaryInput<long double> &,
const BinaryOutput<long double> &, double, RoundingMode);
-template <typename T>
+ template <typename T, typename R>
void explain_binary_operation_one_output_error(Operation op,
const BinaryInput<T> &input,
- T libc_result,
+ R libc_result,
double ulp_tolerance,
RoundingMode rounding) {
unsigned int precision = get_precision<T>(ulp_tolerance);
@@ -1059,10 +1059,10 @@ template bool compare_binary_operation_two_outputs<long double>(
Operation, const BinaryInput<long double> &,
const BinaryOutput<long double> &, double, RoundingMode);
-template <typename T>
+ template <typename T, typename R>
bool compare_binary_operation_one_output(Operation op,
const BinaryInput<T> &input,
- T libc_result, double ulp_tolerance,
+ R libc_result, double ulp_tolerance,
RoundingMode rounding) {
unsigned int precision = get_precision<T>(ulp_tolerance);
MPFRNumber mpfr_result =
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.h b/libc/utils/MPFRWrapper/MPFRUtils.h
index 8e9a770834df9..e4b0cdbd57219 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.h
+++ b/libc/utils/MPFRWrapper/MPFRUtils.h
@@ -153,17 +153,17 @@ bool compare_unary_operation_two_outputs(Operation op, T input,
const BinaryOutput<T> &libc_output,
double ulp_tolerance,
RoundingMode rounding);
-template <typename T>
+ template <typename T>
bool compare_binary_operation_two_outputs(Operation op,
const BinaryInput<T> &input,
const BinaryOutput<T> &libc_output,
double ulp_tolerance,
RoundingMode rounding);
-template <typename T>
+ template <typename T, typename R>
bool compare_binary_operation_one_output(Operation op,
const BinaryInput<T> &input,
- T libc_output, double ulp_tolerance,
+ R libc_output, double ulp_tolerance,
RoundingMode rounding);
template <typename InputType, typename OutputType>
@@ -188,10 +188,10 @@ void explain_binary_operation_two_outputs_error(
const BinaryOutput<T> &match_value, double ulp_tolerance,
RoundingMode rounding);
-template <typename T>
+ template <typename T, typename R>
void explain_binary_operation_one_output_error(Operation op,
const BinaryInput<T> &input,
- T match_value,
+ R match_value,
double ulp_tolerance,
RoundingMode rounding);
@@ -236,7 +236,7 @@ class MPFRMatcher : public testing::Matcher<OutputType> {
rounding);
}
- template <typename T> bool match(const BinaryInput<T> &in, T out) {
+ template <typename T, typename R> bool match(const BinaryInput<T> &in, R out) {
return compare_binary_operation_one_output(op, in, out, ulp_tolerance,
rounding);
}
@@ -269,7 +269,7 @@ class MPFRMatcher : public testing::Matcher<OutputType> {
rounding);
}
- template <typename T> void explain_error(const BinaryInput<T> &in, T out) {
+ template <typename T, typename R> void explain_error(const BinaryInput<T> &in, R out) {
explain_binary_operation_one_output_error(op, in, out, ulp_tolerance,
rounding);
}
>From 731ed7653b248fc2dd5690f6024100f31c8e7a22 Mon Sep 17 00:00:00 2001
From: Job Hernandez <hj93 at protonmail.com>
Date: Fri, 21 Jun 2024 21:40:31 -0700
Subject: [PATCH 3/7] update
---
libc/utils/MPFRWrapper/MPFRUtils.cpp | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp
index 18d0d7a853029..bf48483aad42f 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.cpp
+++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp
@@ -914,19 +914,19 @@ void explain_binary_operation_one_output_error(Operation op,
tlog << "Libc result: " << mpfrMatchValue.str() << '\n'
<< "MPFR result: " << mpfr_result.str() << '\n';
- tlog << "Libc floating point result bits: " << str(FPBits<T>(libc_result))
+ tlog << "Libc floating point result bits: " << str(FPBits<R>(libc_result))
<< '\n';
tlog << " MPFR rounded bits: "
- << str(FPBits<T>(mpfr_result.as<T>())) << '\n';
+ << str(FPBits<R>(mpfr_result.as<R>())) << '\n';
tlog << "ULP error: " << mpfr_result.ulp_as_mpfr_number(libc_result).str()
<< '\n';
}
-template void explain_binary_operation_one_output_error<float>(
+template void explain_binary_operation_one_output_error(
Operation, const BinaryInput<float> &, float, double, RoundingMode);
-template void explain_binary_operation_one_output_error<double>(
- Operation, const BinaryInput<double> &, double, double, RoundingMode);
-template void explain_binary_operation_one_output_error<long double>(
+template void explain_binary_operation_one_output_error(
+ Operation, const BinaryInput<double> &, float, double, RoundingMode);
+template void explain_binary_operation_one_output_error(
Operation, const BinaryInput<long double> &, long double, double,
RoundingMode);
@@ -1072,11 +1072,11 @@ bool compare_binary_operation_one_output(Operation op,
return (ulp <= ulp_tolerance);
}
-template bool compare_binary_operation_one_output<float>(
+template bool compare_binary_operation_one_output(
Operation, const BinaryInput<float> &, float, double, RoundingMode);
-template bool compare_binary_operation_one_output<double>(
- Operation, const BinaryInput<double> &, double, double, RoundingMode);
-template bool compare_binary_operation_one_output<long double>(
+template bool compare_binary_operation_one_output(
+ Operation, const BinaryInput<double> &, float, double, RoundingMode);
+template bool compare_binary_operation_one_output(
Operation, const BinaryInput<long double> &, long double, double,
RoundingMode);
>From c3b5973617f438cb5a17c38a0e9b0c8062a214fd Mon Sep 17 00:00:00 2001
From: Job Hernandez <hj93 at protonmail.com>
Date: Sat, 22 Jun 2024 08:41:57 -0700
Subject: [PATCH 4/7] update
---
libc/utils/MPFRWrapper/MPFRUtils.cpp | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp
index bf48483aad42f..095f2244c2362 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.cpp
+++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp
@@ -899,7 +899,7 @@ void explain_binary_operation_one_output_error(Operation op,
R libc_result,
double ulp_tolerance,
RoundingMode rounding) {
- unsigned int precision = get_precision<T>(ulp_tolerance);
+ unsigned int precision = get_precision<R>(ulp_tolerance);
MPFRNumber mpfrX(input.x, precision);
MPFRNumber mpfrY(input.y, precision);
FPBits<T> xbits(input.x);
@@ -924,6 +924,8 @@ void explain_binary_operation_one_output_error(Operation op,
template void explain_binary_operation_one_output_error(
Operation, const BinaryInput<float> &, float, double, RoundingMode);
+template void explain_binary_operation_one_output_error(
+ Operation, const BinaryInput<double> &, double, double, RoundingMode);
template void explain_binary_operation_one_output_error(
Operation, const BinaryInput<double> &, float, double, RoundingMode);
template void explain_binary_operation_one_output_error(
@@ -1064,7 +1066,7 @@ bool compare_binary_operation_one_output(Operation op,
const BinaryInput<T> &input,
R libc_result, double ulp_tolerance,
RoundingMode rounding) {
- unsigned int precision = get_precision<T>(ulp_tolerance);
+ unsigned int precision = get_precision<R>(ulp_tolerance);
MPFRNumber mpfr_result =
binary_operation_one_output(op, input.x, input.y, precision, rounding);
double ulp = mpfr_result.ulp(libc_result);
@@ -1074,6 +1076,8 @@ bool compare_binary_operation_one_output(Operation op,
template bool compare_binary_operation_one_output(
Operation, const BinaryInput<float> &, float, double, RoundingMode);
+template bool compare_binary_operation_one_output(
+ Operation, const BinaryInput<double> &, double, double, RoundingMode);
template bool compare_binary_operation_one_output(
Operation, const BinaryInput<double> &, float, double, RoundingMode);
template bool compare_binary_operation_one_output(
>From 19d5e6b604bce877732b19bbca1ecd9eb348c856 Mon Sep 17 00:00:00 2001
From: Job Hernandez <hj93 at protonmail.com>
Date: Sat, 22 Jun 2024 09:55:31 -0700
Subject: [PATCH 5/7] update
---
libc/test/src/math/FMulTest.h | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/libc/test/src/math/FMulTest.h b/libc/test/src/math/FMulTest.h
index 0f5dc2e40de10..b2fec1f856c5a 100644
--- a/libc/test/src/math/FMulTest.h
+++ b/libc/test/src/math/FMulTest.h
@@ -16,17 +16,17 @@
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
-template <typename T, typename R>
+template <typename OutType, typename InType>
class FmulMPFRTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
- DECLARE_SPECIAL_CONSTANTS(T)
+ DECLARE_SPECIAL_CONSTANTS(InType)
public:
- typedef T (*FMulFunc)(R, R);
+ typedef OutType (*FMulFunc)(InType, InType);
void testFMulMPFR(FMulFunc func) {
constexpr int N = 10;
- mpfr::BinaryInput<T> INPUTS[N] = {
+ mpfr::BinaryInput<InType> INPUTS[N] = {
{3.0, 5.0}, {0x1.0p1, 0x1.0p-131}, {0x1.0p2, 0x1.0p-129},
{1.0,1.0}, {-0.0, -0.0}, {-0.0, 0.0}, {0.0, -0.0},
{0x1.0p100, 0x1.0p100},
@@ -35,15 +35,15 @@ class FmulMPFRTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
};
for (int i = 0; i < N; ++i) {
- T x = INPUTS[i].x;
- T y = INPUTS[i].y;
+ InType x = INPUTS[i].x;
+ InType y = INPUTS[i].y;
ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fmul, INPUTS[i], func(x,y), 0.5);
}
}
void testSpecialInputsMPFR(FMulFunc func) {
constexpr int N = 27;
- mpfr::BinaryInput<T> INPUTS[N] = {
+ mpfr::BinaryInput<InType> INPUTS[N] = {
{inf, 0x1.0p-129}, {0x1.0p-129, inf}, {inf, 2.0}, {3.0, inf}, {0.0, 0.0},
{neg_inf, aNaN}, {aNaN, neg_inf}, {neg_inf, neg_inf},
{0.0, neg_inf}, {neg_inf, 0.0},
@@ -56,16 +56,16 @@ class FmulMPFRTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
for (int i = 0; i < N; ++i) {
- T x = INPUTS[i].x;
- T y = INPUTS[i].y;
+ InType x = INPUTS[i].x;
+ InType y = INPUTS[i].y;
ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fmul, INPUTS[i], func(x, y), 0.5);
}
}
};
-#define LIST_FMUL_MPFR_TESTS(T, R, func) \
- using LlvmLibcFmulTest = FmulMPFRTest<T, R>; \
+#define LIST_FMUL_MPFR_TESTS(OutType, InType, func) \
+ using LlvmLibcFmulTest = FmulMPFRTest<OutType, InType>; \
TEST_F(LlvmLibcFmulTest, MulMpfr) { testFMulMPFR(&func); } \
TEST_F(LlvmLibcFmulTest, NanInfMpfr) { testSpecialInputsMPFR(&func); }
>From 6b95664e012822884303bd319dd1e6194b393844 Mon Sep 17 00:00:00 2001
From: Job Hernandez <hj93 at protonmail.com>
Date: Sat, 22 Jun 2024 17:52:38 -0700
Subject: [PATCH 6/7] tests pass!
---
libc/utils/MPFRWrapper/MPFRUtils.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.h b/libc/utils/MPFRWrapper/MPFRUtils.h
index e4b0cdbd57219..0789a241e4020 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.h
+++ b/libc/utils/MPFRWrapper/MPFRUtils.h
@@ -294,7 +294,8 @@ constexpr bool is_valid_operation() {
(op == Operation::Fma && internal::IsTernaryInput<InputType>::VALUE &&
cpp::is_floating_point_v<
typename internal::MakeScalarInput<InputType>::type> &&
- cpp::is_floating_point_v<OutputType>);
+ cpp::is_floating_point_v<OutputType>) ||
+ (op == Operation::Fmul && !internal::AreMatchingBinaryInputAndBinaryOutput<InputType, OutputType>::VALUE);
if (IS_NARROWING_OP)
return true;
return (Operation::BeginUnaryOperationsSingleOutput < op &&
@@ -309,6 +310,10 @@ constexpr bool is_valid_operation() {
op < Operation::EndBinaryOperationsSingleOutput &&
cpp::is_floating_point_v<OutputType> &&
cpp::is_same_v<InputType, BinaryInput<OutputType>>) ||
+ (Operation::BeginBinaryOperationsSingleOutput < op &&
+ op < Operation::EndBinaryOperationsSingleOutput &&
+ cpp::is_floating_point_v<OutputType> &&
+ !cpp::is_same_v<InputType, BinaryInput<OutputType>>) ||
(Operation::BeginBinaryOperationsTwoOutputs < op &&
op < Operation::EndBinaryOperationsTwoOutputs &&
internal::AreMatchingBinaryInputAndBinaryOutput<InputType,
>From 9da903541a9fd62dc215b57012a3c08867b3e75e Mon Sep 17 00:00:00 2001
From: Job Hernandez <hj93 at protonmail.com>
Date: Sat, 22 Jun 2024 17:54:58 -0700
Subject: [PATCH 7/7] format code
---
libc/test/src/math/FMulTest.h | 92 +++++++++++++++++-----------
libc/test/src/math/smoke/FMulTest.h | 88 ++++++++++++++++----------
libc/utils/MPFRWrapper/MPFRUtils.cpp | 37 ++++++-----
libc/utils/MPFRWrapper/MPFRUtils.h | 16 +++--
4 files changed, 141 insertions(+), 92 deletions(-)
diff --git a/libc/test/src/math/FMulTest.h b/libc/test/src/math/FMulTest.h
index b2fec1f856c5a..02428e149fc10 100644
--- a/libc/test/src/math/FMulTest.h
+++ b/libc/test/src/math/FMulTest.h
@@ -24,50 +24,70 @@ class FmulMPFRTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
public:
typedef OutType (*FMulFunc)(InType, InType);
- void testFMulMPFR(FMulFunc func) {
- constexpr int N = 10;
- mpfr::BinaryInput<InType> INPUTS[N] = {
- {3.0, 5.0}, {0x1.0p1, 0x1.0p-131}, {0x1.0p2, 0x1.0p-129},
- {1.0,1.0}, {-0.0, -0.0}, {-0.0, 0.0}, {0.0, -0.0},
- {0x1.0p100, 0x1.0p100},
- {1.0, 1.0 + 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150},
- {1.0, 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150}
- };
+ void testFMulMPFR(FMulFunc func) {
+ constexpr int N = 10;
+ mpfr::BinaryInput<InType> INPUTS[N] = {
+ {3.0, 5.0},
+ {0x1.0p1, 0x1.0p-131},
+ {0x1.0p2, 0x1.0p-129},
+ {1.0, 1.0},
+ {-0.0, -0.0},
+ {-0.0, 0.0},
+ {0.0, -0.0},
+ {0x1.0p100, 0x1.0p100},
+ {1.0, 1.0 + 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150},
+ {1.0, 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150}};
- for (int i = 0; i < N; ++i) {
- InType x = INPUTS[i].x;
- InType y = INPUTS[i].y;
- ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fmul, INPUTS[i], func(x,y), 0.5);
- }
- }
+ for (int i = 0; i < N; ++i) {
+ InType x = INPUTS[i].x;
+ InType y = INPUTS[i].y;
+ ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fmul, INPUTS[i],
+ func(x, y), 0.5);
+ }
+ }
void testSpecialInputsMPFR(FMulFunc func) {
constexpr int N = 27;
- mpfr::BinaryInput<InType> INPUTS[N] = {
- {inf, 0x1.0p-129}, {0x1.0p-129, inf}, {inf, 2.0}, {3.0, inf}, {0.0, 0.0},
- {neg_inf, aNaN}, {aNaN, neg_inf}, {neg_inf, neg_inf},
- {0.0, neg_inf}, {neg_inf, 0.0},
- {neg_inf, 1.0}, {1.0, neg_inf},
- {neg_inf, 0x1.0p-129}, {0x1.0p-129, neg_inf},
- {0.0, 0x1.0p-129}, {inf, 0.0}, {0.0, inf},
- {0.0, aNaN}, {2.0, aNaN}, {0x1.0p-129, aNaN}, {inf, aNaN}, {aNaN, aNaN},
- {0.0, sNaN}, {2.0, sNaN}, {0x1.0p-129, sNaN}, {inf, sNaN}, {sNaN, sNaN}
- };
-
+ mpfr::BinaryInput<InType> INPUTS[N] = {{inf, 0x1.0p-129},
+ {0x1.0p-129, inf},
+ {inf, 2.0},
+ {3.0, inf},
+ {0.0, 0.0},
+ {neg_inf, aNaN},
+ {aNaN, neg_inf},
+ {neg_inf, neg_inf},
+ {0.0, neg_inf},
+ {neg_inf, 0.0},
+ {neg_inf, 1.0},
+ {1.0, neg_inf},
+ {neg_inf, 0x1.0p-129},
+ {0x1.0p-129, neg_inf},
+ {0.0, 0x1.0p-129},
+ {inf, 0.0},
+ {0.0, inf},
+ {0.0, aNaN},
+ {2.0, aNaN},
+ {0x1.0p-129, aNaN},
+ {inf, aNaN},
+ {aNaN, aNaN},
+ {0.0, sNaN},
+ {2.0, sNaN},
+ {0x1.0p-129, sNaN},
+ {inf, sNaN},
+ {sNaN, sNaN}};
for (int i = 0; i < N; ++i) {
- InType x = INPUTS[i].x;
- InType y = INPUTS[i].y;
- ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fmul, INPUTS[i], func(x, y), 0.5);
+ InType x = INPUTS[i].x;
+ InType y = INPUTS[i].y;
+ ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fmul, INPUTS[i],
+ func(x, y), 0.5);
}
-}
-
+ }
};
-#define LIST_FMUL_MPFR_TESTS(OutType, InType, func) \
- using LlvmLibcFmulTest = FmulMPFRTest<OutType, InType>; \
- TEST_F(LlvmLibcFmulTest, MulMpfr) { testFMulMPFR(&func); } \
- TEST_F(LlvmLibcFmulTest, NanInfMpfr) { testSpecialInputsMPFR(&func); }
-
+#define LIST_FMUL_MPFR_TESTS(OutType, InType, func) \
+ using LlvmLibcFmulTest = FmulMPFRTest<OutType, InType>; \
+ TEST_F(LlvmLibcFmulTest, MulMpfr) { testFMulMPFR(&func); } \
+ TEST_F(LlvmLibcFmulTest, NanInfMpfr) { testSpecialInputsMPFR(&func); }
#endif // LLVM_LIBC_TEST_SRC_MATH_FMULTEST_H
diff --git a/libc/test/src/math/smoke/FMulTest.h b/libc/test/src/math/smoke/FMulTest.h
index 40d4b4d930326..066dce826bea0 100644
--- a/libc/test/src/math/smoke/FMulTest.h
+++ b/libc/test/src/math/smoke/FMulTest.h
@@ -98,44 +98,65 @@ class FmulTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(sNaN, sNaN));
}
- void testMPFR(FMulFunc func) {
- constexpr int N = 10;
- mpfr::BinaryInput<T> INPUTS[N] = {
- {3.0, 5.0}, {0x1.0p1, 0x1.0p-131}, {0x1.0p2, 0x1.0p-129},
- {1.0,1.0}, {-0.0, -0.0}, {-0.0, 0.0}, {0.0, -0.0},
- {0x1.0p100, 0x1.0p100},
- {1.0, 1.0 + 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150},
- {1.0, 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150}
- };
-
- for (int i = 0; i < N; ++i) {
- T x = INPUTS[i].x;
- T y = INPUTS[i].y;
- ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fmul, INPUTS[i], LIBC_NAMESPACE::fmul(x,y), 0.5);
- }
- }
+ void testMPFR(FMulFunc func) {
+ constexpr int N = 10;
+ mpfr::BinaryInput<T> INPUTS[N] = {
+ {3.0, 5.0},
+ {0x1.0p1, 0x1.0p-131},
+ {0x1.0p2, 0x1.0p-129},
+ {1.0, 1.0},
+ {-0.0, -0.0},
+ {-0.0, 0.0},
+ {0.0, -0.0},
+ {0x1.0p100, 0x1.0p100},
+ {1.0, 1.0 + 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150},
+ {1.0, 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150}};
+
+ for (int i = 0; i < N; ++i) {
+ T x = INPUTS[i].x;
+ T y = INPUTS[i].y;
+ ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fmul, INPUTS[i],
+ LIBC_NAMESPACE::fmul(x, y), 0.5);
+ }
+ }
void testSpecialInputsMPFR(FMulFunc func) {
constexpr int N = 27;
- mpfr::BinaryInput<T> INPUTS[N] = {
- {inf, 0x1.0p-129}, {0x1.0p-129, inf}, {inf, 2.0}, {3.0, inf}, {0.0, 0.0},
- {neg_inf, aNaN}, {aNaN, neg_inf}, {neg_inf, neg_inf},
- {0.0, neg_inf}, {neg_inf, 0.0},
- {neg_inf, 1.0}, {1.0, neg_inf},
- {neg_inf, 0x1.0p-129}, {0x1.0p-129, neg_inf},
- {0.0, 0x1.0p-129}, {inf, 0.0}, {0.0, inf},
- {0.0, aNaN}, {2.0, aNaN}, {0x1.0p-129, aNaN}, {inf, aNaN}, {aNaN, aNaN},
- {0.0, sNaN}, {2.0, sNaN}, {0x1.0p-129, sNaN}, {inf, sNaN}, {sNaN, sNaN}
- };
-
+ mpfr::BinaryInput<T> INPUTS[N] = {{inf, 0x1.0p-129},
+ {0x1.0p-129, inf},
+ {inf, 2.0},
+ {3.0, inf},
+ {0.0, 0.0},
+ {neg_inf, aNaN},
+ {aNaN, neg_inf},
+ {neg_inf, neg_inf},
+ {0.0, neg_inf},
+ {neg_inf, 0.0},
+ {neg_inf, 1.0},
+ {1.0, neg_inf},
+ {neg_inf, 0x1.0p-129},
+ {0x1.0p-129, neg_inf},
+ {0.0, 0x1.0p-129},
+ {inf, 0.0},
+ {0.0, inf},
+ {0.0, aNaN},
+ {2.0, aNaN},
+ {0x1.0p-129, aNaN},
+ {inf, aNaN},
+ {aNaN, aNaN},
+ {0.0, sNaN},
+ {2.0, sNaN},
+ {0x1.0p-129, sNaN},
+ {inf, sNaN},
+ {sNaN, sNaN}};
for (int i = 0; i < N; ++i) {
- T x = INPUTS[i].x;
- T y = INPUTS[i].y;
- ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fmul, INPUTS[i], LIBC_NAMESPACE::fmul(x, y), 0.5);
+ T x = INPUTS[i].x;
+ T y = INPUTS[i].y;
+ ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Fmul, INPUTS[i],
+ LIBC_NAMESPACE::fmul(x, y), 0.5);
}
-}
-
+ }
};
#define LIST_FMUL_TESTS(T, R, func) \
@@ -143,7 +164,6 @@ class FmulTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
TEST_F(LlvmLibcFmulTest, Mul) { testMul(&func); } \
TEST_F(LlvmLibcFmulTest, NaNInf) { testSpecialInputs(&func); } \
TEST_F(LlvmLibcFmulTest, MulMpfr) { testMPFR(&func); } \
- TEST_F(LlvmLibcFmulTest, NanInfMpfr) { testSpecialInputsMPFR(&func); }
-
+ TEST_F(LlvmLibcFmulTest, NanInfMpfr) { testSpecialInputsMPFR(&func); }
#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMULTEST_H
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp
index 095f2244c2362..ff16a1dabc841 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.cpp
+++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp
@@ -893,7 +893,7 @@ template void explain_binary_operation_two_outputs_error<long double>(
Operation, const BinaryInput<long double> &,
const BinaryOutput<long double> &, double, RoundingMode);
- template <typename T, typename R>
+template <typename T, typename R>
void explain_binary_operation_one_output_error(Operation op,
const BinaryInput<T> &input,
R libc_result,
@@ -922,15 +922,17 @@ void explain_binary_operation_one_output_error(Operation op,
<< '\n';
}
-template void explain_binary_operation_one_output_error(
- Operation, const BinaryInput<float> &, float, double, RoundingMode);
+template void
+explain_binary_operation_one_output_error(Operation, const BinaryInput<float> &,
+ float, double, RoundingMode);
template void explain_binary_operation_one_output_error(
Operation, const BinaryInput<double> &, double, double, RoundingMode);
template void explain_binary_operation_one_output_error(
Operation, const BinaryInput<double> &, float, double, RoundingMode);
-template void explain_binary_operation_one_output_error(
- Operation, const BinaryInput<long double> &, long double, double,
- RoundingMode);
+template void
+explain_binary_operation_one_output_error(Operation,
+ const BinaryInput<long double> &,
+ long double, double, RoundingMode);
template <typename InputType, typename OutputType>
void explain_ternary_operation_one_output_error(
@@ -1061,7 +1063,7 @@ template bool compare_binary_operation_two_outputs<long double>(
Operation, const BinaryInput<long double> &,
const BinaryOutput<long double> &, double, RoundingMode);
- template <typename T, typename R>
+template <typename T, typename R>
bool compare_binary_operation_one_output(Operation op,
const BinaryInput<T> &input,
R libc_result, double ulp_tolerance,
@@ -1074,15 +1076,18 @@ bool compare_binary_operation_one_output(Operation op,
return (ulp <= ulp_tolerance);
}
-template bool compare_binary_operation_one_output(
- Operation, const BinaryInput<float> &, float, double, RoundingMode);
-template bool compare_binary_operation_one_output(
- Operation, const BinaryInput<double> &, double, double, RoundingMode);
-template bool compare_binary_operation_one_output(
- Operation, const BinaryInput<double> &, float, double, RoundingMode);
-template bool compare_binary_operation_one_output(
- Operation, const BinaryInput<long double> &, long double, double,
- RoundingMode);
+template bool compare_binary_operation_one_output(Operation,
+ const BinaryInput<float> &,
+ float, double, RoundingMode);
+template bool compare_binary_operation_one_output(Operation,
+ const BinaryInput<double> &,
+ double, double, RoundingMode);
+template bool compare_binary_operation_one_output(Operation,
+ const BinaryInput<double> &,
+ float, double, RoundingMode);
+template bool
+compare_binary_operation_one_output(Operation, const BinaryInput<long double> &,
+ long double, double, RoundingMode);
template <typename InputType, typename OutputType>
bool compare_ternary_operation_one_output(Operation op,
diff --git a/libc/utils/MPFRWrapper/MPFRUtils.h b/libc/utils/MPFRWrapper/MPFRUtils.h
index 0789a241e4020..93572d7ea6661 100644
--- a/libc/utils/MPFRWrapper/MPFRUtils.h
+++ b/libc/utils/MPFRWrapper/MPFRUtils.h
@@ -153,14 +153,14 @@ bool compare_unary_operation_two_outputs(Operation op, T input,
const BinaryOutput<T> &libc_output,
double ulp_tolerance,
RoundingMode rounding);
- template <typename T>
+template <typename T>
bool compare_binary_operation_two_outputs(Operation op,
const BinaryInput<T> &input,
const BinaryOutput<T> &libc_output,
double ulp_tolerance,
RoundingMode rounding);
- template <typename T, typename R>
+template <typename T, typename R>
bool compare_binary_operation_one_output(Operation op,
const BinaryInput<T> &input,
R libc_output, double ulp_tolerance,
@@ -188,7 +188,7 @@ void explain_binary_operation_two_outputs_error(
const BinaryOutput<T> &match_value, double ulp_tolerance,
RoundingMode rounding);
- template <typename T, typename R>
+template <typename T, typename R>
void explain_binary_operation_one_output_error(Operation op,
const BinaryInput<T> &input,
R match_value,
@@ -236,7 +236,8 @@ class MPFRMatcher : public testing::Matcher<OutputType> {
rounding);
}
- template <typename T, typename R> bool match(const BinaryInput<T> &in, R out) {
+ template <typename T, typename R>
+ bool match(const BinaryInput<T> &in, R out) {
return compare_binary_operation_one_output(op, in, out, ulp_tolerance,
rounding);
}
@@ -269,7 +270,8 @@ class MPFRMatcher : public testing::Matcher<OutputType> {
rounding);
}
- template <typename T, typename R> void explain_error(const BinaryInput<T> &in, R out) {
+ template <typename T, typename R>
+ void explain_error(const BinaryInput<T> &in, R out) {
explain_binary_operation_one_output_error(op, in, out, ulp_tolerance,
rounding);
}
@@ -295,7 +297,9 @@ constexpr bool is_valid_operation() {
cpp::is_floating_point_v<
typename internal::MakeScalarInput<InputType>::type> &&
cpp::is_floating_point_v<OutputType>) ||
- (op == Operation::Fmul && !internal::AreMatchingBinaryInputAndBinaryOutput<InputType, OutputType>::VALUE);
+ (op == Operation::Fmul &&
+ !internal::AreMatchingBinaryInputAndBinaryOutput<InputType,
+ OutputType>::VALUE);
if (IS_NARROWING_OP)
return true;
return (Operation::BeginUnaryOperationsSingleOutput < op &&
More information about the libc-commits
mailing list