[llvm-branch-commits] [libc] [llvm] [libc][math] Add integer-only implementation for exp2f. (PR #233177)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Oct 17 20:32:21 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: lntue
<details>
<summary>Changes</summary>
- Correctly rounded to all rounding mode (statically).
- Share core computations with expf integer-only static-rounding version
- Optimize for code size.
Assisted-by: Gemini for analysis and refactoring.
---
Patch is 27.71 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/233177.diff
15 Files Affected:
- (added) libc/shared/math/static_rounding/exp2f.h (+30)
- (modified) libc/shared/static_rounding_math.h (+1)
- (modified) libc/src/__support/math/CMakeLists.txt (+17)
- (modified) libc/src/__support/math/exp2f.h (+11-2)
- (added) libc/src/__support/math/exp2f_integer_eval.h (+131)
- (modified) libc/test/shared/shared_math_test.cpp (+28)
- (modified) libc/test/src/math/CMakeLists.txt (+1)
- (modified) libc/test/src/math/exhaustive/CMakeLists.txt (+3)
- (modified) libc/test/src/math/exhaustive/exp2f_test.cpp (+18)
- (modified) libc/test/src/math/exp2f_test.cpp (+44-17)
- (modified) libc/test/src/math/smoke/CMakeLists.txt (+1)
- (modified) libc/test/src/math/smoke/exp2f_test.cpp (+39-13)
- (modified) utils/bazel/llvm-project-overlay/libc/BUILD.bazel (+32-1)
- (modified) utils/bazel/llvm-project-overlay/libc/test/src/math/BUILD.bazel (+1)
- (modified) utils/bazel/llvm-project-overlay/libc/test/src/math/smoke/BUILD.bazel (+1)
``````````diff
diff --git a/libc/shared/math/static_rounding/exp2f.h b/libc/shared/math/static_rounding/exp2f.h
new file mode 100644
index 00000000000000..142031e4daf9ab
--- /dev/null
+++ b/libc/shared/math/static_rounding/exp2f.h
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the shared statically-rounded exp2f(x) function
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_MATH_STATIC_ROUNDING_EXP2F_H
+#define LLVM_LIBC_SHARED_MATH_STATIC_ROUNDING_EXP2F_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/exp2f_integer_eval.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+namespace static_rounding {
+
+using math::static_rounding::exp2f;
+
+} // namespace static_rounding
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_STATIC_ROUNDING_EXP2F_H
diff --git a/libc/shared/static_rounding_math.h b/libc/shared/static_rounding_math.h
index 5488354a9b552d..9fc00ade2be962 100644
--- a/libc/shared/static_rounding_math.h
+++ b/libc/shared/static_rounding_math.h
@@ -15,6 +15,7 @@
#define LLVM_LIBC_SHARED_STATIC_ROUNDING_MATH_H
#include "shared/libc_common.h"
+#include "shared/math/static_rounding/exp2f.h"
#include "shared/math/static_rounding/expf.h"
#endif // LLVM_LIBC_SHARED_STATIC_ROUNDING_MATH_H
diff --git a/libc/src/__support/math/CMakeLists.txt b/libc/src/__support/math/CMakeLists.txt
index 6e3837886df6cd..396bcbcb49f575 100644
--- a/libc/src/__support/math/CMakeLists.txt
+++ b/libc/src/__support/math/CMakeLists.txt
@@ -4369,6 +4369,21 @@ add_header_library(
libc.src.__support.macros.optimization
)
+add_header_library(
+ exp2f_integer_eval
+ HDRS
+ exp2f_integer_eval.h
+ DEPENDS
+ .exp2f_integer_utils
+ libc.hdr.fenv_macros
+ libc.src.__support.CPP.bit
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.types
+)
+
add_header_library(
exp2f
HDRS
@@ -4376,9 +4391,11 @@ add_header_library(
DEPENDS
.exp2f_double_eval
.exp2f_float_eval
+ .exp2f_integer_eval
libc.src.__support.common
libc.src.__support.macros.config
libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.cpu_features
)
add_header_library(
diff --git a/libc/src/__support/math/exp2f.h b/libc/src/__support/math/exp2f.h
index e7ce1ec29c03b3..0d08fa6c117649 100644
--- a/libc/src/__support/math/exp2f.h
+++ b/libc/src/__support/math/exp2f.h
@@ -17,6 +17,7 @@
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/cpu_features.h"
#if defined(LIBC_MATH_HAS_SKIP_ACCURATE_PASS) && \
(defined(LIBC_MATH_HAS_SMALL_TABLES) || \
@@ -25,11 +26,19 @@
#include "src/__support/math/exp2f_float_eval.h"
#define LIBC_MATH_EXP2F_IMPL float_eval
-#else // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+#elif !defined(LIBC_TARGET_CPU_HAS_FPU_DOUBLE) && \
+ defined(LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY) && \
+ defined(LIBC_MATH_HAS_NO_EXCEPT) && defined(LIBC_MATH_HAS_NO_ERRNO)
+
+#include "src/__support/math/exp2f_integer_eval.h"
+#define LIBC_MATH_EXP2F_IMPL integer_eval
+
+#else
+
#include "src/__support/math/exp2f_double_eval.h"
#define LIBC_MATH_EXP2F_IMPL double_eval
-#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+#endif
namespace LIBC_NAMESPACE_DECL {
namespace math {
diff --git a/libc/src/__support/math/exp2f_integer_eval.h b/libc/src/__support/math/exp2f_integer_eval.h
new file mode 100644
index 00000000000000..5d60a465fd759a
--- /dev/null
+++ b/libc/src/__support/math/exp2f_integer_eval.h
@@ -0,0 +1,131 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Integer-only implementation of exp2f.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXP2F_INTEGER_EVAL_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_EXP2F_INTEGER_EVAL_H
+
+#include "hdr/fenv_macros.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/macros/properties/types.h"
+#include "src/__support/math/exp2f_integer_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace math {
+namespace static_rounding {
+
+LIBC_ALWAYS_INLINE uint32_t exp2f_bits(uint32_t x_u,
+ [[maybe_unused]] int rounding) {
+ using FPBits = fputil::FPBits<float>;
+
+ bool is_neg = (x_u >> 31) != 0;
+ uint32_t x_abs = x_u & 0x7fff'ffffU;
+ uint32_t x_e = x_abs >> FPBits::FRACTION_LEN;
+
+ // When |x| < 2^-24 (x_e <= 102) or |x| >= 128 (x_e >= 134):
+ if (LIBC_UNLIKELY(x_e - 103U >= 31U)) {
+ // |x| < 2^-24
+ if (x_e <= 102U) {
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ if (LIBC_UNLIKELY(rounding != FE_TONEAREST)) {
+ if (x_abs == 0)
+ return 0x3f80'0000U; // 1.0f
+
+ if (rounding == FE_UPWARD && !is_neg)
+ return 0x3f80'0001U; // 0x1.000002p+0f = 1.0f + 2^-23f
+
+ if ((rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO) && is_neg)
+ return 0x3f7f'ffffU; // 0x1.fffffep-1f = 1.0f - 2^-24f
+
+ return 0x3f80'0000U; // 1.0f
+ }
+#endif // !LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ // For FE_TONEAREST, 2^x rounds to 1.0f (0x3f80'0000U) or
+ // 1.0f - 2^-24f (0x3f7f'ffffU) when
+ // x < log2(1 - 2^-25) ~ -0x1.715476p-25f (0xb338'aa3bU).
+ return 0x3f80'0000U - static_cast<uint32_t>(x_u > 0xb338'aa3bU);
+ }
+
+ // exp2(nan) = nan
+ if (x_abs > 0x7f80'0000U) // |x| > +inf (x is NaN)
+ return x_u | 0x0040'0000U; // silence signaling NaN
+
+ // x >= 128 or +inf:
+ // exp2(x) = +inf for FE_TONEAREST, FE_UPWARD
+ // = FLT_MAX for FE_TOWARDZERO, FE_DOWNWARD
+ if (!is_neg) {
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ if ((rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO) &&
+ x_u < 0x7f80'0000U) // x < +inf
+ return 0x7f7f'ffffU; // 0x1.fffffep+127f (FLT_MAX)
+#endif // !LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ return 0x7f80'0000U; // +inf
+ }
+
+ // x <= -150.0f (0xc316'0000U) or -inf:
+ // exp2(x) = 2^-149 for FE_UPWARD
+ // = +0.0f otherwise
+ if (x_u >= 0xc316'0000U) {
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ if (rounding == FE_UPWARD && x_u < 0xff80'0000U) // x > -inf
+ return 0x0000'0001U; // 0x1.0p-149f (FLT_TRUE_MIN)
+#endif // !LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ return 0x0000'0000U; // +0.0f
+ }
+ }
+
+ // Range reduction:
+ // k = floor(x)
+ // x = k + u, with u in [0, 1)
+ // 2^x = 2^(k + u) = 2^k * 2^u
+ //
+ // For all remaining inputs, x_e is in [103, 134], so shifting the 24-bit
+ // significand of |x| places the binary point of |x| at bit 54.
+ // On 32-bit targets, s = 134 - x_e is in [0, 31], avoiding undefined 32-bit
+ // shift amounts.
+#if defined(LIBC_TYPES_HAS_INT128) && !defined(LIBC_MATH_HAS_SMALL_TABLES)
+ uint64_t m = (x_u & 0x007f'ffffU) | 0x0080'0000U;
+ uint64_t u_bits = m << (x_e - 96U);
+#else // !defined(LIBC_TYPES_HAS_INT128) || defined(LIBC_MATH_HAS_SMALL_TABLES)
+ uint32_t m_hi = ((x_u & 0x007f'ffffU) | 0x0080'0000U) << 6;
+ uint32_t s = 134U - x_e;
+ uint32_t u_lo = (m_hi << 1) << (31U - s);
+ uint32_t u_hi = m_hi >> s;
+ uint64_t u_bits = (static_cast<uint64_t>(u_hi) << 32) | u_lo;
+#endif // defined(LIBC_TYPES_HAS_INT128) && !defined(LIBC_MATH_HAS_SMALL_TABLES)
+
+ return exp2f_eval_bits(u_bits, is_neg, rounding);
+}
+
+// Statically rounded, no-except implementation of exp2f using integer-only
+// arithmetic.
+LIBC_ALWAYS_INLINE float exp2f(float x, [[maybe_unused]] int rounding) {
+ return cpp::bit_cast<float>(exp2f_bits(cpp::bit_cast<uint32_t>(x), rounding));
+}
+
+} // namespace static_rounding
+
+namespace integer_eval {
+
+LIBC_ALWAYS_INLINE float exp2f(float x) {
+ return static_rounding::exp2f(x, FE_TONEAREST);
+}
+
+} // namespace integer_eval
+} // namespace math
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_EXP2F_INTEGER_EVAL_H
diff --git a/libc/test/shared/shared_math_test.cpp b/libc/test/shared/shared_math_test.cpp
index dbbcaab32ce77d..d0581b5dababa9 100644
--- a/libc/test/shared/shared_math_test.cpp
+++ b/libc/test/shared/shared_math_test.cpp
@@ -913,6 +913,13 @@ TEST(LlvmLibcSharedMathTest, StaticRounding) {
EXPECT_FP_EQ(
1.0f, LIBC_NAMESPACE::shared::static_rounding::expf(0.0f, FE_TONEAREST));
+ EXPECT_FP_EQ(
+ 1.0f, LIBC_NAMESPACE::shared::static_rounding::exp2f(0.0f, FE_TONEAREST));
+
+ EXPECT_FP_EQ(
+ 2.0f, LIBC_NAMESPACE::shared::static_rounding::exp2f(1.0f, FE_TONEAREST));
+ EXPECT_FP_EQ(0.5f, LIBC_NAMESPACE::shared::static_rounding::exp2f(
+ -1.0f, FE_TONEAREST));
EXPECT_FP_EQ(0x1.5bf0a8p+1f, LIBC_NAMESPACE::shared::static_rounding::expf(
1.0f, FE_TONEAREST));
@@ -923,21 +930,42 @@ TEST(LlvmLibcSharedMathTest, StaticRounding) {
EXPECT_FP_EQ(0x1.5bf0a8p+1f, LIBC_NAMESPACE::shared::static_rounding::expf(
1.0f, FE_TOWARDZERO));
+ EXPECT_FP_EQ(0x1.6a09e6p+0f, LIBC_NAMESPACE::shared::static_rounding::exp2f(
+ 0.5f, FE_TONEAREST));
+ EXPECT_FP_EQ(0x1.6a09e8p+0f,
+ LIBC_NAMESPACE::shared::static_rounding::exp2f(0.5f, FE_UPWARD));
+ EXPECT_FP_EQ(0x1.6a09e6p+0f, LIBC_NAMESPACE::shared::static_rounding::exp2f(
+ 0.5f, FE_DOWNWARD));
+ EXPECT_FP_EQ(0x1.6a09e6p+0f, LIBC_NAMESPACE::shared::static_rounding::exp2f(
+ 0.5f, FE_TOWARDZERO));
+
int rounding_modes[] = {FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO};
for (int rm : rounding_modes) {
EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::shared::static_rounding::expf(0.0f, rm));
EXPECT_FP_EQ(1.0f,
LIBC_NAMESPACE::shared::static_rounding::expf(-0.0f, rm));
+ EXPECT_FP_EQ(1.0f,
+ LIBC_NAMESPACE::shared::static_rounding::exp2f(0.0f, rm));
+ EXPECT_FP_EQ(1.0f,
+ LIBC_NAMESPACE::shared::static_rounding::exp2f(-0.0f, rm));
EXPECT_TRUE(FPBits(LIBC_NAMESPACE::shared::static_rounding::expf(
FPBits::quiet_nan().get_val(), rm))
.is_nan());
+ EXPECT_TRUE(FPBits(LIBC_NAMESPACE::shared::static_rounding::exp2f(
+ FPBits::quiet_nan().get_val(), rm))
+ .is_nan());
EXPECT_FP_EQ(FPBits::inf(Sign::POS).get_val(),
LIBC_NAMESPACE::shared::static_rounding::expf(
FPBits::inf(Sign::POS).get_val(), rm));
+ EXPECT_FP_EQ(FPBits::inf(Sign::POS).get_val(),
+ LIBC_NAMESPACE::shared::static_rounding::exp2f(
+ FPBits::inf(Sign::POS).get_val(), rm));
EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::shared::static_rounding::expf(
FPBits::inf(Sign::NEG).get_val(), rm));
+ EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::shared::static_rounding::exp2f(
+ FPBits::inf(Sign::NEG).get_val(), rm));
}
}
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 921dbf220eb372..1a3225b1b7df4d 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -1400,6 +1400,7 @@ add_fp_unittest(
libc.src.math.exp2f
libc.src.__support.math.exp2f_double_eval
libc.src.__support.math.exp2f_float_eval
+ libc.src.__support.math.exp2f_integer_eval
libc.src.__support.FPUtil.fp_bits
)
diff --git a/libc/test/src/math/exhaustive/CMakeLists.txt b/libc/test/src/math/exhaustive/CMakeLists.txt
index e1a91fca9b4c81..e19f86b34637d2 100644
--- a/libc/test/src/math/exhaustive/CMakeLists.txt
+++ b/libc/test/src/math/exhaustive/CMakeLists.txt
@@ -255,8 +255,11 @@ add_fp_unittest(
exp2f_test.cpp
DEPENDS
.exhaustive_test
+ .exhaustive_test_static_rounding
libc.src.math.exp2f
+ libc.src.__support.math.exp2f_double_eval
libc.src.__support.math.exp2f_float_eval
+ libc.src.__support.math.exp2f_integer_eval
libc.src.__support.FPUtil.fp_bits
LINK_LIBRARIES
-lpthread
diff --git a/libc/test/src/math/exhaustive/exp2f_test.cpp b/libc/test/src/math/exhaustive/exp2f_test.cpp
index 33f94adb48455b..79559d5bc2a52e 100644
--- a/libc/test/src/math/exhaustive/exp2f_test.cpp
+++ b/libc/test/src/math/exhaustive/exp2f_test.cpp
@@ -6,9 +6,12 @@
//
//===----------------------------------------------------------------------===//
+#include "src/__support/math/exp2f_double_eval.h"
#include "src/__support/math/exp2f_float_eval.h"
+#include "src/__support/math/exp2f_integer_eval.h"
#include "src/math/exp2f.h"
#include "test/src/math/exhaustive/exhaustive_test.h"
+#include "test/src/math/exhaustive/exhaustive_test_static_rounding.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
@@ -50,3 +53,18 @@ TEST_F(LlvmLibcExp2fFloatExhaustiveTest, PositiveRange) {
TEST_F(LlvmLibcExp2fFloatExhaustiveTest, NegativeRange) {
test_full_range(mpfr::RoundingMode::Nearest, NEG_START, NEG_STOP);
}
+
+// Statically rounded implementation: tested against double_eval across all
+// roundings.
+using LlvmLibcExp2fStaticRoundingExhaustiveTest =
+ LlvmLibcStaticallyRoundedUnaryOpExhaustiveMathTest<
+ float, LIBC_NAMESPACE::math::double_eval::exp2f,
+ LIBC_NAMESPACE::math::static_rounding::exp2f>;
+
+TEST_F(LlvmLibcExp2fStaticRoundingExhaustiveTest, PositiveRange) {
+ test_full_range_all_roundings(POS_START, POS_STOP);
+}
+
+TEST_F(LlvmLibcExp2fStaticRoundingExhaustiveTest, NegativeRange) {
+ test_full_range_all_roundings(NEG_START, NEG_STOP);
+}
diff --git a/libc/test/src/math/exp2f_test.cpp b/libc/test/src/math/exp2f_test.cpp
index d5ed25b8aa0929..47761afd932f01 100644
--- a/libc/test/src/math/exp2f_test.cpp
+++ b/libc/test/src/math/exp2f_test.cpp
@@ -20,6 +20,7 @@
#include "src/__support/macros/optimization.h"
#include "src/__support/math/exp2f_double_eval.h"
#include "src/__support/math/exp2f_float_eval.h"
+#include "src/__support/math/exp2f_integer_eval.h"
#include "src/math/exp2f.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
@@ -35,21 +36,26 @@ namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
class Exp2fTest : public LIBC_NAMESPACE::testing::FPTest<float> {
public:
- void test_special_numbers(float (*func)(float)) {
+ void test_special_numbers(float (*func)(float), bool check_errno = true) {
EXPECT_FP_EQ(aNaN, func(aNaN));
- EXPECT_MATH_ERRNO(0);
+ if (check_errno)
+ EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(inf, func(inf));
- EXPECT_MATH_ERRNO(0);
+ if (check_errno)
+ EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(0.0f, func(neg_inf));
- EXPECT_MATH_ERRNO(0);
+ if (check_errno)
+ EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(1.0f, func(0.0f));
- EXPECT_MATH_ERRNO(0);
+ if (check_errno)
+ EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(1.0f, func(-0.0f));
- EXPECT_MATH_ERRNO(0);
+ if (check_errno)
+ EXPECT_MATH_ERRNO(0);
}
void test_overflow(float (*func)(float),
@@ -70,7 +76,7 @@ class Exp2fTest : public LIBC_NAMESPACE::testing::FPTest<float> {
}
void test_tricky_inputs(float (*func)(float), double ulp_tolerance = 0.5,
- bool all_rounding = true) {
+ bool all_rounding = true, bool check_errno = true) {
constexpr int N = 12;
constexpr uint32_t INPUTS[N] = {
0x3b429d37U, /*0x1.853a6ep-9f*/
@@ -95,7 +101,9 @@ class Exp2fTest : public LIBC_NAMESPACE::testing::FPTest<float> {
} else {
EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, func(x), ulp_tolerance);
}
- EXPECT_MATH_ERRNO(0);
+ if (check_errno) {
+ EXPECT_MATH_ERRNO(0);
+ }
}
}
@@ -159,25 +167,44 @@ class Exp2fTest : public LIBC_NAMESPACE::testing::FPTest<float> {
}
};
-#define LIST_EXP2F_TESTS(suffix, func, ulp_tolerance, all_rounding) \
+#define LIST_EXP2F_TESTS(suffix, func, ulp_tolerance, all_rounding, \
+ check_exception_and_errno, check_errno) \
using LlvmLibcExp2fTest##suffix = Exp2fTest; \
TEST_F(LlvmLibcExp2fTest##suffix, SpecialNumbers) { \
- test_special_numbers(&func); \
+ test_special_numbers(&func, check_errno); \
+ } \
+ TEST_F(LlvmLibcExp2fTest##suffix, Overflow) { \
+ test_overflow(&func, check_exception_and_errno); \
} \
- TEST_F(LlvmLibcExp2fTest##suffix, Overflow) { test_overflow(&func); } \
TEST_F(LlvmLibcExp2fTest##suffix, TrickyInputs) { \
- test_tricky_inputs(&func, ulp_tolerance, all_rounding); \
+ test_tricky_inputs(&func, ulp_tolerance, all_rounding, check_errno); \
} \
TEST_F(LlvmLibcExp2fTest##suffix, Underflow) { \
- test_underflow(&func, ulp_tolerance, all_rounding); \
+ test_underflow(&func, ulp_tolerance, all_rounding, \
+ check_exception_and_errno); \
} \
TEST_F(LlvmLibcExp2fTest##suffix, InFloatRange) { \
- test_in_range(&func, ulp_tolerance, all_rounding); \
+ test_in_range(&func, ulp_tolerance, all_rounding, check_errno); \
}
LIST_EXP2F_TESTS(Default, LIBC_NAMESPACE::exp2f,
- /*ulp_tolerance=*/TOLERANCE + 0.5, /*all_rounding=*/true)
+ /*ulp_tolerance=*/TOLERANCE + 0.5, /*all_rounding=*/true,
+ /*check_exception_and_errno=*/true, /*check_errno=*/true)
LIST_EXP2F_TESTS(DoubleEval, LIBC_NAMESPACE::math::double_eval::exp2f,
- /*ulp_tolerance=*/TOLERANCE + 0.5, /*all_rounding=*/true)
+ /*ulp_tolerance=*/TOLERANCE + 0.5, /*all_rounding=*/true,
+ /*check_exception_and_errno=*/true, /*check_errno=*/true)
LIST_EXP2F_TESTS(FloatEval, LIBC_NAMESPACE::math::float_eval::exp2f,
- /*ulp_tolerance=*/1.5, /*all_rounding=*/false)
+ /*ulp_tolerance=*/1.5, /*all_rounding=*/false,
+ /*check_exception_and_errno=*/true, /*check_errno=*/true)
+LIST_EXP2F_TESTS(IntegerEval, LIBC_NAMESPACE::math::integer_eval::exp2f,
+ /*ulp_tolerance=*/0.5, /*all_rounding=*/false,
+ /*check_exception_and_errno=*/false, /*check_errno=*/false)
+
+static float exp2f_static_rounding(float x) {
+ return LIBC_NAMESPACE::math::static_rounding::exp2f(
+ x, LIBC_NAMESPACE::fputil::quick_get_round());
+}
+
+LIST_EXP2F_TESTS(StaticRounding, exp2f_static_rounding,
+ ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/233177
More information about the llvm-branch-commits
mailing list