[libcxx-commits] [libcxx] d78ca73 - [libc++] Fix the rotate direction used in countl_zero()
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Sep 12 15:20:09 PDT 2023
Author: Armando MartÃn
Date: 2023-09-12T18:19:56-04:00
New Revision: d78ca7324c88a2658492f722222cc8c1eb4ace71
URL: https://github.com/llvm/llvm-project/commit/d78ca7324c88a2658492f722222cc8c1eb4ace71
DIFF: https://github.com/llvm/llvm-project/commit/d78ca7324c88a2658492f722222cc8c1eb4ace71.diff
LOG: [libc++] Fix the rotate direction used in countl_zero()
This "bug" was probably not noticed because it doesn't affect any integer
type we currently support. It requires integers with more than 2x the
size of `unsigned long long`. However, with such types, the algorithm
used to break down the large integer into groups of size `unsigned long long`
didn't work because we rotated in the wrong direction.
For example, the 256 bit number (1 << 255) would yield the wrong answer
when used with the algorithm before this patch.
In particular, note that the current rotation happens to work for 128 bit
integers because it just swaps the halves in this case.
Differential Revision: https://reviews.llvm.org/D134625
Co-authored-by: Louis Dionne <ldionne.2 at gmail.com>
Added:
Modified:
libcxx/include/__bit/countl.h
libcxx/include/__bit/rotate.h
Removed:
################################################################################
diff --git a/libcxx/include/__bit/countl.h b/libcxx/include/__bit/countl.h
index 5d5744ac9a6529f..23a7c42773be57c 100644
--- a/libcxx/include/__bit/countl.h
+++ b/libcxx/include/__bit/countl.h
@@ -74,7 +74,7 @@ int __countl_zero(_Tp __t) _NOEXCEPT
int __iter = 0;
const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
while (true) {
- __t = std::__rotr(__t, __ulldigits);
+ __t = std::__rotl(__t, __ulldigits);
if ((__iter = std::__countl_zero(static_cast<unsigned long long>(__t))) != __ulldigits)
break;
__ret += __iter;
diff --git a/libcxx/include/__bit/rotate.h b/libcxx/include/__bit/rotate.h
index 74413ed0383f5f4..d848056c3350d03 100644
--- a/libcxx/include/__bit/rotate.h
+++ b/libcxx/include/__bit/rotate.h
@@ -35,11 +35,16 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotr(_Tp __t, int __cn
return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig)));
}
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotl(_Tp __t, int __cnt) _NOEXCEPT {
+ return std::__rotr(__t, -__cnt);
+}
+
#if _LIBCPP_STD_VER >= 20
template <__libcpp_unsigned_integer _Tp>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, int __cnt) noexcept {
- return std::__rotr(__t, -__cnt);
+ return std::__rotl(__t, __cnt);
}
template <__libcpp_unsigned_integer _Tp>
More information about the libcxx-commits
mailing list