Skip to content

[libc][math] Skip checking for exceptional values when LIBC_MATH_SKIP_ACCURATE_PASS is set. #130811

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 11, 2025

Conversation

lntue
Copy link
Contributor

@lntue lntue commented Mar 11, 2025

No description provided.

@llvmbot
Copy link
Member

llvmbot commented Mar 11, 2025

@llvm/pr-subscribers-libc

Author: None (lntue)

Changes

Patch is 40.92 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/130811.diff

34 Files Affected:

  • (modified) libc/src/math/generic/acosf.cpp (+4)
  • (modified) libc/src/math/generic/acosf16.cpp (+4)
  • (modified) libc/src/math/generic/acoshf.cpp (+6-1)
  • (modified) libc/src/math/generic/asinf.cpp (+6)
  • (modified) libc/src/math/generic/asinhf.cpp (+5)
  • (modified) libc/src/math/generic/cosf.cpp (+4)
  • (modified) libc/src/math/generic/cosf16.cpp (+4)
  • (modified) libc/src/math/generic/coshf16.cpp (+4)
  • (modified) libc/src/math/generic/erff.cpp (+2)
  • (modified) libc/src/math/generic/exp10f16.cpp (+4)
  • (modified) libc/src/math/generic/exp10m1f.cpp (+6)
  • (modified) libc/src/math/generic/exp10m1f16.cpp (+6)
  • (modified) libc/src/math/generic/exp2f16.cpp (+4)
  • (modified) libc/src/math/generic/exp2f_impl.h (+6-4)
  • (modified) libc/src/math/generic/exp2m1f.cpp (+6)
  • (modified) libc/src/math/generic/exp2m1f16.cpp (+6)
  • (modified) libc/src/math/generic/expf.cpp (+2)
  • (modified) libc/src/math/generic/expf16.cpp (+6)
  • (modified) libc/src/math/generic/expm1f16.cpp (+7)
  • (modified) libc/src/math/generic/log10f.cpp (+2)
  • (modified) libc/src/math/generic/log10f16.cpp (+4)
  • (modified) libc/src/math/generic/log1pf.cpp (+10)
  • (modified) libc/src/math/generic/log2f16.cpp (+4)
  • (modified) libc/src/math/generic/logf.cpp (+4)
  • (modified) libc/src/math/generic/logf16.cpp (+4)
  • (modified) libc/src/math/generic/sincosf.cpp (+4)
  • (modified) libc/src/math/generic/sinf.cpp (+2)
  • (modified) libc/src/math/generic/sinf16.cpp (+5)
  • (modified) libc/src/math/generic/sinhf.cpp (+2)
  • (modified) libc/src/math/generic/sinhf16.cpp (+4)
  • (modified) libc/src/math/generic/tanf.cpp (+7-1)
  • (modified) libc/src/math/generic/tanf16.cpp (+5-1)
  • (modified) libc/src/math/generic/tanhf16.cpp (+4)
  • (modified) libc/src/math/generic/tanpif16.cpp (+5)
diff --git a/libc/src/math/generic/acosf.cpp b/libc/src/math/generic/acosf.cpp
index 3c097a7871380..509a5ebc4973e 100644
--- a/libc/src/math/generic/acosf.cpp
+++ b/libc/src/math/generic/acosf.cpp
@@ -20,6 +20,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 static constexpr size_t N_EXCEPTS = 4;
 
 // Exceptional values when |x| <= 0.5
@@ -34,6 +35,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> ACOSF_EXCEPTS = {{
     // x = -0x1.04c444p-12, acosf(x) = 0x1.923p0 (RZ)
     {0xb9826222, 0x3fc91800, 1, 0, 1},
 }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
 LLVM_LIBC_FUNCTION(float, acosf, (float x)) {
   using FPBits = typename fputil::FPBits<float>;
@@ -51,9 +53,11 @@ LLVM_LIBC_FUNCTION(float, acosf, (float x)) {
       //   acos(x) = pi/2 - asin(x)
       //           ~ pi/2 - x - x^3 / 6
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
       // Check for exceptional values
       if (auto r = ACOSF_EXCEPTS.lookup(x_uint); LIBC_UNLIKELY(r.has_value()))
         return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
       double xd = static_cast<double>(x);
       return static_cast<float>(fputil::multiply_add(
diff --git a/libc/src/math/generic/acosf16.cpp b/libc/src/math/generic/acosf16.cpp
index 858da3bfaa918..202a950fbb5dd 100644
--- a/libc/src/math/generic/acosf16.cpp
+++ b/libc/src/math/generic/acosf16.cpp
@@ -27,6 +27,7 @@ namespace LIBC_NAMESPACE_DECL {
 static constexpr float PI_OVER_2 = 0x1.921fb6p0f;
 static constexpr float PI = 0x1.921fb6p1f;
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 static constexpr size_t N_EXCEPTS = 2;
 
 static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSF16_EXCEPTS{{
@@ -34,6 +35,7 @@ static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSF16_EXCEPTS{{
     {0xacaf, 0x3e93, 1, 0, 0},
     {0xb874, 0x4052, 1, 0, 1},
 }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
 LLVM_LIBC_FUNCTION(float16, acosf16, (float16 x)) {
   using FPBits = fputil::FPBits<float16>;
@@ -64,9 +66,11 @@ LLVM_LIBC_FUNCTION(float16, acosf16, (float16 x)) {
 
   float xf = x;
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
   // Handle exceptional values
   if (auto r = ACOSF16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
     return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
   // |x| == 0x1p0, x is 1 or -1
   // if x is (-)1, return pi, else
diff --git a/libc/src/math/generic/acoshf.cpp b/libc/src/math/generic/acoshf.cpp
index 6158063d30521..c4927fa27a84b 100644
--- a/libc/src/math/generic/acoshf.cpp
+++ b/libc/src/math/generic/acoshf.cpp
@@ -22,7 +22,6 @@ namespace LIBC_NAMESPACE_DECL {
 LLVM_LIBC_FUNCTION(float, acoshf, (float x)) {
   using FPBits_t = typename fputil::FPBits<float>;
   FPBits_t xbits(x);
-  uint32_t x_u = xbits.uintval();
 
   if (LIBC_UNLIKELY(x <= 1.0f)) {
     if (x == 1.0f)
@@ -33,6 +32,8 @@ LLVM_LIBC_FUNCTION(float, acoshf, (float x)) {
     return FPBits_t::quiet_nan().get_val();
   }
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+  uint32_t x_u = xbits.uintval();
   if (LIBC_UNLIKELY(x_u >= 0x4f8ffb03)) {
     if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
       return x;
@@ -64,6 +65,10 @@ LLVM_LIBC_FUNCTION(float, acoshf, (float x)) {
       return round_result_slightly_up(0x1.451436p6f);
     }
   }
+#else
+  if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
+    return x;
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
   double x_d = static_cast<double>(x);
   // acosh(x) = log(x + sqrt(x^2 - 1))
diff --git a/libc/src/math/generic/asinf.cpp b/libc/src/math/generic/asinf.cpp
index b54a9e7b2b00b..da854417e85fe 100644
--- a/libc/src/math/generic/asinf.cpp
+++ b/libc/src/math/generic/asinf.cpp
@@ -21,6 +21,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 static constexpr size_t N_EXCEPTS = 2;
 
 // Exceptional values when |x| <= 0.5
@@ -40,6 +41,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> ASINF_EXCEPTS_HI = {{
     // x = 0x1.ee836cp-1, asinf(x) = 0x1.4f0654p0 (RZ)
     {0x3f7741b6, 0x3fa7832a, 1, 0, 0},
 }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
 LLVM_LIBC_FUNCTION(float, asinf, (float x)) {
   using FPBits = typename fputil::FPBits<float>;
@@ -82,10 +84,12 @@ LLVM_LIBC_FUNCTION(float, asinf, (float x)) {
 #endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
     }
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
     // Check for exceptional values
     if (auto r = ASINF_EXCEPTS_LO.lookup_odd(x_abs, x_sign);
         LIBC_UNLIKELY(r.has_value()))
       return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
     // For |x| <= 0.5, we approximate asinf(x) by:
     //   asin(x) = x * P(x^2)
@@ -111,10 +115,12 @@ LLVM_LIBC_FUNCTION(float, asinf, (float x)) {
     return FPBits::quiet_nan().get_val();
   }
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
   // Check for exceptional values
   if (auto r = ASINF_EXCEPTS_HI.lookup_odd(x_abs, x_sign);
       LIBC_UNLIKELY(r.has_value()))
     return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
   // When |x| > 0.5, we perform range reduction as follow:
   //
diff --git a/libc/src/math/generic/asinhf.cpp b/libc/src/math/generic/asinhf.cpp
index 1d68ac9ea13bc..9cdb7b8394e9d 100644
--- a/libc/src/math/generic/asinhf.cpp
+++ b/libc/src/math/generic/asinhf.cpp
@@ -49,6 +49,7 @@ LLVM_LIBC_FUNCTION(float, asinhf, (float x)) {
   double x_sign = SIGN[x_u >> 31];
   double x_d = x;
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
   // Helper functions to set results for exceptional cases.
   auto round_result_slightly_down = [x_sign](float r) -> float {
     return fputil::multiply_add(static_cast<float>(x_sign), r,
@@ -95,6 +96,10 @@ LLVM_LIBC_FUNCTION(float, asinhf, (float x)) {
       return round_result_slightly_down(0x1.e1b92p3f);
     }
   }
+#else
+  if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
+    return x;
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
   // asinh(x) = log(x + sqrt(x^2 + 1))
   return static_cast<float>(
diff --git a/libc/src/math/generic/cosf.cpp b/libc/src/math/generic/cosf.cpp
index 23e3db067e669..6ea24f9ccd3fa 100644
--- a/libc/src/math/generic/cosf.cpp
+++ b/libc/src/math/generic/cosf.cpp
@@ -20,6 +20,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 // Exceptional cases for cosf.
 static constexpr size_t N_EXCEPTS = 6;
 
@@ -38,6 +39,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> COSF_EXCEPTS{{
     // x = 0x1.ddebdep120, cos(x) = 0x1.114438p-1 (RZ)
     {0x7beef5ef, 0x3f08a21c, 1, 0, 0},
 }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
 LLVM_LIBC_FUNCTION(float, cosf, (float x)) {
   using FPBits = typename fputil::FPBits<float>;
@@ -108,8 +110,10 @@ LLVM_LIBC_FUNCTION(float, cosf, (float x)) {
 #endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
   }
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
   if (auto r = COSF_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value()))
     return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
   // x is inf or nan.
   if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
diff --git a/libc/src/math/generic/cosf16.cpp b/libc/src/math/generic/cosf16.cpp
index 534e07854474e..4d42db981ce71 100644
--- a/libc/src/math/generic/cosf16.cpp
+++ b/libc/src/math/generic/cosf16.cpp
@@ -19,6 +19,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 constexpr size_t N_EXCEPTS = 4;
 
 constexpr fputil::ExceptValues<float16, N_EXCEPTS> COSF16_EXCEPTS{{
@@ -28,6 +29,7 @@ constexpr fputil::ExceptValues<float16, N_EXCEPTS> COSF16_EXCEPTS{{
     {0x5c49, 0xb8c6, 0, 1, 0},
     {0x7acc, 0xa474, 0, 1, 0},
 }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
 LLVM_LIBC_FUNCTION(float16, cosf16, (float16 x)) {
   using FPBits = fputil::FPBits<float16>;
@@ -53,9 +55,11 @@ LLVM_LIBC_FUNCTION(float16, cosf16, (float16 x)) {
   //          = cos(k * pi/32) * cos(y * pi/32) -
   //            sin(k * pi/32) * sin(y * pi/32)
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
   // Handle exceptional values
   if (auto r = COSF16_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value()))
     return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
   // cos(+/-0) = 1
   if (LIBC_UNLIKELY(x_abs == 0U))
diff --git a/libc/src/math/generic/coshf16.cpp b/libc/src/math/generic/coshf16.cpp
index cca7581c70e0e..6668e77000f0c 100644
--- a/libc/src/math/generic/coshf16.cpp
+++ b/libc/src/math/generic/coshf16.cpp
@@ -20,6 +20,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 static constexpr fputil::ExceptValues<float16, 9> COSHF16_EXCEPTS_POS = {{
     // x = 0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ)
     {0x29a8U, 0x3c00U, 1U, 0U, 1U},
@@ -51,6 +52,7 @@ static constexpr fputil::ExceptValues<float16, 4> COSHF16_EXCEPTS_NEG = {{
     // x = -0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ)
     {0xc97cU, 0x7715U, 1U, 0U, 1U},
 }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
 LLVM_LIBC_FUNCTION(float16, coshf16, (float16 x)) {
   using FPBits = fputil::FPBits<float16>;
@@ -89,6 +91,7 @@ LLVM_LIBC_FUNCTION(float16, coshf16, (float16 x)) {
     }
   }
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
   if (x_bits.is_pos()) {
     if (auto r = COSHF16_EXCEPTS_POS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
       return r.value();
@@ -96,6 +99,7 @@ LLVM_LIBC_FUNCTION(float16, coshf16, (float16 x)) {
     if (auto r = COSHF16_EXCEPTS_NEG.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
       return r.value();
   }
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
   return eval_sinh_or_cosh</*IsSinh=*/false>(x);
 }
diff --git a/libc/src/math/generic/erff.cpp b/libc/src/math/generic/erff.cpp
index 15357452759ea..016afe4a68140 100644
--- a/libc/src/math/generic/erff.cpp
+++ b/libc/src/math/generic/erff.cpp
@@ -141,6 +141,7 @@ LLVM_LIBC_FUNCTION(float, erff, (float x)) {
     return ONE[sign] + SMALL[sign];
   }
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
   // Exceptional mask = common 0 bits of 2 exceptional values.
   constexpr uint32_t EXCEPT_MASK = 0x809a'6184U;
 
@@ -155,6 +156,7 @@ LLVM_LIBC_FUNCTION(float, erff, (float x)) {
     if (x_abs == 0U)
       return x;
   }
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
   // Polynomial approximation:
   //   erf(x) ~ x * (c0 + c1 * x^2 + c2 * x^4 + ... + c7 * x^14)
diff --git a/libc/src/math/generic/exp10f16.cpp b/libc/src/math/generic/exp10f16.cpp
index f2002e9f146c0..31abf3b4f89b2 100644
--- a/libc/src/math/generic/exp10f16.cpp
+++ b/libc/src/math/generic/exp10f16.cpp
@@ -26,6 +26,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 #ifdef LIBC_TARGET_CPU_HAS_FMA_FLOAT
 static constexpr size_t N_EXP10F16_EXCEPTS = 5;
 #else
@@ -53,6 +54,7 @@ static constexpr fputil::ExceptValues<float16, N_EXP10F16_EXCEPTS>
         {0x446eU, 0x7690U, 1U, 0U, 1U},
 #endif
     }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
 LLVM_LIBC_FUNCTION(float16, exp10f16, (float16 x)) {
   using FPBits = fputil::FPBits<float16>;
@@ -119,8 +121,10 @@ LLVM_LIBC_FUNCTION(float16, exp10f16, (float16 x)) {
     }
   }
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
   if (auto r = EXP10F16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
     return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
   // 10^x = 2^((hi + mid) * log2(10)) * 10^lo
   auto [exp2_hi_mid, exp10_lo] = exp10_range_reduction(x);
diff --git a/libc/src/math/generic/exp10m1f.cpp b/libc/src/math/generic/exp10m1f.cpp
index c0e302eea7b08..e973b2921c2e4 100644
--- a/libc/src/math/generic/exp10m1f.cpp
+++ b/libc/src/math/generic/exp10m1f.cpp
@@ -22,6 +22,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 static constexpr size_t N_EXCEPTS_LO = 11;
 
 static constexpr fputil::ExceptValues<float, N_EXCEPTS_LO> EXP10M1F_EXCEPTS_LO =
@@ -94,6 +95,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS_HI> EXP10M1F_EXCEPTS_HI =
         // x = -0x1.ca4322p-5, exp10m1f(x) = -0x1.ef073p-4 (RZ)
         {0xbd65'2191U, 0xbdf7'8398U, 0U, 1U, 1U},
     }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
 LLVM_LIBC_FUNCTION(float, exp10m1f, (float x)) {
   using FPBits = fputil::FPBits<float>;
@@ -119,8 +121,10 @@ LLVM_LIBC_FUNCTION(float, exp10m1f, (float x)) {
 
   // When |x| <= log10(2) * 2^(-6)
   if (LIBC_UNLIKELY(x_abs <= 0x3b9a'209bU)) {
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
     if (auto r = EXP10M1F_EXCEPTS_LO.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
       return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
     double dx = x;
     double dx_sq = dx * dx;
@@ -192,8 +196,10 @@ LLVM_LIBC_FUNCTION(float, exp10m1f, (float x)) {
     }
   }
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
   if (auto r = EXP10M1F_EXCEPTS_HI.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
     return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
   // Range reduction: 10^x = 2^(mid + hi) * 10^lo
   //   rr = (2^(mid + hi), lo)
diff --git a/libc/src/math/generic/exp10m1f16.cpp b/libc/src/math/generic/exp10m1f16.cpp
index 41e2c2bb14b04..545c479694811 100644
--- a/libc/src/math/generic/exp10m1f16.cpp
+++ b/libc/src/math/generic/exp10m1f16.cpp
@@ -24,6 +24,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 static constexpr fputil::ExceptValues<float16, 3> EXP10M1F16_EXCEPTS_LO = {{
     // (input, RZ output, RU offset, RD offset, RN offset)
     // x = 0x1.5c4p-4, exp10m1f16(x) = 0x1.bacp-3 (RZ)
@@ -58,6 +59,7 @@ static constexpr fputil::ExceptValues<float16, N_EXP10M1F16_EXCEPTS_HI>
         {0x44bdU, 0x7aaeU, 1U, 0U, 1U},
 #endif
     }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
 LLVM_LIBC_FUNCTION(float16, exp10m1f16, (float16 x)) {
   using FPBits = fputil::FPBits<float16>;
@@ -122,9 +124,11 @@ LLVM_LIBC_FUNCTION(float16, exp10m1f16, (float16 x)) {
       if (LIBC_UNLIKELY(x_abs == 0))
         return x;
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
       if (auto r = EXP10M1F16_EXCEPTS_LO.lookup(x_u);
           LIBC_UNLIKELY(r.has_value()))
         return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
       float xf = x;
       // Degree-5 minimax polynomial generated by Sollya with the following
@@ -153,8 +157,10 @@ LLVM_LIBC_FUNCTION(float16, exp10m1f16, (float16 x)) {
     }
   }
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
   if (auto r = EXP10M1F16_EXCEPTS_HI.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
     return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
   // exp10(x) = exp2((hi + mid) * log2(10)) * exp10(lo)
   auto [exp2_hi_mid, exp10_lo] = exp10_range_reduction(x);
diff --git a/libc/src/math/generic/exp2f16.cpp b/libc/src/math/generic/exp2f16.cpp
index 858053fe2bccb..5c039c59df1af 100644
--- a/libc/src/math/generic/exp2f16.cpp
+++ b/libc/src/math/generic/exp2f16.cpp
@@ -21,6 +21,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 static constexpr fputil::ExceptValues<float16, 3> EXP2F16_EXCEPTS = {{
     // (input, RZ output, RU offset, RD offset, RN offset)
     // x = 0x1.714p-11, exp2f16(x) = 0x1p+0 (RZ)
@@ -30,6 +31,7 @@ static constexpr fputil::ExceptValues<float16, 3> EXP2F16_EXCEPTS = {{
     // x = -0x1.d5cp-4, exp2f16(x) = 0x1.d8cp-1 (RZ)
     {0xaf57U, 0x3b63U, 1U, 0U, 0U},
 }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
 LLVM_LIBC_FUNCTION(float16, exp2f16, (float16 x)) {
   using FPBits = fputil::FPBits<float16>;
@@ -82,8 +84,10 @@ LLVM_LIBC_FUNCTION(float16, exp2f16, (float16 x)) {
     }
   }
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
   if (auto r = EXP2F16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
     return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
   // exp2(x) = exp2(hi + mid) * exp2(lo)
   auto [exp2_hi_mid, exp2_lo] = exp2_range_reduction(x);
diff --git a/libc/src/math/generic/exp2f_impl.h b/libc/src/math/generic/exp2f_impl.h
index ae2d0628c1205..5c6c2bd415188 100644
--- a/libc/src/math/generic/exp2f_impl.h
+++ b/libc/src/math/generic/exp2f_impl.h
@@ -27,10 +27,6 @@ namespace LIBC_NAMESPACE_DECL {
 namespace generic {
 
 LIBC_INLINE float exp2f(float x) {
-  constexpr uint32_t EXVAL1 = 0x3b42'9d37U;
-  constexpr uint32_t EXVAL2 = 0xbcf3'a937U;
-  constexpr uint32_t EXVAL_MASK = EXVAL1 & EXVAL2;
-
   using FPBits = typename fputil::FPBits<float>;
   FPBits xbits(x);
 
@@ -46,6 +42,11 @@ LIBC_INLINE float exp2f(float x) {
         return 1.0f + x;
       }
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
+      constexpr uint32_t EXVAL1 = 0x3b42'9d37U;
+      constexpr uint32_t EXVAL2 = 0xbcf3'a937U;
+      constexpr uint32_t EXVAL_MASK = EXVAL1 & EXVAL2;
+
       // Check exceptional values.
       if (LIBC_UNLIKELY((x_u & EXVAL_MASK) == EXVAL_MASK)) {
         if (LIBC_UNLIKELY(x_u == EXVAL1)) { // x = 0x1.853a6ep-9f
@@ -54,6 +55,7 @@ LIBC_INLINE float exp2f(float x) {
           return fputil::round_result_slightly_down(0x1.f58d62p-1f);
         }
       }
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
       // Minimax polynomial generated by Sollya with:
       // > P = fpminimax((2^x - 1)/x, 5, [|D...|], [-2^-5, 2^-5]);
diff --git a/libc/src/math/generic/exp2m1f.cpp b/libc/src/math/generic/exp2m1f.cpp
index 2060dc34cc9bf..4913a5e4277e4 100644
--- a/libc/src/math/generic/exp2m1f.cpp
+++ b/libc/src/math/generic/exp2m1f.cpp
@@ -23,6 +23,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 static constexpr size_t N_EXCEPTS_LO = 8;
 
 static constexpr fputil::ExceptValues<float, N_EXCEPTS_LO> EXP2M1F_EXCEPTS_LO =
@@ -58,6 +59,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS_HI> EXP2M1F_EXCEPTS_HI =
         // x = -0x1.de7b9cp-5, exp2m1f(x) = -0x1.4508f4p-5 (RZ)
         {0xbd6f'3dceU, 0xbd22'847aU, 0U, 1U, 1U},
     }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
 LLVM_LIBC_FUNCTION(float, exp2m1f, (float x)) {
   using FPBits = fputil::FPBits<float>;
@@ -70,8 +72,10 @@ LLVM_LIBC_FUNCTION(float, exp2m1f, (float x)) {
   if (LIBC_UNLIKELY(x_abs >= 0x4300'0000U || x_abs <= 0x3d00'0000U)) {
     // |x| <= 2^-5
     if (x_abs <= 0x3d00'0000U) {
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
       if (auto r = EXP2M1F_EXCEPTS_LO.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
         return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
       // Minimax polynomial generated by Sollya with:
       // > display = hexadecimal;
@@ -121,8 +125,10 @@ LLVM_LIBC_FUNCTION(float, exp2m1f, (float x)) {
     return -1.0f;
   }
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
   if (auto r = EXP2M1F_EXCEPTS_HI.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
     return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
   // For -25 < x < 128, to compute 2^x, we perform the following range
   // reduction: find hi, mid, lo such that:
diff --git a/libc/src/math/generic/exp2m1f16.cpp b/libc/src/math/generic/exp2m1f16.cpp
index eceb76f1893e2..61633cd2cfcfb 100644
--- a/libc/src/math/generic/exp2m1f16.cpp
+++ b/libc/src/math/generic/exp2m1f16.cpp
@@ -24,6 +24,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 static constexpr fputil::ExceptValues<float16, 6> EXP2M1F16_EXCEPTS_LO = {{
     // (input, RZ output, RU offset, RD offset, RN offset)
     // x = 0x1.cf4p-13, exp2m1f16(x) = 0x1.41p-13 (RZ)
@@ -72,6 +73,7 @@ static constexpr fputil::ExceptValues<float16, N_EXP2M1F16_EXCEPTS_HI>
         {0xba8dU, 0xb6edU, 0U, 1U, 1U},
 #endif
     }};
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
 LLVM_LIBC_FUNCTION(float16, exp2m1f16, (float16 x)) {
   using FPBits = fputil::FPBits<float16>;
@@ -132,9 +134,11 @@ LLVM_LIBC_FUNCTION(float16, exp2m1f16, (float16 x)) {
 
     // When |x| <= 2^(-3).
     if (x_abs <= 0x3000U) {
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
       if (auto r = EXP2M1F16_EXCEPTS_LO.lookup(x_u);
           LIBC_UNLIKELY(r.has_value()))
         return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
       float xf = x;
       // Degree-5 minimax polynomial generated by Sollya with the following
@@ -149,8 +153,10 @@ LLVM_LIBC_FUNCTION(float16, exp2m1f16, (float16 x)) {
     }
   }
 
+#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
   if (auto r = EXP2M1F16_EXCEPTS_HI.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
     return r.value();
+#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
 
   // exp2(x) = exp2(hi + mid) * exp2(lo)
   auto [exp2_hi_mid, exp2_lo] = exp2_range_reduction(x);
diff --git a/libc/src/math/generic/expf.cpp b/libc/src/math/generic/expf.cpp
index ee5c2a32b6c6b..fa507d4d9322c 100644
--- a/libc/src/math/generic/expf.cpp
+++ b/libc/src/math/generic/expf.cpp
@@ -28,10 +28,12 @@ LLVM_LIBC...
[truncated]

Copy link
Contributor

@michaelrj-google michaelrj-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@lntue lntue merged commit d578148 into llvm:main Mar 11, 2025
16 of 17 checks passed
@lntue lntue deleted the exceptional branch March 11, 2025 21:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants