[libc-commits] [libc] [libc][math] Added missing floating point exception for log10p1f16 (PR #188171)
via libc-commits
libc-commits at lists.llvm.org
Tue Mar 24 01:31:00 PDT 2026
https://github.com/Sukumarsawant updated https://github.com/llvm/llvm-project/pull/188171
>From b10ebc6118f9715280cd114ae2b0ba8794a0d828 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 24 Mar 2026 10:03:59 +0530
Subject: [PATCH 1/2] feat: fix spurious underflow
---
libc/src/__support/math/log10p1f16.h | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/libc/src/__support/math/log10p1f16.h b/libc/src/__support/math/log10p1f16.h
index 54533c994df81..93dd1f8824632 100644
--- a/libc/src/__support/math/log10p1f16.h
+++ b/libc/src/__support/math/log10p1f16.h
@@ -40,6 +40,18 @@ LIBC_INLINE float16 log10p1f16(float16 x) {
uint16_t x_u = x_bits.uintval();
uint16_t x_abs = x_u & 0x7fffU;
+ auto pre_rounding_check = [](double x) {
+ constexpr double MIN_NORMAL = 0x1.0p-14;
+ constexpr double midpoint = 0x1.ffcp-15;
+
+ double x_abs = x > 0 ? x : -x;
+ // [min-ulp/2,min) -> min
+ if (x_abs < MIN_NORMAL && x_abs >= midpoint &&
+ fputil::fenv_is_round_to_nearest()) {
+ x = (x > 0) ? MIN_NORMAL : -MIN_NORMAL;
+ }
+ return static_cast<float16>(x);
+ };
// If x is +-0, NaN, +/-inf, or |x| <= 2^-3.
if (LIBC_UNLIKELY(x_abs <= 0x3000U || x_abs >= 0x7c00U)) {
// log10p1(NaN) = NaN
@@ -105,7 +117,7 @@ LIBC_INLINE float16 log10p1f16(float16 x) {
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
float xf = x;
- return fputil::cast<float16>(
+ return pre_rounding_check(
xf * fputil::polyeval(xf, 0x1.bcb7b2p-2f, -0x1.bcb4cp-3f,
0x1.2875bcp-3f, -0x1.c2946ep-4f,
0x1.69da2p-4f));
@@ -195,7 +207,7 @@ LIBC_INLINE float16 log10p1f16(float16 x) {
v * fputil::polyeval(v, 0x1.bcb7bp-2f, -0x1.bce168p-3f, 0x1.28acb8p-3f);
// log10(1.mant) = log10(f) + log10(1 + d/f)
float log10_1_mant = LOG10F_F[f] + log10p1_d_over_f;
- return fputil::cast<float16>(
+ return pre_rounding_check(
fputil::multiply_add(static_cast<float>(m), LOG10F_2, log10_1_mant));
}
>From 1a2ae45c68c3e6df46489eb33c836e5aad8082d3 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 24 Mar 2026 14:00:31 +0530
Subject: [PATCH 2/2] fputil::cast
---
libc/src/__support/math/log10p1f16.h | 29 +++++++++++++---------------
1 file changed, 13 insertions(+), 16 deletions(-)
diff --git a/libc/src/__support/math/log10p1f16.h b/libc/src/__support/math/log10p1f16.h
index 93dd1f8824632..87bd37b37bea3 100644
--- a/libc/src/__support/math/log10p1f16.h
+++ b/libc/src/__support/math/log10p1f16.h
@@ -40,18 +40,6 @@ LIBC_INLINE float16 log10p1f16(float16 x) {
uint16_t x_u = x_bits.uintval();
uint16_t x_abs = x_u & 0x7fffU;
- auto pre_rounding_check = [](double x) {
- constexpr double MIN_NORMAL = 0x1.0p-14;
- constexpr double midpoint = 0x1.ffcp-15;
-
- double x_abs = x > 0 ? x : -x;
- // [min-ulp/2,min) -> min
- if (x_abs < MIN_NORMAL && x_abs >= midpoint &&
- fputil::fenv_is_round_to_nearest()) {
- x = (x > 0) ? MIN_NORMAL : -MIN_NORMAL;
- }
- return static_cast<float16>(x);
- };
// If x is +-0, NaN, +/-inf, or |x| <= 2^-3.
if (LIBC_UNLIKELY(x_abs <= 0x3000U || x_abs >= 0x7c00U)) {
// log10p1(NaN) = NaN
@@ -115,12 +103,21 @@ LIBC_INLINE float16 log10p1f16(float16 x) {
if (auto r = LOG10P1F16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
return r.value();
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
-
+ constexpr double MIN_NORMAL = 0x1.0p-14;
+ constexpr double midpoint = 0x1.ffcp-15;
float xf = x;
- return pre_rounding_check(
- xf * fputil::polyeval(xf, 0x1.bcb7b2p-2f, -0x1.bcb4cp-3f,
+ float result = (xf * fputil::polyeval(xf, 0x1.bcb7b2p-2f, -0x1.bcb4cp-3f,
0x1.2875bcp-3f, -0x1.c2946ep-4f,
0x1.69da2p-4f));
+
+ float result_abs = result > 0 ? result : -result;
+ // [min-ulp/2,min) -> min
+ if (result_abs < MIN_NORMAL && result_abs >= midpoint &&
+ (fputil::fenv_is_round_to_nearest() || fputil::fenv_is_round_up())) {
+ result = (result > 0) ? MIN_NORMAL : -MIN_NORMAL;
+ }
+ return fputil::cast<float16>(result);
+
}
}
@@ -207,7 +204,7 @@ LIBC_INLINE float16 log10p1f16(float16 x) {
v * fputil::polyeval(v, 0x1.bcb7bp-2f, -0x1.bce168p-3f, 0x1.28acb8p-3f);
// log10(1.mant) = log10(f) + log10(1 + d/f)
float log10_1_mant = LOG10F_F[f] + log10p1_d_over_f;
- return pre_rounding_check(
+ return fputil::cast<float16>(
fputil::multiply_add(static_cast<float>(m), LOG10F_2, log10_1_mant));
}
More information about the libc-commits
mailing list