summaryrefslogtreecommitdiff
path: root/absl/base/internal/bits.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/base/internal/bits.h')
-rw-r--r--absl/base/internal/bits.h33
1 files changed, 17 insertions, 16 deletions
diff --git a/absl/base/internal/bits.h b/absl/base/internal/bits.h
index 8b03453c..81648e2c 100644
--- a/absl/base/internal/bits.h
+++ b/absl/base/internal/bits.h
@@ -24,7 +24,7 @@
// Clang on Windows has __builtin_clzll; otherwise we need to use the
// windows intrinsic functions.
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && !defined(__clang__)
#include <intrin.h>
#if defined(_M_X64)
#pragma intrinsic(_BitScanReverse64)
@@ -36,7 +36,7 @@
#include "absl/base/attributes.h"
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && !defined(__clang__)
// We can achieve something similar to attribute((always_inline)) with MSVC by
// using the __forceinline keyword, however this is not perfect. MSVC is
// much less aggressive about inlining, and even with the __forceinline keyword.
@@ -73,24 +73,25 @@ ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64Slow(uint64_t n) {
}
ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64(uint64_t n) {
-#if defined(_MSC_VER) && defined(_M_X64)
+#if defined(_MSC_VER) && !defined(__clang__) && defined(_M_X64)
// MSVC does not have __buitin_clzll. Use _BitScanReverse64.
unsigned long result = 0; // NOLINT(runtime/int)
if (_BitScanReverse64(&result, n)) {
return 63 - result;
}
return 64;
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER) && !defined(__clang__)
// MSVC does not have __buitin_clzll. Compose two calls to _BitScanReverse
unsigned long result = 0; // NOLINT(runtime/int)
- if ((n >> 32) && _BitScanReverse(&result, n >> 32)) {
+ if ((n >> 32) &&
+ _BitScanReverse(&result, static_cast<unsigned long>(n >> 32))) {
return 31 - result;
}
- if (_BitScanReverse(&result, n)) {
+ if (_BitScanReverse(&result, static_cast<unsigned long>(n))) {
return 63 - result;
}
return 64;
-#elif defined(__GNUC__)
+#elif defined(__GNUC__) || defined(__clang__)
// Use __builtin_clzll, which uses the following instructions:
// x86: bsr
// ARM64: clz
@@ -126,13 +127,13 @@ ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros32Slow(uint64_t n) {
}
ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros32(uint32_t n) {
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && !defined(__clang__)
unsigned long result = 0; // NOLINT(runtime/int)
if (_BitScanReverse(&result, n)) {
return 31 - result;
}
return 32;
-#elif defined(__GNUC__)
+#elif defined(__GNUC__) || defined(__clang__)
// Use __builtin_clz, which uses the following instructions:
// x86: bsr
// ARM64: clz
@@ -163,19 +164,19 @@ ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero64Slow(uint64_t n) {
}
ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero64(uint64_t n) {
-#if defined(_MSC_VER) && defined(_M_X64)
+#if defined(_MSC_VER) && !defined(__clang__) && defined(_M_X64)
unsigned long result = 0; // NOLINT(runtime/int)
_BitScanForward64(&result, n);
return result;
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER) && !defined(__clang__)
unsigned long result = 0; // NOLINT(runtime/int)
if (static_cast<uint32_t>(n) == 0) {
- _BitScanForward(&result, n >> 32);
+ _BitScanForward(&result, static_cast<unsigned long>(n >> 32));
return result + 32;
}
- _BitScanForward(&result, n);
+ _BitScanForward(&result, static_cast<unsigned long>(n));
return result;
-#elif defined(__GNUC__)
+#elif defined(__GNUC__) || defined(__clang__)
static_assert(sizeof(unsigned long long) == sizeof(n), // NOLINT(runtime/int)
"__builtin_ctzll does not take 64-bit arg");
return __builtin_ctzll(n);
@@ -196,11 +197,11 @@ ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero32Slow(uint32_t n) {
}
ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero32(uint32_t n) {
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && !defined(__clang__)
unsigned long result = 0; // NOLINT(runtime/int)
_BitScanForward(&result, n);
return result;
-#elif defined(__GNUC__)
+#elif defined(__GNUC__) || defined(__clang__)
static_assert(sizeof(int) == sizeof(n),
"__builtin_ctz does not take 32-bit arg");
return __builtin_ctz(n);