1*9e7688c7STue Ly //===-- Unittests for log1pf ----------------------------------------------===//
2*9e7688c7STue Ly //
3*9e7688c7STue Ly // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*9e7688c7STue Ly // See https://llvm.org/LICENSE.txt for license information.
5*9e7688c7STue Ly // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*9e7688c7STue Ly //
7*9e7688c7STue Ly //===----------------------------------------------------------------------===//
8*9e7688c7STue Ly 
9*9e7688c7STue Ly #include "src/__support/FPUtil/FPBits.h"
10*9e7688c7STue Ly #include "src/math/log1pf.h"
11*9e7688c7STue Ly #include "utils/MPFRWrapper/MPFRUtils.h"
12*9e7688c7STue Ly #include "utils/UnitTest/FPMatcher.h"
13*9e7688c7STue Ly #include "utils/UnitTest/Test.h"
14*9e7688c7STue Ly #include <math.h>
15*9e7688c7STue Ly 
16*9e7688c7STue Ly #include <errno.h>
17*9e7688c7STue Ly #include <stdint.h>
18*9e7688c7STue Ly 
19*9e7688c7STue Ly namespace mpfr = __llvm_libc::testing::mpfr;
20*9e7688c7STue Ly 
21*9e7688c7STue Ly DECLARE_SPECIAL_CONSTANTS(float)
22*9e7688c7STue Ly 
TEST(LlvmLibclog1pfTest,SpecialNumbers)23*9e7688c7STue Ly TEST(LlvmLibclog1pfTest, SpecialNumbers) {
24*9e7688c7STue Ly   EXPECT_FP_EQ(aNaN, __llvm_libc::log1pf(aNaN));
25*9e7688c7STue Ly   EXPECT_FP_EQ(inf, __llvm_libc::log1pf(inf));
26*9e7688c7STue Ly   EXPECT_TRUE(FPBits((__llvm_libc::log1pf(neg_inf))).is_nan());
27*9e7688c7STue Ly   EXPECT_FP_EQ(zero, __llvm_libc::log1pf(0.0f));
28*9e7688c7STue Ly   EXPECT_FP_EQ(neg_zero, __llvm_libc::log1pf(-0.0f));
29*9e7688c7STue Ly   EXPECT_FP_EQ(neg_inf, __llvm_libc::log1pf(-1.0f));
30*9e7688c7STue Ly }
31*9e7688c7STue Ly 
TEST(LlvmLibclog1pfTest,TrickyInputs)32*9e7688c7STue Ly TEST(LlvmLibclog1pfTest, TrickyInputs) {
33*9e7688c7STue Ly   constexpr int N = 20;
34*9e7688c7STue Ly   constexpr uint32_t INPUTS[N] = {
35*9e7688c7STue Ly       0x35c00006U, /*0x1.80000cp-20f*/
36*9e7688c7STue Ly       0x35400003U, /*0x1.800006p-21f*/
37*9e7688c7STue Ly       0x3640000cU, /*0x1.800018p-19f*/
38*9e7688c7STue Ly       0x36c00018U, /*0x1.80003p-18f*/
39*9e7688c7STue Ly       0x3710001bU, /*0x1.200036p-17f*/
40*9e7688c7STue Ly       0x37400030U, /*0x1.80006p-17f*/
41*9e7688c7STue Ly       0x3770004bU, /*0x1.e00096p-17f*/
42*9e7688c7STue Ly       0x3b9315c8U, /*0x1.262b9p-8f*/
43*9e7688c7STue Ly       0x3c6eb7afU, /*0x1.dd6f5ep-7f*/
44*9e7688c7STue Ly       0x41078febU, /*0x1.0f1fd6p+3f*/
45*9e7688c7STue Ly       0x5cd69e88U, /*0x1.ad3d1p+58f*/
46*9e7688c7STue Ly       0x65d890d3U, /*0x1.b121a6p+76f*/
47*9e7688c7STue Ly       0x6f31a8ecU, /*0x1.6351d8p+95f*/
48*9e7688c7STue Ly       0x7a17f30aU, /*0x1.2fe614p+117f*/
49*9e7688c7STue Ly       0xb53ffffdU, /*-0x1.7ffffap-21f*/
50*9e7688c7STue Ly       0xb70fffe5U, /*-0x1.1fffcap-17f*/
51*9e7688c7STue Ly       0xbb0ec8c4U, /*-0x1.1d9188p-9f*/
52*9e7688c7STue Ly       0xbc4d092cU, /*-0x1.9a1258p-7f*/
53*9e7688c7STue Ly       0xbc657728U, /*-0x1.caee5p-7f*/
54*9e7688c7STue Ly       0xbd1d20afU, /*-0x1.3a415ep-5f*/
55*9e7688c7STue Ly   };
56*9e7688c7STue Ly   for (int i = 0; i < N; ++i) {
57*9e7688c7STue Ly     float x = float(FPBits(INPUTS[i]));
58*9e7688c7STue Ly     EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log1p, x,
59*9e7688c7STue Ly                                    __llvm_libc::log1pf(x), 0.5);
60*9e7688c7STue Ly   }
61*9e7688c7STue Ly }
62*9e7688c7STue Ly 
TEST(LlvmLibclog1pfTest,InFloatRange)63*9e7688c7STue Ly TEST(LlvmLibclog1pfTest, InFloatRange) {
64*9e7688c7STue Ly   constexpr uint32_t COUNT = 1000000;
65*9e7688c7STue Ly   constexpr uint32_t STEP = UINT32_MAX / COUNT;
66*9e7688c7STue Ly   for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
67*9e7688c7STue Ly     float x = float(FPBits(v));
68*9e7688c7STue Ly     if (isnan(x) || isinf(x))
69*9e7688c7STue Ly       continue;
70*9e7688c7STue Ly     errno = 0;
71*9e7688c7STue Ly     float result = __llvm_libc::log1pf(x);
72*9e7688c7STue Ly     // If the computation resulted in an error or did not produce valid result
73*9e7688c7STue Ly     // in the single-precision floating point range, then ignore comparing with
74*9e7688c7STue Ly     // MPFR result as MPFR can still produce valid results because of its
75*9e7688c7STue Ly     // wider precision.
76*9e7688c7STue Ly     if (isnan(result) || isinf(result) || errno != 0)
77*9e7688c7STue Ly       continue;
78*9e7688c7STue Ly     ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log1p, x,
79*9e7688c7STue Ly                                    __llvm_libc::log1pf(x), 0.5);
80*9e7688c7STue Ly   }
81*9e7688c7STue Ly }
82