[libc-commits] [libc] [libc][math] Fix FP signed-zero add/sub for zero operands (PR #183243)
via libc-commits
libc-commits at lists.llvm.org
Tue Feb 24 21:56:36 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: Hanliang Xu (Hanliang-Xu)
<details>
<summary>Changes</summary>
(-0.0) + (-0.0) and (-0.0) - (+0.0) returned +0.0 instead of -0.0.
Ensure these cases comply with IEEE 754 ยง6.3 rule.
---
Full diff: https://github.com/llvm/llvm-project/pull/183243.diff
3 Files Affected:
- (modified) libc/src/__support/FPUtil/generic/add_sub.h (+2)
- (modified) libc/test/src/math/smoke/AddTest.h (+10-2)
- (modified) libc/test/src/math/smoke/SubTest.h (+10-2)
``````````diff
diff --git a/libc/src/__support/FPUtil/generic/add_sub.h b/libc/src/__support/FPUtil/generic/add_sub.h
index 9f3ecff0eb233..4ef9ce06ebf95 100644
--- a/libc/src/__support/FPUtil/generic/add_sub.h
+++ b/libc/src/__support/FPUtil/generic/add_sub.h
@@ -96,6 +96,8 @@ add_or_sub(InType x, InType y) {
if (x_bits.is_zero()) {
if (y_bits.is_zero()) {
+ if (is_effectively_add)
+ return OutFPBits::zero(x_bits.sign()).get_val();
switch (quick_get_round()) {
case FE_DOWNWARD:
return OutFPBits::zero(Sign::NEG).get_val();
diff --git a/libc/test/src/math/smoke/AddTest.h b/libc/test/src/math/smoke/AddTest.h
index d0a9dcb9c2830..e6dc18de19403 100644
--- a/libc/test/src/math/smoke/AddTest.h
+++ b/libc/test/src/math/smoke/AddTest.h
@@ -165,6 +165,10 @@ class AddTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ(OutType(-1.0), func(InType(-2.0), InType(1.0)));
EXPECT_FP_EQ(OutType(-3.0), func(InType(-2.0), InType(-1.0)));
}
+
+ void test_signed_zero_result(AddFunc func) {
+ EXPECT_FP_EQ(OutType(-0.0), func(InType(-0.0), InType(-0.0)));
+ }
};
#define LIST_ADD_TESTS(OutType, InType, func) \
@@ -176,7 +180,8 @@ class AddTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
TEST_F(LlvmLibcAddTest, RangeErrors) { test_range_errors(&func); } \
TEST_F(LlvmLibcAddTest, InexactResults) { test_inexact_results(&func); } \
TEST_F(LlvmLibcAddTest, MixedNormality) { test_mixed_normality(&func); } \
- TEST_F(LlvmLibcAddTest, MixedSigns) { test_mixed_signs(&func); }
+ TEST_F(LlvmLibcAddTest, MixedSigns) { test_mixed_signs(&func); } \
+ TEST_F(LlvmLibcAddTest, SignedZeroResult) { test_signed_zero_result(&func); }
#define LIST_ADD_SAME_TYPE_TESTS(suffix, OutType, InType, func) \
using LlvmLibcAddTest##suffix = AddTest<OutType, InType>; \
@@ -193,6 +198,9 @@ class AddTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
TEST_F(LlvmLibcAddTest##suffix, MixedNormality) { \
test_mixed_normality(&func); \
} \
- TEST_F(LlvmLibcAddTest##suffix, MixedSigns) { test_mixed_signs(&func); }
+ TEST_F(LlvmLibcAddTest##suffix, MixedSigns) { test_mixed_signs(&func); } \
+ TEST_F(LlvmLibcAddTest##suffix, SignedZeroResult) { \
+ test_signed_zero_result(&func); \
+ }
#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_ADDTEST_H
diff --git a/libc/test/src/math/smoke/SubTest.h b/libc/test/src/math/smoke/SubTest.h
index 79086aa0bfb72..669af15c4b687 100644
--- a/libc/test/src/math/smoke/SubTest.h
+++ b/libc/test/src/math/smoke/SubTest.h
@@ -156,6 +156,10 @@ class SubTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
EXPECT_FP_EQ(OutType(-3.0), func(InType(-2.0), InType(1.0)));
EXPECT_FP_EQ(OutType(-1.0), func(InType(-2.0), InType(-1.0)));
}
+
+ void test_signed_zero_result(SubFunc func) {
+ EXPECT_FP_EQ(OutType(-0.0), func(InType(-0.0), InType(0.0)));
+ }
};
#define LIST_SUB_TESTS(OutType, InType, func) \
@@ -166,7 +170,8 @@ class SubTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
} \
TEST_F(LlvmLibcSubTest, RangeErrors) { test_range_errors(&func); } \
TEST_F(LlvmLibcSubTest, InexactResults) { test_inexact_results(&func); } \
- TEST_F(LlvmLibcSubTest, MixedSigns) { test_mixed_signs(&func); }
+ TEST_F(LlvmLibcSubTest, MixedSigns) { test_mixed_signs(&func); } \
+ TEST_F(LlvmLibcSubTest, SignedZeroResult) { test_signed_zero_result(&func); }
#define LIST_SUB_SAME_TYPE_TESTS(suffix, OutType, InType, func) \
using LlvmLibcSubTest##suffix = SubTest<OutType, InType>; \
@@ -180,6 +185,9 @@ class SubTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
TEST_F(LlvmLibcSubTest##suffix, InexactResults) { \
test_inexact_results(&func); \
} \
- TEST_F(LlvmLibcSubTest##suffix, MixedSigns) { test_mixed_signs(&func); }
+ TEST_F(LlvmLibcSubTest##suffix, MixedSigns) { test_mixed_signs(&func); } \
+ TEST_F(LlvmLibcSubTest##suffix, SignedZeroResult) { \
+ test_signed_zero_result(&func); \
+ }
#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_SUBTEST_H
``````````
</details>
https://github.com/llvm/llvm-project/pull/183243
More information about the libc-commits
mailing list