[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