[libc-commits] [libc] [libc][math] Skip checking for exceptional values when LIBC_MATH_SKIP_ACCURATE_PASS is set. (PR #130811)
via libc-commits
libc-commits at lists.llvm.org
Tue Mar 11 11:23:00 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: None (lntue)
<details>
<summary>Changes</summary>
---
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
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]
``````````
</details>
https://github.com/llvm/llvm-project/pull/130811
More information about the libc-commits
mailing list