196d85726SSiva Chandra Reddy //===-- Unittests for expf ------------------------------------------------===//
296d85726SSiva Chandra Reddy //
396d85726SSiva Chandra Reddy // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
496d85726SSiva Chandra Reddy // See https://llvm.org/LICENSE.txt for license information.
596d85726SSiva Chandra Reddy // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
696d85726SSiva Chandra Reddy //
796d85726SSiva Chandra Reddy //===----------------------------------------------------------------------===//
896d85726SSiva Chandra Reddy
9c120edc7SMichael Jones #include "src/__support/FPUtil/FPBits.h"
1096d85726SSiva Chandra Reddy #include "src/math/expf.h"
1196d85726SSiva Chandra Reddy #include "utils/MPFRWrapper/MPFRUtils.h"
126c3f53c7SSiva Chandra Reddy #include "utils/UnitTest/FPMatcher.h"
1396d85726SSiva Chandra Reddy #include "utils/UnitTest/Test.h"
143e18fb33SMichael Jones #include <math.h>
1596d85726SSiva Chandra Reddy
1635e2e448SSiva Chandra Reddy #include <errno.h>
1796d85726SSiva Chandra Reddy #include <stdint.h>
1896d85726SSiva Chandra Reddy
1996d85726SSiva Chandra Reddy namespace mpfr = __llvm_libc::testing::mpfr;
2096d85726SSiva Chandra Reddy
21e7e71e94SSiva Chandra Reddy DECLARE_SPECIAL_CONSTANTS(float)
22e7e71e94SSiva Chandra Reddy
TEST(LlvmLibcExpfTest,SpecialNumbers)231df0dbfcSMichael Jones TEST(LlvmLibcExpfTest, SpecialNumbers) {
2435e2e448SSiva Chandra Reddy errno = 0;
2596d85726SSiva Chandra Reddy
26e7e71e94SSiva Chandra Reddy EXPECT_FP_EQ(aNaN, __llvm_libc::expf(aNaN));
27ffb410d3STue Ly EXPECT_MATH_ERRNO(0);
2896d85726SSiva Chandra Reddy
29e7e71e94SSiva Chandra Reddy EXPECT_FP_EQ(inf, __llvm_libc::expf(inf));
30ffb410d3STue Ly EXPECT_MATH_ERRNO(0);
3196d85726SSiva Chandra Reddy
321c92911eSMichael Jones EXPECT_FP_EQ(0.0f, __llvm_libc::expf(neg_inf));
33ffb410d3STue Ly EXPECT_MATH_ERRNO(0);
3496d85726SSiva Chandra Reddy
35e7e71e94SSiva Chandra Reddy EXPECT_FP_EQ(1.0f, __llvm_libc::expf(0.0f));
36ffb410d3STue Ly EXPECT_MATH_ERRNO(0);
3796d85726SSiva Chandra Reddy
38e7e71e94SSiva Chandra Reddy EXPECT_FP_EQ(1.0f, __llvm_libc::expf(-0.0f));
39ffb410d3STue Ly EXPECT_MATH_ERRNO(0);
4096d85726SSiva Chandra Reddy }
4196d85726SSiva Chandra Reddy
TEST(LlvmLibcExpfTest,Overflow)421df0dbfcSMichael Jones TEST(LlvmLibcExpfTest, Overflow) {
4335e2e448SSiva Chandra Reddy errno = 0;
44e7e71e94SSiva Chandra Reddy EXPECT_FP_EQ(inf, __llvm_libc::expf(float(FPBits(0x7f7fffffU))));
45ffb410d3STue Ly EXPECT_MATH_ERRNO(ERANGE);
4696d85726SSiva Chandra Reddy
47e7e71e94SSiva Chandra Reddy EXPECT_FP_EQ(inf, __llvm_libc::expf(float(FPBits(0x42cffff8U))));
48ffb410d3STue Ly EXPECT_MATH_ERRNO(ERANGE);
4996d85726SSiva Chandra Reddy
50e7e71e94SSiva Chandra Reddy EXPECT_FP_EQ(inf, __llvm_libc::expf(float(FPBits(0x42d00008U))));
51ffb410d3STue Ly EXPECT_MATH_ERRNO(ERANGE);
5296d85726SSiva Chandra Reddy }
5396d85726SSiva Chandra Reddy
TEST(LlvmLibcExpfTest,Underflow)541df0dbfcSMichael Jones TEST(LlvmLibcExpfTest, Underflow) {
5535e2e448SSiva Chandra Reddy errno = 0;
56e7e71e94SSiva Chandra Reddy EXPECT_FP_EQ(0.0f, __llvm_libc::expf(float(FPBits(0xff7fffffU))));
57ffb410d3STue Ly EXPECT_MATH_ERRNO(ERANGE);
5896d85726SSiva Chandra Reddy
59e7e71e94SSiva Chandra Reddy float x = float(FPBits(0xc2cffff8U));
6038cadd90STue Ly EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x, __llvm_libc::expf(x),
6138cadd90STue Ly 0.5);
62ffb410d3STue Ly EXPECT_MATH_ERRNO(ERANGE);
6396d85726SSiva Chandra Reddy
64e7e71e94SSiva Chandra Reddy x = float(FPBits(0xc2d00008U));
6538cadd90STue Ly EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x, __llvm_libc::expf(x),
6638cadd90STue Ly 0.5);
67ffb410d3STue Ly EXPECT_MATH_ERRNO(ERANGE);
6896d85726SSiva Chandra Reddy }
6996d85726SSiva Chandra Reddy
7096d85726SSiva Chandra Reddy // Test with inputs which are the borders of underflow/overflow but still
7196d85726SSiva Chandra Reddy // produce valid results without setting errno.
TEST(LlvmLibcExpfTest,Borderline)721df0dbfcSMichael Jones TEST(LlvmLibcExpfTest, Borderline) {
7396d85726SSiva Chandra Reddy float x;
7496d85726SSiva Chandra Reddy
7535e2e448SSiva Chandra Reddy errno = 0;
76e7e71e94SSiva Chandra Reddy x = float(FPBits(0x42affff8U));
7738cadd90STue Ly ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x, __llvm_libc::expf(x),
7838cadd90STue Ly 0.5);
79ffb410d3STue Ly EXPECT_MATH_ERRNO(0);
8096d85726SSiva Chandra Reddy
81e7e71e94SSiva Chandra Reddy x = float(FPBits(0x42b00008U));
8238cadd90STue Ly ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x, __llvm_libc::expf(x),
8338cadd90STue Ly 0.5);
84ffb410d3STue Ly EXPECT_MATH_ERRNO(0);
8596d85726SSiva Chandra Reddy
86e7e71e94SSiva Chandra Reddy x = float(FPBits(0xc2affff8U));
8738cadd90STue Ly ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x, __llvm_libc::expf(x),
8838cadd90STue Ly 0.5);
89ffb410d3STue Ly EXPECT_MATH_ERRNO(0);
9096d85726SSiva Chandra Reddy
91e7e71e94SSiva Chandra Reddy x = float(FPBits(0xc2b00008U));
9238cadd90STue Ly ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x, __llvm_libc::expf(x),
9338cadd90STue Ly 0.5);
94ffb410d3STue Ly EXPECT_MATH_ERRNO(0);
95*6168b422STue Ly
96*6168b422STue Ly x = float(FPBits(0xc236bd8cU));
97*6168b422STue Ly EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x, __llvm_libc::expf(x),
98*6168b422STue Ly 0.5);
99*6168b422STue Ly EXPECT_MATH_ERRNO(0);
10096d85726SSiva Chandra Reddy }
10196d85726SSiva Chandra Reddy
TEST(LlvmLibcExpfTest,InFloatRange)1021df0dbfcSMichael Jones TEST(LlvmLibcExpfTest, InFloatRange) {
10325226f3eSMichael Jones constexpr uint32_t COUNT = 1000000;
10425226f3eSMichael Jones constexpr uint32_t STEP = UINT32_MAX / COUNT;
10525226f3eSMichael Jones for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
106e7e71e94SSiva Chandra Reddy float x = float(FPBits(v));
10796d85726SSiva Chandra Reddy if (isnan(x) || isinf(x))
10896d85726SSiva Chandra Reddy continue;
10935e2e448SSiva Chandra Reddy errno = 0;
11096d85726SSiva Chandra Reddy float result = __llvm_libc::expf(x);
11196d85726SSiva Chandra Reddy
11296d85726SSiva Chandra Reddy // If the computation resulted in an error or did not produce valid result
11396d85726SSiva Chandra Reddy // in the single-precision floating point range, then ignore comparing with
11496d85726SSiva Chandra Reddy // MPFR result as MPFR can still produce valid results because of its
11596d85726SSiva Chandra Reddy // wider precision.
11635e2e448SSiva Chandra Reddy if (isnan(result) || isinf(result) || errno != 0)
11796d85726SSiva Chandra Reddy continue;
11838cadd90STue Ly EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp, x,
11938cadd90STue Ly __llvm_libc::expf(x), 0.5);
12096d85726SSiva Chandra Reddy }
12196d85726SSiva Chandra Reddy }
122