Skip to content

Commit

Permalink
[X86] Describe wbnoinvd instruction
Browse files Browse the repository at this point in the history
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
  • Loading branch information
GBuella committed Apr 11, 2018
1 parent d11b6ed commit 2ef36f3
Show file tree
Hide file tree
Showing 14 changed files with 67 additions and 1 deletion.
9 changes: 9 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsX86.td
Expand Up @@ -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<[], [], []>;
}
5 changes: 4 additions & 1 deletion llvm/lib/Support/Host.cpp
Expand Up @@ -1213,9 +1213,12 @@ bool sys::getHostCPUFeatures(StringMap<bool> &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);
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/X86/X86.td
Expand Up @@ -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
Expand Down Expand Up @@ -825,6 +827,7 @@ def : IcelakeClientProc<"icelake-client">;
class IcelakeServerProc<string Name> : ProcModel<Name, SkylakeServerModel,
ICLFeatures.Value, [
ProcIntelICX,
FeatureWBNOINVD,
FeatureHasFastGather
]>;
def : IcelakeServerProc<"icelake-server">;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/X86/X86InstrInfo.td
Expand Up @@ -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()">,
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/X86/X86InstrSystem.td
Expand Up @@ -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

//===----------------------------------------------------------------------===//
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/X86/X86Subtarget.cpp
Expand Up @@ -324,6 +324,7 @@ void X86Subtarget::initializeEnvironment() {
HasSGX = false;
HasCLFLUSHOPT = false;
HasCLWB = false;
HasWBNOINVD = false;
HasRDPID = false;
UseRetpoline = false;
UseRetpolineExternalThunk = false;
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/X86/X86Subtarget.h
Expand Up @@ -360,6 +360,9 @@ class X86Subtarget final : public X86GenSubtargetInfo {
/// Processor supports Cache Line Write Back instruction
bool HasCLWB;

/// Processor supports Write Back No Invalidate instruction
bool HasWBNOINVD;

/// Processor support RDPID instruction
bool HasRDPID;

Expand Down Expand Up @@ -621,6 +624,7 @@ class X86Subtarget final : public X86GenSubtargetInfo {
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; }
Expand Down
18 changes: 18 additions & 0 deletions 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
3 changes: 3 additions & 0 deletions llvm/test/MC/Disassembler/X86/x86-16.txt
Expand Up @@ -791,3 +791,6 @@

# CHECK: callw -1
0xe8 0xff 0xff

# CHECK: wbnoinvd
0xf3 0x0f 0x09
3 changes: 3 additions & 0 deletions llvm/test/MC/Disassembler/X86/x86-32.txt
Expand Up @@ -820,3 +820,6 @@

# CHECK: ptwritel %eax
0xf3 0x0f 0xae 0xe0

# CHECK: wbnoinvd
0xf3 0x0f 0x09
3 changes: 3 additions & 0 deletions llvm/test/MC/Disassembler/X86/x86-64.txt
Expand Up @@ -516,3 +516,6 @@

# CHECK: ptwriteq %rax
0xf3 0x48 0x0f 0xae 0xe0

# CHECK: wbnoinvd
0xf3 0x0f 0x09
4 changes: 4 additions & 0 deletions llvm/test/MC/X86/x86-16.s
Expand Up @@ -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
4 changes: 4 additions & 0 deletions llvm/test/MC/X86/x86-32-coverage.s
Expand Up @@ -2788,6 +2788,10 @@
// CHECK: encoding: [0x0f,0x09]
wbinvd

// CHECK: wbnoinvd
// CHECK: encoding: [0xf3,0x0f,0x09]
wbnoinvd

// CHECK: cpuid
// CHECK: encoding: [0x0f,0xa2]
cpuid
Expand Down
4 changes: 4 additions & 0 deletions llvm/test/MC/X86/x86-64.s
Expand Up @@ -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"
Expand Down

0 comments on commit 2ef36f3

Please sign in to comment.