| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| //===-- Implementation header for log2f -------------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIBC_SRC_MATH_LOG2F_H | ||
| #define LLVM_LIBC_SRC_MATH_LOG2F_H | ||
|
|
||
| namespace __llvm_libc { | ||
|
|
||
| float log2f(float x); | ||
|
|
||
| } // namespace __llvm_libc | ||
|
|
||
| #endif // LLVM_LIBC_SRC_MATH_LOG2F_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| //===-- Differential test for log2f ---------------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "SingleInputSingleOutputDiff.h" | ||
|
|
||
| #include "src/math/log2f.h" | ||
|
|
||
| #include <math.h> | ||
|
|
||
| SINGLE_INPUT_SINGLE_OUTPUT_DIFF(float, __llvm_libc::log2f, ::log2f, | ||
| "log2f_diff.log") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| //===-- Differential test for log2f ---------------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "SingleInputSingleOutputDiff.h" | ||
|
|
||
| #include "src/math/log2f.h" | ||
|
|
||
| #include <math.h> | ||
|
|
||
| SINGLE_INPUT_SINGLE_OUTPUT_PERF(float, __llvm_libc::log2f, ::log2f, | ||
| "log2f_perf.log") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| //===-- Exhaustive test for log2f -----------------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "exhaustive_test.h" | ||
| #include "src/__support/FPUtil/FPBits.h" | ||
| #include "src/math/log2f.h" | ||
| #include "utils/MPFRWrapper/MPFRUtils.h" | ||
| #include "utils/UnitTest/FPMatcher.h" | ||
|
|
||
| using FPBits = __llvm_libc::fputil::FPBits<float>; | ||
|
|
||
| namespace mpfr = __llvm_libc::testing::mpfr; | ||
|
|
||
| struct LlvmLibcLog2fExhaustiveTest : public LlvmLibcExhaustiveTest<uint32_t> { | ||
| void check(uint32_t start, uint32_t stop, | ||
| mpfr::RoundingMode rounding) override { | ||
| mpfr::ForceRoundingMode r(rounding); | ||
| uint32_t bits = start; | ||
| do { | ||
| FPBits xbits(bits); | ||
| float x = float(xbits); | ||
| EXPECT_MPFR_MATCH(mpfr::Operation::Log2, x, __llvm_libc::log2f(x), 0.5, | ||
| rounding); | ||
| } while (bits++ < stop); | ||
| } | ||
| }; | ||
|
|
||
| TEST_F(LlvmLibcLog2fExhaustiveTest, RoundNearestTieToEven) { | ||
| test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16, | ||
| mpfr::RoundingMode::Nearest); | ||
| } | ||
|
|
||
| TEST_F(LlvmLibcLog2fExhaustiveTest, RoundUp) { | ||
| test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16, | ||
| mpfr::RoundingMode::Upward); | ||
| } | ||
|
|
||
| TEST_F(LlvmLibcLog2fExhaustiveTest, RoundDown) { | ||
| test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16, | ||
| mpfr::RoundingMode::Downward); | ||
| } | ||
|
|
||
| TEST_F(LlvmLibcLog2fExhaustiveTest, RoundTowardZero) { | ||
| test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16, | ||
| mpfr::RoundingMode::TowardZero); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| //===-- Unittests for log2f -----------------------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "src/__support/FPUtil/FPBits.h" | ||
| #include "src/math/log2f.h" | ||
| #include "utils/MPFRWrapper/MPFRUtils.h" | ||
| #include "utils/UnitTest/FPMatcher.h" | ||
| #include "utils/UnitTest/Test.h" | ||
| #include <math.h> | ||
|
|
||
| #include <errno.h> | ||
| #include <stdint.h> | ||
|
|
||
| namespace mpfr = __llvm_libc::testing::mpfr; | ||
|
|
||
| DECLARE_SPECIAL_CONSTANTS(float) | ||
|
|
||
| TEST(LlvmLibcLog2fTest, SpecialNumbers) { | ||
| EXPECT_FP_EQ(aNaN, __llvm_libc::log2f(aNaN)); | ||
| EXPECT_FP_EQ(inf, __llvm_libc::log2f(inf)); | ||
| EXPECT_TRUE(FPBits(__llvm_libc::log2f(neg_inf)).is_nan()); | ||
| EXPECT_FP_EQ(neg_inf, __llvm_libc::log2f(0.0f)); | ||
| EXPECT_FP_EQ(neg_inf, __llvm_libc::log2f(-0.0f)); | ||
| EXPECT_TRUE(FPBits(__llvm_libc::log2f(-1.0f)).is_nan()); | ||
| EXPECT_FP_EQ(zero, __llvm_libc::log2f(1.0f)); | ||
| } | ||
|
|
||
| TEST(LlvmLibcLog2fTest, TrickyInputs) { | ||
| constexpr int N = 9; | ||
| constexpr uint32_t INPUTS[N] = {0x3f7d57f5U, 0x3f7ed848U, 0x3f7fd6ccU, | ||
| 0x3f7fffffU, 0x3f80079bU, 0x3f81d0b5U, | ||
| 0x3f82e602U, 0x3f83c98dU, 0x3f8cba39U}; | ||
|
|
||
| for (int i = 0; i < N; ++i) { | ||
| float x = float(FPBits(INPUTS[i])); | ||
| EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log2, x, | ||
| __llvm_libc::log2f(x), 0.5); | ||
| } | ||
| } | ||
|
|
||
| TEST(LlvmLibcLog2fTest, InFloatRange) { | ||
| constexpr uint32_t COUNT = 1000000; | ||
| constexpr uint32_t STEP = UINT32_MAX / COUNT; | ||
| for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) { | ||
| float x = float(FPBits(v)); | ||
| if (isnan(x) || isinf(x)) | ||
| continue; | ||
| errno = 0; | ||
| float result = __llvm_libc::log2f(x); | ||
| // If the computation resulted in an error or did not produce valid result | ||
| // in the single-precision floating point range, then ignore comparing with | ||
| // MPFR result as MPFR can still produce valid results because of its | ||
| // wider precision. | ||
| if (isnan(result) || isinf(result) || errno != 0) | ||
| continue; | ||
| ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log2, x, | ||
| __llvm_libc::log2f(x), 0.5); | ||
| } | ||
| } |