summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJia Tan <jiat0218@gmail.com>2023-04-19 21:59:03 +0800
committerJia Tan <jiat0218@gmail.com>2023-04-25 20:19:28 +0800
commit12321a9390acc076b414035a46df9d7545ac379f (patch)
tree65f90a946e8d514e4cbd0b4bb929c90bd8b9b521
parentd1f0e01c395960efd6c29ff144eda4f4c8c1c6d3 (diff)
downloadxz-12321a9390acc076b414035a46df9d7545ac379f.tar.gz
tuklib_integer: Use __builtin_clz() with Clang.
Clang has support for __builtin_clz(), but previously Clang would fallback to either the MSVC intrinsic or the regular C code. This was discovered due to a bug where a new version of Clang required the <intrin.h> header file in order to use the MSVC intrinsics. Thanks to Anton Kochkov for notifying us about the bug.
-rw-r--r--src/common/tuklib_integer.h6
1 files changed, 3 insertions, 3 deletions
diff --git a/src/common/tuklib_integer.h b/src/common/tuklib_integer.h
index b58ef68..2125695 100644
--- a/src/common/tuklib_integer.h
+++ b/src/common/tuklib_integer.h
@@ -630,7 +630,7 @@ bsr32(uint32_t n)
#if defined(__INTEL_COMPILER)
return _bit_scan_reverse(n);
-#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX == UINT32_MAX
+#elif (TUKLIB_GNUC_REQ(3, 4) || defined(__clang__)) && UINT_MAX == UINT32_MAX
// GCC >= 3.4 has __builtin_clz(), which gives good results on
// multiple architectures. On x86, __builtin_clz() ^ 31U becomes
// either plain BSR (so the XOR gets optimized away) or LZCNT and
@@ -684,7 +684,7 @@ clz32(uint32_t n)
#if defined(__INTEL_COMPILER)
return _bit_scan_reverse(n) ^ 31U;
-#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX == UINT32_MAX
+#elif (TUKLIB_GNUC_REQ(3, 4) || defined(__clang__)) && UINT_MAX == UINT32_MAX
return (uint32_t)__builtin_clz(n);
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
@@ -739,7 +739,7 @@ ctz32(uint32_t n)
#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX >= UINT32_MAX
return (uint32_t)__builtin_ctz(n);
-#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+#elif (TUKLIB_GNUC_REQ(3, 4) || defined(__clang__)) && UINT_MAX == UINT32_MAX
uint32_t i;
__asm__("bsfl %1, %0" : "=r" (i) : "rm" (n));
return i;