diff options
author | Gabor Buella <gabor.buella@intel.com> | 2018-05-25 06:32:05 +0000 |
---|---|---|
committer | Gabor Buella <gabor.buella@intel.com> | 2018-05-25 06:32:05 +0000 |
commit | d2f1ab1b1001d0ddf9ab227e1666ec9477e47eb9 (patch) | |
tree | 5868d9c0d1c932a357627d340020f44db58d5c40 | |
parent | 79fffe351561eaa837a81abe5a55284ae9b4472f (diff) | |
download | bcm5719-llvm-d2f1ab1b1001d0ddf9ab227e1666ec9477e47eb9.tar.gz bcm5719-llvm-d2f1ab1b1001d0ddf9ab227e1666ec9477e47eb9.zip |
[x86] invpcid LLVM intrinsic
Re-add the feature flag for invpcid, which was removed in r294561.
Add an intrinsic, which always uses a 32 bit integer as first argument,
while the instruction actually uses a 64 bit register in 64 bit mode
for the INVPCID_TYPE argument.
Reviewers: craig.topper
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D47141
llvm-svn: 333255
-rw-r--r-- | llvm/include/llvm/IR/IntrinsicsX86.td | 8 | ||||
-rw-r--r-- | llvm/lib/Support/Host.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86.td | 3 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.td | 1 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrSystem.td | 20 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86Subtarget.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86Subtarget.h | 4 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/invpcid-intrinsic.ll | 43 |
8 files changed, 78 insertions, 3 deletions
diff --git a/llvm/include/llvm/IR/IntrinsicsX86.td b/llvm/include/llvm/IR/IntrinsicsX86.td index f3357514b2f..7ec9f830876 100644 --- a/llvm/include/llvm/IR/IntrinsicsX86.td +++ b/llvm/include/llvm/IR/IntrinsicsX86.td @@ -6186,3 +6186,11 @@ let TargetPrefix = "x86" in { def int_x86_ptwrite64 : GCCBuiltin<"__builtin_ia32_ptwrite64">, Intrinsic<[], [llvm_i64_ty], []>; } + +//===----------------------------------------------------------------------===// +// INVPCID - Invalidate Process-Context Identifier + +let TargetPrefix = "x86" in { + def int_x86_invpcid : GCCBuiltin<"__builtin_ia32_invpcid">, + Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty], []>; +} diff --git a/llvm/lib/Support/Host.cpp b/llvm/lib/Support/Host.cpp index 775db63d7de..2c718dd3f5a 100644 --- a/llvm/lib/Support/Host.cpp +++ b/llvm/lib/Support/Host.cpp @@ -1231,6 +1231,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) { // AVX2 is only supported if we have the OS save support from AVX. Features["avx2"] = HasLeaf7 && ((EBX >> 5) & 1) && HasAVXSave; Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1); + Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1); Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1); // AVX512 is only supported if the OS supports the context save for it. Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save; diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index b5d115d29a4..d92fd677829 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -245,6 +245,8 @@ def FeatureSlowDivide64 : SubtargetFeature<"idivq-to-divl", def FeaturePadShortFunctions : SubtargetFeature<"pad-short-functions", "PadShortFunctions", "true", "Pad short functions">; +def FeatureINVPCID : SubtargetFeature<"invpcid", "HasINVPCID", "true", + "Invalidate Process-Context Identifier">; def FeatureSGX : SubtargetFeature<"sgx", "HasSGX", "true", "Enable Software Guard Extensions">; def FeatureCLFLUSHOPT : SubtargetFeature<"clflushopt", "HasCLFLUSHOPT", "true", @@ -730,6 +732,7 @@ def HSWFeatures : ProcessorFeatures<IVBFeatures.Value, [ FeatureBMI2, FeatureERMSB, FeatureFMA, + FeatureINVPCID, FeatureLZCNT, FeatureMOVBE, FeatureFastVariableShuffle diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 0190baa696d..d2d2e50283f 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -904,6 +904,7 @@ def HasCLWB : Predicate<"Subtarget->hasCLWB()">; def HasWBNOINVD : Predicate<"Subtarget->hasWBNOINVD()">; def HasRDPID : Predicate<"Subtarget->hasRDPID()">; def HasWAITPKG : Predicate<"Subtarget->hasWAITPKG()">; +def HasINVPCID : Predicate<"Subtarget->hasINVPCID()">; def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">; def HasPCONFIG : Predicate<"Subtarget->hasPCONFIG()">; def Not64BitMode : Predicate<"!Subtarget->is64Bit()">, diff --git a/llvm/lib/Target/X86/X86InstrSystem.td b/llvm/lib/Target/X86/X86InstrSystem.td index 19f15478a78..2772ea66814 100644 --- a/llvm/lib/Target/X86/X86InstrSystem.td +++ b/llvm/lib/Target/X86/X86InstrSystem.td @@ -635,13 +635,27 @@ let Predicates = [HasFSGSBase, In64BitMode], SchedRW = [WriteSystem] in { // INVPCID Instruction let SchedRW = [WriteSystem] in { def INVPCID32 : I<0x82, MRMSrcMem, (outs), (ins GR32:$src1, i128mem:$src2), - "invpcid\t{$src2, $src1|$src1, $src2}", []>, T8PD, - Requires<[Not64BitMode]>; + "invpcid\t{$src2, $src1|$src1, $src2}", + [(int_x86_invpcid GR32:$src1, addr:$src2)]>, T8PD, + Requires<[Not64BitMode, HasINVPCID]>; def INVPCID64 : I<0x82, MRMSrcMem, (outs), (ins GR64:$src1, i128mem:$src2), "invpcid\t{$src2, $src1|$src1, $src2}", []>, T8PD, - Requires<[In64BitMode]>; + Requires<[In64BitMode, HasINVPCID]>; } // SchedRW +let Predicates = [In64BitMode, HasINVPCID] in { + // The instruction can only use a 64 bit register as the register argument + // in 64 bit mode, while the intrinsic only accepts a 32 bit argument + // corresponding to it. + // The accepted values for now are 0,1,2,3 anyways (see Intel SDM -- INVCPID + // type),/ so it doesn't hurt us that one can't supply a 64 bit value here. + def : Pat<(int_x86_invpcid GR32:$src1, addr:$src2), + (INVPCID64 + (SUBREG_TO_REG (i64 0), (MOV32rr GR32:$src1), sub_32bit), + addr:$src2)>; +} + + //===----------------------------------------------------------------------===// // SMAP Instruction let Defs = [EFLAGS], SchedRW = [WriteSystem] in { diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index 1ffe40b9e28..1417c4b6832 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -322,6 +322,7 @@ void X86Subtarget::initializeEnvironment() { HasPTWRITE = false; HasMPX = false; HasSHSTK = false; + HasINVPCID = false; HasSGX = false; HasPCONFIG = false; HasCLFLUSHOPT = false; diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index ea42e9a65f6..a9a06b0954e 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -360,6 +360,9 @@ protected: /// using Shadow Stack bool HasSHSTK; + /// Processor supports Invalidate Process-Context Identifier + bool HasINVPCID; + /// Processor has Software Guard Extensions bool HasSGX; @@ -644,6 +647,7 @@ public: bool hasWAITPKG() const { return HasWAITPKG; } bool hasPCONFIG() const { return HasPCONFIG; } bool hasSGX() const { return HasSGX; } + bool hasINVPCID() const { return HasINVPCID; } bool useRetpoline() const { return UseRetpoline; } bool useRetpolineExternalThunk() const { return UseRetpolineExternalThunk; } diff --git a/llvm/test/CodeGen/X86/invpcid-intrinsic.ll b/llvm/test/CodeGen/X86/invpcid-intrinsic.ll new file mode 100644 index 00000000000..bd0ff038bf7 --- /dev/null +++ b/llvm/test/CodeGen/X86/invpcid-intrinsic.ll @@ -0,0 +1,43 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=i386-unknown-unknown -mattr=+invpcid | FileCheck %s --check-prefix=X86 +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+invpcid | FileCheck %s --check-prefix=X86_64 + +define void @test_invpcid(i32 %type, i8* %descriptor) { +; X86-LABEL: test_invpcid: +; X86: # %bb.0: # %entry +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: invpcid (%eax), %ecx +; X86-NEXT: retl +; +; X86_64-LABEL: test_invpcid: +; X86_64: # %bb.0: # %entry +; X86_64-NEXT: movl %edi, %eax +; X86_64-NEXT: invpcid (%rsi), %rax +; X86_64-NEXT: retq +entry: + call void @llvm.x86.invpcid(i32 %type, i8* %descriptor) + ret void +} + +define void @test_invpcid2(i32* readonly %type, i8* %descriptor) { +; X86-LABEL: test_invpcid2: +; X86: # %bb.0: # %entry +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl (%ecx), %ecx +; X86-NEXT: invpcid (%eax), %ecx +; X86-NEXT: retl +; +; X86_64-LABEL: test_invpcid2: +; X86_64: # %bb.0: # %entry +; X86_64-NEXT: movl (%rdi), %eax +; X86_64-NEXT: invpcid (%rsi), %rax +; X86_64-NEXT: retq +entry: + %0 = load i32, i32* %type, align 4 + tail call void @llvm.x86.invpcid(i32 %0, i8* %descriptor) #1 + ret void +} + +declare void @llvm.x86.invpcid(i32, i8*) |