-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc] first_trailing_one(0)
should be 0
.
#130155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-libc Author: Connector Switch (c8ef) ChangesFix this minor bug. See more context at #129892. Full diff: https://github.com/llvm/llvm-project/pull/130155.diff 3 Files Affected:
diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h
index f44624a7eafce..b8d0a0487eeb8 100644
--- a/libc/src/__support/big_int.h
+++ b/libc/src/__support/big_int.h
@@ -1383,8 +1383,9 @@ first_trailing_zero(T value) {
template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
first_trailing_one(T value) {
- return value == cpp::numeric_limits<T>::max() ? 0
- : cpp::countr_zero(value) + 1;
+ return (value == 0 || value == cpp::numeric_limits<T>::max())
+ ? 0
+ : cpp::countr_zero(value) + 1;
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/math_extras.h b/libc/src/__support/math_extras.h
index 6f4a006aad270..c40fdb9cc97a1 100644
--- a/libc/src/__support/math_extras.h
+++ b/libc/src/__support/math_extras.h
@@ -146,8 +146,9 @@ first_trailing_zero(T value) {
template <typename T>
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int>
first_trailing_one(T value) {
- return value == cpp::numeric_limits<T>::max() ? 0
- : cpp::countr_zero(value) + 1;
+ return (value == 0 || value == cpp::numeric_limits<T>::max())
+ ? 0
+ : cpp::countr_zero(value) + 1;
}
template <typename T>
diff --git a/libc/test/src/__support/math_extras_test.cpp b/libc/test/src/__support/math_extras_test.cpp
index 01b216081d034..d77bc5d2f80de 100644
--- a/libc/test/src/__support/math_extras_test.cpp
+++ b/libc/test/src/__support/math_extras_test.cpp
@@ -95,6 +95,7 @@ TYPED_TEST(LlvmLibcBitTest, FirstTrailingZero, UnsignedTypesNoBigInt) {
}
TYPED_TEST(LlvmLibcBitTest, FirstTrailingOne, UnsignedTypesNoBigInt) {
+ EXPECT_EQ(first_trailing_one<T>(static_cast<T>(0)), 0);
EXPECT_EQ(first_trailing_one<T>(cpp::numeric_limits<T>::max()), 0);
for (int i = 0U; i != cpp::numeric_limits<T>::digits; ++i) {
auto lhs = T(T(1) << size_t(i));
|
@@ -1383,8 +1383,9 @@ first_trailing_zero(T value) { | |||
template <typename T> | |||
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int> | |||
first_trailing_one(T value) { | |||
return value == cpp::numeric_limits<T>::max() ? 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it should be just value == 0
. When value
is not 0, cpp::countr_zero(value) + 1
should be correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will fail with inputs like USHRT_MAX
because we need it to return 0, but cpp::countr_zero(USHRT_MAX) + 1 = 1
.
libc/src/__support/math_extras.h
Outdated
@@ -146,8 +146,9 @@ first_trailing_zero(T value) { | |||
template <typename T> | |||
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_unsigned_v<T>, int> | |||
first_trailing_one(T value) { | |||
return value == cpp::numeric_limits<T>::max() ? 0 | |||
: cpp::countr_zero(value) + 1; | |||
return (value == 0 || value == cpp::numeric_limits<T>::max()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it should be just value == 0
, the other case is cpp::countr_zero(value) + 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will fail with inputs like USHRT_MAX
because we need it to return 0, but cpp::countr_zero(USHRT_MAX) + 1 = 1
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why should it return 0 with USHRT_MAX
? The least significant index of the first bit 1 of USHRT_MAX
is 0, so according to the spec, stdc_first_trailing_one_us(USHRT_MAX)
should be 1. Hence cpp::countr_zero(USHRT_MAX) + 1
is the correct. If our tests do not reflect that, then the tests also need to be updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it finally. Sorry for being careless. I'll update this tonight.
@lntue Please take another look, thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for finding and fixing the issue!
Fix this minor bug. See more context at llvm#129892.
Fix this minor bug. See more context at #129892.