Index: llvm/trunk/include/llvm/IR/IntrinsicsX86.td =================================================================== --- llvm/trunk/include/llvm/IR/IntrinsicsX86.td +++ llvm/trunk/include/llvm/IR/IntrinsicsX86.td @@ -6401,3 +6401,12 @@ def int_x86_clzero : GCCBuiltin<"__builtin_ia32_clzero">, Intrinsic<[], [llvm_ptr_ty], []>; } + +//===----------------------------------------------------------------------===// +// Cache line write back intrinsics + +// Write back no-invalidate +let TargetPrefix = "x86" in { + def int_x86_wbnoinvd : GCCBuiltin<"__builtin_ia32_wbnoinvd">, + Intrinsic<[], [], []>; +} Index: llvm/trunk/lib/Support/Host.cpp =================================================================== --- llvm/trunk/lib/Support/Host.cpp +++ llvm/trunk/lib/Support/Host.cpp @@ -1213,9 +1213,12 @@ Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1); Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1); + // Miscellaneous memory related features, detected by + // using the 0x80000008 leaf of the CPUID instruction bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 && !getX86CpuIDAndInfo(0x80000008, &EAX, &EBX, &ECX, &EDX); - Features["clzero"] = HasExtLeaf8 && ((EBX >> 0) & 1); + Features["clzero"] = HasExtLeaf8 && ((EBX >> 0) & 1); + Features["wbnoinvd"] = HasExtLeaf8 && ((EBX >> 9) & 1); bool HasLeaf7 = MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX); Index: llvm/trunk/lib/Target/X86/X86.td =================================================================== --- llvm/trunk/lib/Target/X86/X86.td +++ llvm/trunk/lib/Target/X86/X86.td @@ -249,6 +249,8 @@ "Flush A Cache Line Optimized">; def FeatureCLWB : SubtargetFeature<"clwb", "HasCLWB", "true", "Cache Line Write Back">; +def FeatureWBNOINVD : SubtargetFeature<"wbnoinvd", "HasWBNOINVD", "true", + "Write Back No Invalidate">; def FeatureRDPID : SubtargetFeature<"rdpid", "HasRDPID", "true", "Support RDPID instructions">; // On some processors, instructions that implicitly take two memory operands are @@ -825,6 +827,7 @@ class IcelakeServerProc : ProcModel; def : IcelakeServerProc<"icelake-server">; Index: llvm/trunk/lib/Target/X86/X86InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td @@ -888,6 +888,7 @@ def HasIBT : Predicate<"Subtarget->hasIBT()">; def HasCLFLUSHOPT : Predicate<"Subtarget->hasCLFLUSHOPT()">; def HasCLWB : Predicate<"Subtarget->hasCLWB()">; +def HasWBNOINVD : Predicate<"Subtarget->hasWBNOINVD()">; def HasRDPID : Predicate<"Subtarget->hasRDPID()">; def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">; def Not64BitMode : Predicate<"!Subtarget->is64Bit()">, Index: llvm/trunk/lib/Target/X86/X86InstrSystem.td =================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSystem.td +++ llvm/trunk/lib/Target/X86/X86InstrSystem.td @@ -482,6 +482,12 @@ let SchedRW = [WriteSystem] in { def INVD : I<0x08, RawFrm, (outs), (ins), "invd", [], IIC_INVD>, TB; def WBINVD : I<0x09, RawFrm, (outs), (ins), "wbinvd", [], IIC_INVD>, TB; + +// wbnoinvd is like wbinvd, except without invalidation +// encoding: like wbinvd + an 0xF3 prefix +def WBNOINVD : I<0x09, RawFrm, (outs), (ins), "wbnoinvd", + [(int_x86_wbnoinvd)], IIC_INVD>, XS, + Requires<[HasWBNOINVD]>; } // SchedRW //===----------------------------------------------------------------------===// Index: llvm/trunk/lib/Target/X86/X86Subtarget.h =================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.h +++ llvm/trunk/lib/Target/X86/X86Subtarget.h @@ -360,6 +360,9 @@ /// Processor supports Cache Line Write Back instruction bool HasCLWB; + /// Processor supports Write Back No Invalidate instruction + bool HasWBNOINVD; + /// Processor support RDPID instruction bool HasRDPID; @@ -621,6 +624,7 @@ bool hasIBT() const { return HasIBT; } bool hasCLFLUSHOPT() const { return HasCLFLUSHOPT; } bool hasCLWB() const { return HasCLWB; } + bool hasWBNOINVD() const { return HasWBNOINVD; } bool hasRDPID() const { return HasRDPID; } bool useRetpoline() const { return UseRetpoline; } bool useRetpolineExternalThunk() const { return UseRetpolineExternalThunk; } Index: llvm/trunk/lib/Target/X86/X86Subtarget.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp @@ -324,6 +324,7 @@ HasSGX = false; HasCLFLUSHOPT = false; HasCLWB = false; + HasWBNOINVD = false; HasRDPID = false; UseRetpoline = false; UseRetpolineExternalThunk = false; Index: llvm/trunk/test/CodeGen/X86/wbnoinvd-intrinsic.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/wbnoinvd-intrinsic.ll +++ llvm/trunk/test/CodeGen/X86/wbnoinvd-intrinsic.ll @@ -0,0 +1,18 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+wbnoinvd | FileCheck %s -check-prefix=CHECK32 +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+wbnoinvd | FileCheck %s -check-prefix=CHECK64 + +define void @wbnoinvd() nounwind { +; CHECK32-LABEL: wbnoinvd: +; CHECK32: # %bb.0: +; CHECK32-NEXT: wbnoinvd +; CHECK32-NEXT: retl +; +; CHECK64-LABEL: wbnoinvd: +; CHECK64: # %bb.0: +; CHECK64-NEXT: wbnoinvd +; CHECK64-NEXT: retq + tail call void @llvm.x86.wbnoinvd() + ret void +} +declare void @llvm.x86.wbnoinvd() nounwind Index: llvm/trunk/test/MC/Disassembler/X86/x86-16.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/X86/x86-16.txt +++ llvm/trunk/test/MC/Disassembler/X86/x86-16.txt @@ -791,3 +791,6 @@ # CHECK: callw -1 0xe8 0xff 0xff + +# CHECK: wbnoinvd +0xf3 0x0f 0x09 Index: llvm/trunk/test/MC/Disassembler/X86/x86-32.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/X86/x86-32.txt +++ llvm/trunk/test/MC/Disassembler/X86/x86-32.txt @@ -820,3 +820,6 @@ # CHECK: ptwritel %eax 0xf3 0x0f 0xae 0xe0 + +# CHECK: wbnoinvd +0xf3 0x0f 0x09 Index: llvm/trunk/test/MC/Disassembler/X86/x86-64.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/X86/x86-64.txt +++ llvm/trunk/test/MC/Disassembler/X86/x86-64.txt @@ -516,3 +516,6 @@ # CHECK: ptwriteq %rax 0xf3 0x48 0x0f 0xae 0xe0 + +# CHECK: wbnoinvd +0xf3 0x0f 0x09 Index: llvm/trunk/test/MC/X86/x86-16.s =================================================================== --- llvm/trunk/test/MC/X86/x86-16.s +++ llvm/trunk/test/MC/X86/x86-16.s @@ -969,3 +969,7 @@ // CHECK: lgdtw 4(%eax) // CHECK: encoding: [0x67,0x0f,0x01,0x50,0x04] data32 lgdt 4(%eax) + +// CHECK: wbnoinvd +// CHECK: encoding: [0xf3,0x0f,0x09] +wbnoinvd Index: llvm/trunk/test/MC/X86/x86-32-coverage.s =================================================================== --- llvm/trunk/test/MC/X86/x86-32-coverage.s +++ llvm/trunk/test/MC/X86/x86-32-coverage.s @@ -2788,6 +2788,10 @@ // CHECK: encoding: [0x0f,0x09] wbinvd +// CHECK: wbnoinvd +// CHECK: encoding: [0xf3,0x0f,0x09] + wbnoinvd + // CHECK: cpuid // CHECK: encoding: [0x0f,0xa2] cpuid Index: llvm/trunk/test/MC/X86/x86-64.s =================================================================== --- llvm/trunk/test/MC/X86/x86-64.s +++ llvm/trunk/test/MC/X86/x86-64.s @@ -1559,6 +1559,10 @@ // CHECK: encoding: [0xf3,0x48,0x0f,0xae,0xe0] ptwriteq %rax +// CHECK: wbnoinvd +// CHECK: encoding: [0xf3,0x0f,0x09] +wbnoinvd + // __asm __volatile( // "pushf \n\t" // "popf \n\t"