bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

count-trailing-zeros: Fix a link error on 32-bit MSVC


From: Bruno Haible
Subject: count-trailing-zeros: Fix a link error on 32-bit MSVC
Date: Mon, 05 Sep 2022 01:32:04 +0200

On 32-bit MSVC, I'm seeing this link error:

/home/bruno/msvc/compile cl -nologo  -MD  -L/usr/local/msvc32/lib -o 
test-count-trailing-zeros.exe test-count-trailing-zeros.obj libtests.a 
../gllib/libgnu.a libtests.a ../gllib/libgnu.a libtests.a  
test-count-trailing-zeros.obj : error LNK2019: unresolved external symbol 
__BitScanForward64 referenced in function _count_trailing_zeros_ll
test-count-trailing-zeros.exe : fatal error LNK1120: 1 unresolved externals
make[4]: *** [Makefile:16533: test-count-trailing-zeros.exe] Error 2

The reason is that, as documented in
https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64
_BitScanForward64 does not exist in 32-bit mode.

This patch fixes it.


2022-09-04  Bruno Haible  <bruno@clisp.org>

        count-trailing-zeros: Fix a link error on 32-bit MSVC.
        * lib/count-trailing-zeros.h: Correct syntax for #pragma intrinsic.
        (count_trailing_zeros_ll): Use two _BitScanForward invocations instead
        of a _BitScanForward64 invocation.

diff --git a/lib/count-trailing-zeros.h b/lib/count-trailing-zeros.h
index 9a989a4324..61fbdf2980 100644
--- a/lib/count-trailing-zeros.h
+++ b/lib/count-trailing-zeros.h
@@ -43,8 +43,10 @@ extern "C" {
 # define COUNT_TRAILING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE)               \
   return x ? BUILTIN (x) : CHAR_BIT * sizeof x;
 #elif _MSC_VER
-# pragma intrinsic _BitScanForward
-# pragma intrinsic _BitScanForward64
+# pragma intrinsic (_BitScanForward)
+# if defined _M_X64
+#  pragma intrinsic (_BitScanForward64)
+# endif
 # define COUNT_TRAILING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE)               \
     do                                                                  \
       {                                                                 \
@@ -101,8 +103,18 @@ count_trailing_zeros_l (unsigned long int x)
 COUNT_TRAILING_ZEROS_INLINE int
 count_trailing_zeros_ll (unsigned long long int x)
 {
+#if (defined _MSC_VER && !defined __clang__) && !defined _M_X64
+  /* 32-bit MSVC does not have _BitScanForward64, only _BitScanForward.  */
+  unsigned long result;
+  if (_BitScanForward (&result, (unsigned long) x))
+    return result;
+  if (_BitScanForward (&result, (unsigned long) (x >> 32)))
+    return result + 32;
+  return CHAR_BIT * sizeof x;
+#else
   COUNT_TRAILING_ZEROS (__builtin_ctzll, _BitScanForward64,
                         unsigned long long int);
+#endif
 }
 
 #ifdef __cplusplus






reply via email to

[Prev in Thread] Current Thread [Next in Thread]