Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libc / test / src / math / NextAfterTest.h
blob4e450cf5bc1e9e79cd97709b29c68b5b0596f761
1 //===-- Utility class to test different flavors of nextafter ----*- 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 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H
10 #define LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H
12 #include "src/__support/CPP/bit.h"
13 #include "src/__support/CPP/type_traits.h"
14 #include "src/__support/FPUtil/BasicOperations.h"
15 #include "src/__support/FPUtil/FPBits.h"
16 #include "test/UnitTest/FPMatcher.h"
17 #include "test/UnitTest/Test.h"
18 #include <math.h>
20 template <typename T>
21 class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test {
22 using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
23 using MantissaWidth = LIBC_NAMESPACE::fputil::MantissaWidth<T>;
24 using UIntType = typename FPBits::UIntType;
26 static constexpr int BIT_WIDTH_OF_TYPE =
27 LIBC_NAMESPACE::fputil::FloatProperties<T>::BIT_WIDTH;
29 const T zero = T(FPBits::zero());
30 const T neg_zero = T(FPBits::neg_zero());
31 const T inf = T(FPBits::inf());
32 const T neg_inf = T(FPBits::neg_inf());
33 const T nan = T(FPBits::build_quiet_nan(1));
34 const UIntType min_subnormal = FPBits::MIN_SUBNORMAL;
35 const UIntType max_subnormal = FPBits::MAX_SUBNORMAL;
36 const UIntType min_normal = FPBits::MIN_NORMAL;
37 const UIntType max_normal = FPBits::MAX_NORMAL;
39 public:
40 typedef T (*NextAfterFunc)(T, T);
42 void testNaN(NextAfterFunc func) {
43 ASSERT_FP_EQ(func(nan, 0), nan);
44 ASSERT_FP_EQ(func(0, nan), nan);
47 void testBoundaries(NextAfterFunc func) {
48 ASSERT_FP_EQ(func(zero, neg_zero), neg_zero);
49 ASSERT_FP_EQ(func(neg_zero, zero), zero);
51 // 'from' is zero|neg_zero.
52 T x = zero;
53 T result = func(x, T(1));
54 UIntType expected_bits = 1;
55 T expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
56 ASSERT_FP_EQ(result, expected);
58 result = func(x, T(-1));
59 expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + 1;
60 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
61 ASSERT_FP_EQ(result, expected);
63 x = neg_zero;
64 result = func(x, 1);
65 expected_bits = 1;
66 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
67 ASSERT_FP_EQ(result, expected);
69 result = func(x, -1);
70 expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + 1;
71 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
72 ASSERT_FP_EQ(result, expected);
74 // 'from' is max subnormal value.
75 x = LIBC_NAMESPACE::cpp::bit_cast<T>(max_subnormal);
76 result = func(x, 1);
77 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(min_normal);
78 ASSERT_FP_EQ(result, expected);
80 result = func(x, 0);
81 expected_bits = max_subnormal - 1;
82 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
83 ASSERT_FP_EQ(result, expected);
85 x = -x;
87 result = func(x, -1);
88 expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_normal;
89 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
90 ASSERT_FP_EQ(result, expected);
92 result = func(x, 0);
93 expected_bits =
94 (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_subnormal - 1;
95 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
96 ASSERT_FP_EQ(result, expected);
98 // 'from' is min subnormal value.
99 x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_subnormal);
100 result = func(x, 1);
101 expected_bits = min_subnormal + 1;
102 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
103 ASSERT_FP_EQ(result, expected);
104 ASSERT_FP_EQ(func(x, 0), 0);
106 x = -x;
107 result = func(x, -1);
108 expected_bits =
109 (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_subnormal + 1;
110 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
111 ASSERT_FP_EQ(result, expected);
112 ASSERT_FP_EQ(func(x, 0), T(-0.0));
114 // 'from' is min normal.
115 x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_normal);
116 result = func(x, 0);
117 expected_bits = max_subnormal;
118 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
119 ASSERT_FP_EQ(result, expected);
121 result = func(x, inf);
122 expected_bits = min_normal + 1;
123 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
124 ASSERT_FP_EQ(result, expected);
126 x = -x;
127 result = func(x, 0);
128 expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_subnormal;
129 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
130 ASSERT_FP_EQ(result, expected);
132 result = func(x, -inf);
133 expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_normal + 1;
134 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
135 ASSERT_FP_EQ(result, expected);
137 // 'from' is max normal and 'to' is infinity.
138 x = LIBC_NAMESPACE::cpp::bit_cast<T>(max_normal);
139 result = func(x, inf);
140 ASSERT_FP_EQ(result, inf);
142 result = func(-x, -inf);
143 ASSERT_FP_EQ(result, -inf);
145 // 'from' is infinity.
146 x = inf;
147 result = func(x, 0);
148 expected_bits = max_normal;
149 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
150 ASSERT_FP_EQ(result, expected);
151 ASSERT_FP_EQ(func(x, inf), inf);
153 x = neg_inf;
154 result = func(x, 0);
155 expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_normal;
156 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits);
157 ASSERT_FP_EQ(result, expected);
158 ASSERT_FP_EQ(func(x, neg_inf), neg_inf);
160 // 'from' is a power of 2.
161 x = T(32.0);
162 result = func(x, 0);
163 FPBits x_bits = FPBits(x);
164 FPBits result_bits = FPBits(result);
165 ASSERT_EQ(result_bits.get_unbiased_exponent(),
166 uint16_t(x_bits.get_unbiased_exponent() - 1));
167 ASSERT_EQ(result_bits.get_mantissa(),
168 (UIntType(1) << MantissaWidth::VALUE) - 1);
170 result = func(x, T(33.0));
171 result_bits = FPBits(result);
172 ASSERT_EQ(result_bits.get_unbiased_exponent(),
173 x_bits.get_unbiased_exponent());
174 ASSERT_EQ(result_bits.get_mantissa(), x_bits.get_mantissa() + UIntType(1));
176 x = -x;
178 result = func(x, 0);
179 result_bits = FPBits(result);
180 ASSERT_EQ(result_bits.get_unbiased_exponent(),
181 uint16_t(x_bits.get_unbiased_exponent() - 1));
182 ASSERT_EQ(result_bits.get_mantissa(),
183 (UIntType(1) << MantissaWidth::VALUE) - 1);
185 result = func(x, T(-33.0));
186 result_bits = FPBits(result);
187 ASSERT_EQ(result_bits.get_unbiased_exponent(),
188 x_bits.get_unbiased_exponent());
189 ASSERT_EQ(result_bits.get_mantissa(), x_bits.get_mantissa() + UIntType(1));
193 #define LIST_NEXTAFTER_TESTS(T, func) \
194 using LlvmLibcNextAfterTest = NextAfterTestTemplate<T>; \
195 TEST_F(LlvmLibcNextAfterTest, TestNaN) { testNaN(&func); } \
196 TEST_F(LlvmLibcNextAfterTest, TestBoundaries) { testBoundaries(&func); }
198 #endif // LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H