From b81b64a961fc23fb3466d2a71a542803c9c55fcc Mon Sep 17 00:00:00 2001 From: Matevz Kovacic <117923752+matevz-kovacic@users.noreply.github.com> Date: Thu, 6 Aug 2026 08:49:46 +0200 Subject: [PATCH 1/2] compiler: apply TARGET_ATTRIBUTE under clang-cl, not only under __GNUC__ portability_macros.h enables DYNAMIC_BMI2 for clang-cl by testing __clang__ && __has_attribute(__target__). compiler.h then gates TARGET_ATTRIBUTE on __GNUC__, which clang-cl does not define, so BMI2_TARGET_ATTRIBUTE expands to nothing and the dispatched _bmi2 entry points are compiled without BMI2. Test the attribute directly with __has_attribute, keeping the __GNUC__ test as a fallback for compilers without __has_attribute. No change on any compiler that defines __GNUC__. --- lib/common/compiler.h | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/common/compiler.h b/lib/common/compiler.h index 5e70570ec7a..1351495997f 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -118,8 +118,26 @@ #endif -/* target attribute */ -#if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) +/* target attribute + * + * This condition must stay in sync with the one DYNAMIC_BMI2 uses in + * portability_macros.h. clang in MSVC-compatible mode (clang-cl) supports + * __attribute__((__target__)) but does not define __GNUC__, so testing + * __GNUC__ alone silently expands this to nothing while DYNAMIC_BMI2 + * remains enabled -- the runtime dispatch then calls _bmi2 entry points + * that were compiled with no BMI2 at all. + */ +#if defined(__has_attribute) +# if __has_attribute(__target__) +# define ZSTD_HAS_TARGET_ATTRIBUTE 1 +# endif +#endif +#if !defined(ZSTD_HAS_TARGET_ATTRIBUTE) && \ + (defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__)) +# define ZSTD_HAS_TARGET_ATTRIBUTE 1 +#endif + +#if defined(ZSTD_HAS_TARGET_ATTRIBUTE) # define TARGET_ATTRIBUTE(target) __attribute__((__target__(target))) #else # define TARGET_ATTRIBUTE(target) From 4afc10ef28d9df8b212dbeb28d0ea4dab6519699 Mon Sep 17 00:00:00 2001 From: Matevz Kovacic <117923752+matevz-kovacic@users.noreply.github.com> Date: Thu, 6 Aug 2026 08:49:52 +0200 Subject: [PATCH 2/2] compiler: honour LIKELY/UNLIKELY under clang-cl Same __GNUC__ gate as TARGET_ATTRIBUTE. clang-cl supports __builtin_expect, so test for it with __has_builtin and keep __GNUC__ as a fallback. Without this, every branch hint in the library is discarded under clang-cl. --- lib/common/compiler.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/common/compiler.h b/lib/common/compiler.h index 1351495997f..2cb8b1615aa 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -201,7 +201,16 @@ * If you can remove a LIKELY/UNLIKELY annotation without speed changes in gcc * and clang, please do. */ -#if defined(__GNUC__) +#if defined(__has_builtin) +# if __has_builtin(__builtin_expect) +# define ZSTD_HAS_BUILTIN_EXPECT 1 +# endif +#endif +#if !defined(ZSTD_HAS_BUILTIN_EXPECT) && defined(__GNUC__) +# define ZSTD_HAS_BUILTIN_EXPECT 1 +#endif + +#if defined(ZSTD_HAS_BUILTIN_EXPECT) #define LIKELY(x) (__builtin_expect((x), 1)) #define UNLIKELY(x) (__builtin_expect((x), 0)) #else