14e5f8b4dSTue Ly //===-- Unittests for expm1f-----------------------------------------------===//
24e5f8b4dSTue Ly //
34e5f8b4dSTue Ly // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44e5f8b4dSTue Ly // See https://llvm.org/LICENSE.txt for license information.
54e5f8b4dSTue Ly // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64e5f8b4dSTue Ly //
74e5f8b4dSTue Ly //===----------------------------------------------------------------------===//
84e5f8b4dSTue Ly 
9c120edc7SMichael Jones #include "src/__support/FPUtil/FPBits.h"
104e5f8b4dSTue Ly #include "src/math/expm1f.h"
114e5f8b4dSTue Ly #include "utils/MPFRWrapper/MPFRUtils.h"
126c3f53c7SSiva Chandra Reddy #include "utils/UnitTest/FPMatcher.h"
134e5f8b4dSTue Ly #include "utils/UnitTest/Test.h"
144e5f8b4dSTue Ly #include <math.h>
154e5f8b4dSTue Ly 
164e5f8b4dSTue Ly #include <errno.h>
174e5f8b4dSTue Ly #include <stdint.h>
184e5f8b4dSTue Ly 
194e5f8b4dSTue Ly namespace mpfr = __llvm_libc::testing::mpfr;
204e5f8b4dSTue Ly 
21e7e71e94SSiva Chandra Reddy DECLARE_SPECIAL_CONSTANTS(float)
22e7e71e94SSiva Chandra Reddy 
TEST(LlvmLibcExpm1fTest,SpecialNumbers)234e5f8b4dSTue Ly TEST(LlvmLibcExpm1fTest, SpecialNumbers) {
244e5f8b4dSTue Ly   errno = 0;
254e5f8b4dSTue Ly 
26e7e71e94SSiva Chandra Reddy   EXPECT_FP_EQ(aNaN, __llvm_libc::expm1f(aNaN));
27ffb410d3STue Ly   EXPECT_MATH_ERRNO(0);
284e5f8b4dSTue Ly 
29e7e71e94SSiva Chandra Reddy   EXPECT_FP_EQ(inf, __llvm_libc::expm1f(inf));
30ffb410d3STue Ly   EXPECT_MATH_ERRNO(0);
314e5f8b4dSTue Ly 
321c92911eSMichael Jones   EXPECT_FP_EQ(-1.0f, __llvm_libc::expm1f(neg_inf));
33ffb410d3STue Ly   EXPECT_MATH_ERRNO(0);
344e5f8b4dSTue Ly 
35e7e71e94SSiva Chandra Reddy   EXPECT_FP_EQ(0.0f, __llvm_libc::expm1f(0.0f));
36ffb410d3STue Ly   EXPECT_MATH_ERRNO(0);
374e5f8b4dSTue Ly 
38e7e71e94SSiva Chandra Reddy   EXPECT_FP_EQ(-0.0f, __llvm_libc::expm1f(-0.0f));
39ffb410d3STue Ly   EXPECT_MATH_ERRNO(0);
404e5f8b4dSTue Ly }
414e5f8b4dSTue Ly 
TEST(LlvmLibcExpm1fTest,Overflow)424e5f8b4dSTue Ly TEST(LlvmLibcExpm1fTest, Overflow) {
434e5f8b4dSTue Ly   errno = 0;
44e7e71e94SSiva Chandra Reddy   EXPECT_FP_EQ(inf, __llvm_libc::expm1f(float(FPBits(0x7f7fffffU))));
45ffb410d3STue Ly   EXPECT_MATH_ERRNO(ERANGE);
464e5f8b4dSTue Ly 
47e7e71e94SSiva Chandra Reddy   EXPECT_FP_EQ(inf, __llvm_libc::expm1f(float(FPBits(0x42cffff8U))));
48ffb410d3STue Ly   EXPECT_MATH_ERRNO(ERANGE);
494e5f8b4dSTue Ly 
50e7e71e94SSiva Chandra Reddy   EXPECT_FP_EQ(inf, __llvm_libc::expm1f(float(FPBits(0x42d00008U))));
51ffb410d3STue Ly   EXPECT_MATH_ERRNO(ERANGE);
524e5f8b4dSTue Ly }
534e5f8b4dSTue Ly 
TEST(LlvmLibcExpm1fTest,Underflow)544e5f8b4dSTue Ly TEST(LlvmLibcExpm1fTest, Underflow) {
554e5f8b4dSTue Ly   errno = 0;
56e7e71e94SSiva Chandra Reddy   EXPECT_FP_EQ(-1.0f, __llvm_libc::expm1f(float(FPBits(0xff7fffffU))));
574e5f8b4dSTue Ly 
58e7e71e94SSiva Chandra Reddy   float x = float(FPBits(0xc2cffff8U));
59e7e71e94SSiva Chandra Reddy   EXPECT_FP_EQ(-1.0f, __llvm_libc::expm1f(x));
604e5f8b4dSTue Ly 
61e7e71e94SSiva Chandra Reddy   x = float(FPBits(0xc2d00008U));
62e7e71e94SSiva Chandra Reddy   EXPECT_FP_EQ(-1.0f, __llvm_libc::expm1f(x));
634e5f8b4dSTue Ly }
644e5f8b4dSTue Ly 
654e5f8b4dSTue Ly // Test with inputs which are the borders of underflow/overflow but still
664e5f8b4dSTue Ly // produce valid results without setting errno.
TEST(LlvmLibcExpm1fTest,Borderline)674e5f8b4dSTue Ly TEST(LlvmLibcExpm1fTest, Borderline) {
684e5f8b4dSTue Ly   float x;
694e5f8b4dSTue Ly 
704e5f8b4dSTue Ly   errno = 0;
71e7e71e94SSiva Chandra Reddy   x = float(FPBits(0x42affff8U));
7264af346bSTue Ly   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
7364af346bSTue Ly                                  __llvm_libc::expm1f(x), 0.5);
74ffb410d3STue Ly   EXPECT_MATH_ERRNO(0);
754e5f8b4dSTue Ly 
76e7e71e94SSiva Chandra Reddy   x = float(FPBits(0x42b00008U));
7764af346bSTue Ly   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
7864af346bSTue Ly                                  __llvm_libc::expm1f(x), 0.5);
79ffb410d3STue Ly   EXPECT_MATH_ERRNO(0);
804e5f8b4dSTue Ly 
81e7e71e94SSiva Chandra Reddy   x = float(FPBits(0xc2affff8U));
8264af346bSTue Ly   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
8364af346bSTue Ly                                  __llvm_libc::expm1f(x), 0.5);
84ffb410d3STue Ly   EXPECT_MATH_ERRNO(0);
854e5f8b4dSTue Ly 
86e7e71e94SSiva Chandra Reddy   x = float(FPBits(0xc2b00008U));
8764af346bSTue Ly   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
8864af346bSTue Ly                                  __llvm_libc::expm1f(x), 0.5);
8964af346bSTue Ly   EXPECT_MATH_ERRNO(0);
9064af346bSTue Ly 
9164af346bSTue Ly   x = float(FPBits(0x3dc252ddU));
9264af346bSTue Ly   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
9364af346bSTue Ly                                  __llvm_libc::expm1f(x), 0.5);
94ffb410d3STue Ly   EXPECT_MATH_ERRNO(0);
95a5466f04STue Ly 
96a5466f04STue Ly   x = float(FPBits(0x3e35bec5U));
97a5466f04STue Ly   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
98a5466f04STue Ly                                  __llvm_libc::expm1f(x), 0.5);
99a5466f04STue Ly   EXPECT_MATH_ERRNO(0);
100*484319f4STue Ly 
101*484319f4STue Ly   x = float(FPBits(0x942ed494U));
102*484319f4STue Ly   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
103*484319f4STue Ly                                  __llvm_libc::expm1f(x), 0.5);
104*484319f4STue Ly   EXPECT_MATH_ERRNO(0);
105*484319f4STue Ly 
106*484319f4STue Ly   x = float(FPBits(0xbdc1c6cbU));
107*484319f4STue Ly   ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
108*484319f4STue Ly                                  __llvm_libc::expm1f(x), 0.5);
109*484319f4STue Ly   EXPECT_MATH_ERRNO(0);
1104e5f8b4dSTue Ly }
1114e5f8b4dSTue Ly 
TEST(LlvmLibcExpm1fTest,InFloatRange)1124e5f8b4dSTue Ly TEST(LlvmLibcExpm1fTest, InFloatRange) {
11325226f3eSMichael Jones   constexpr uint32_t COUNT = 1000000;
11425226f3eSMichael Jones   constexpr uint32_t STEP = UINT32_MAX / COUNT;
11525226f3eSMichael Jones   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
116e7e71e94SSiva Chandra Reddy     float x = float(FPBits(v));
1174e5f8b4dSTue Ly     if (isnan(x) || isinf(x))
1184e5f8b4dSTue Ly       continue;
1194e5f8b4dSTue Ly     errno = 0;
1204e5f8b4dSTue Ly     float result = __llvm_libc::expm1f(x);
1214e5f8b4dSTue Ly 
1224e5f8b4dSTue Ly     // If the computation resulted in an error or did not produce valid result
1234e5f8b4dSTue Ly     // in the single-precision floating point range, then ignore comparing with
1244e5f8b4dSTue Ly     // MPFR result as MPFR can still produce valid results because of its
1254e5f8b4dSTue Ly     // wider precision.
1264e5f8b4dSTue Ly     if (isnan(result) || isinf(result) || errno != 0)
1274e5f8b4dSTue Ly       continue;
12864af346bSTue Ly     ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1, x,
12964af346bSTue Ly                                    __llvm_libc::expm1f(x), 0.5);
1304e5f8b4dSTue Ly   }
1314e5f8b4dSTue Ly }
132