[libc-commits] [libc] [libc][math] Fix exp10m1f(-0) in SKIP_ACCURATE_PASS mode (PR #197650)
Simon Tatham via libc-commits
libc-commits at lists.llvm.org
Thu May 14 03:44:38 PDT 2026
https://github.com/statham-arm created https://github.com/llvm/llvm-project/pull/197650
exp10m1f(-0) should return -0, just like expm1f does. But if you build with the LIBC_MATH_SKIP_ACCURATE_PASS flag, it accidentally returned +0, and failed the src.math.smoke.exp10m1f_test test.
The check for -0 is normally done by EXP10M1F_EXCEPTS_LO, a list of cases that are misrounded by the calculation in the branch for small input values. In SKIP_ACCURATE_PASS, that list is omitted, trading off accuracy for code size. But the check for -0 went with them. The fix is to reinsert that in a `#else` clause, if the list isn't included.
>From 5b6880c71b2c46f155b9167704cfba8e599b1512 Mon Sep 17 00:00:00 2001
From: Simon Tatham <simon.tatham at arm.com>
Date: Wed, 13 May 2026 17:02:35 +0100
Subject: [PATCH] [libc][math] Fix exp10m1f(-0) in SKIP_ACCURATE_PASS mode
exp10m1f(-0) should return -0, just like expm1f does. But if you build
with the LIBC_MATH_SKIP_ACCURATE_PASS flag, it accidentally returned
+0, and failed the src.math.smoke.exp10m1f_test test.
The check for -0 is normally done by EXP10M1F_EXCEPTS_LO, a list of
cases that are misrounded by the calculation in the branch for small
input values. In SKIP_ACCURATE_PASS, that list is omitted, trading off
accuracy for code size. But the check for -0 went with them. The fix
is to reinsert that in a `#else` clause, if the list isn't included.
---
libc/src/__support/math/exp10m1f.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/libc/src/__support/math/exp10m1f.h b/libc/src/__support/math/exp10m1f.h
index b423f24808ed0..d0edee49eedc4 100644
--- a/libc/src/__support/math/exp10m1f.h
+++ b/libc/src/__support/math/exp10m1f.h
@@ -132,6 +132,15 @@ LIBC_INLINE LIBC_CONSTEXPR float exp10m1f(float x) {
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
if (auto r = EXP10M1F_EXCEPTS_LO.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
return r.value();
+#else
+ // Even if we're not checking for the misrounded cases in this interval, we
+ // must still check for -0 as input and return -0 as output, rather than +0
+ // as the code below would compute.
+ //
+ // We might as well check for both zeroes at once, in fact, since it's no
+ // slower.
+ if (LIBC_UNLIKELY(x_abs == 0))
+ return x;
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
double dx = x;
More information about the libc-commits
mailing list