From 2ef36f3571c83650f3e1bac42c810c289851d865 Mon Sep 17 00:00:00 2001 From: Gabor Buella Date: Wed, 11 Apr 2018 20:01:57 +0000 Subject: [PATCH] [X86] Describe wbnoinvd instruction Similar to the wbinvd instruction, except this one does not invalidate caches. Ring 0 only. The encoding matches a wbinvd instruction with an F3 prefix. Reviewers: craig.topper, zvi, ashlykov Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D43816 llvm-svn: 329847 --- llvm/include/llvm/IR/IntrinsicsX86.td | 9 +++++++++ llvm/lib/Support/Host.cpp | 5 ++++- llvm/lib/Target/X86/X86.td | 3 +++ llvm/lib/Target/X86/X86InstrInfo.td | 1 + llvm/lib/Target/X86/X86InstrSystem.td | 6 ++++++ llvm/lib/Target/X86/X86Subtarget.cpp | 1 + llvm/lib/Target/X86/X86Subtarget.h | 4 ++++ llvm/test/CodeGen/X86/wbnoinvd-intrinsic.ll | 18 ++++++++++++++++++ llvm/test/MC/Disassembler/X86/x86-16.txt | 3 +++ llvm/test/MC/Disassembler/X86/x86-32.txt | 3 +++ llvm/test/MC/Disassembler/X86/x86-64.txt | 3 +++ llvm/test/MC/X86/x86-16.s | 4 ++++ llvm/test/MC/X86/x86-32-coverage.s | 4 ++++ llvm/test/MC/X86/x86-64.s | 4 ++++ 14 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/X86/wbnoinvd-intrinsic.ll diff --git a/llvm/include/llvm/IR/IntrinsicsX86.td b/llvm/include/llvm/IR/IntrinsicsX86.td index a0ece92..53285b1 100644 --- a/llvm/include/llvm/IR/IntrinsicsX86.td +++ b/llvm/include/llvm/IR/IntrinsicsX86.td @@ -6401,3 +6401,12 @@ let TargetPrefix = "x86" in { 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<[], [], []>; +} diff --git a/llvm/lib/Support/Host.cpp b/llvm/lib/Support/Host.cpp index 656e257..304a9e3 100644 --- a/llvm/lib/Support/Host.cpp +++ b/llvm/lib/Support/Host.cpp @@ -1213,9 +1213,12 @@ bool sys::getHostCPUFeatures(StringMap &Features) { 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); diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index 0d0ec76..292a504 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -249,6 +249,8 @@ def FeatureCLFLUSHOPT : SubtargetFeature<"clflushopt", "HasCLFLUSHOPT", "true", "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 @@ def : IcelakeClientProc<"icelake-client">; class IcelakeServerProc : ProcModel; def : IcelakeServerProc<"icelake-server">; diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 56566ea..04b67dc 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -888,6 +888,7 @@ def HasSHSTK : Predicate<"Subtarget->hasSHSTK()">; 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()">, diff --git a/llvm/lib/Target/X86/X86InstrSystem.td b/llvm/lib/Target/X86/X86InstrSystem.td index e2a9a15..5834041 100644 --- a/llvm/lib/Target/X86/X86InstrSystem.td +++ b/llvm/lib/Target/X86/X86InstrSystem.td @@ -482,6 +482,12 @@ let Defs = [EAX, EBX, ECX, EDX], Uses = [EAX, ECX] in 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 //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index c6ebaef..1eec351 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -324,6 +324,7 @@ void X86Subtarget::initializeEnvironment() { HasSGX = false; HasCLFLUSHOPT = false; HasCLWB = false; + HasWBNOINVD = false; HasRDPID = false; UseRetpoline = false; UseRetpolineExternalThunk = false; diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index ba4f341..72af939 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -360,6 +360,9 @@ protected: /// 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 @@ public: 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; } diff --git a/llvm/test/CodeGen/X86/wbnoinvd-intrinsic.ll b/llvm/test/CodeGen/X86/wbnoinvd-intrinsic.ll new file mode 100644 index 0000000..a8c17f4 --- /dev/null +++ b/llvm/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 diff --git a/llvm/test/MC/Disassembler/X86/x86-16.txt b/llvm/test/MC/Disassembler/X86/x86-16.txt index 4c12cc0..60341ad 100644 --- a/llvm/test/MC/Disassembler/X86/x86-16.txt +++ b/llvm/test/MC/Disassembler/X86/x86-16.txt @@ -791,3 +791,6 @@ # CHECK: callw -1 0xe8 0xff 0xff + +# CHECK: wbnoinvd +0xf3 0x0f 0x09 diff --git a/llvm/test/MC/Disassembler/X86/x86-32.txt b/llvm/test/MC/Disassembler/X86/x86-32.txt index cc05dfb..6fedf21 100644 --- a/llvm/test/MC/Disassembler/X86/x86-32.txt +++ b/llvm/test/MC/Disassembler/X86/x86-32.txt @@ -820,3 +820,6 @@ # CHECK: ptwritel %eax 0xf3 0x0f 0xae 0xe0 + +# CHECK: wbnoinvd +0xf3 0x0f 0x09 diff --git a/llvm/test/MC/Disassembler/X86/x86-64.txt b/llvm/test/MC/Disassembler/X86/x86-64.txt index a4f0db4..882b2f6 100644 --- a/llvm/test/MC/Disassembler/X86/x86-64.txt +++ b/llvm/test/MC/Disassembler/X86/x86-64.txt @@ -516,3 +516,6 @@ # CHECK: ptwriteq %rax 0xf3 0x48 0x0f 0xae 0xe0 + +# CHECK: wbnoinvd +0xf3 0x0f 0x09 diff --git a/llvm/test/MC/X86/x86-16.s b/llvm/test/MC/X86/x86-16.s index d006290..b890be3 100644 --- a/llvm/test/MC/X86/x86-16.s +++ b/llvm/test/MC/X86/x86-16.s @@ -969,3 +969,7 @@ data32 // CHECK: lgdtw 4(%eax) // CHECK: encoding: [0x67,0x0f,0x01,0x50,0x04] data32 lgdt 4(%eax) + +// CHECK: wbnoinvd +// CHECK: encoding: [0xf3,0x0f,0x09] +wbnoinvd diff --git a/llvm/test/MC/X86/x86-32-coverage.s b/llvm/test/MC/X86/x86-32-coverage.s index 9e49a43..f2ab0f4 100644 --- a/llvm/test/MC/X86/x86-32-coverage.s +++ b/llvm/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 diff --git a/llvm/test/MC/X86/x86-64.s b/llvm/test/MC/X86/x86-64.s index 2e2379d..9e8694141 100644 --- a/llvm/test/MC/X86/x86-64.s +++ b/llvm/test/MC/X86/x86-64.s @@ -1559,6 +1559,10 @@ ptwriteq 0xdeadbeef(%rbx,%rcx,8) // 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" -- 2.7.4