[UCRT] Fix GCC/Clang SIMD compilation

GCC and Clang need to mark functions that use SSE/AVX etc, either with a function attribute or a pragma around the function. strlen uses a template function that either uses SSE2 or AVX2. Previously the template was surrounded with pragmas to allow both SSE2 and AVX2, but that makes GCC assume that it can use AVX2 instructions even in the SSE2 version. To fix this the template instances are now build in individual compilation units for SSE2 and AVX, separate from the "dispatcher" function.
Now ucrtbase doesn't crash anymore on GCC build.

Another issue was the namespace around strnlen_mode, which has confused clang so much, that it forgot to instantiate the template code.
This commit is contained in:
Timo Kreuzer 2025-07-22 20:17:46 +03:00
parent e2deec8235
commit 719ea022ec
5 changed files with 92 additions and 10 deletions

View file

@ -19,22 +19,27 @@
#if defined _CRT_SIMD_SUPPORT_AVAILABLE
#if defined(__clang__)
#define _UCRT_ENABLE_EXTENDED_ISA \
#define _UCRT_ENABLE_SSE2 \
_Pragma("clang attribute push(__attribute__((target(\"sse2\"))), apply_to=function)")
#define _UCRT_ENABLE_AVX2 \
_Pragma("clang attribute push(__attribute__((target(\"sse2,avx,avx2\"))), apply_to=function)")
#define _UCRT_RESTORE_DEFAULT_ISA \
_Pragma("clang attribute pop")
#elif defined(__GNUC__)
#define _UCRT_ENABLE_EXTENDED_ISA \
#define _UCRT_ENABLE_SSE2 \
_Pragma("GCC push_options") \
_Pragma("GCC target(\"sse2\")")
#define _UCRT_ENABLE_AVX2 \
_Pragma("GCC push_options") \
_Pragma("GCC target(\"avx2\")")
#define _UCRT_RESTORE_DEFAULT_ISA \
_Pragma("GCC pop_options")
#else
#define _UCRT_ENABLE_EXTENDED_ISA
#define _UCRT_ENABLE_SSE2
#define _UCRT_ENABLE_AVX2
#define _UCRT_RESTORE_DEFAULT_ISA
#endif
_UCRT_ENABLE_EXTENDED_ISA
extern "C" int __isa_available;
@ -70,6 +75,7 @@ _UCRT_ENABLE_EXTENDED_ISA
};
_UCRT_ENABLE_SSE2
template <>
struct __crt_simd_cleanup_guard<__crt_simd_isa::sse2>
@ -120,7 +126,9 @@ _UCRT_ENABLE_EXTENDED_ISA
}
};
_UCRT_RESTORE_DEFAULT_ISA
_UCRT_ENABLE_AVX2
template <>
struct __crt_simd_cleanup_guard<__crt_simd_isa::avx2>