[libc-commits] [libc] [libc][NFC] Make LIBC_MATH safer and some minor improvements for floating point exception tests. (PR #199392)
via libc-commits
libc-commits at lists.llvm.org
Sat May 23 18:59:12 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: lntue
<details>
<summary>Changes</summary>
- Wrap LIBC_MATH usages inside parentheses
- Skip clearing exceptions when not needed.
- Skip FE_INEXACT when testing FE_UNDERFLOW / FE_OVERFLOW for basic ops.
---
Patch is 30.76 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/199392.diff
11 Files Affected:
- (modified) libc/cmake/modules/LLVMLibCCompileOptionRules.cmake (+1-1)
- (modified) libc/src/__support/macros/optimization.h (+5-5)
- (modified) libc/src/__support/math/cbrt.h (+1-1)
- (modified) libc/src/__support/math/expm1.h (+1-1)
- (modified) libc/test/UnitTest/FPMatcher.h (+58-28)
- (modified) libc/test/src/math/smoke/AddTest.h (+21-26)
- (modified) libc/test/src/math/smoke/DivTest.h (+24-32)
- (modified) libc/test/src/math/smoke/MulTest.h (+26-36)
- (modified) libc/test/src/math/smoke/NextAfterTest.h (+2-2)
- (modified) libc/test/src/math/smoke/NextTowardTest.h (+2-2)
- (modified) libc/test/src/math/smoke/SubTest.h (+27-37)
``````````diff
diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
index 338eae3cee337..c65fc4db605c9 100644
--- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
+++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
@@ -147,7 +147,7 @@ function(_get_compile_options_from_config output_var)
endif()
if(LIBC_CONF_MATH_OPTIMIZATIONS)
- libc_add_definition(config_options "LIBC_MATH=${LIBC_CONF_MATH_OPTIMIZATIONS}")
+ libc_add_definition(config_options "LIBC_MATH=(${LIBC_CONF_MATH_OPTIMIZATIONS})")
if(LIBC_CONF_MATH_OPTIMIZATIONS MATCHES "LIBC_MATH_NO_ERRNO")
list(APPEND config_options "-fno-math-errno")
endif()
diff --git a/libc/src/__support/macros/optimization.h b/libc/src/__support/macros/optimization.h
index a1e5766393190..411653439c88c 100644
--- a/libc/src/__support/macros/optimization.h
+++ b/libc/src/__support/macros/optimization.h
@@ -61,23 +61,23 @@ LIBC_INLINE constexpr bool expects_bool_condition(T value, T expected) {
#define LIBC_MATH 0
#endif // LIBC_MATH
-#if (LIBC_MATH & LIBC_MATH_SKIP_ACCURATE_PASS)
+#if ((LIBC_MATH) & LIBC_MATH_SKIP_ACCURATE_PASS)
#define LIBC_MATH_HAS_SKIP_ACCURATE_PASS
#endif
-#if (LIBC_MATH & LIBC_MATH_SMALL_TABLES)
+#if ((LIBC_MATH) & LIBC_MATH_SMALL_TABLES)
#define LIBC_MATH_HAS_SMALL_TABLES
#endif
-#if (LIBC_MATH & LIBC_MATH_INTERMEDIATE_COMP_IN_FLOAT)
+#if ((LIBC_MATH) & LIBC_MATH_INTERMEDIATE_COMP_IN_FLOAT)
#define LIBC_MATH_HAS_INTERMEDIATE_COMP_IN_FLOAT
#endif
-#if (LIBC_MATH & LIBC_MATH_NO_ERRNO)
+#if ((LIBC_MATH) & LIBC_MATH_NO_ERRNO)
#define LIBC_MATH_HAS_NO_ERRNO
#endif
-#if (LIBC_MATH & LIBC_MATH_NO_EXCEPT)
+#if ((LIBC_MATH) & LIBC_MATH_NO_EXCEPT)
#define LIBC_MATH_HAS_NO_EXCEPT
#endif
diff --git a/libc/src/__support/math/cbrt.h b/libc/src/__support/math/cbrt.h
index 1998731aeb4f8..d727745f9ebed 100644
--- a/libc/src/__support/math/cbrt.h
+++ b/libc/src/__support/math/cbrt.h
@@ -23,7 +23,7 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
-#if ((LIBC_MATH & LIBC_MATH_SKIP_ACCURATE_PASS) != 0)
+#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
#define LIBC_MATH_CBRT_SKIP_ACCURATE_PASS
#endif
diff --git a/libc/src/__support/math/expm1.h b/libc/src/__support/math/expm1.h
index 0e581ea29fcd7..861f177b8ceee 100644
--- a/libc/src/__support/math/expm1.h
+++ b/libc/src/__support/math/expm1.h
@@ -32,7 +32,7 @@ namespace math {
namespace expm1_internal {
-#if ((LIBC_MATH & LIBC_MATH_SKIP_ACCURATE_PASS) != 0)
+#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
#define LIBC_MATH_EXPM1_SKIP_ACCURATE_PASS
#endif
diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h
index bc6ac367877e5..cba41f4f107de 100644
--- a/libc/test/UnitTest/FPMatcher.h
+++ b/libc/test/UnitTest/FPMatcher.h
@@ -295,48 +295,76 @@ struct ModifyMXCSR {
ASSERT_THAT(actual, LIBC_NAMESPACE::testing::getMatcher< \
LIBC_NAMESPACE::testing::TestCond::NE>(expected))
+#ifdef LIBC_MATH_HAS_NO_ERRNO
+
#define EXPECT_MATH_ERRNO(expected) \
do { \
- if ((LIBC_MATH & LIBC_MATH_NO_ERRNO) == 0) \
- if (math_errhandling & MATH_ERRNO) { \
- int actual = libc_errno; \
- libc_errno = 0; \
- EXPECT_EQ(actual, expected); \
- } \
} while (0)
#define ASSERT_MATH_ERRNO(expected) \
do { \
- if ((LIBC_MATH & LIBC_MATH_NO_ERRNO) == 0) \
- if (math_errhandling & MATH_ERRNO) { \
- int actual = libc_errno; \
- libc_errno = 0; \
- ASSERT_EQ(actual, expected); \
- } \
} while (0)
+#else
+
+#define EXPECT_MATH_ERRNO(expected) \
+ do { \
+ if (math_errhandling & MATH_ERRNO) { \
+ int actual = libc_errno; \
+ libc_errno = 0; \
+ EXPECT_EQ(actual, expected); \
+ } \
+ } while (0)
+
+#define ASSERT_MATH_ERRNO(expected) \
+ do { \
+ if (math_errhandling & MATH_ERRNO) { \
+ int actual = libc_errno; \
+ libc_errno = 0; \
+ ASSERT_EQ(actual, expected); \
+ } \
+ } while (0)
+
+#endif // LIBC_MATH_HAS_NO_ERRNO
+
+#ifdef LIBC_MATH_HAS_NO_EXCEPT
+
+#define EXPECT_FP_EXCEPTION(expected) \
+ do { \
+ } while (0)
+
+#define ASSERT_FP_EXCEPTION(expected) \
+ do { \
+ } while (0)
+
+#define EXPECT_FP_EQ_WITH_EXCEPTION(expected_val, actual_val, expected_except) \
+ EXPECT_FP_EQ(expected_val, actual_val)
+
+#define EXPECT_FP_IS_NAN_WITH_EXCEPTION(actual_val, expected_except) \
+ EXPECT_FP_IS_NAN(actual_val)
+
+#else // !LIBC_MATH_HAS_NO_EXCEPT
+
#define EXPECT_FP_EXCEPTION(expected) \
do { \
- if ((LIBC_MATH & LIBC_MATH_NO_EXCEPT) == 0) \
- if (math_errhandling & MATH_ERREXCEPT) { \
- EXPECT_EQ( \
- LIBC_NAMESPACE::fputil::test_except( \
- static_cast<int>(FE_ALL_EXCEPT)) & \
- ((expected) ? (expected) : static_cast<int>(FE_ALL_EXCEPT)), \
- (expected)); \
- } \
+ if (math_errhandling & MATH_ERREXCEPT) { \
+ EXPECT_EQ( \
+ LIBC_NAMESPACE::fputil::test_except( \
+ static_cast<int>(FE_ALL_EXCEPT)) & \
+ ((expected) ? (expected) : static_cast<int>(FE_ALL_EXCEPT)), \
+ (expected)); \
+ } \
} while (0)
#define ASSERT_FP_EXCEPTION(expected) \
do { \
- if ((LIBC_MATH & LIBC_MATH_NO_EXCEPT) == 0) \
- if (math_errhandling & MATH_ERREXCEPT) { \
- ASSERT_EQ( \
- LIBC_NAMESPACE::fputil::test_except( \
- static_cast<int>(FE_ALL_EXCEPT)) & \
- ((expected) ? (expected) : static_cast<int>(FE_ALL_EXCEPT)), \
- (expected)); \
- } \
+ if (math_errhandling & MATH_ERREXCEPT) { \
+ ASSERT_EQ( \
+ LIBC_NAMESPACE::fputil::test_except( \
+ static_cast<int>(FE_ALL_EXCEPT)) & \
+ ((expected) ? (expected) : static_cast<int>(FE_ALL_EXCEPT)), \
+ (expected)); \
+ } \
} while (0)
#define EXPECT_FP_EQ_WITH_EXCEPTION(expected_val, actual_val, expected_except) \
@@ -353,6 +381,8 @@ struct ModifyMXCSR {
EXPECT_FP_EXCEPTION(expected_except); \
} while (0)
+#endif // LIBC_MATH_HAS_NO_EXCEPT
+
#define EXPECT_FP_EQ_ROUNDING_MODE(expected, actual, rounding_mode) \
do { \
using namespace LIBC_NAMESPACE::fputil::testing; \
diff --git a/libc/test/src/math/smoke/AddTest.h b/libc/test/src/math/smoke/AddTest.h
index 511ea581d5232..ac68d06366462 100644
--- a/libc/test/src/math/smoke/AddTest.h
+++ b/libc/test/src/math/smoke/AddTest.h
@@ -68,72 +68,67 @@ class AddTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
if (ForceRoundingMode r(RoundingMode::Nearest); r.success) {
EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(in.max_normal, in.max_normal),
- FE_OVERFLOW | FE_INEXACT);
+ FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
- EXPECT_FP_EQ_WITH_EXCEPTION(-inf,
- func(in.neg_max_normal, in.neg_max_normal),
- FE_OVERFLOW | FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ -inf, func(in.neg_max_normal, in.neg_max_normal), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
EXPECT_FP_EQ_WITH_EXCEPTION(zero, func(in.min_denormal, in.min_denormal),
- FE_UNDERFLOW | FE_INEXACT);
+ FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
EXPECT_FP_EQ_WITH_EXCEPTION(
neg_zero, func(in.neg_min_denormal, in.neg_min_denormal),
- FE_UNDERFLOW | FE_INEXACT);
+ FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
}
if (ForceRoundingMode r(RoundingMode::TowardZero); r.success) {
- EXPECT_FP_EQ_WITH_EXCEPTION(max_normal,
- func(in.max_normal, in.max_normal),
- FE_OVERFLOW | FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ max_normal, func(in.max_normal, in.max_normal), FE_OVERFLOW);
EXPECT_FP_EQ_WITH_EXCEPTION(neg_max_normal,
func(in.neg_max_normal, in.neg_max_normal),
- FE_OVERFLOW | FE_INEXACT);
+ FE_OVERFLOW);
EXPECT_FP_EQ_WITH_EXCEPTION(zero, func(in.min_denormal, in.min_denormal),
- FE_UNDERFLOW | FE_INEXACT);
+ FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
EXPECT_FP_EQ_WITH_EXCEPTION(
neg_zero, func(in.neg_min_denormal, in.neg_min_denormal),
- FE_UNDERFLOW | FE_INEXACT);
+ FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
}
if (ForceRoundingMode r(RoundingMode::Downward); r.success) {
- EXPECT_FP_EQ_WITH_EXCEPTION(max_normal,
- func(in.max_normal, in.max_normal),
- FE_OVERFLOW | FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(-inf,
- func(in.neg_max_normal, in.neg_max_normal),
- FE_OVERFLOW | FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ max_normal, func(in.max_normal, in.max_normal), FE_OVERFLOW);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ -inf, func(in.neg_max_normal, in.neg_max_normal), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
EXPECT_FP_EQ_WITH_EXCEPTION(zero, func(in.min_denormal, in.min_denormal),
- FE_UNDERFLOW | FE_INEXACT);
+ FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
EXPECT_FP_EQ_WITH_EXCEPTION(
neg_min_denormal, func(in.neg_min_denormal, in.neg_min_denormal),
- FE_UNDERFLOW | FE_INEXACT);
+ FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
}
if (ForceRoundingMode r(RoundingMode::Upward); r.success) {
EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(in.max_normal, in.max_normal),
- FE_OVERFLOW | FE_INEXACT);
+ FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
EXPECT_FP_EQ_WITH_EXCEPTION(neg_max_normal,
func(in.neg_max_normal, in.neg_max_normal),
- FE_OVERFLOW | FE_INEXACT);
+ FE_OVERFLOW);
- EXPECT_FP_EQ_WITH_EXCEPTION(min_denormal,
- func(in.min_denormal, in.min_denormal),
- FE_UNDERFLOW | FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ min_denormal, func(in.min_denormal, in.min_denormal), FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
EXPECT_FP_EQ_WITH_EXCEPTION(
neg_zero, func(in.neg_min_denormal, in.neg_min_denormal),
- FE_UNDERFLOW | FE_INEXACT);
+ FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
}
#endif
diff --git a/libc/test/src/math/smoke/DivTest.h b/libc/test/src/math/smoke/DivTest.h
index ff82f68827a12..a911ba8b72224 100644
--- a/libc/test/src/math/smoke/DivTest.h
+++ b/libc/test/src/math/smoke/DivTest.h
@@ -84,72 +84,64 @@ class DivTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
if (ForceRoundingMode r(RoundingMode::Nearest); r.success) {
EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(in.max_normal, in.min_normal),
- FE_OVERFLOW | FE_INEXACT);
+ FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
- EXPECT_FP_EQ_WITH_EXCEPTION(-inf,
- func(in.neg_max_normal, in.min_denormal),
- FE_OVERFLOW | FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ -inf, func(in.neg_max_normal, in.min_denormal), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
EXPECT_FP_EQ_WITH_EXCEPTION(zero, func(in.min_denormal, in.max_normal),
- FE_UNDERFLOW | FE_INEXACT);
+ FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
- EXPECT_FP_EQ_WITH_EXCEPTION(neg_zero,
- func(in.neg_min_denormal, in.max_normal),
- FE_UNDERFLOW | FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ neg_zero, func(in.neg_min_denormal, in.max_normal), FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
}
if (ForceRoundingMode r(RoundingMode::TowardZero); r.success) {
- EXPECT_FP_EQ_WITH_EXCEPTION(max_normal,
- func(in.max_normal, in.min_normal),
- FE_OVERFLOW | FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ max_normal, func(in.max_normal, in.min_normal), FE_OVERFLOW);
EXPECT_FP_EQ_WITH_EXCEPTION(neg_max_normal,
func(in.neg_max_normal, in.min_denormal),
- FE_OVERFLOW | FE_INEXACT);
+ FE_OVERFLOW);
EXPECT_FP_EQ_WITH_EXCEPTION(zero, func(in.min_denormal, in.max_normal),
- FE_UNDERFLOW | FE_INEXACT);
+ FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
- EXPECT_FP_EQ_WITH_EXCEPTION(neg_zero,
- func(in.neg_min_denormal, in.max_normal),
- FE_UNDERFLOW | FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ neg_zero, func(in.neg_min_denormal, in.max_normal), FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
}
if (ForceRoundingMode r(RoundingMode::Downward); r.success) {
- EXPECT_FP_EQ_WITH_EXCEPTION(max_normal,
- func(in.max_normal, in.min_normal),
- FE_OVERFLOW | FE_INEXACT);
- EXPECT_FP_EQ_WITH_EXCEPTION(-inf,
- func(in.neg_max_normal, in.min_denormal),
- FE_OVERFLOW | FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ max_normal, func(in.max_normal, in.min_normal), FE_OVERFLOW);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ -inf, func(in.neg_max_normal, in.min_denormal), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
EXPECT_FP_EQ_WITH_EXCEPTION(zero, func(in.min_denormal, in.max_normal),
- FE_UNDERFLOW | FE_INEXACT);
+ FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
EXPECT_FP_EQ_WITH_EXCEPTION(neg_min_denormal,
func(in.neg_min_denormal, in.max_normal),
- FE_UNDERFLOW | FE_INEXACT);
+ FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
}
if (ForceRoundingMode r(RoundingMode::Upward); r.success) {
EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(in.max_normal, in.min_normal),
- FE_OVERFLOW | FE_INEXACT);
+ FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
EXPECT_FP_EQ_WITH_EXCEPTION(neg_max_normal,
func(in.neg_max_normal, in.min_denormal),
- FE_OVERFLOW | FE_INEXACT);
+ FE_OVERFLOW);
- EXPECT_FP_EQ_WITH_EXCEPTION(min_denormal,
- func(in.min_denormal, in.max_normal),
- FE_UNDERFLOW | FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ min_denormal, func(in.min_denormal, in.max_normal), FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
- EXPECT_FP_EQ_WITH_EXCEPTION(neg_zero,
- func(in.neg_min_denormal, in.max_normal),
- FE_UNDERFLOW | FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ neg_zero, func(in.neg_min_denormal, in.max_normal), FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
}
}
diff --git a/libc/test/src/math/smoke/MulTest.h b/libc/test/src/math/smoke/MulTest.h
index 5020067d433a7..08f0bcf9f62ce 100644
--- a/libc/test/src/math/smoke/MulTest.h
+++ b/libc/test/src/math/smoke/MulTest.h
@@ -73,72 +73,62 @@ class MulTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
if (ForceRoundingMode r(RoundingMode::Nearest); r.success) {
EXPECT_FP_EQ_WITH_EXCEPTION(inf, func(in.max_normal, in.max_normal),
- FE_OVERFLOW | FE_INEXACT);
+ FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
- EXPECT_FP_EQ_WITH_EXCEPTION(neg_inf,
- func(in.neg_max_normal, in.max_normal),
- FE_OVERFLOW | FE_INEXACT);
+ EXPECT_FP_EQ_WITH_EXCEPTION(
+ neg_inf, func(in.neg_max_normal, in.max_normal), FE_OVERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
EXPECT_FP_EQ_WITH_EXCEPTION(zero, func(in.min_denormal, in.min_denormal),
- FE_UNDERFLOW | FE_INEXACT);
+ FE_UNDERFLOW);
EXPECT_MATH_ERRNO(ERANGE);
- EXPECT_FP_EQ_WITH_EXCEPTION(neg_zero,
- func(i...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/199392
More information about the libc-commits
mailing list