Index: llvm/trunk/include/llvm/IR/IntrinsicsX86.td =================================================================== --- llvm/trunk/include/llvm/IR/IntrinsicsX86.td +++ llvm/trunk/include/llvm/IR/IntrinsicsX86.td @@ -6425,3 +6425,13 @@ def int_x86_movdir64b : GCCBuiltin<"__builtin_ia32_movdir64b">, Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], []>; } + +//===----------------------------------------------------------------------===// +// PTWrite - Write data to processor trace pocket + +let TargetPrefix = "x86" in { + def int_x86_ptwrite32 : GCCBuiltin<"__builtin_ia32_ptwrite32">, + Intrinsic<[], [llvm_i32_ty], []>; + def int_x86_ptwrite64 : GCCBuiltin<"__builtin_ia32_ptwrite64">, + Intrinsic<[], [llvm_i64_ty], []>; +} Index: llvm/trunk/lib/Support/Host.cpp =================================================================== --- llvm/trunk/lib/Support/Host.cpp +++ llvm/trunk/lib/Support/Host.cpp @@ -1286,6 +1286,11 @@ Features["xsavec"] = HasLeafD && ((EAX >> 1) & 1) && HasAVXSave; Features["xsaves"] = HasLeafD && ((EAX >> 3) & 1) && HasAVXSave; + bool HasLeaf14 = MaxLevel >= 0x14 && + !getX86CpuIDAndInfoEx(0x14, 0x0, &EAX, &EBX, &ECX, &EDX); + + Features["ptwrite"] = HasLeaf14 && ((EBX >> 4) & 1); + return true; } #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__)) Index: llvm/trunk/lib/Target/X86/X86.td =================================================================== --- llvm/trunk/lib/Target/X86/X86.td +++ llvm/trunk/lib/Target/X86/X86.td @@ -232,6 +232,8 @@ "Enable Cache Line Zero">; def FeatureCLDEMOTE : SubtargetFeature<"cldemote", "HasCLDEMOTE", "true", "Enable Cache Demote">; +def FeaturePTWRITE : SubtargetFeature<"ptwrite", "HasPTWRITE", "true", + "Support ptwrite instruction">; def FeatureMPX : SubtargetFeature<"mpx", "HasMPX", "true", "Support MPX instructions">; def FeatureLEAForSP : SubtargetFeature<"lea-sp", "UseLeaForSP", "true", @@ -624,23 +626,25 @@ ]>; def : GoldmontProc<"goldmont">; -class GoldmontPlusProc : ProcModel; + +class GoldmontPlusProc : ProcModel; def : GoldmontPlusProc<"goldmont-plus">; class TremontProc : ProcModel; def : TremontProc<"tremont">; Index: llvm/trunk/lib/Target/X86/X86InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td @@ -894,6 +894,7 @@ def HasCLDEMOTE : Predicate<"Subtarget->hasCLDEMOTE()">; def HasMOVDIRI : Predicate<"Subtarget->hasMOVDIRI()">; def HasMOVDIR64B : Predicate<"Subtarget->hasMOVDIR64B()">; +def HasPTWRITE : Predicate<"Subtarget->hasPTWRITE()">; def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">; def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">; def HasMPX : Predicate<"Subtarget->hasMPX()">; Index: llvm/trunk/lib/Target/X86/X86InstrSystem.td =================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSystem.td +++ llvm/trunk/lib/Target/X86/X86InstrSystem.td @@ -688,18 +688,21 @@ //===----------------------------------------------------------------------===// -// PTWRITE Instruction +// PTWRITE Instruction - Write Data to a Processor Trace Packet let SchedRW = [WriteSystem] in { - def PTWRITEm: I<0xAE, MRM4m, (outs), (ins i32mem:$dst), - "ptwrite{l}\t$dst", []>, XS; + "ptwrite{l}\t$dst", [(int_x86_ptwrite32 (loadi32 addr:$dst))]>, XS, + Requires<[HasPTWRITE]>; def PTWRITE64m : RI<0xAE, MRM4m, (outs), (ins i64mem:$dst), - "ptwrite{q}\t$dst", []>, XS, Requires<[In64BitMode]>; + "ptwrite{q}\t$dst", [(int_x86_ptwrite64 (loadi64 addr:$dst))]>, XS, + Requires<[In64BitMode, HasPTWRITE]>; def PTWRITEr : I<0xAE, MRM4r, (outs), (ins GR32:$dst), - "ptwrite{l}\t$dst", []>, XS; + "ptwrite{l}\t$dst", [(int_x86_ptwrite32 GR32:$dst)]>, XS, + Requires<[HasPTWRITE]>; def PTWRITE64r : RI<0xAE, MRM4r, (outs), (ins GR64:$dst), - "ptwrite{q}\t$dst", []>, XS, Requires<[In64BitMode]>; + "ptwrite{q}\t$dst", [(int_x86_ptwrite64 GR64:$dst)]>, XS, + Requires<[In64BitMode, HasPTWRITE]>; } // SchedRW //===----------------------------------------------------------------------===// @@ -719,4 +722,4 @@ let Uses = [RAX, RBX, RCX, RDX], Defs = [RAX, RBX, RCX, RDX, EFLAGS] in def PCONFIG : I<0x01, MRM_C5, (outs), (ins), "pconfig", []>, TB, Requires<[HasPCONFIG]>; -} // SchedRW \ No newline at end of file +} // SchedRW Index: llvm/trunk/lib/Target/X86/X86Subtarget.h =================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.h +++ llvm/trunk/lib/Target/X86/X86Subtarget.h @@ -215,6 +215,9 @@ /// Processor has MOVDIR64B instruction (direct store 64 bytes). bool HasMOVDIR64B; + /// Processor has ptwrite instruction. + bool HasPTWRITE; + /// Processor has Prefetch with intent to Write instruction bool HasPREFETCHWT1; @@ -593,6 +596,7 @@ bool hasCLDEMOTE() const { return HasCLDEMOTE; } bool hasMOVDIRI() const { return HasMOVDIRI; } bool hasMOVDIR64B() const { return HasMOVDIR64B; } + bool hasPTWRITE() const { return HasPTWRITE; } bool isSHLDSlow() const { return IsSHLDSlow; } bool isPMULLDSlow() const { return IsPMULLDSlow; } bool isUnalignedMem16Slow() const { return IsUAMem16Slow; } Index: llvm/trunk/test/CodeGen/X86/ptwrite32-intrinsic.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/ptwrite32-intrinsic.ll +++ llvm/trunk/test/CodeGen/X86/ptwrite32-intrinsic.ll @@ -0,0 +1,56 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=i386-unknown-unknown -mattr=+ptwrite | FileCheck %s --check-prefix=X86 +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+ptwrite | FileCheck %s --check-prefix=X86_64 + +define void @test_ptwrite(i32 %value) { +; X86-LABEL: test_ptwrite: +; X86: # %bb.0: # %entry +; X86-NEXT: ptwritel {{[0-9]+}}(%esp) +; X86-NEXT: retl +; +; X86_64-LABEL: test_ptwrite: +; X86_64: # %bb.0: # %entry +; X86_64-NEXT: ptwritel %edi +; X86_64-NEXT: retq +entry: + call void @llvm.x86.ptwrite32(i32 %value) + ret void +} + +define void @test_ptwrite2(i32 %x) { +; X86-LABEL: test_ptwrite2: +; X86: # %bb.0: # %entry +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: incl %eax +; X86-NEXT: ptwritel %eax +; X86-NEXT: retl +; +; X86_64-LABEL: test_ptwrite2: +; X86_64: # %bb.0: # %entry +; X86_64-NEXT: incl %edi +; X86_64-NEXT: ptwritel %edi +; X86_64-NEXT: retq +entry: + %value = add i32 %x, 1 + call void @llvm.x86.ptwrite32(i32 %value) + ret void +} + +define void @test_ptwrite32p(i32* %pointer) { +; X86-LABEL: test_ptwrite32p: +; X86: # %bb.0: # %entry +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: ptwritel (%eax) +; X86-NEXT: retl +; +; X86_64-LABEL: test_ptwrite32p: +; X86_64: # %bb.0: # %entry +; X86_64-NEXT: ptwritel (%rdi) +; X86_64-NEXT: retq +entry: + %value = load i32, i32* %pointer, align 4 + call void @llvm.x86.ptwrite32(i32 %value) + ret void +} + +declare void @llvm.x86.ptwrite32(i32) Index: llvm/trunk/test/CodeGen/X86/ptwrite64-intrinsic.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/ptwrite64-intrinsic.ll +++ llvm/trunk/test/CodeGen/X86/ptwrite64-intrinsic.ll @@ -0,0 +1,25 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+ptwrite | FileCheck %s + +define void @test_ptwrite64(i64 %value) { +; CHECK-LABEL: test_ptwrite64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ptwriteq %rdi +; CHECK-NEXT: retq +entry: + call void @llvm.x86.ptwrite64(i64 %value) + ret void +} + +define void @test_ptwrite64p(i64* %pointer) { +; CHECK-LABEL: test_ptwrite64p: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ptwriteq (%rdi) +; CHECK-NEXT: retq +entry: + %value = load i64, i64* %pointer, align 8 + call void @llvm.x86.ptwrite64(i64 %value) + ret void +} + +declare void @llvm.x86.ptwrite64(i64)