[X86][PKU] Add {RD,WR}PKRU intrinsics
authorAsaf Badouh <asaf.badouh@intel.com>
Thu, 31 Dec 2015 08:31:13 +0000 (08:31 +0000)
committerAsaf Badouh <asaf.badouh@intel.com>
Thu, 31 Dec 2015 08:31:13 +0000 (08:31 +0000)
Differential Revision: http://reviews.llvm.org/D15808

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256670 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/IntrinsicsX86.td
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86InstrSystem.td
test/CodeGen/X86/pku.ll [new file with mode: 0644]

index 18390f85351057e8c598c055f4d811cb0c1d7a03..2b092cbec9611181ec39ae60ccf45da6835335f9 100644 (file)
@@ -3919,9 +3919,9 @@ let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
 // Support protection key
 let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
   def int_x86_rdpkru : GCCBuiltin <"__builtin_ia32_rdpkru">,
-              Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>;
+              Intrinsic<[llvm_i32_ty], [], []>;
   def int_x86_wrpkru : GCCBuiltin<"__builtin_ia32_wrpkru">,
-              Intrinsic<[], [llvm_i32_ty], [IntrNoMem]>;
+              Intrinsic<[], [llvm_i32_ty], []>;
 }
 //===----------------------------------------------------------------------===//
 // Half float conversion
index 0927c2f4fa50540bc0c3278e5db54f4f4dc0a0d4..050ad177f2f38605129a325b436ff602b5ca0161 100644 (file)
@@ -21144,6 +21144,47 @@ static MachineBasicBlock *EmitPCMPSTRI(MachineInstr *MI, MachineBasicBlock *BB,
   return BB;
 }
 
+static MachineBasicBlock *EmitWRPKRU(MachineInstr *MI, MachineBasicBlock *BB,
+                                     const X86Subtarget *Subtarget) {
+  DebugLoc dl = MI->getDebugLoc();
+  const TargetInstrInfo *TII = Subtarget->getInstrInfo();
+
+  // insert input VAL into EAX
+  BuildMI(*BB, MI, dl, TII->get(TargetOpcode::COPY), X86::EAX)
+                           .addReg(MI->getOperand(0).getReg());
+  // insert zero to ECX
+  BuildMI(*BB, MI, dl, TII->get(X86::XOR32rr), X86::ECX)
+                           .addReg(X86::ECX)
+                           .addReg(X86::ECX);
+  // insert zero to EDX
+  BuildMI(*BB, MI, dl, TII->get(X86::XOR32rr), X86::EDX)
+                           .addReg(X86::EDX)
+                           .addReg(X86::EDX);
+  // insert WRPKRU instruction
+  BuildMI(*BB, MI, dl, TII->get(X86::WRPKRUr));
+
+  MI->eraseFromParent(); // The pseudo is gone now.
+  return BB;
+}
+
+static MachineBasicBlock *EmitRDPKRU(MachineInstr *MI, MachineBasicBlock *BB,
+                                     const X86Subtarget *Subtarget) {
+  DebugLoc dl = MI->getDebugLoc();
+  const TargetInstrInfo *TII = Subtarget->getInstrInfo();
+
+  // insert zero to ECX
+  BuildMI(*BB, MI, dl, TII->get(X86::XOR32rr), X86::ECX)
+                           .addReg(X86::ECX)
+                           .addReg(X86::ECX);
+  // insert RDPKRU instruction
+  BuildMI(*BB, MI, dl, TII->get(X86::RDPKRUr));
+  BuildMI(*BB, MI, dl, TII->get(TargetOpcode::COPY), MI->getOperand(0).getReg())
+                           .addReg(X86::EAX);
+
+  MI->eraseFromParent(); // The pseudo is gone now.
+  return BB;
+}
+
 static MachineBasicBlock *EmitMonitor(MachineInstr *MI, MachineBasicBlock *BB,
                                       const X86Subtarget *Subtarget) {
   DebugLoc dl = MI->getDebugLoc();
@@ -22611,7 +22652,11 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
   // Thread synchronization.
   case X86::MONITOR:
     return EmitMonitor(MI, BB, Subtarget);
-
+  // PKU feature
+  case X86::WRPKRU:
+    return EmitWRPKRU(MI, BB, Subtarget);
+  case X86::RDPKRU:
+    return EmitRDPKRU(MI, BB, Subtarget);
   // xbegin
   case X86::XBEGIN:
     return EmitXBegin(MI, BB, Subtarget->getInstrInfo());
index 85e17f516f913960c9c1e1a2e44df894daf20a3f..b842b84e9083b970f6b7536d450fbf20298ec283 100644 (file)
@@ -551,10 +551,17 @@ let Defs = [RAX, RDX, RSI], Uses = [RAX, RSI] in
   def MONTMUL : I<0xa6, MRM_C0, (outs), (ins), "montmul", []>, TB;
 //==-----------------------------------------------------------------------===//
 // PKU  - enable protection key
+let usesCustomInserter = 1 in {
+  def WRPKRU : PseudoI<(outs), (ins GR32:$src),
+                [(int_x86_wrpkru GR32:$src)]>;
+  def RDPKRU : PseudoI<(outs GR32:$dst), (ins),
+                [(set GR32:$dst, (int_x86_rdpkru))]>;
+}
+
 let Defs = [EAX, EDX], Uses = [ECX] in 
-  def RDPKRU : I<0x01, MRM_EE, (outs), (ins), "rdpkru", []>, TB;
+  def RDPKRUr : I<0x01, MRM_EE, (outs), (ins), "rdpkru", []>, TB;
 let Uses = [EAX, ECX, EDX] in
-  def WRPKRU : I<0x01, MRM_EF, (outs), (ins), "wrpkru", []>, TB;
+  def WRPKRUr : I<0x01, MRM_EF, (outs), (ins), "wrpkru", []>, TB;
 
 //===----------------------------------------------------------------------===//
 // FS/GS Base Instructions
diff --git a/test/CodeGen/X86/pku.ll b/test/CodeGen/X86/pku.ll
new file mode 100644 (file)
index 0000000..cbb83ae
--- /dev/null
@@ -0,0 +1,25 @@
+; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=knl --show-mc-encoding| FileCheck %s\r
+declare i32 @llvm.x86.rdpkru()\r
+declare void @llvm.x86.wrpkru(i32)\r
+\r
+define void @test_x86_wrpkru(i32 %src) {\r
+; CHECK-LABEL: test_x86_wrpkru:\r
+; CHECK:       ## BB#0:\r
+; CHECK-NEXT:    xorl    %ecx, %ecx\r
+; CHECK-NEXT:    xorl    %edx, %edx\r
+; CHECK-NEXT:    movl    %edi, %eax\r
+; CHECK-NEXT:    wrpkru\r
+; CHECK-NEXT:    retq\r
+  call void @llvm.x86.wrpkru(i32 %src) \r
+  ret void\r
+}\r
+\r
+define i32 @test_x86_rdpkru() {\r
+; CHECK-LABEL: test_x86_rdpkru:\r
+; CHECK:      ## BB#0:\r
+; CHECK-NEXT: xorl    %ecx, %ecx\r
+; CHECK-NEXT: rdpkru\r
+; CHECK-NEXT: retq\r
+  %res = call i32 @llvm.x86.rdpkru() \r
+  ret i32 %res \r
+}\r