[X86] Add TSXLDTRK instructions.
Summary: For more details about these instructions, please refer to the latest ISE document: https://software.intel.com/en-us/download/intel-architecture-instruction-set-extensions-programming-reference
Reviewers: craig.topper, RKSimon, LuoYuanke
Reviewed By: craig.topper
Subscribers: mgorny, hiraditya, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D77205
diff --git a/llvm/include/llvm/IR/IntrinsicsX86.td b/llvm/include/llvm/IR/IntrinsicsX86.td
index 8623be7..4a85b03 100644
--- a/llvm/include/llvm/IR/IntrinsicsX86.td
+++ b/llvm/include/llvm/IR/IntrinsicsX86.td
@@ -4938,3 +4938,13 @@
def int_x86_serialize : GCCBuiltin<"__builtin_ia32_serialize">,
Intrinsic<[], [], []>;
}
+
+//===----------------------------------------------------------------------===//
+// TSXLDTRK - TSX Suspend Load Address Tracking
+
+let TargetPrefix = "x86" in {
+ def int_x86_xsusldtrk : GCCBuiltin<"__builtin_ia32_xsusldtrk">,
+ Intrinsic<[], [], []>;
+ def int_x86_xresldtrk : GCCBuiltin<"__builtin_ia32_xresldtrk">,
+ Intrinsic<[], [], []>;
+}
diff --git a/llvm/lib/Support/Host.cpp b/llvm/lib/Support/Host.cpp
index 6b8f7ca..f236456 100644
--- a/llvm/lib/Support/Host.cpp
+++ b/llvm/lib/Support/Host.cpp
@@ -1478,6 +1478,7 @@
Features["enqcmd"] = HasLeaf7 && ((ECX >> 29) & 1);
Features["serialize"] = HasLeaf7 && ((EDX >> 14) & 1);
+ Features["tsxldtrk"] = HasLeaf7 && ((EDX >> 16) & 1);
// There are two CPUID leafs which information associated with the pconfig
// instruction:
// EAX=0x7, ECX=0x0 indicates the availability of the instruction (via the 18th
diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td
index 13ccf3c..49dbfde 100644
--- a/llvm/lib/Target/X86/X86.td
+++ b/llvm/lib/Target/X86/X86.td
@@ -275,6 +275,8 @@
"Has ENQCMD instructions">;
def FeatureSERIALIZE : SubtargetFeature<"serialize", "HasSERIALIZE", "true",
"Has serialize instruction">;
+def FeatureTSXLDTRK : SubtargetFeature<"tsxldtrk", "HasTSXLDTRK", "true",
+ "Support TSXLDTRK instructions">;
// On some processors, instructions that implicitly take two memory operands are
// slow. In practice, this means that CALL, PUSH, and POP with memory operands
// should be avoided in favor of a MOV + register CALL/PUSH/POP.
diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td
index 4e2bc02..6daa6ef 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.td
+++ b/llvm/lib/Target/X86/X86InstrInfo.td
@@ -956,6 +956,7 @@
def HasPCONFIG : Predicate<"Subtarget->hasPCONFIG()">;
def HasENQCMD : Predicate<"Subtarget->hasENQCMD()">;
def HasSERIALIZE : Predicate<"Subtarget->hasSERIALIZE()">;
+def HasTSXLDTRK : Predicate<"Subtarget->hasTSXLDTRK()">;
def Not64BitMode : Predicate<"!Subtarget->is64Bit()">,
AssemblerPredicate<(all_of (not Mode64Bit)), "Not 64-bit mode">;
def In64BitMode : Predicate<"Subtarget->is64Bit()">,
@@ -2870,6 +2871,16 @@
Requires<[HasSERIALIZE]>;
//===----------------------------------------------------------------------===//
+// TSXLDTRK - TSX Suspend Load Address Tracking
+//
+let Predicates = [HasTSXLDTRK] in {
+ def XSUSLDTRK : I<0x01, MRM_E8, (outs), (ins), "xsusldtrk",
+ [(int_x86_xsusldtrk)]>, XD;
+ def XRESLDTRK : I<0x01, MRM_E9, (outs), (ins), "xresldtrk",
+ [(int_x86_xresldtrk)]>, XD;
+}
+
+//===----------------------------------------------------------------------===//
// Pattern fragments to auto generate TBM instructions.
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h
index a23588a..658401c 100644
--- a/llvm/lib/Target/X86/X86Subtarget.h
+++ b/llvm/lib/Target/X86/X86Subtarget.h
@@ -400,6 +400,9 @@
/// Processor supports SERIALIZE instruction
bool HasSERIALIZE = false;
+ /// Processor supports TSXLDTRK instruction
+ bool HasTSXLDTRK = false;
+
/// Processor has a single uop BEXTR implementation.
bool HasFastBEXTR = false;
@@ -716,6 +719,7 @@
bool hasINVPCID() const { return HasINVPCID; }
bool hasENQCMD() const { return HasENQCMD; }
bool hasSERIALIZE() const { return HasSERIALIZE; }
+ bool hasTSXLDTRK() const { return HasTSXLDTRK; }
bool useRetpolineIndirectCalls() const { return UseRetpolineIndirectCalls; }
bool useRetpolineIndirectBranches() const {
return UseRetpolineIndirectBranches;
diff --git a/llvm/test/CodeGen/X86/tsxldtrk-intrinsic.ll b/llvm/test/CodeGen/X86/tsxldtrk-intrinsic.ll
new file mode 100644
index 0000000..5b780e1
--- /dev/null
+++ b/llvm/test/CodeGen/X86/tsxldtrk-intrinsic.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+tsxldtrk | FileCheck %s --check-prefix=X64
+; RUN: llc < %s -mtriple=i386-unknown-unknown -mattr=+tsxldtrk | FileCheck %s --check-prefix=X86
+; RUN: llc < %s -mtriple=x86_64-linux-gnux32 -mattr=+tsxldtrk | FileCheck %s --check-prefix=X32
+
+define void @test_tsxldtrk() {
+; X64-LABEL: test_tsxldtrk:
+; X64: # %bb.0: # %entry
+; X64-NEXT: xsusldtrk
+; X64-NEXT: xresldtrk
+; X64-NEXT: retq
+;
+; X86-LABEL: test_tsxldtrk:
+; X86: # %bb.0: # %entry
+; X86-NEXT: xsusldtrk
+; X86-NEXT: xresldtrk
+; X86-NEXT: retl
+;
+; X32-LABEL: test_tsxldtrk:
+; X32: # %bb.0: # %entry
+; X32-NEXT: xsusldtrk
+; X32-NEXT: xresldtrk
+; X32-NEXT: retq
+entry:
+ call void @llvm.x86.xsusldtrk()
+ call void @llvm.x86.xresldtrk()
+ ret void
+}
+
+declare void @llvm.x86.xsusldtrk()
+declare void @llvm.x86.xresldtrk()
+
diff --git a/llvm/test/MC/Disassembler/X86/x86-16.txt b/llvm/test/MC/Disassembler/X86/x86-16.txt
index 95948e3..824daef 100644
--- a/llvm/test/MC/Disassembler/X86/x86-16.txt
+++ b/llvm/test/MC/Disassembler/X86/x86-16.txt
@@ -839,3 +839,9 @@
# CHECK: serialize
0x0f 0x01 0xe8
+
+# CHECK: xsusldtrk
+0xf2 0x0f 0x01 0xe8
+
+# CHECK: xresldtrk
+0xf2 0x0f 0x01 0xe9
diff --git a/llvm/test/MC/Disassembler/X86/x86-32.txt b/llvm/test/MC/Disassembler/X86/x86-32.txt
index 9e04cc2..5fba2a8 100644
--- a/llvm/test/MC/Disassembler/X86/x86-32.txt
+++ b/llvm/test/MC/Disassembler/X86/x86-32.txt
@@ -946,3 +946,9 @@
# CHECK: serialize
0x0f 0x01 0xe8
+
+# CHECK: xsusldtrk
+0xf2 0x0f 0x01 0xe8
+
+# CHECK: xresldtrk
+0xf2 0x0f 0x01 0xe9
diff --git a/llvm/test/MC/Disassembler/X86/x86-64.txt b/llvm/test/MC/Disassembler/X86/x86-64.txt
index 8ef1363..2237484 100644
--- a/llvm/test/MC/Disassembler/X86/x86-64.txt
+++ b/llvm/test/MC/Disassembler/X86/x86-64.txt
@@ -694,3 +694,9 @@
# CHECK: serialize
0x0f 0x01 0xe8
+
+# CHECK: xsusldtrk
+0xf2 0x0f 0x01 0xe8
+
+# CHECK: xresldtrk
+0xf2 0x0f 0x01 0xe9
diff --git a/llvm/test/MC/X86/x86-16.s b/llvm/test/MC/X86/x86-16.s
index 531a530..955f1e2 100644
--- a/llvm/test/MC/X86/x86-16.s
+++ b/llvm/test/MC/X86/x86-16.s
@@ -1033,3 +1033,11 @@
// CHECK: serialize
// CHECK: encoding: [0x0f,0x01,0xe8]
serialize
+
+// CHECK: xsusldtrk
+// CHECK: encoding: [0xf2,0x0f,0x01,0xe8]
+xsusldtrk
+
+// CHECK: xresldtrk
+// CHECK: encoding: [0xf2,0x0f,0x01,0xe9]
+xresldtrk
diff --git a/llvm/test/MC/X86/x86-32-coverage.s b/llvm/test/MC/X86/x86-32-coverage.s
index 0e6d0af..4e199c7 100644
--- a/llvm/test/MC/X86/x86-32-coverage.s
+++ b/llvm/test/MC/X86/x86-32-coverage.s
@@ -10880,3 +10880,11 @@
// CHECK: serialize
// CHECK: encoding: [0x0f,0x01,0xe8]
serialize
+
+// CHECK: xsusldtrk
+// CHECK: encoding: [0xf2,0x0f,0x01,0xe8]
+xsusldtrk
+
+// CHECK: xresldtrk
+// CHECK: encoding: [0xf2,0x0f,0x01,0xe9]
+xresldtrk
diff --git a/llvm/test/MC/X86/x86-64.s b/llvm/test/MC/X86/x86-64.s
index 8339e67..a1c7e43 100644
--- a/llvm/test/MC/X86/x86-64.s
+++ b/llvm/test/MC/X86/x86-64.s
@@ -1881,3 +1881,11 @@
// CHECK: serialize
// CHECK: encoding: [0x0f,0x01,0xe8]
serialize
+
+// CHECK: xsusldtrk
+// CHECK: encoding: [0xf2,0x0f,0x01,0xe8]
+xsusldtrk
+
+// CHECK: xresldtrk
+// CHECK: encoding: [0xf2,0x0f,0x01,0xe9]
+xresldtrk