[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