From 1c772918c412e395bec10f31518e5011b1338552 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 18 Oct 2022 18:07:09 +0100 Subject: [PATCH 1/2] Fix MSVC implementation of `CountBits()` function See: https://learn.microsoft.com/en-us/cpp/intrinsics/bitscanreverse-bitscanreverse64?view=msvc-170 --- src/int_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/int_utils.h b/src/int_utils.h index 62b2c38..c6384ca 100644 --- a/src/int_utils.h +++ b/src/int_utils.h @@ -149,7 +149,7 @@ static inline int CountBits(I val, int max) { ret = _BitScanReverse64(&index, val); } if (!ret) return 0; - return index; + return index + 1; #else while (max && (val >> (max - 1) == 0)) --max; return max; From 0078bedda6078dee91067268ad5fb60b119fd2fb Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 18 Oct 2022 18:12:08 +0100 Subject: [PATCH 2/2] Ignore `HAVE_CLZ` macro when building with MSVC `__builtin_clz*` intrinsics are not available for MSVC. --- src/int_utils.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/int_utils.h b/src/int_utils.h index c6384ca..d21ba56 100644 --- a/src/int_utils.h +++ b/src/int_utils.h @@ -129,17 +129,7 @@ constexpr inline I Mask() { return ((I((I(-1)) << (std::numeric_limits::digit /** Compute the smallest power of two that is larger than val. */ template static inline int CountBits(I val, int max) { -#ifdef HAVE_CLZ - (void)max; - if (val == 0) return 0; - if (std::numeric_limits::digits >= std::numeric_limits::digits) { - return std::numeric_limits::digits - __builtin_clz(val); - } else if (std::numeric_limits::digits >= std::numeric_limits::digits) { - return std::numeric_limits::digits - __builtin_clzl(val); - } else { - return std::numeric_limits::digits - __builtin_clzll(val); - } -#elif _MSC_VER +#ifdef _MSC_VER (void)max; unsigned long index; unsigned char ret; @@ -150,6 +140,16 @@ static inline int CountBits(I val, int max) { } if (!ret) return 0; return index + 1; +#elif HAVE_CLZ + (void)max; + if (val == 0) return 0; + if (std::numeric_limits::digits >= std::numeric_limits::digits) { + return std::numeric_limits::digits - __builtin_clz(val); + } else if (std::numeric_limits::digits >= std::numeric_limits::digits) { + return std::numeric_limits::digits - __builtin_clzl(val); + } else { + return std::numeric_limits::digits - __builtin_clzll(val); + } #else while (max && (val >> (max - 1) == 0)) --max; return max;