1 //===-- Unittests for exp2f -----------------------------------------------===//
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 #include "include/errno.h"
10 #include "src/errno/llvmlibc_errno.h"
11 #include "src/math/exp2f.h"
12 #include "utils/FPUtil/BitPatterns.h"
13 #include "utils/FPUtil/ClassificationFunctions.h"
14 #include "utils/FPUtil/FloatOperations.h"
15 #include "utils/FPUtil/FloatProperties.h"
16 #include "utils/MPFRWrapper/MPFRUtils.h"
17 #include "utils/UnitTest/Test.h"
18 #include <math.h>
19
20 #include <stdint.h>
21
22 using __llvm_libc::fputil::isNegativeQuietNaN;
23 using __llvm_libc::fputil::isQuietNaN;
24 using __llvm_libc::fputil::valueAsBits;
25 using __llvm_libc::fputil::valueFromBits;
26
27 using BitPatterns = __llvm_libc::fputil::BitPatterns<float>;
28
29 namespace mpfr = __llvm_libc::testing::mpfr;
30
TEST(exp2fTest,SpecialNumbers)31 TEST(exp2fTest, SpecialNumbers) {
32 llvmlibc_errno = 0;
33
34 EXPECT_TRUE(
35 isQuietNaN(__llvm_libc::exp2f(valueFromBits(BitPatterns::aQuietNaN))));
36 EXPECT_EQ(llvmlibc_errno, 0);
37
38 EXPECT_TRUE(isNegativeQuietNaN(
39 __llvm_libc::exp2f(valueFromBits(BitPatterns::aNegativeQuietNaN))));
40 EXPECT_EQ(llvmlibc_errno, 0);
41
42 EXPECT_TRUE(isQuietNaN(
43 __llvm_libc::exp2f(valueFromBits(BitPatterns::aSignallingNaN))));
44 EXPECT_EQ(llvmlibc_errno, 0);
45
46 EXPECT_TRUE(isNegativeQuietNaN(
47 __llvm_libc::exp2f(valueFromBits(BitPatterns::aNegativeSignallingNaN))));
48 EXPECT_EQ(llvmlibc_errno, 0);
49
50 EXPECT_EQ(BitPatterns::inf,
51 valueAsBits(__llvm_libc::exp2f(valueFromBits(BitPatterns::inf))));
52 EXPECT_EQ(llvmlibc_errno, 0);
53
54 EXPECT_EQ(BitPatterns::zero, valueAsBits(__llvm_libc::exp2f(
55 valueFromBits(BitPatterns::negInf))));
56 EXPECT_EQ(llvmlibc_errno, 0);
57
58 EXPECT_EQ(BitPatterns::one,
59 valueAsBits(__llvm_libc::exp2f(valueFromBits(BitPatterns::zero))));
60 EXPECT_EQ(llvmlibc_errno, 0);
61
62 EXPECT_EQ(BitPatterns::one, valueAsBits(__llvm_libc::exp2f(
63 valueFromBits(BitPatterns::negZero))));
64 EXPECT_EQ(llvmlibc_errno, 0);
65 }
66
TEST(ExpfTest,Overflow)67 TEST(ExpfTest, Overflow) {
68 llvmlibc_errno = 0;
69 EXPECT_EQ(BitPatterns::inf,
70 valueAsBits(__llvm_libc::exp2f(valueFromBits(0x7f7fffffU))));
71 EXPECT_EQ(llvmlibc_errno, ERANGE);
72
73 llvmlibc_errno = 0;
74 EXPECT_EQ(BitPatterns::inf,
75 valueAsBits(__llvm_libc::exp2f(valueFromBits(0x43000000U))));
76 EXPECT_EQ(llvmlibc_errno, ERANGE);
77
78 llvmlibc_errno = 0;
79 EXPECT_EQ(BitPatterns::inf,
80 valueAsBits(__llvm_libc::exp2f(valueFromBits(0x43000001U))));
81 EXPECT_EQ(llvmlibc_errno, ERANGE);
82 }
83
84 // Test with inputs which are the borders of underflow/overflow but still
85 // produce valid results without setting errno.
TEST(ExpfTest,Borderline)86 TEST(ExpfTest, Borderline) {
87 float x;
88
89 llvmlibc_errno = 0;
90 x = valueFromBits(0x42fa0001U);
91 EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
92 EXPECT_EQ(llvmlibc_errno, 0);
93
94 x = valueFromBits(0x42ffffffU);
95 EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
96 EXPECT_EQ(llvmlibc_errno, 0);
97
98 x = valueFromBits(0xc2fa0001U);
99 EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
100 EXPECT_EQ(llvmlibc_errno, 0);
101
102 x = valueFromBits(0xc2fc0000U);
103 EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
104 EXPECT_EQ(llvmlibc_errno, 0);
105
106 x = valueFromBits(0xc2fc0001U);
107 EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
108 EXPECT_EQ(llvmlibc_errno, 0);
109
110 x = valueFromBits(0xc3150000U);
111 EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
112 EXPECT_EQ(llvmlibc_errno, 0);
113 }
114
TEST(ExpfTest,Underflow)115 TEST(ExpfTest, Underflow) {
116 llvmlibc_errno = 0;
117 EXPECT_EQ(BitPatterns::zero,
118 valueAsBits(__llvm_libc::exp2f(valueFromBits(0xff7fffffU))));
119 EXPECT_EQ(llvmlibc_errno, ERANGE);
120
121 llvmlibc_errno = 0;
122 float x = valueFromBits(0xc3158000U);
123 EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
124 EXPECT_EQ(llvmlibc_errno, ERANGE);
125
126 llvmlibc_errno = 0;
127 x = valueFromBits(0xc3165432U);
128 EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
129 EXPECT_EQ(llvmlibc_errno, ERANGE);
130 }
131
TEST(exp2fTest,InFloatRange)132 TEST(exp2fTest, InFloatRange) {
133 constexpr uint32_t count = 1000000;
134 constexpr uint32_t step = UINT32_MAX / count;
135 for (uint32_t i = 0, v = 0; i <= count; ++i, v += step) {
136 float x = valueFromBits(v);
137 if (isnan(x) || isinf(x))
138 continue;
139 llvmlibc_errno = 0;
140 float result = __llvm_libc::exp2f(x);
141
142 // If the computation resulted in an error or did not produce valid result
143 // in the single-precision floating point range, then ignore comparing with
144 // MPFR result as MPFR can still produce valid results because of its
145 // wider precision.
146 if (isnan(result) || isinf(result) || llvmlibc_errno != 0)
147 continue;
148 ASSERT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
149 }
150 }
151