[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, "ient));
+ EXPECT_FP_EQ_WITH_EXCEPTION(nan, func(x, y, "ient), FE_INVALID);
+ EXPECT_MATH_ERRNO(EDOM);
x = neg_inf;
- EXPECT_FP_EQ(nan, func(x, y, "ient));
+ EXPECT_FP_EQ_WITH_EXCEPTION(nan, func(x, y, "ient), FE_INVALID);
+ EXPECT_MATH_ERRNO(EDOM);
x = T(1.0);
y = zero;
- EXPECT_FP_EQ(nan, func(x, y, "ient));
+ EXPECT_FP_EQ_WITH_EXCEPTION(nan, func(x, y, "ient), FE_INVALID);
+ EXPECT_MATH_ERRNO(EDOM);
y = neg_zero;
- EXPECT_FP_EQ(nan, func(x, y, "ient));
+ EXPECT_FP_EQ_WITH_EXCEPTION(nan, func(x, y, "ient), 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, "ient));
+ 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, "ient),
+ FE_INVALID);
+ EXPECT_MATH_ERRNO(0);
+ EXPECT_FALSE(FPBits(result).is_signaling_nan());
+ EXPECT_FP_EQ_WITH_EXCEPTION(nan, result = func(other, snan, "ient),
+ 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, "ient), 0);
+ EXPECT_MATH_ERRNO(0);
+ EXPECT_FP_EQ_WITH_EXCEPTION(nan, func(inf, nan, "ient), 0);
+ EXPECT_MATH_ERRNO(0);
+
x = zero;
y = T(1.0);
EXPECT_FP_EQ(func(x, y, "ient), zero);
``````````
</details>
https://github.com/llvm/llvm-project/pull/236474
More information about the libc-commits
mailing list