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