[libc-commits] [libc] d1e261e - [libc] Fix fxdivi tests on 32-bit targets (#223675)
via libc-commits
libc-commits at lists.llvm.org
Wed Sep 16 01:58:49 PDT 2026
Author: Victor Campos
Date: 2026-09-16T09:58:43+01:00
New Revision: d1e261e574e9612fe3f4056730809617323f1758
URL: https://github.com/llvm/llvm-project/commit/d1e261e574e9612fe3f4056730809617323f1758
DIFF: https://github.com/llvm/llvm-project/commit/d1e261e574e9612fe3f4056730809617323f1758.diff
LOG: [libc] Fix fxdivi tests on 32-bit targets (#223675)
Guard saturation operands against overflow and correct boundary
expectations for the range and precision of 32-bit long.
Fixes issue introduced in a969579a9129891bccb63fcc69e76d74b299f322.
Assisted-by: Codex. Entirely done by the AI and reviewed by me.
Added:
Modified:
libc/test/src/stdfix/FxDiviTest.h
Removed:
################################################################################
diff --git a/libc/test/src/stdfix/FxDiviTest.h b/libc/test/src/stdfix/FxDiviTest.h
index 3ee90d71c0542..4ff14c41b621d 100644
--- a/libc/test/src/stdfix/FxDiviTest.h
+++ b/libc/test/src/stdfix/FxDiviTest.h
@@ -84,6 +84,7 @@ class FxDiviTest : public LIBC_NAMESPACE::testing::Test {
}
void testEdgeCases(FxDiviFunc func) {
+ constexpr int int_digits = cpp::numeric_limits<IntType>::digits;
constexpr IntType int_max = cpp::numeric_limits<IntType>::max();
EXPECT_EQ(func(0, 10), fx_zero);
@@ -91,7 +92,7 @@ class FxDiviTest : public LIBC_NAMESPACE::testing::Test {
EXPECT_EQ(func(0, -10), fx_zero);
}
- if constexpr (is_signed && (F < cpp::numeric_limits<IntType>::digits)) {
+ if constexpr (is_signed && (F < int_digits)) {
constexpr IntType edge = static_cast<IntType>(1) << F;
EXPECT_EQ(func(-edge, edge), static_cast<FXType>(-1));
if constexpr (has_integral) {
@@ -105,16 +106,24 @@ class FxDiviTest : public LIBC_NAMESPACE::testing::Test {
EXPECT_EQ(func(int_max, int_max), static_cast<FXType>(1));
EXPECT_TRUE(abs_
diff (func(int_max - 1, int_max),
static_cast<FXType>(1) - epsilon) <= epsilon);
- EXPECT_EQ(func(int_max, 1), fx_max);
+ // Integer extrema need not overflow the fixed-point result type.
+ if constexpr (int_digits <= FXRep::INTEGRAL_LEN)
+ EXPECT_EQ(func(int_max, 1), static_cast<FXType>(int_max));
+ else
+ EXPECT_EQ(func(int_max, 1), fx_max);
} else {
EXPECT_EQ(func(int_max, int_max), fx_max);
- EXPECT_EQ(func(int_max - 1, int_max), fx_max);
+ // When the integer and fraction precisions match, this quotient can
+ // round to one ulp below fx_max.
+ if constexpr (int_digits == F)
+ EXPECT_TRUE(abs_
diff (func(int_max - 1, int_max), fx_max) <= epsilon);
+ else
+ EXPECT_EQ(func(int_max - 1, int_max), fx_max);
EXPECT_EQ(func(27, 23), fx_max);
}
- // Cannot EXPECT_EQ even though int_max is a power of 2 because rounding
- // direction for magnitudes smaller than the representable precision is
- // implementation defined. The result must be within 1 ulp.
+ // Rounding direction for magnitudes smaller than the representable
+ // precision is implementation defined. The result must be within 1 ulp.
EXPECT_TRUE(abs_
diff (func(1, int_max), fx_zero) <= epsilon);
if constexpr (is_signed) {
@@ -129,15 +138,25 @@ class FxDiviTest : public LIBC_NAMESPACE::testing::Test {
EXPECT_EQ(func(int_min, int_min), fx_max);
}
- EXPECT_EQ(func(int_min, 1), fx_min);
+ if constexpr (int_digits <= FXRep::INTEGRAL_LEN) {
+ EXPECT_EQ(func(int_min, 1), static_cast<FXType>(int_min));
+ EXPECT_EQ(func(int_max, -1), -static_cast<FXType>(int_max));
+ } else {
+ EXPECT_EQ(func(int_min, 1), fx_min);
+ EXPECT_EQ(func(int_max, -1), fx_min);
+ }
// Cannot EXPECT_EQ even though int_min is a power of 2 because rounding
// direction for magnitudes smaller than the representable precision is
// implementation defined. The result must be within 1 ulp.
EXPECT_TRUE(abs_
diff (func(1, int_min), fx_zero) <= epsilon);
- EXPECT_EQ(func(int_min, -1), fx_max);
- EXPECT_EQ(func(int_max, -1), fx_min);
+ // The positive magnitude of int_min needs one more integral bit than
+ // int_max. Convert before negating to avoid integer overflow.
+ if constexpr (int_digits < FXRep::INTEGRAL_LEN)
+ EXPECT_EQ(func(int_min, -1), -static_cast<FXType>(int_min));
+ else
+ EXPECT_EQ(func(int_min, -1), fx_max);
}
if constexpr (has_integral) {
@@ -166,13 +185,14 @@ class FxDiviTest : public LIBC_NAMESPACE::testing::Test {
}
}
- if constexpr (has_integral) {
- constexpr IntType over_max =
- static_cast<IntType>(6) *
- (static_cast<IntType>(1) << FXRep::INTEGRAL_LEN);
- EXPECT_EQ(func(over_max, 3), fx_max);
+ // Construct saturation operands only when they fit in IntType.
+ if constexpr (has_integral && FXRep::INTEGRAL_LEN < int_digits) {
constexpr IntType at_max = static_cast<IntType>(1) << FXRep::INTEGRAL_LEN;
EXPECT_EQ(func(at_max, 1), fx_max);
+ if constexpr (at_max <= int_max / 6) {
+ constexpr IntType over_max = static_cast<IntType>(6) * at_max;
+ EXPECT_EQ(func(over_max, 3), fx_max);
+ }
}
}
@@ -196,7 +216,7 @@ class FxDiviTest : public LIBC_NAMESPACE::testing::Test {
}
}
- void testInvalidNumbers(FxDiviFunc func) {
+ void testInvalidNumbers([[maybe_unused]] FxDiviFunc func) {
EXPECT_DEATH([func] { func(1, 0); }, WITH_SIGNAL(-1));
if constexpr (is_signed) {
EXPECT_DEATH([func] { func(-1, 0); }, WITH_SIGNAL(-1));
More information about the libc-commits
mailing list