From 7da648bdd03a2fce7ab214f0425efb3a1ec1f4fe Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Fri, 2 May 2025 16:15:33 -0700 Subject: [PATCH 1/3] Reapply "[Win/X86] Make _m_prefetch[w] builtins to avoid winnt.h conflicts (#115099)" This reverts commit 83ff9d4a34b1e579dd809759d13b70b8837f0cde. Don't change the builtin signature of _mm_prefetch this time. --- clang/include/clang/Basic/BuiltinsX86.td | 10 ++++++++-- clang/lib/CodeGen/TargetBuiltins/X86.cpp | 11 +++++++++++ clang/lib/Headers/prfchwintrin.h | 23 ++++++++++------------- clang/lib/Headers/xmmintrin.h | 9 +++++---- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/clang/include/clang/Basic/BuiltinsX86.td b/clang/include/clang/Basic/BuiltinsX86.td index 67cbbfdec7aaf..dbf3cca19546e 100644 --- a/clang/include/clang/Basic/BuiltinsX86.td +++ b/clang/include/clang/Basic/BuiltinsX86.td @@ -138,6 +138,12 @@ let Attributes = [Const, NoThrow, RequiredVectorWidth<256>], Features = "avx" in } } +// PRFCHW +let Features = "prfchw", Header = "intrin.h", Attributes = [NoThrow, Const] in { + def _m_prefetch : X86LibBuiltin<"void(void *)">; + def _m_prefetchw : X86LibBuiltin<"void(void volatile const *)">; +} + // Mechanically ported builtins from the original `.def` file. // @@ -146,8 +152,8 @@ let Attributes = [Const, NoThrow, RequiredVectorWidth<256>], Features = "avx" in // current formulation is based on what was easiest to recognize from the // pre-TableGen version. -let Features = "mmx", Attributes = [NoThrow, Const] in { - def _mm_prefetch : X86NoPrefixBuiltin<"void(char const *, int)">; +let Features = "sse", Header = "xmmintrin.h", Attributes = [NoThrow, Const] in { + def _mm_prefetch : X86LibBuiltin<"void(char const *, int)">; } let Features = "sse", Attributes = [NoThrow] in { diff --git a/clang/lib/CodeGen/TargetBuiltins/X86.cpp b/clang/lib/CodeGen/TargetBuiltins/X86.cpp index 3c2a77ab3fe4e..e23d19d2f6b6b 100644 --- a/clang/lib/CodeGen/TargetBuiltins/X86.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/X86.cpp @@ -804,6 +804,17 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, Function *F = CGM.getIntrinsic(Intrinsic::prefetch, Address->getType()); return Builder.CreateCall(F, {Address, RW, Locality, Data}); } + case X86::BI_m_prefetch: + case X86::BI_m_prefetchw: { + Value *Address = Ops[0]; + // The 'w' suffix implies write. + Value *RW = + ConstantInt::get(Int32Ty, BuiltinID == X86::BI_m_prefetchw ? 1 : 0); + Value *Locality = ConstantInt::get(Int32Ty, 0x3); + Value *Data = ConstantInt::get(Int32Ty, 1); + Function *F = CGM.getIntrinsic(Intrinsic::prefetch, Address->getType()); + return Builder.CreateCall(F, {Address, RW, Locality, Data}); + } case X86::BI_mm_clflush: { return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_clflush), Ops[0]); diff --git a/clang/lib/Headers/prfchwintrin.h b/clang/lib/Headers/prfchwintrin.h index eaea5f3cf8feb..8ec55d7073716 100644 --- a/clang/lib/Headers/prfchwintrin.h +++ b/clang/lib/Headers/prfchwintrin.h @@ -14,6 +14,10 @@ #ifndef __PRFCHWINTRIN_H #define __PRFCHWINTRIN_H +#if defined(__cplusplus) +extern "C" { +#endif + /// Loads a memory sequence containing the specified memory address into /// all data cache levels. /// @@ -26,11 +30,7 @@ /// /// \param __P /// A pointer specifying the memory address to be prefetched. -static __inline__ void __attribute__((__always_inline__, __nodebug__)) -_m_prefetch(void *__P) -{ - __builtin_prefetch (__P, 0, 3 /* _MM_HINT_T0 */); -} +void _m_prefetch(void *__P); /// Loads a memory sequence containing the specified memory address into /// the L1 data cache and sets the cache-coherency state to modified. @@ -48,13 +48,10 @@ _m_prefetch(void *__P) /// /// \param __P /// A pointer specifying the memory address to be prefetched. -static __inline__ void __attribute__((__always_inline__, __nodebug__)) -_m_prefetchw(volatile const void *__P) -{ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wcast-qual" - __builtin_prefetch ((const void*)__P, 1, 3 /* _MM_HINT_T0 */); -#pragma clang diagnostic pop -} +void _m_prefetchw(volatile const void *__P); + +#if defined(__cplusplus) +} // extern "C" +#endif #endif /* __PRFCHWINTRIN_H */ diff --git a/clang/lib/Headers/xmmintrin.h b/clang/lib/Headers/xmmintrin.h index 20e66d190113a..1fb070bca827e 100644 --- a/clang/lib/Headers/xmmintrin.h +++ b/clang/lib/Headers/xmmintrin.h @@ -2197,10 +2197,7 @@ _mm_storer_ps(float *__p, __m128 __a) #define _MM_HINT_T2 1 #define _MM_HINT_NTA 0 -#ifndef _MSC_VER -/* FIXME: We have to #define this because "sel" must be a constant integer, and - Sema doesn't do any form of constant propagation yet. */ - +#if 0 /// Loads one cache line of data from the specified address to a location /// closer to the processor. /// @@ -2225,6 +2222,10 @@ _mm_storer_ps(float *__p, __m128 __a) /// be generated. \n /// _MM_HINT_T2: Move data using the T2 hint. The PREFETCHT2 instruction will /// be generated. +/// +/// _mm_prefetch is implemented as a "library builtin" directly in Clang, +/// similar to how it is done in MSVC. Clang will warn if the user doesn't +/// include xmmintrin.h or immintrin.h. #define _mm_prefetch(a, sel) (__builtin_prefetch((const void *)(a), \ ((sel) >> 2) & 1, (sel) & 0x3)) #endif From 3ae34add8e105b30ccedd5f058decc4d3157ffdd Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Fri, 9 May 2025 15:37:55 -0700 Subject: [PATCH 2/3] Make _m_prefetch use the mmx feature, and keep the _mm_prefetch macro --- clang/include/clang/Basic/BuiltinsX86.td | 6 ++++-- clang/lib/Headers/xmmintrin.h | 10 +++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/Basic/BuiltinsX86.td b/clang/include/clang/Basic/BuiltinsX86.td index dbf3cca19546e..a4acc72fdc37d 100644 --- a/clang/include/clang/Basic/BuiltinsX86.td +++ b/clang/include/clang/Basic/BuiltinsX86.td @@ -138,13 +138,15 @@ let Attributes = [Const, NoThrow, RequiredVectorWidth<256>], Features = "avx" in } } +let Features = "mmx", Header = "mmintrin.h", Attributes = [NoThrow, Const] in { + def _m_prefetch : X86LibBuiltin<"void(void *)">; +} + // PRFCHW let Features = "prfchw", Header = "intrin.h", Attributes = [NoThrow, Const] in { - def _m_prefetch : X86LibBuiltin<"void(void *)">; def _m_prefetchw : X86LibBuiltin<"void(void volatile const *)">; } - // Mechanically ported builtins from the original `.def` file. // // TODO: Build structured ways of synthesizing relevant groups and improve the diff --git a/clang/lib/Headers/xmmintrin.h b/clang/lib/Headers/xmmintrin.h index 1fb070bca827e..6a6436977303f 100644 --- a/clang/lib/Headers/xmmintrin.h +++ b/clang/lib/Headers/xmmintrin.h @@ -2197,7 +2197,11 @@ _mm_storer_ps(float *__p, __m128 __a) #define _MM_HINT_T2 1 #define _MM_HINT_NTA 0 -#if 0 +#ifndef _MSC_VER +// If _MSC_VER is defined, we use the builtin variant of _mm_prefetch. +// Otherwise, we provide this macro, which includes a cast, allowing the user +// to pass a pointer of any time. The _mm_prefetch accepts char to match MSVC. + /// Loads one cache line of data from the specified address to a location /// closer to the processor. /// @@ -2222,10 +2226,6 @@ _mm_storer_ps(float *__p, __m128 __a) /// be generated. \n /// _MM_HINT_T2: Move data using the T2 hint. The PREFETCHT2 instruction will /// be generated. -/// -/// _mm_prefetch is implemented as a "library builtin" directly in Clang, -/// similar to how it is done in MSVC. Clang will warn if the user doesn't -/// include xmmintrin.h or immintrin.h. #define _mm_prefetch(a, sel) (__builtin_prefetch((const void *)(a), \ ((sel) >> 2) & 1, (sel) & 0x3)) #endif From 70bb9241d8c88cbde4063d606b729cb070084421 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Fri, 9 May 2025 15:50:01 -0700 Subject: [PATCH 3/3] Add missing mmintrin.h header entry --- clang/include/clang/Basic/BuiltinHeaders.def | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/include/clang/Basic/BuiltinHeaders.def b/clang/include/clang/Basic/BuiltinHeaders.def index 8e4a2f9bee9aa..709d552d5b498 100644 --- a/clang/include/clang/Basic/BuiltinHeaders.def +++ b/clang/include/clang/Basic/BuiltinHeaders.def @@ -22,6 +22,7 @@ HEADER(INTRIN_H, "intrin.h") HEADER(MALLOC_H, "malloc.h") HEADER(MATH_H, "math.h") HEADER(MEMORY, "memory") +HEADER(MMINTRIN_H, "mmintrin.h") HEADER(OBJC_MESSAGE_H, "objc/message.h") HEADER(OBJC_OBJC_AUTO_H, "objc/objc-auto.h") HEADER(OBJC_OBJC_EXCEPTION_H, "objc/objc-exception.h")