[libcxx-commits] [libcxx] [libcxx] Use generic builtins for popcount, clz and ctz (PR #86563)

Nick Desaulniers via libcxx-commits libcxx-commits at lists.llvm.org
Mon Mar 25 14:41:21 PDT 2024


================
@@ -58,6 +74,9 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countl_zero(_Tp __t) _
   if (__t == 0)
     return numeric_limits<_Tp>::digits;
 
+#if __has_builtin(__builtin_clzg)
+  return __builtin_clzg(__t) - (numeric_limits<unsigned>::digits - numeric_limits<_Tp>::digits);
+#else
----------------
nickdesaulniers wrote:

I think it would be simpler (and more obvious to fellow reviewers) to do something like:
```diff
diff --git a/libcxx/include/__bit/countl.h b/libcxx/include/__bit/countl.h
index 396cfc2c3f40..5951bc1cc9f9 100644
--- a/libcxx/include/__bit/countl.h
+++ b/libcxx/include/__bit/countl.h
@@ -24,6 +24,14 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#if __has_builtin(__builtin_clzg)
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countl_zero(_Tp __t) _NOEXCEPT {
+static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_zero requires an unsigned integer type");
+  return __builtin_clzg(__x, numeric_limits<_Tp>::digits);
+}
+#else
+
 _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_clz(unsigned __x) _NOEXCEPT {
   return __builtin_clz(__x);
 }
@@ -80,6 +88,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countl_zero(_Tp __t) _
     return __ret + __iter;
   }
 }
+#endif // __has_builtin(__builtin_clzg)
 
 #if _LIBCPP_STD_VER >= 20
```
then update callsites of `__libcpp_clz` to just use `__countl_zero` instead.

If updating the callsites is untenable, then the range of that `#if __has_builtin(__builtin_clzg) can be tightened up to just skip the existing definition of __countl_zero (and not touch definitions of `__libcpp_clz`).

https://github.com/llvm/llvm-project/pull/86563


More information about the libcxx-commits mailing list