[llvm] r269911 - Add new flag and intrinsic support for MWAITX and MONITORX instructions

Aaron Ballman via llvm-commits llvm-commits at lists.llvm.org
Wed May 18 05:56:16 PDT 2016


On Wed, May 18, 2016 at 8:46 AM, Aaron Ballman <aaron at aaronballman.com> wrote:
> On Wed, May 18, 2016 at 7:59 AM, Ashutosh Nema via llvm-commits
> <llvm-commits at lists.llvm.org> wrote:
>> Author: ashutosh
>> Date: Wed May 18 06:59:12 2016
>> New Revision: 269911
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=269911&view=rev
>> Log:
>> Add new flag and intrinsic support for MWAITX and MONITORX instructions
>>
>> Summary:
>>
>> MONITORX/MWAITX instructions provide similar capability to the MONITOR/MWAIT
>> pair while adding a timer function, such that another termination of the MWAITX
>> instruction occurs when the timer expires. The presence of the MONITORX and
>> MWAITX instructions is indicated by CPUID 8000_0001, ECX, bit 29.
>>
>> The MONITORX and MWAITX instructions are intercepted by the same bits that
>> intercept MONITOR and MWAIT. MONITORX instruction establishes a range to be
>> monitored. MWAITX instruction causes the processor to stop instruction execution
>> and enter an implementation-dependent optimized state until occurrence of a
>> class of events.
>>
>> Opcode of MONITORX instruction is "0F 01 FA". Opcode of MWAITX instruction is
>> "0F 01 FB". These opcode information is used in adding tests for the
>> disassembler.
>>
>> These instructions are enabled for AMD's bdver4 architecture.
>>
>> Patch by Ganesh Gopalasubramanian!
>>
>> Reviewers: echristo, craig.topper, RKSimon
>> Subscribers: RKSimon, joker.eph, llvm-commits
>> Differential Revision: http://reviews.llvm.org/D19795
>>
>> Added:
>>     llvm/trunk/test/CodeGen/X86/mwaitx.ll
>> Modified:
>>     llvm/trunk/include/llvm/IR/IntrinsicsX86.td
>>     llvm/trunk/lib/Support/Host.cpp
>>     llvm/trunk/lib/Target/X86/X86.td
>>     llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>>     llvm/trunk/lib/Target/X86/X86InstrInfo.td
>>     llvm/trunk/lib/Target/X86/X86InstrSSE.td
>>     llvm/trunk/lib/Target/X86/X86Schedule.td
>>     llvm/trunk/lib/Target/X86/X86Subtarget.cpp
>>     llvm/trunk/lib/Target/X86/X86Subtarget.h
>>     llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt
>>     llvm/trunk/test/MC/Disassembler/X86/x86-32.txt
>>
>> Modified: llvm/trunk/include/llvm/IR/IntrinsicsX86.td
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IntrinsicsX86.td?rev=269911&r1=269910&r2=269911&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/IR/IntrinsicsX86.td (original)
>> +++ llvm/trunk/include/llvm/IR/IntrinsicsX86.td Wed May 18 06:59:12 2016
>> @@ -8709,3 +8709,14 @@ let TargetPrefix = "x86" in {
>>    def int_x86_sha256msg2 : GCCBuiltin<"__builtin_ia32_sha256msg2">,
>>        Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
>>  }
>> +
>> +//===----------------------------------------------------------------------===//
>> +// Thread synchronization ops with timer.
>> +let TargetPrefix = "x86" in {
>> +  def int_x86_monitorx
>> +      : GCCBuiltin<"__builtin_ia32_monitorx">,
>> +        Intrinsic<[], [ llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty ], []>;
>> +  def int_x86_mwaitx
>> +      : GCCBuiltin<"__builtin_ia32_mwaitx">,
>> +        Intrinsic<[], [ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty ], []>;
>> +}
>>
>> Modified: llvm/trunk/lib/Support/Host.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Host.cpp?rev=269911&r1=269910&r2=269911&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Support/Host.cpp (original)
>> +++ llvm/trunk/lib/Support/Host.cpp Wed May 18 06:59:12 2016
>> @@ -252,6 +252,7 @@ StringRef sys::getHostCPUName() {
>>    GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
>>    bool Em64T = (EDX >> 29) & 0x1;
>>    bool HasTBM = (ECX >> 21) & 0x1;
>> +  bool HasMWAITX = (ECX >> 29) & 0x1;
>
> This variable is not used anywhere; should it be removed?
>
>>
>>    if (memcmp(text.c, "GenuineIntel", 12) == 0) {
>>      switch (Family) {
>> @@ -803,6 +804,7 @@ bool sys::getHostCPUFeatures(StringMap<b
>>    Features["xop"]    = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
>>    Features["fma4"]   = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
>>    Features["tbm"]    = HasExtLeaf1 && ((ECX >> 21) & 1);
>> +  Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
>
> Or should it be used here instead of (ECX >> 29) & 1?

Ah, nevermind, I was missing context. I think the variable is simply
unused and can be removed.

~Aaron
>
> ~Aaron
>
>>
>>    bool HasLeaf7 = MaxLevel >= 7 &&
>>                    !GetX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
>>
>> Modified: llvm/trunk/lib/Target/X86/X86.td
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.td?rev=269911&r1=269910&r2=269911&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/X86/X86.td (original)
>> +++ llvm/trunk/lib/Target/X86/X86.td Wed May 18 06:59:12 2016
>> @@ -198,6 +198,8 @@ def FeatureRDSEED  : SubtargetFeature<"r
>>                                        "Support RDSEED instruction">;
>>  def FeatureLAHFSAHF : SubtargetFeature<"sahf", "HasLAHFSAHF", "true",
>>                                         "Support LAHF and SAHF instructions">;
>> +def FeatureMWAITX  : SubtargetFeature<"mwaitx", "HasMWAITX", "true",
>> +                                      "Enable MONITORX/MWAITX timer functionality">;
>>  def FeatureMPX     : SubtargetFeature<"mpx", "HasMPX", "true",
>>                                        "Support MPX instructions">;
>>  def FeatureLEAForSP : SubtargetFeature<"lea-sp", "UseLeaForSP", "true",
>> @@ -728,7 +730,8 @@ def : Proc<"bdver4", [
>>    FeatureFMA,
>>    FeatureXSAVEOPT,
>>    FeatureFSGSBase,
>> -  FeatureLAHFSAHF
>> +  FeatureLAHFSAHF,
>> +  FeatureMWAITX
>>  ]>;
>>
>>  def : Proc<"geode",           [FeatureX87, FeatureSlowUAMem16, Feature3DNowA]>;
>>
>> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=269911&r1=269910&r2=269911&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
>> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed May 18 06:59:12 2016
>> @@ -22349,7 +22349,8 @@ static MachineBasicBlock *emitRDPKRU(Mac
>>  }
>>
>>  static MachineBasicBlock *emitMonitor(MachineInstr *MI, MachineBasicBlock *BB,
>> -                                      const X86Subtarget &Subtarget) {
>> +                                      const X86Subtarget &Subtarget,
>> +                                      unsigned Opc) {
>>    DebugLoc dl = MI->getDebugLoc();
>>    const TargetInstrInfo *TII = Subtarget.getInstrInfo();
>>    // Address into RAX/EAX, other two args into ECX, EDX.
>> @@ -22366,7 +22367,7 @@ static MachineBasicBlock *emitMonitor(Ma
>>      .addReg(MI->getOperand(ValOps+1).getReg());
>>
>>    // The instruction doesn't actually take any operands though.
>> -  BuildMI(*BB, MI, dl, TII->get(X86::MONITORrrr));
>> +  BuildMI(*BB, MI, dl, TII->get(Opc));
>>
>>    MI->eraseFromParent(); // The pseudo is gone now.
>>    return BB;
>> @@ -23867,7 +23868,9 @@ X86TargetLowering::EmitInstrWithCustomIn
>>
>>    // Thread synchronization.
>>    case X86::MONITOR:
>> -    return emitMonitor(MI, BB, Subtarget);
>> +    return emitMonitor(MI, BB, Subtarget, X86::MONITORrrr);
>> +  case X86::MONITORX:
>> +    return emitMonitor(MI, BB, Subtarget, X86::MONITORXrrr);
>>    // PKU feature
>>    case X86::WRPKRU:
>>      return emitWRPKRU(MI, BB, Subtarget);
>>
>> Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=269911&r1=269910&r2=269911&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
>> +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Wed May 18 06:59:12 2016
>> @@ -847,6 +847,7 @@ def HasPRFCHW    : Predicate<"Subtarget-
>>  def HasRDSEED    : Predicate<"Subtarget->hasRDSEED()">;
>>  def HasPrefetchW : Predicate<"Subtarget->hasPRFCHW()">;
>>  def HasLAHFSAHF  : Predicate<"Subtarget->hasLAHFSAHF()">;
>> +def HasMWAITX    : Predicate<"Subtarget->hasMWAITX()">;
>>  def FPStackf32   : Predicate<"!Subtarget->hasSSE1()">;
>>  def FPStackf64   : Predicate<"!Subtarget->hasSSE2()">;
>>  def HasMPX       : Predicate<"Subtarget->hasMPX()">;
>> @@ -2401,22 +2402,34 @@ defm TZMSK   : tbm_binary_intr<0x01, "tz
>>  //===----------------------------------------------------------------------===//
>>  // MONITORX/MWAITX Instructions
>>  //
>> -let SchedRW = [WriteSystem] in {
>> -let Uses = [EAX, ECX, EDX] in
>> -def MONITORXrrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", [],
>> -                    IIC_SSE_MONITOR>, TB;
>> -let Uses = [ECX, EAX, EBX] in
>> -def MWAITXrr   : I<0x01, MRM_FB, (outs), (ins), "mwaitx", [], IIC_SSE_MWAIT>,
>> -                 TB;
>> +let SchedRW = [ WriteSystem ] in {
>> +  let usesCustomInserter = 1 in {
>> +    def MONITORX : PseudoI<(outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
>> +                           [(int_x86_monitorx addr:$src1, GR32:$src2, GR32:$src3)]>,
>> +                   Requires<[ HasMWAITX ]>;
>> +  }
>> +
>> +  let Uses = [ EAX, ECX, EDX ] in {
>> +    def MONITORXrrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", [], IIC_SSE_MONITORX>,
>> +                      TB, Requires<[ HasMWAITX ]>;
>> +  }
>> +
>> +  let Uses = [ ECX, EAX, EBX ] in {
>> +    def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
>> +                    [(int_x86_mwaitx ECX, EAX, EBX)], IIC_SSE_MWAITX>,
>> +                    TB, Requires<[ HasMWAITX ]>;
>> +  }
>>  } // SchedRW
>>
>> -def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrr)>, Requires<[Not64BitMode]>;
>> -def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrr)>, Requires<[In64BitMode]>;
>> +def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrrr)>,
>> +      Requires<[ Not64BitMode ]>;
>> +def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrrr)>,
>> +      Requires<[ In64BitMode ]>;
>>
>>  def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORXrrr)>,
>> -      Requires<[Not64BitMode]>;
>> +      Requires<[ Not64BitMode ]>;
>>  def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORXrrr)>,
>> -      Requires<[In64BitMode]>;
>> +      Requires<[ In64BitMode ]>;
>>
>>  //===----------------------------------------------------------------------===//
>>  // CLZERO Instruction
>>
>> Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=269911&r1=269910&r2=269911&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original)
>> +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed May 18 06:59:12 2016
>> @@ -5802,6 +5802,7 @@ def MONITOR : PseudoI<(outs), (ins i32me
>>  let Uses = [EAX, ECX, EDX] in
>>  def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", [], IIC_SSE_MONITOR>,
>>                   TB, Requires<[HasSSE3]>;
>> +
>>  let Uses = [ECX, EAX] in
>>  def MWAITrr   : I<0x01, MRM_C9, (outs), (ins), "mwait",
>>                  [(int_x86_sse3_mwait ECX, EAX)], IIC_SSE_MWAIT>,
>>
>> Modified: llvm/trunk/lib/Target/X86/X86Schedule.td
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Schedule.td?rev=269911&r1=269910&r2=269911&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/X86/X86Schedule.td (original)
>> +++ llvm/trunk/lib/Target/X86/X86Schedule.td Wed May 18 06:59:12 2016
>> @@ -364,6 +364,8 @@ def IIC_SSE_PALIGNRR : InstrItinClass;
>>  def IIC_SSE_PALIGNRM : InstrItinClass;
>>  def IIC_SSE_MWAIT : InstrItinClass;
>>  def IIC_SSE_MONITOR : InstrItinClass;
>> +def IIC_SSE_MWAITX : InstrItinClass;
>> +def IIC_SSE_MONITORX : InstrItinClass;
>>
>>  def IIC_SSE_PREFETCH : InstrItinClass;
>>  def IIC_SSE_PAUSE : InstrItinClass;
>>
>> Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=269911&r1=269910&r2=269911&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original)
>> +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Wed May 18 06:59:12 2016
>> @@ -313,6 +313,7 @@ void X86Subtarget::initializeEnvironment
>>    HasPRFCHW = false;
>>    HasRDSEED = false;
>>    HasLAHFSAHF = false;
>> +  HasMWAITX = false;
>>    HasMPX = false;
>>    IsBTMemSlow = false;
>>    IsSHLDSlow = false;
>>
>> Modified: llvm/trunk/lib/Target/X86/X86Subtarget.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=269911&r1=269910&r2=269911&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/X86/X86Subtarget.h (original)
>> +++ llvm/trunk/lib/Target/X86/X86Subtarget.h Wed May 18 06:59:12 2016
>> @@ -164,6 +164,9 @@ protected:
>>    /// Processor has LAHF/SAHF instructions.
>>    bool HasLAHFSAHF;
>>
>> +  /// Processor has MONITORX/MWAITX instructions.
>> +  bool HasMWAITX;
>> +
>>    /// Processor has Prefetch with intent to Write instruction
>>    bool HasPFPREFETCHWT1;
>>
>> @@ -421,6 +424,7 @@ public:
>>    bool hasPRFCHW() const { return HasPRFCHW; }
>>    bool hasRDSEED() const { return HasRDSEED; }
>>    bool hasLAHFSAHF() const { return HasLAHFSAHF; }
>> +  bool hasMWAITX() const { return HasMWAITX; }
>>    bool isBTMemSlow() const { return IsBTMemSlow; }
>>    bool isSHLDSlow() const { return IsSHLDSlow; }
>>    bool isUnalignedMem16Slow() const { return IsUAMem16Slow; }
>>
>> Added: llvm/trunk/test/CodeGen/X86/mwaitx.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/mwaitx.ll?rev=269911&view=auto
>> ==============================================================================
>> --- llvm/trunk/test/CodeGen/X86/mwaitx.ll (added)
>> +++ llvm/trunk/test/CodeGen/X86/mwaitx.ll Wed May 18 06:59:12 2016
>> @@ -0,0 +1,38 @@
>> +; RUN: llc < %s -mtriple=x86_64-linux -mattr=+mwaitx | FileCheck %s
>> +; RUN: llc < %s -mtriple=x86_64-win32 -mattr=+mwaitx | FileCheck %s -check-prefix=WIN64
>> +; RUN: llc < %s -mtriple=x86_64-linux -mcpu=bdver4 | FileCheck %s
>> +; RUN: llc < %s -mtriple=x86_64-win32 -mcpu=bdver4 | FileCheck %s -check-prefix=WIN64
>> +
>> +; CHECK-LABEL: foo:
>> +; CHECK: leaq    (%rdi), %rax
>> +; CHECK-NEXT: movl    %esi, %ecx
>> +; CHECK-NEXT: monitorx
>> +; WIN64-LABEL: foo:
>> +; WIN64:      leaq    (%rcx), %rax
>> +; WIN64-NEXT: movl    %edx, %ecx
>> +; WIN64-NEXT: movl    %r8d, %edx
>> +; WIN64-NEXT: monitorx
>> +define void @foo(i8* %P, i32 %E, i32 %H) nounwind {
>> +entry:
>> +  tail call void @llvm.x86.monitorx(i8* %P, i32 %E, i32 %H)
>> +  ret void
>> +}
>> +
>> +declare void @llvm.x86.monitorx(i8*, i32, i32) nounwind
>> +
>> +; CHECK-LABEL: bar:
>> +; CHECK: movl    %edi, %ecx
>> +; CHECK-NEXT: movl    %esi, %eax
>> +; CHECK-NEXT: movl    %edx, %ebx
>> +; CHECK-NEXT: mwaitx
>> +; WIN64-LABEL: bar:
>> +; WIN64:      movl    %edx, %eax
>> +; WIN64:      movl    %r8d, %ebx
>> +; WIN64-NEXT: mwaitx
>> +define void @bar(i32 %E, i32 %H, i32 %C) nounwind {
>> +entry:
>> +  tail call void @llvm.x86.mwaitx(i32 %E, i32 %H, i32 %C)
>> +  ret void
>> +}
>> +
>> +declare void @llvm.x86.mwaitx(i32, i32, i32) nounwind
>>
>> Modified: llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt?rev=269911&r1=269910&r2=269911&view=diff
>> ==============================================================================
>> --- llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt (original)
>> +++ llvm/trunk/test/MC/Disassembler/X86/simple-tests.txt Wed May 18 06:59:12 2016
>> @@ -51,6 +51,12 @@
>>  # CHECK: rdtscp
>>  0x0f 0x01 0xf9
>>
>> +# CHECK: monitorx
>> +0x0f 0x01 0xfa
>> +
>> +# CHECK: mwaitx
>> +0x0f 0x01 0xfb
>> +
>>  # CHECK: vmxon
>>  0xf3 0x0f 0xc7 0x30
>>
>>
>> Modified: llvm/trunk/test/MC/Disassembler/X86/x86-32.txt
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/X86/x86-32.txt?rev=269911&r1=269910&r2=269911&view=diff
>> ==============================================================================
>> --- llvm/trunk/test/MC/Disassembler/X86/x86-32.txt (original)
>> +++ llvm/trunk/test/MC/Disassembler/X86/x86-32.txt Wed May 18 06:59:12 2016
>> @@ -90,6 +90,12 @@
>>  # CHECK: rdtscp
>>  0x0f 0x01 0xf9
>>
>> +# CHECK: monitorx
>> +0x0f 0x01 0xfa
>> +
>> +# CHECK: mwaitx
>> +0x0f 0x01 0xfb
>> +
>>  # CHECK: vmxon
>>  0xf3 0x0f 0xc7 0x30
>>
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list