From 2a37ff523f9ce32fce8f6c673b019642f6d10e03 Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Fri, 16 Oct 2026 16:56:40 +0900 Subject: [PATCH] Allow setting XSIMD_WITH_SSE3, SSSE3, SSE4_1 and SSE4_2 manually with MSVC MSVC doesn't define __SSE3__, __SSSE3__, __SSE4_1__ or __SSE4_2__ even with /arch:SSE4.2. So users need to define these reserved identifiers to enable these instruction sets with MSVC since #881. But defining them may break other libraries. For example, simdjson >= 5 uses GCC builtins such as __builtin_ctz when __SSE2__ is defined: https://github.com/apache/arrow/issues/51690 This allows users to set XSIMD_WITH_SSE3, XSIMD_WITH_SSSE3, XSIMD_WITH_SSE4_1 and XSIMD_WITH_SSE4_2 manually only with MSVC. For example, users can enable SSE4.2 with MSVC by -DXSIMD_WITH_SSE4_2=1. Lower instruction sets are enabled automatically by the existing MSVC workaround. This also allows selecting SSE3 or SSSE3 with MSVC requested in #878. Other compilers including clang-cl define these macros based on compiler flags and require the corresponding compiler flags to use intrinsics. So setting them manually with other compilers is reported as an error. Co-Authored-By: Claude Opus 5.5 --- include/xsimd/config/xsimd_config.hpp | 36 ++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/include/xsimd/config/xsimd_config.hpp b/include/xsimd/config/xsimd_config.hpp index 7c570b3cd..86dde7d12 100644 --- a/include/xsimd/config/xsimd_config.hpp +++ b/include/xsimd/config/xsimd_config.hpp @@ -111,8 +111,15 @@ * @ingroup xsimd_config_macro * * Set to 1 if SSE3 is available at compile-time, to 0 otherwise. + * + * It can be set manually only with MSVC because MSVC doesn't define + * __SSE3__ even when SSE3 is enabled. */ -#ifdef __SSE3__ +#ifdef XSIMD_WITH_SSE3 +#if !defined(_MSC_VER) || defined(__clang__) +#error "XSIMD_WITH_SSE3 can be set manually only with MSVC" +#endif +#elif defined(__SSE3__) #define XSIMD_WITH_SSE3 1 #else #define XSIMD_WITH_SSE3 0 @@ -122,8 +129,15 @@ * @ingroup xsimd_config_macro * * Set to 1 if SSSE3 is available at compile-time, to 0 otherwise. + * + * It can be set manually only with MSVC because MSVC doesn't define + * __SSSE3__ even when SSSE3 is enabled. */ -#ifdef __SSSE3__ +#ifdef XSIMD_WITH_SSSE3 +#if !defined(_MSC_VER) || defined(__clang__) +#error "XSIMD_WITH_SSSE3 can be set manually only with MSVC" +#endif +#elif defined(__SSSE3__) #define XSIMD_WITH_SSSE3 1 #else #define XSIMD_WITH_SSSE3 0 @@ -133,8 +147,15 @@ * @ingroup xsimd_config_macro * * Set to 1 if SSE4.1 is available at compile-time, to 0 otherwise. + * + * It can be set manually only with MSVC because MSVC doesn't define + * __SSE4_1__ even when SSE4.1 is enabled. */ -#ifdef __SSE4_1__ +#ifdef XSIMD_WITH_SSE4_1 +#if !defined(_MSC_VER) || defined(__clang__) +#error "XSIMD_WITH_SSE4_1 can be set manually only with MSVC" +#endif +#elif defined(__SSE4_1__) #define XSIMD_WITH_SSE4_1 1 #else #define XSIMD_WITH_SSE4_1 0 @@ -144,8 +165,15 @@ * @ingroup xsimd_config_macro * * Set to 1 if SSE4.2 is available at compile-time, to 0 otherwise. + * + * It can be set manually only with MSVC because MSVC doesn't define + * __SSE4_2__ even when SSE4.2 is enabled. */ -#ifdef __SSE4_2__ +#ifdef XSIMD_WITH_SSE4_2 +#if !defined(_MSC_VER) || defined(__clang__) +#error "XSIMD_WITH_SSE4_2 can be set manually only with MSVC" +#endif +#elif defined(__SSE4_2__) #define XSIMD_WITH_SSE4_2 1 #else #define XSIMD_WITH_SSE4_2 0