summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGabor Buella <gabor.buella@intel.com>2018-05-25 06:32:05 +0000
committerGabor Buella <gabor.buella@intel.com>2018-05-25 06:32:05 +0000
commitd2f1ab1b1001d0ddf9ab227e1666ec9477e47eb9 (patch)
tree5868d9c0d1c932a357627d340020f44db58d5c40
parent79fffe351561eaa837a81abe5a55284ae9b4472f (diff)
downloadbcm5719-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.td8
-rw-r--r--llvm/lib/Support/Host.cpp1
-rw-r--r--llvm/lib/Target/X86/X86.td3
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.td1
-rw-r--r--llvm/lib/Target/X86/X86InstrSystem.td20
-rw-r--r--llvm/lib/Target/X86/X86Subtarget.cpp1
-rw-r--r--llvm/lib/Target/X86/X86Subtarget.h4
-rw-r--r--llvm/test/CodeGen/X86/invpcid-intrinsic.ll43
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*)
OpenPOWER on IntegriCloud