aboutsummaryrefslogtreecommitdiff
path: root/libc/test
diff options
context:
space:
mode:
authorJob Henandez Lara <hj93@protonmail.com>2024-06-08 12:07:27 -0700
committerGitHub <noreply@github.com>2024-06-08 15:07:27 -0400
commit263be9fb0085001630e0431782a0ac0da7ab58ae (patch)
tree1c4897cca79689cb45a992a7c51903d6bc33950a /libc/test
parent1e92ad41d8ef46fa3c628b05ba8ed481fedc17bd (diff)
downloadllvm-263be9fb0085001630e0431782a0ac0da7ab58ae.zip
llvm-263be9fb0085001630e0431782a0ac0da7ab58ae.tar.gz
llvm-263be9fb0085001630e0431782a0ac0da7ab58ae.tar.bz2
[libc][math][c23] fmul correcly rounded to all rounding modes (#91537)
This is an implementation of floating point multiplication: It will consist of - `double x double -> float`
Diffstat (limited to 'libc/test')
-rw-r--r--libc/test/src/math/smoke/CMakeLists.txt13
-rw-r--r--libc/test/src/math/smoke/FMulTest.h104
-rw-r--r--libc/test/src/math/smoke/fmul_test.cpp13
3 files changed, 130 insertions, 0 deletions
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 07e8b5d..8d5b4e6 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -2401,6 +2401,19 @@ add_fp_unittest(
)
add_fp_unittest(
+ fmul_test
+ SUITE
+ libc-math-smoke-tests
+ SRCS
+ fmul_test.cpp
+ HDRS
+ FMulTest.h
+ DEPENDS
+ libc.src.math.fmul
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
sqrtf_test
SUITE
libc-math-smoke-tests
diff --git a/libc/test/src/math/smoke/FMulTest.h b/libc/test/src/math/smoke/FMulTest.h
new file mode 100644
index 0000000..33fb82c
--- /dev/null
+++ b/libc/test/src/math/smoke/FMulTest.h
@@ -0,0 +1,104 @@
+//===-- 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_SMOKE_FMULTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMULTEST_H
+
+#include "test/UnitTest/FEnvSafeTest.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T, typename R>
+class FmulTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
+
+ DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+ typedef T (*FMulFunc)(R, R);
+
+ void testMul(FMulFunc func) {
+
+ EXPECT_FP_EQ_ALL_ROUNDING(T(15.0), func(3.0, 5.0));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0x1.0p-130), func(0x1.0p1, 0x1.0p-131));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0x1.0p-127), func(0x1.0p2, 0x1.0p-129));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(1.0), func(1.0, 1.0));
+
+ EXPECT_FP_EQ_ALL_ROUNDING(T(0.0), func(-0.0, -0.0));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.0), func(0.0, -0.0));
+ EXPECT_FP_EQ_ALL_ROUNDING(T(-0.0), func(-0.0, 0.0));
+
+ EXPECT_FP_EQ_ROUNDING_NEAREST(inf, func(0x1.0p100, 0x1.0p100));
+ EXPECT_FP_EQ_ROUNDING_UPWARD(inf, func(0x1.0p100, 0x1.0p100));
+ EXPECT_FP_EQ_ROUNDING_DOWNWARD(max_normal, func(0x1.0p100, 0x1.0p100));
+ EXPECT_FP_EQ_ROUNDING_TOWARD_ZERO(max_normal, func(0x1.0p100, 0x1.0p100));
+
+ EXPECT_FP_EQ_ROUNDING_NEAREST(
+ 0x1p0, func(1.0, 1.0 + 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150));
+ EXPECT_FP_EQ_ROUNDING_DOWNWARD(
+ 0x1p0, func(1.0, 1.0 + 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150));
+ EXPECT_FP_EQ_ROUNDING_TOWARD_ZERO(
+ 0x1p0, func(1.0, 1.0 + 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150));
+ EXPECT_FP_EQ_ROUNDING_UPWARD(
+ 0x1p0, func(1.0, 1.0 + 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150));
+
+ EXPECT_FP_EQ_ROUNDING_NEAREST(
+ 0x1.0p-128f + 0x1.0p-148f,
+ func(1.0, 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150));
+ EXPECT_FP_EQ_ROUNDING_UPWARD(
+ 0x1.0p-128f + 0x1.0p-148f,
+ func(1.0, 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150));
+ EXPECT_FP_EQ_ROUNDING_DOWNWARD(
+ 0x1.0p-128f + 0x1.0p-149f,
+ func(1.0, 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150));
+ EXPECT_FP_EQ_ROUNDING_TOWARD_ZERO(
+ 0x1.0p-128f + 0x1.0p-149f,
+ func(1.0, 0x1.0p-128 + 0x1.0p-149 + 0x1.0p-150));
+ }
+
+ void testSpecialInputs(FMulFunc func) {
+ EXPECT_FP_EQ_ALL_ROUNDING(inf, func(inf, 0x1.0p-129));
+ EXPECT_FP_EQ_ALL_ROUNDING(inf, func(0x1.0p-129, inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(inf, func(inf, 2.0));
+ EXPECT_FP_EQ_ALL_ROUNDING(inf, func(3.0, inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(0.0, func(0.0, 0.0));
+
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(neg_inf, aNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(aNaN, neg_inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(inf, func(neg_inf, neg_inf));
+
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(0.0, neg_inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(neg_inf, 0.0));
+
+ EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, func(neg_inf, 1.0));
+ EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, func(1.0, neg_inf));
+
+ EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, func(neg_inf, 0x1.0p-129));
+ EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, func(0x1.0p-129, neg_inf));
+
+ EXPECT_FP_EQ_ALL_ROUNDING(0.0, func(0.0, 0x1.0p-129));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(inf, 0.0));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(0.0, inf));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(0.0, aNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(2.0, aNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(0x1.0p-129, aNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(inf, aNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(aNaN, aNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(0.0, sNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(2.0, sNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(0x1.0p-129, sNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(inf, sNaN));
+ EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(sNaN, sNaN));
+ }
+};
+
+#define LIST_FMUL_TESTS(T, R, func) \
+ using LlvmLibcFmulTest = FmulTest<T, R>; \
+ TEST_F(LlvmLibcFmulTest, Mul) { testMul(&func); } \
+ TEST_F(LlvmLibcFmulTest, NaNInf) { testSpecialInputs(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_FMULTEST_H
diff --git a/libc/test/src/math/smoke/fmul_test.cpp b/libc/test/src/math/smoke/fmul_test.cpp
new file mode 100644
index 0000000..0eb664f
--- /dev/null
+++ b/libc/test/src/math/smoke/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_TESTS(float, double, LIBC_NAMESPACE::fmul)