[libc-commits] [libc] [libc][math] Preserve the sign of tiny asinhf16 zeros (PR #236479)

via libc-commits libc-commits at lists.llvm.org
Wed Oct 28 20:24:45 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: sriramshastry

<details>
<summary>Changes</summary>

Preserve the input sign after the existing tiny-input asinhf16 correction rounds to zero.
Cover negative minimum subnormal in upward/toward-zero modes and positive minimum
subnormal in downward mode.

## Validation

Tested independently at ea08830d976fbe61384695d33e0acafee8d88737 on x86-64 Linux with
GCC 13 and Clang 18. Both baseline smoke configurations fail per compiler; both patched
configurations pass. MPFR 4.2.1 comparisons cover both zeros and all 2,046 nonzero half
subnormals in every rounding mode: zero patched bit mismatches, including zero sign.
This is a value/sign oracle, not an exception or errno oracle. Changed-hunk formatting
and whitespace checks pass.

## Scope and Review

Limit the claim to signed-zero correction at tiny inputs. I don't claim this fixes all
asinhf16 underflow reporting.

## Updated submission base

Submission base: 10c142fa799e258285b6cfb8fce153864586152d.
The standalone baseline/patched results above remain recorded at their original
tested snapshot. At this newer base, the fourteen-only combined suite passes
150 native configurations per compiler and twelve four-mode numerical runs,
with zero value or scoped-reporting mismatches.

Signed-off-by: sriramshastry <sriramshastry@<!-- -->gmail.com>


---
Full diff: https://github.com/llvm/llvm-project/pull/236479.diff


2 Files Affected:

- (modified) libc/src/__support/math/asinhf16.h (+10-4) 
- (modified) libc/test/src/math/smoke/asinhf16_test.cpp (+15) 


``````````diff
diff --git a/libc/src/__support/math/asinhf16.h b/libc/src/__support/math/asinhf16.h
index e6f108763969bc..6c38159c20a766 100644
--- a/libc/src/__support/math/asinhf16.h
+++ b/libc/src/__support/math/asinhf16.h
@@ -89,10 +89,16 @@ LIBC_INLINE constexpr float16 asinhf16(float16 x) {
     if (LIBC_UNLIKELY(x_abs < 0x29c6)) {
 #ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
       int rounding = fputil::quick_get_round();
-      if ((rounding == FE_UPWARD || rounding == FE_TOWARDZERO) && xf < 0)
-        return fputil::cast<float16>(xf + 0x1p-24f);
-      if ((rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO) && xf > 0)
-        return fputil::cast<float16>(xf - 0x1p-24f);
+      if ((rounding == FE_UPWARD || rounding == FE_TOWARDZERO) && xf < 0) {
+        FPBits result(fputil::cast<float16>(xf + 0x1p-24f));
+        result.set_sign(xbits.sign());
+        return result.get_val();
+      }
+      if ((rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO) && xf > 0) {
+        FPBits result(fputil::cast<float16>(xf - 0x1p-24f));
+        result.set_sign(xbits.sign());
+        return result.get_val();
+      }
 #endif
       return fputil::cast<float16>(xf);
     }
diff --git a/libc/test/src/math/smoke/asinhf16_test.cpp b/libc/test/src/math/smoke/asinhf16_test.cpp
index f17300cf980e25..c3c2bf8c6cf39f 100644
--- a/libc/test/src/math/smoke/asinhf16_test.cpp
+++ b/libc/test/src/math/smoke/asinhf16_test.cpp
@@ -32,3 +32,18 @@ TEST_F(LlvmLibcAsinhf16Test, SpecialNumbers) {
   EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::asinhf16(neg_inf));
   EXPECT_MATH_ERRNO(0);
 }
+
+TEST_F(LlvmLibcAsinhf16Test, TinySignedZeros) {
+  using Bits = LIBC_NAMESPACE::fputil::FPBits<float16>;
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+  EXPECT_FP_EQ_ROUNDING_UPWARD(
+      Bits::zero(LIBC_NAMESPACE::Sign::NEG).get_val(),
+      LIBC_NAMESPACE::asinhf16(Bits(uint16_t(0x8001)).get_val()));
+  EXPECT_FP_EQ_ROUNDING_TOWARD_ZERO(
+      Bits::zero(LIBC_NAMESPACE::Sign::NEG).get_val(),
+      LIBC_NAMESPACE::asinhf16(Bits(uint16_t(0x8001)).get_val()));
+  EXPECT_FP_EQ_ROUNDING_DOWNWARD(
+      Bits::zero().get_val(),
+      LIBC_NAMESPACE::asinhf16(Bits(uint16_t(1)).get_val()));
+#endif
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/236479


More information about the libc-commits mailing list