Index: include/clang/Basic/BuiltinsX86.def =================================================================== --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -1880,6 +1880,11 @@ TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "", "mwaitx") TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx") +// WAITPKG +TARGET_BUILTIN(__builtin_ia32_umonitor, "vv*", "", "waitpkg") +TARGET_BUILTIN(__builtin_ia32_umwait, "UcUiUiUi", "", "waitpkg") +TARGET_BUILTIN(__builtin_ia32_tpause, "UcUiUiUi", "", "waitpkg") + // CLZERO TARGET_BUILTIN(__builtin_ia32_clzero, "vv*", "", "clzero") Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -2678,6 +2678,8 @@ def mno_vaes : Flag<["-"], "mno-vaes">, Group; def mvpclmulqdq : Flag<["-"], "mvpclmulqdq">, Group; def mno_vpclmulqdq : Flag<["-"], "mno-vpclmulqdq">, Group; +def mwaitpkg : Flag<["-"], "mwaitpkg">, Group; +def mno_waitpkg : Flag<["-"], "mno-waitpkg">, Group; def mxop : Flag<["-"], "mxop">, Group; def mno_xop : Flag<["-"], "mno-xop">, Group; def mxsave : Flag<["-"], "mxsave">, Group; Index: lib/Basic/Targets/X86.h =================================================================== --- lib/Basic/Targets/X86.h +++ lib/Basic/Targets/X86.h @@ -102,6 +102,7 @@ bool HasRetpolineExternalThunk = false; bool HasLAHFSAHF = false; bool HasWBNOINVD = false; + bool HasWAITPKG = false; protected: /// \brief Enumeration of all of the X86 CPUs supported by Clang. Index: lib/Basic/Targets/X86.cpp =================================================================== --- lib/Basic/Targets/X86.cpp +++ lib/Basic/Targets/X86.cpp @@ -247,6 +247,7 @@ case CK_Tremont: setFeatureEnabledImpl(Features, "cldemote", true); setFeatureEnabledImpl(Features, "gfni", true); + setFeatureEnabledImpl(Features, "waitpkg", true); LLVM_FALLTHROUGH; case CK_GoldmontPlus: setFeatureEnabledImpl(Features, "rdpid", true); @@ -818,6 +819,8 @@ HasRetpolineExternalThunk = true; } else if (Feature == "+sahf") { HasLAHFSAHF = true; + } else if (Feature == "+waitpkg") { + HasWAITPKG = true; } X86SSEEnum Level = llvm::StringSwitch(Feature) @@ -1172,6 +1175,8 @@ Builder.defineMacro("__RDPID__"); if (HasCLDEMOTE) Builder.defineMacro("__CLDEMOTE__"); + if (HasWAITPKG) + Builder.defineMacro("__WAITPKG__"); // Each case falls through to the previous one here. switch (SSELevel) { @@ -1323,6 +1328,7 @@ .Case("vaes", true) .Case("vpclmulqdq", true) .Case("wbnoinvd", true) + .Case("waitpkg", true) .Case("x87", true) .Case("xop", true) .Case("xsave", true) @@ -1399,6 +1405,7 @@ .Case("vaes", HasVAES) .Case("vpclmulqdq", HasVPCLMULQDQ) .Case("wbnoinvd", HasWBNOINVD) + .Case("waitpkg", HasWAITPKG) .Case("x86", true) .Case("x86_32", getTriple().getArch() == llvm::Triple::x86) .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64) Index: lib/Headers/CMakeLists.txt =================================================================== --- lib/Headers/CMakeLists.txt +++ lib/Headers/CMakeLists.txt @@ -96,6 +96,7 @@ varargs.h vecintrin.h vpclmulqdqintrin.h + waitpkgintrin.h wbnoinvdintrin.h wmmintrin.h __wmmintrin_aes.h Index: lib/Headers/cpuid.h =================================================================== --- lib/Headers/cpuid.h +++ lib/Headers/cpuid.h @@ -177,6 +177,7 @@ #define bit_AVX512VBMI 0x00000002 #define bit_PKU 0x00000004 #define bit_OSPKE 0x00000010 +#define bit_WAITPKG 0x00000020 #define bit_AVX512VBMI2 0x00000040 #define bit_SHSTK 0x00000080 #define bit_GFNI 0x00000100 Index: lib/Headers/waitpkgintrin.h =================================================================== --- /dev/null +++ lib/Headers/waitpkgintrin.h @@ -0,0 +1,56 @@ +/*===----------------------- waitpkgintrin.h - WAITPKG --------------------=== + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-----------------------------------------------------------------------=== + */ +#ifndef __X86INTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef _WAITPKGINTRIN_H +#define _WAITPKGINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS \ + __attribute__((__always_inline__, __nodebug__, __target__("waitpkg"))) + +static __inline__ void __DEFAULT_FN_ATTRS +_umonitor (void * __address) +{ + __builtin_ia32_umonitor (__address); +} + +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_umwait (unsigned int __control, unsigned long long __counter) +{ + return __builtin_ia32_umwait (__control, + (unsigned int)(__counter >> 32), (unsigned int)__counter); +} + +static __inline__ unsigned char __DEFAULT_FN_ATTRS +_tpause (unsigned int __control, unsigned long long __counter) +{ + return __builtin_ia32_tpause (__control, + (unsigned int)(__counter >> 32), (unsigned int)__counter); +} + +#undef __DEFAULT_FN_ATTRS + +#endif /* _WAITPKGINTRIN_H */ Index: lib/Headers/x86intrin.h =================================================================== --- lib/Headers/x86intrin.h +++ lib/Headers/x86intrin.h @@ -96,4 +96,8 @@ #include #endif +#if !defined(_MSC_VER) || __has_feature(modules) || defined(__WAITPKG__) +#include +#endif + #endif /* __X86INTRIN_H */ Index: test/CodeGen/waitpkg.c =================================================================== --- /dev/null +++ test/CodeGen/waitpkg.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 %s -ffreestanding -triple x86_64-unknown-unknown -emit-llvm -target-feature +waitpkg -Wall -pedantic -o - | FileCheck %s +// RUN: %clang_cc1 %s -ffreestanding -triple i386-unknown-unknown -emit-llvm -target-feature +waitpkg -Wall -pedantic -o - | FileCheck %s + +#include + +#include +#include + +void test_umonitor(void *address) { + //CHECK-LABEL: @test_umonitor + //CHECK: call void @llvm.x86.umonitor(i8* %{{.*}}) + return _umonitor(address); +} + +uint8_t test_umwait(uint32_t control, uint64_t counter) { + //CHECK-LABEL: @test_umwait + //CHECK: call i8 @llvm.x86.umwait(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) + return _umwait(control, counter); +} + +uint8_t test_tpause(uint32_t control, uint64_t counter) { + //CHECK-LABEL: @test_tpause + //CHECK: call i8 @llvm.x86.tpause(i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}) + return _tpause(control, counter); +} Index: test/Driver/x86-target-features.c =================================================================== --- test/Driver/x86-target-features.c +++ test/Driver/x86-target-features.c @@ -144,3 +144,8 @@ // RUN: %clang -target i386-linux-gnu -mretpoline -mno-retpoline-external-thunk %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-RETPOLINE-EXTERNAL-THUNK %s // RETPOLINE-EXTERNAL-THUNK: "-target-feature" "+retpoline-external-thunk" // NO-RETPOLINE-EXTERNAL-THUNK: "-target-feature" "-retpoline-external-thunk" + +// RUN: %clang -target i386-linux-gnu -mwaitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=WAITPKG %s +// RUN: %clang -target i386-linux-gnu -mno-waitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-WAITPKG %s +// WAITPKG: "-target-feature" "+waitpkg" +// NO-WAITPKG: "-target-feature" "-waitpkg" Index: test/Preprocessor/predefined-arch-macros.c =================================================================== --- test/Preprocessor/predefined-arch-macros.c +++ test/Preprocessor/predefined-arch-macros.c @@ -1482,6 +1482,7 @@ // CHECK_TRM_M32: #define __SSE_MATH__ 1 // CHECK_TRM_M32: #define __SSE__ 1 // CHECK_TRM_M32: #define __SSSE3__ 1 +// CHECK_TRM_M32: #define __WAITPKG__ 1 // CHECK_TRM_M32: #define __XSAVEC__ 1 // CHECK_TRM_M32: #define __XSAVEOPT__ 1 // CHECK_TRM_M32: #define __XSAVES__ 1 @@ -1518,6 +1519,7 @@ // CHECK_TRM_M64: #define __SSE4_2__ 1 // CHECK_TRM_M64: #define __SSE__ 1 // CHECK_TRM_M64: #define __SSSE3__ 1 +// CHECK_TRM_M64: #define __WAITPKG__ 1 // CHECK_TRM_M64: #define __XSAVEC__ 1 // CHECK_TRM_M64: #define __XSAVEOPT__ 1 // CHECK_TRM_M64: #define __XSAVES__ 1