[libc-commits] [libc] [libc][math] Report remquo domain errors and quiet signaling NaNs (PR #236474)

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


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: sriramshastry

<details>
<summary>Changes</summary>

Report FE_INVALID and EDOM for the existing remquo invalid domain cases. Check both
operands for signaling NaNs before quiet NaN propagation, raise FE_INVALID and return a
quiet NaN. Extend the shared tests for both operand orders and NaN precedence, without
constraining the unspecified quotient on NaN results.

## Validation

Tested independently at ea08830d976fbe61384695d33e0acafee8d88737 on x86-64 Linux,
Release, GCC 13 and Clang 18. With only the revised tests, 8/8 smoke target
configurations fail per compiler; with the repair, 8/8 pass. Both signaling-NaN operand
orders explicitly check quietness; quiet-NaN precedence, domain flags, and errno are
covered without asserting the unspecified quotient output.

## Scope and Review

Check both NaN operands before ordinary qNaN propagation. Do not assert the unspecified
quotient output for NaN/domain errors.

## 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/236474.diff


2 Files Affected:

- (modified) libc/src/__support/FPUtil/DivisionAndRemainderOperations.h (+8-1) 
- (modified) libc/test/src/math/smoke/RemQuoTest.h (+29-4) 


``````````diff
diff --git a/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h b/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
index bc22a2331f12d7..a7707382506d15 100644
--- a/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
+++ b/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
@@ -27,12 +27,19 @@ static constexpr int QUOTIENT_LSB_BITS = 3;
 template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
 LIBC_INLINE constexpr T remquo(T x, T y, int &q) {
   FPBits<T> xbits(x), ybits(y);
+  if (xbits.is_signaling_nan() || ybits.is_signaling_nan()) {
+    raise_except_if_required(FE_INVALID);
+    return FPBits<T>::quiet_nan().get_val();
+  }
   if (xbits.is_nan())
     return x;
   if (ybits.is_nan())
     return y;
-  if (xbits.is_inf() || ybits.is_zero())
+  if (xbits.is_inf() || ybits.is_zero()) {
+    set_errno_if_required(EDOM);
+    raise_except_if_required(FE_INVALID);
     return FPBits<T>::quiet_nan().get_val();
+  }
 
   if (xbits.is_zero()) {
     q = 0;
diff --git a/libc/test/src/math/smoke/RemQuoTest.h b/libc/test/src/math/smoke/RemQuoTest.h
index ec0e7636f52599..53a1c6a5bcfedc 100644
--- a/libc/test/src/math/smoke/RemQuoTest.h
+++ b/libc/test/src/math/smoke/RemQuoTest.h
@@ -36,15 +36,19 @@ class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
 
     y = T(1.0);
     x = inf;
-    EXPECT_FP_EQ(nan, func(x, y, &quotient));
+    EXPECT_FP_EQ_WITH_EXCEPTION(nan, func(x, y, &quotient), FE_INVALID);
+    EXPECT_MATH_ERRNO(EDOM);
     x = neg_inf;
-    EXPECT_FP_EQ(nan, func(x, y, &quotient));
+    EXPECT_FP_EQ_WITH_EXCEPTION(nan, func(x, y, &quotient), FE_INVALID);
+    EXPECT_MATH_ERRNO(EDOM);
 
     x = T(1.0);
     y = zero;
-    EXPECT_FP_EQ(nan, func(x, y, &quotient));
+    EXPECT_FP_EQ_WITH_EXCEPTION(nan, func(x, y, &quotient), FE_INVALID);
+    EXPECT_MATH_ERRNO(EDOM);
     y = neg_zero;
-    EXPECT_FP_EQ(nan, func(x, y, &quotient));
+    EXPECT_FP_EQ_WITH_EXCEPTION(nan, func(x, y, &quotient), FE_INVALID);
+    EXPECT_MATH_ERRNO(EDOM);
 
     y = nan;
     x = T(1.0);
@@ -58,6 +62,27 @@ class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
     y = nan;
     EXPECT_FP_EQ(nan, func(x, y, &quotient));
 
+    const T snan = FPBits::signaling_nan().get_val();
+    const T finite = T(1.0);
+    const T others[] = {finite, zero, inf, nan, snan};
+    T result = zero;
+    for (T other : others) {
+      EXPECT_FP_EQ_WITH_EXCEPTION(nan, result = func(snan, other, &quotient),
+                                  FE_INVALID);
+      EXPECT_MATH_ERRNO(0);
+      EXPECT_FALSE(FPBits(result).is_signaling_nan());
+      EXPECT_FP_EQ_WITH_EXCEPTION(nan, result = func(other, snan, &quotient),
+                                  FE_INVALID);
+      EXPECT_MATH_ERRNO(0);
+      EXPECT_FALSE(FPBits(result).is_signaling_nan());
+    }
+
+    // A quiet NaN takes precedence over an otherwise invalid domain.
+    EXPECT_FP_EQ_WITH_EXCEPTION(nan, func(nan, zero, &quotient), 0);
+    EXPECT_MATH_ERRNO(0);
+    EXPECT_FP_EQ_WITH_EXCEPTION(nan, func(inf, nan, &quotient), 0);
+    EXPECT_MATH_ERRNO(0);
+
     x = zero;
     y = T(1.0);
     EXPECT_FP_EQ(func(x, y, &quotient), zero);

``````````

</details>


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


More information about the libc-commits mailing list