xref: /aosp_15_r20/external/llvm-libc/test/src/math/AddTest.h (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1 //===-- Utility class to test different flavors of float add ----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIBC_TEST_SRC_MATH_ADDTEST_H
10 #define LLVM_LIBC_TEST_SRC_MATH_ADDTEST_H
11 
12 #include "test/UnitTest/FEnvSafeTest.h"
13 #include "test/UnitTest/FPMatcher.h"
14 #include "test/UnitTest/Test.h"
15 #include "utils/MPFRWrapper/MPFRUtils.h"
16 
17 namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
18 
19 template <typename OutType, typename InType>
20 class AddTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
21 
22   struct InConstants {
23     DECLARE_SPECIAL_CONSTANTS(InType)
24   };
25 
26   using InFPBits = typename InConstants::FPBits;
27   using InStorageType = typename InConstants::StorageType;
28 
29   static constexpr InStorageType IN_MAX_NORMAL_U =
30       InFPBits::max_normal().uintval();
31   static constexpr InStorageType IN_MIN_NORMAL_U =
32       InFPBits::min_normal().uintval();
33   static constexpr InStorageType IN_MAX_SUBNORMAL_U =
34       InFPBits::max_subnormal().uintval();
35   static constexpr InStorageType IN_MIN_SUBNORMAL_U =
36       InFPBits::min_subnormal().uintval();
37 
38 public:
39   typedef OutType (*AddFunc)(InType, InType);
40 
test_subnormal_range(AddFunc func)41   void test_subnormal_range(AddFunc func) {
42     constexpr InStorageType COUNT = 100'001;
43     constexpr InStorageType STEP =
44         (IN_MAX_SUBNORMAL_U - IN_MIN_SUBNORMAL_U) / COUNT;
45     for (InStorageType i = 0, v = 0, w = IN_MAX_SUBNORMAL_U; i <= COUNT;
46          ++i, v += STEP, w -= STEP) {
47       InType x = InFPBits(v).get_val();
48       InType y = InFPBits(w).get_val();
49       mpfr::BinaryInput<InType> input{x, y};
50       EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Add, input, func(x, y),
51                                      0.5);
52     }
53   }
54 
55   void test_normal_range(AddFunc func) {
56     constexpr InStorageType COUNT = 100'001;
57     constexpr InStorageType STEP = (IN_MAX_NORMAL_U - IN_MIN_NORMAL_U) / COUNT;
58     for (InStorageType i = 0, v = 0, w = IN_MAX_NORMAL_U; i <= COUNT;
59          ++i, v += STEP, w -= STEP) {
60       InType x = InFPBits(v).get_val();
61       InType y = InFPBits(w).get_val();
62       mpfr::BinaryInput<InType> input{x, y};
63       EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Add, input, func(x, y),
64                                      0.5);
65     }
66   }
67 };
68 
69 #define LIST_ADD_TESTS(OutType, InType, func)                                  \
70   using LlvmLibcAddTest = AddTest<OutType, InType>;                            \
71   TEST_F(LlvmLibcAddTest, SubnormalRange) { test_subnormal_range(&func); }     \
72   TEST_F(LlvmLibcAddTest, NormalRange) { test_normal_range(&func); }
73 
74 #endif // LLVM_LIBC_TEST_SRC_MATH_ADDTEST_H
75