-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[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
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…_ACCURATE_PASS is set.
@llvm/pr-subscribers-libc Author: None (lntue) ChangesPatch is 40.92 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/130811.diff 34 Files Affected:
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]
|
michaelrj-google
approved these changes
Mar 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
No description provided.