https://github.com/Thibault-Monnier updated https://github.com/llvm/llvm-project/pull/175452
>From 4fc9a07698e1a4627a050ba6fa9df3f1f8725451 Mon Sep 17 00:00:00 2001 From: Thibault-Monnier <[email protected]> Date: Thu, 11 Dec 2025 22:02:35 +0100 Subject: [PATCH 01/13] Detect sse4.2 availability at runtime to use it on modern processors --- clang/lib/Lex/Lexer.cpp | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index b282a600c0e56..3b8fa0b9b7f36 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -46,9 +46,7 @@ #include <string> #include <tuple> -#ifdef __SSE4_2__ #include <nmmintrin.h> -#endif using namespace clang; @@ -1921,9 +1919,17 @@ bool Lexer::LexUnicodeIdentifierStart(Token &Result, uint32_t C, } static const char * -fastParseASCIIIdentifier(const char *CurPtr, - [[maybe_unused]] const char *BufferEnd) { -#ifdef __SSE4_2__ +fastParseASCIIIdentifierScalar(const char *CurPtr, + [[maybe_unused]] const char *BufferEnd) { + unsigned char C = *CurPtr; + while (isAsciiIdentifierContinue(C)) + C = *++CurPtr; + return CurPtr; +} + +__attribute__((target("sse4.2"))) static const char * +fastParseASCIIIdentifierSSE42(const char *CurPtr, + [[maybe_unused]] const char *BufferEnd) { alignas(16) static constexpr char AsciiIdentifierRange[16] = { '_', '_', 'A', 'Z', 'a', 'z', '0', '9', }; @@ -1943,12 +1949,23 @@ fastParseASCIIIdentifier(const char *CurPtr, continue; return CurPtr; } + + return fastParseASCIIIdentifierScalar(CurPtr, BufferEnd); +} + +static bool supportsSSE42() { + static bool SupportsSSE42 = __builtin_cpu_supports("sse4.2"); + return SupportsSSE42; +} + +static const char *fastParseASCIIIdentifier(const char *CurPtr, + const char *BufferEnd) { +#ifndef __SSE4_2__ + if (LLVM_UNLIKELY(!supportsSSE42())) + return fastParseASCIIIdentifierScalar(CurPtr, BufferEnd); #endif - unsigned char C = *CurPtr; - while (isAsciiIdentifierContinue(C)) - C = *++CurPtr; - return CurPtr; + return fastParseASCIIIdentifierSSE42(CurPtr, BufferEnd); } bool Lexer::LexIdentifierContinue(Token &Result, const char *CurPtr) { >From ce3bf515e7a60bd58ff5871352979999f5864b4b Mon Sep 17 00:00:00 2001 From: Thibault-Monnier <[email protected]> Date: Thu, 11 Dec 2025 23:15:40 +0100 Subject: [PATCH 02/13] Only on x86 --- clang/lib/Lex/Lexer.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 3b8fa0b9b7f36..c195237dae1f4 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -46,7 +46,9 @@ #include <string> #include <tuple> +#if defined(__i386__) || defined(__x86_64__) #include <nmmintrin.h> +#endif using namespace clang; @@ -1927,6 +1929,8 @@ fastParseASCIIIdentifierScalar(const char *CurPtr, return CurPtr; } +#if defined(__i386__) || defined(__x86_64__) + __attribute__((target("sse4.2"))) static const char * fastParseASCIIIdentifierSSE42(const char *CurPtr, [[maybe_unused]] const char *BufferEnd) { @@ -1958,14 +1962,22 @@ static bool supportsSSE42() { return SupportsSSE42; } +#endif + static const char *fastParseASCIIIdentifier(const char *CurPtr, const char *BufferEnd) { +#if !defined(__i386__) && !defined(__x86_64__) + return fastParseASCIIIdentifierScalar(CurPtr, BufferEnd); +#else + #ifndef __SSE4_2__ if (LLVM_UNLIKELY(!supportsSSE42())) return fastParseASCIIIdentifierScalar(CurPtr, BufferEnd); #endif return fastParseASCIIIdentifierSSE42(CurPtr, BufferEnd); + +#endif } bool Lexer::LexIdentifierContinue(Token &Result, const char *CurPtr) { >From 2109fdd371822ec77f870c5edbbdfccaaa7615be Mon Sep 17 00:00:00 2001 From: Thibault-Monnier <[email protected]> Date: Sun, 14 Dec 2025 11:32:30 +0100 Subject: [PATCH 03/13] Not on windows --- clang/lib/Lex/Lexer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index c195237dae1f4..86cfb47ca84d5 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -36,6 +36,7 @@ #include "llvm/Support/NativeFormatting.h" #include "llvm/Support/Unicode.h" #include "llvm/Support/UnicodeCharRanges.h" + #include <algorithm> #include <cassert> #include <cstddef> @@ -1929,7 +1930,7 @@ fastParseASCIIIdentifierScalar(const char *CurPtr, return CurPtr; } -#if defined(__i386__) || defined(__x86_64__) +#if defined(__i386__) || defined(__x86_64__) && !defined(_WIN32) __attribute__((target("sse4.2"))) static const char * fastParseASCIIIdentifierSSE42(const char *CurPtr, @@ -1966,7 +1967,7 @@ static bool supportsSSE42() { static const char *fastParseASCIIIdentifier(const char *CurPtr, const char *BufferEnd) { -#if !defined(__i386__) && !defined(__x86_64__) +#if !defined(__i386__) && !defined(__x86_64__) || defined(_WIN32) return fastParseASCIIIdentifierScalar(CurPtr, BufferEnd); #else >From d5485438edd460892bf210916827e0d92fc24065 Mon Sep 17 00:00:00 2001 From: Thibault-Monnier <[email protected]> Date: Sun, 14 Dec 2025 14:37:43 +0100 Subject: [PATCH 04/13] Address comments --- clang/lib/Lex/Lexer.cpp | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 86cfb47ca84d5..470579df233d1 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -1930,7 +1930,12 @@ fastParseASCIIIdentifierScalar(const char *CurPtr, return CurPtr; } -#if defined(__i386__) || defined(__x86_64__) && !defined(_WIN32) +// Fast path for lexing ASCII identifiers using SSE4.2 instructions. +// Only enabled on x86/x86_64 when building with a compiler that supports +// the 'target' attribute, which is used for runtime dispatch. Otherwise, we +// fall back to the scalar implementation. +#if (defined(__i386__) || defined(__x86_64__)) && defined(__has_attribute) && \ + __has_attribute(target) __attribute__((target("sse4.2"))) static const char * fastParseASCIIIdentifierSSE42(const char *CurPtr, @@ -1958,27 +1963,16 @@ fastParseASCIIIdentifierSSE42(const char *CurPtr, return fastParseASCIIIdentifierScalar(CurPtr, BufferEnd); } -static bool supportsSSE42() { - static bool SupportsSSE42 = __builtin_cpu_supports("sse4.2"); - return SupportsSSE42; +__attribute__((target("sse4.2"))) static const char * +fastParseASCIIIdentifier(const char *CurPtr, const char *BufferEnd) { + return fastParseASCIIIdentifierSSE42(CurPtr, BufferEnd); } +__attribute__((target("default"))) #endif - static const char *fastParseASCIIIdentifier(const char *CurPtr, const char *BufferEnd) { -#if !defined(__i386__) && !defined(__x86_64__) || defined(_WIN32) return fastParseASCIIIdentifierScalar(CurPtr, BufferEnd); -#else - -#ifndef __SSE4_2__ - if (LLVM_UNLIKELY(!supportsSSE42())) - return fastParseASCIIIdentifierScalar(CurPtr, BufferEnd); -#endif - - return fastParseASCIIIdentifierSSE42(CurPtr, BufferEnd); - -#endif } bool Lexer::LexIdentifierContinue(Token &Result, const char *CurPtr) { >From 82cf41e460d2fa1105e9abbf925837fa9e9c7b45 Mon Sep 17 00:00:00 2001 From: Thibault-Monnier <[email protected]> Date: Sun, 14 Dec 2025 19:32:29 +0100 Subject: [PATCH 05/13] Not on MSVC --- clang/lib/Lex/Lexer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 470579df233d1..58cd9348d3027 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -1935,7 +1935,7 @@ fastParseASCIIIdentifierScalar(const char *CurPtr, // the 'target' attribute, which is used for runtime dispatch. Otherwise, we // fall back to the scalar implementation. #if (defined(__i386__) || defined(__x86_64__)) && defined(__has_attribute) && \ - __has_attribute(target) + __has_attribute(target) && !defined(_MSC_VER) __attribute__((target("sse4.2"))) static const char * fastParseASCIIIdentifierSSE42(const char *CurPtr, >From d7896bf4cd67116d8a3f59c74b51fce1c0f46951 Mon Sep 17 00:00:00 2001 From: Thibault-Monnier <[email protected]> Date: Sun, 28 Dec 2025 17:48:49 +0100 Subject: [PATCH 06/13] Clean up --- clang/lib/Lex/Lexer.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 58cd9348d3027..ba950dc350edb 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -1921,9 +1921,7 @@ bool Lexer::LexUnicodeIdentifierStart(Token &Result, uint32_t C, return true; } -static const char * -fastParseASCIIIdentifierScalar(const char *CurPtr, - [[maybe_unused]] const char *BufferEnd) { +static const char *fastParseASCIIIdentifierScalar(const char *CurPtr) { unsigned char C = *CurPtr; while (isAsciiIdentifierContinue(C)) C = *++CurPtr; @@ -1936,10 +1934,8 @@ fastParseASCIIIdentifierScalar(const char *CurPtr, // fall back to the scalar implementation. #if (defined(__i386__) || defined(__x86_64__)) && defined(__has_attribute) && \ __has_attribute(target) && !defined(_MSC_VER) - __attribute__((target("sse4.2"))) static const char * -fastParseASCIIIdentifierSSE42(const char *CurPtr, - [[maybe_unused]] const char *BufferEnd) { +fastParseASCIIIdentifierSSE42(const char *CurPtr, const char *BufferEnd) { alignas(16) static constexpr char AsciiIdentifierRange[16] = { '_', '_', 'A', 'Z', 'a', 'z', '0', '9', }; @@ -1960,7 +1956,7 @@ fastParseASCIIIdentifierSSE42(const char *CurPtr, return CurPtr; } - return fastParseASCIIIdentifierScalar(CurPtr, BufferEnd); + return fastParseASCIIIdentifierScalar(CurPtr); } __attribute__((target("sse4.2"))) static const char * @@ -1972,7 +1968,7 @@ __attribute__((target("default"))) #endif static const char *fastParseASCIIIdentifier(const char *CurPtr, const char *BufferEnd) { - return fastParseASCIIIdentifierScalar(CurPtr, BufferEnd); + return fastParseASCIIIdentifierScalar(CurPtr); } bool Lexer::LexIdentifierContinue(Token &Result, const char *CurPtr) { >From 079b0abf7aed81438f1a0b9aa8589399a0e6003a Mon Sep 17 00:00:00 2001 From: Thibault-Monnier <[email protected]> Date: Sun, 11 Jan 2026 21:05:05 +0100 Subject: [PATCH 07/13] Not on windows + fix unused parameter warning --- clang/lib/Lex/Lexer.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index ba950dc350edb..46b496b61c08c 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -1933,7 +1933,7 @@ static const char *fastParseASCIIIdentifierScalar(const char *CurPtr) { // the 'target' attribute, which is used for runtime dispatch. Otherwise, we // fall back to the scalar implementation. #if (defined(__i386__) || defined(__x86_64__)) && defined(__has_attribute) && \ - __has_attribute(target) && !defined(_MSC_VER) + __has_attribute(target) && !defined(_WIN32) __attribute__((target("sse4.2"))) static const char * fastParseASCIIIdentifierSSE42(const char *CurPtr, const char *BufferEnd) { alignas(16) static constexpr char AsciiIdentifierRange[16] = { @@ -1959,15 +1959,11 @@ fastParseASCIIIdentifierSSE42(const char *CurPtr, const char *BufferEnd) { return fastParseASCIIIdentifierScalar(CurPtr); } -__attribute__((target("sse4.2"))) static const char * -fastParseASCIIIdentifier(const char *CurPtr, const char *BufferEnd) { - return fastParseASCIIIdentifierSSE42(CurPtr, BufferEnd); -} - __attribute__((target("default"))) #endif -static const char *fastParseASCIIIdentifier(const char *CurPtr, - const char *BufferEnd) { +static const char * +fastParseASCIIIdentifier(const char *CurPtr, + [[maybe_unused]] const char *BufferEnd) { return fastParseASCIIIdentifierScalar(CurPtr); } >From 0cb3b5c0d61a814a947c20cdbfec7c2be83b80c9 Mon Sep 17 00:00:00 2001 From: Thibault-Monnier <[email protected]> Date: Mon, 12 Jan 2026 19:56:20 +0100 Subject: [PATCH 08/13] Rename function to fix compilation error --- clang/lib/Lex/Lexer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 46b496b61c08c..474b64e6e2341 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -1935,7 +1935,7 @@ static const char *fastParseASCIIIdentifierScalar(const char *CurPtr) { #if (defined(__i386__) || defined(__x86_64__)) && defined(__has_attribute) && \ __has_attribute(target) && !defined(_WIN32) __attribute__((target("sse4.2"))) static const char * -fastParseASCIIIdentifierSSE42(const char *CurPtr, const char *BufferEnd) { +fastParseASCIIIdentifier(const char *CurPtr, const char *BufferEnd) { alignas(16) static constexpr char AsciiIdentifierRange[16] = { '_', '_', 'A', 'Z', 'a', 'z', '0', '9', }; >From f4d1e182a285725b487ab2c6bd909ec93bb24821 Mon Sep 17 00:00:00 2001 From: Thibault-Monnier <[email protected]> Date: Mon, 12 Jan 2026 20:05:19 +0100 Subject: [PATCH 09/13] No runtime check when compiled with SSE4.2 support (POC) --- clang/lib/Lex/Lexer.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 474b64e6e2341..dbef4af5ce01b 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -1932,8 +1932,9 @@ static const char *fastParseASCIIIdentifierScalar(const char *CurPtr) { // Only enabled on x86/x86_64 when building with a compiler that supports // the 'target' attribute, which is used for runtime dispatch. Otherwise, we // fall back to the scalar implementation. -#if (defined(__i386__) || defined(__x86_64__)) && defined(__has_attribute) && \ - __has_attribute(target) && !defined(_WIN32) +#if defined(__SSE4_2__) || (defined(__i386__) || defined(__x86_64__)) && \ + defined(__has_attribute) && \ + __has_attribute(target) && !defined(_WIN32) __attribute__((target("sse4.2"))) static const char * fastParseASCIIIdentifier(const char *CurPtr, const char *BufferEnd) { alignas(16) static constexpr char AsciiIdentifierRange[16] = { @@ -1959,13 +1960,17 @@ fastParseASCIIIdentifier(const char *CurPtr, const char *BufferEnd) { return fastParseASCIIIdentifierScalar(CurPtr); } +#ifndef __SSE4_2__ __attribute__((target("default"))) #endif +#endif +#ifndef __SSE4_2__ static const char * fastParseASCIIIdentifier(const char *CurPtr, [[maybe_unused]] const char *BufferEnd) { return fastParseASCIIIdentifierScalar(CurPtr); } +#endif bool Lexer::LexIdentifierContinue(Token &Result, const char *CurPtr) { // Match [_A-Za-z0-9]*, we have already matched an identifier start. >From 938aec79be93fcc8f1b8cfb829ce933727c36f22 Mon Sep 17 00:00:00 2001 From: Thibault-Monnier <[email protected]> Date: Wed, 14 Jan 2026 20:07:23 +0100 Subject: [PATCH 10/13] Address comments & final fixes --- clang/lib/Lex/Lexer.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index dbef4af5ce01b..7bfaf7a2f8c69 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -1929,13 +1929,16 @@ static const char *fastParseASCIIIdentifierScalar(const char *CurPtr) { } // Fast path for lexing ASCII identifiers using SSE4.2 instructions. -// Only enabled on x86/x86_64 when building with a compiler that supports -// the 'target' attribute, which is used for runtime dispatch. Otherwise, we -// fall back to the scalar implementation. +// Only enabled on x86/x86_64 when building with __SSE4_2__ enabled, or with a +// compiler that supports the 'target' attribute, used for runtime dispatch. +// Otherwise, we fall back to the scalar implementation. +// We avoid runtime check on Windows because it is not yet well-supported. #if defined(__SSE4_2__) || (defined(__i386__) || defined(__x86_64__)) && \ defined(__has_attribute) && \ __has_attribute(target) && !defined(_WIN32) -__attribute__((target("sse4.2"))) static const char * +// "used" is a hack to suppress a false-positive warning due to a bug in +// clang-18 and less. See PR175452. +__attribute__((target("sse4.2"), used)) static const char * fastParseASCIIIdentifier(const char *CurPtr, const char *BufferEnd) { alignas(16) static constexpr char AsciiIdentifierRange[16] = { '_', '_', 'A', 'Z', 'a', 'z', '0', '9', @@ -1965,9 +1968,7 @@ __attribute__((target("default"))) #endif #endif #ifndef __SSE4_2__ -static const char * -fastParseASCIIIdentifier(const char *CurPtr, - [[maybe_unused]] const char *BufferEnd) { +static const char *fastParseASCIIIdentifier(const char *CurPtr, const char *) { return fastParseASCIIIdentifierScalar(CurPtr); } #endif >From e8370a9512f6851d39256139b722b09e783e0305 Mon Sep 17 00:00:00 2001 From: Thibault-Monnier <[email protected]> Date: Thu, 15 Jan 2026 16:28:47 +0100 Subject: [PATCH 11/13] Try simplifying with macros --- clang/lib/Lex/Lexer.cpp | 21 ++++++++------------- llvm/include/llvm/Support/Compiler.h | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 7bfaf7a2f8c69..9a85d184b4c38 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -1933,12 +1933,10 @@ static const char *fastParseASCIIIdentifierScalar(const char *CurPtr) { // compiler that supports the 'target' attribute, used for runtime dispatch. // Otherwise, we fall back to the scalar implementation. // We avoid runtime check on Windows because it is not yet well-supported. -#if defined(__SSE4_2__) || (defined(__i386__) || defined(__x86_64__)) && \ - defined(__has_attribute) && \ - __has_attribute(target) && !defined(_WIN32) -// "used" is a hack to suppress a false-positive warning due to a bug in -// clang-18 and less. See PR175452. -__attribute__((target("sse4.2"), used)) static const char * +#if LLVM_SUPPORTS_RUNTIME_SSE42_CHECK +// LLVM_ATTRIBUTE_USED is a hack to suppress a false-positive warning due to a +// bug in clang-18 and less. See PR175452. +LLVM_ATTRIBUTE_USED __attribute__((target("sse4.2"))) static const char * fastParseASCIIIdentifier(const char *CurPtr, const char *BufferEnd) { alignas(16) static constexpr char AsciiIdentifierRange[16] = { '_', '_', 'A', 'Z', 'a', 'z', '0', '9', @@ -1963,15 +1961,12 @@ fastParseASCIIIdentifier(const char *CurPtr, const char *BufferEnd) { return fastParseASCIIIdentifierScalar(CurPtr); } -#ifndef __SSE4_2__ -__attribute__((target("default"))) +LLVM_UNLESS_SSE42(__attribute__((target("default")))) #endif -#endif -#ifndef __SSE4_2__ -static const char *fastParseASCIIIdentifier(const char *CurPtr, const char *) { +LLVM_UNLESS_SSE42(static const char *fastParseASCIIIdentifier( + const char *CurPtr, const char *) { return fastParseASCIIIdentifierScalar(CurPtr); -} -#endif +}) bool Lexer::LexIdentifierContinue(Token &Result, const char *CurPtr) { // Match [_A-Za-z0-9]*, we have already matched an identifier start. diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h index 56f498a36ae52..720079d83a37e 100644 --- a/llvm/include/llvm/Support/Compiler.h +++ b/llvm/include/llvm/Support/Compiler.h @@ -739,4 +739,25 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); #endif // clang-format on +/// \macro LLVM_UNLESS_SSE42 +/// Expands to its arguments only if SSE4.2 is not enabled. +/// This can be used to annotate code that should only be compiled when SSE4.2 +/// is not available. +#ifdef __SSE4_2__ +#define LLVM_UNLESS_SSE42(...) +#else +#define LLVM_UNLESS_SSE42(...) __VA_ARGS__ +#endif + +/// \macro LLVM_SUPPORTS_RUNTIME_SSE42_CHECK +/// Expands to true if runtime detection of SSE4.2 is supported. +/// This can be used to guard runtime checks for SSE4.2 support. +#if defined(__SSE4_2__) || \ + ((defined(__i386__) || defined(__x86_64__)) && defined(__has_attribute) && \ + __has_attribute(target) && !defined(_WIN32)) +#define LLVM_SUPPORTS_RUNTIME_SSE42_CHECK 1 +#else +#define LLVM_SUPPORTS_RUNTIME_SSE42_CHECK 0 +#endif + #endif >From c5d70f488918b8e4106f4f47c0b504063f7ea4a2 Mon Sep 17 00:00:00 2001 From: Thibault-Monnier <[email protected]> Date: Sun, 18 Jan 2026 13:39:03 +0100 Subject: [PATCH 12/13] Cleanup and address comments --- clang/lib/Lex/Lexer.cpp | 19 +++++++++--------- llvm/include/llvm/Support/Compiler.h | 29 ++++++++++++++++------------ 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 9a85d184b4c38..754e815b7cd43 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -1930,13 +1930,11 @@ static const char *fastParseASCIIIdentifierScalar(const char *CurPtr) { // Fast path for lexing ASCII identifiers using SSE4.2 instructions. // Only enabled on x86/x86_64 when building with __SSE4_2__ enabled, or with a -// compiler that supports the 'target' attribute, used for runtime dispatch. -// Otherwise, we fall back to the scalar implementation. -// We avoid runtime check on Windows because it is not yet well-supported. -#if LLVM_SUPPORTS_RUNTIME_SSE42_CHECK +// compiler and platform that support runtime dispatch. +#if __SSE4_2__ || LLVM_SUPPORTS_RUNTIME_SSE42_CHECK // LLVM_ATTRIBUTE_USED is a hack to suppress a false-positive warning due to a // bug in clang-18 and less. See PR175452. -LLVM_ATTRIBUTE_USED __attribute__((target("sse4.2"))) static const char * +LLVM_ATTRIBUTE_USED LLVM_TARGET_SSE42 static const char * fastParseASCIIIdentifier(const char *CurPtr, const char *BufferEnd) { alignas(16) static constexpr char AsciiIdentifierRange[16] = { '_', '_', 'A', 'Z', 'a', 'z', '0', '9', @@ -1960,13 +1958,14 @@ fastParseASCIIIdentifier(const char *CurPtr, const char *BufferEnd) { return fastParseASCIIIdentifierScalar(CurPtr); } - -LLVM_UNLESS_SSE42(__attribute__((target("default")))) #endif -LLVM_UNLESS_SSE42(static const char *fastParseASCIIIdentifier( - const char *CurPtr, const char *) { + +#ifndef __SSE4_2__ +LLVM_TARGET_DEFAULT static const char * +fastParseASCIIIdentifier(const char *CurPtr, const char *) { return fastParseASCIIIdentifierScalar(CurPtr); -}) +} +#endif bool Lexer::LexIdentifierContinue(Token &Result, const char *CurPtr) { // Match [_A-Za-z0-9]*, we have already matched an identifier start. diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h index 720079d83a37e..a1caebba38edf 100644 --- a/llvm/include/llvm/Support/Compiler.h +++ b/llvm/include/llvm/Support/Compiler.h @@ -739,25 +739,30 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); #endif // clang-format on -/// \macro LLVM_UNLESS_SSE42 -/// Expands to its arguments only if SSE4.2 is not enabled. -/// This can be used to annotate code that should only be compiled when SSE4.2 -/// is not available. -#ifdef __SSE4_2__ -#define LLVM_UNLESS_SSE42(...) -#else -#define LLVM_UNLESS_SSE42(...) __VA_ARGS__ -#endif - /// \macro LLVM_SUPPORTS_RUNTIME_SSE42_CHECK /// Expands to true if runtime detection of SSE4.2 is supported. /// This can be used to guard runtime checks for SSE4.2 support. -#if defined(__SSE4_2__) || \ - ((defined(__i386__) || defined(__x86_64__)) && defined(__has_attribute) && \ +#if ((defined(__i386__) || defined(__x86_64__)) && defined(__has_attribute) && \ __has_attribute(target) && !defined(_WIN32)) #define LLVM_SUPPORTS_RUNTIME_SSE42_CHECK 1 #else #define LLVM_SUPPORTS_RUNTIME_SSE42_CHECK 0 #endif +/// \macro LLVM_TARGET_DEFAULT +/// Function attribute to compile a function with default target features. +#if defined(__has_attribute) && __has_attribute(target) +#define LLVM_TARGET_DEFAULT __attribute__((target("default"))) +#else +#define LLVM_TARGET_DEFAULT +#endif + +/// \macro LLVM_TARGET_SSE42 +/// Function attribute to compile a function with SSE4.2 enabled. +#if defined(__has_attribute) && __has_attribute(target) +#define LLVM_TARGET_SSE42 __attribute__((target("sse4.2"))) +#else +#define LLVM_TARGET_SSE42 +#endif + #endif >From 141ccc95bb0ae7456c9d71d1647574fe96d9c3de Mon Sep 17 00:00:00 2001 From: Thibault-Monnier <[email protected]> Date: Sun, 18 Jan 2026 15:31:28 +0100 Subject: [PATCH 13/13] Try fix breakage --- clang/lib/Lex/Lexer.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 754e815b7cd43..8d66b03a93ee0 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -1958,10 +1958,15 @@ fastParseASCIIIdentifier(const char *CurPtr, const char *BufferEnd) { return fastParseASCIIIdentifierScalar(CurPtr); } + +#ifndef __SSE4_2__ +LLVM_TARGET_DEFAULT +#endif + #endif #ifndef __SSE4_2__ -LLVM_TARGET_DEFAULT static const char * +static const char * fastParseASCIIIdentifier(const char *CurPtr, const char *) { return fastParseASCIIIdentifierScalar(CurPtr); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
