Fix PR33028

- '-verify-mahcineinstrs' starts to complain allocatable live-in physical
  registers on non-entry or non-landing-pad basic blocks.
- Refactor the XBEGIN translation to define EAX on a dedicated fallback code
  path due to XABORT. Add a pseudo instruction to define EAX explicitly to
  avoid add physical register live-in.

Differential Revision: https://reviews.llvm.org/D33168



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303306 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Michael Liao 2017-05-17 21:48:00 +00:00
parent 42d86b3f77
commit 7e11c73f63
3 changed files with 45 additions and 17 deletions

View File

@ -24709,16 +24709,22 @@ static MachineBasicBlock *emitXBegin(MachineInstr &MI, MachineBasicBlock *MBB,
// xbegin sinkMBB // xbegin sinkMBB
// //
// mainMBB: // mainMBB:
// eax = -1 // s0 = -1
//
// fallBB:
// eax = # XABORT_DEF
// s1 = eax
// //
// sinkMBB: // sinkMBB:
// v = eax // v = phi(s0/mainBB, s1/fallBB)
MachineBasicBlock *thisMBB = MBB; MachineBasicBlock *thisMBB = MBB;
MachineFunction *MF = MBB->getParent(); MachineFunction *MF = MBB->getParent();
MachineBasicBlock *mainMBB = MF->CreateMachineBasicBlock(BB); MachineBasicBlock *mainMBB = MF->CreateMachineBasicBlock(BB);
MachineBasicBlock *fallMBB = MF->CreateMachineBasicBlock(BB);
MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(BB); MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(BB);
MF->insert(I, mainMBB); MF->insert(I, mainMBB);
MF->insert(I, fallMBB);
MF->insert(I, sinkMBB); MF->insert(I, sinkMBB);
// Transfer the remainder of BB and its successor edges to sinkMBB. // Transfer the remainder of BB and its successor edges to sinkMBB.
@ -24726,25 +24732,40 @@ static MachineBasicBlock *emitXBegin(MachineInstr &MI, MachineBasicBlock *MBB,
std::next(MachineBasicBlock::iterator(MI)), MBB->end()); std::next(MachineBasicBlock::iterator(MI)), MBB->end());
sinkMBB->transferSuccessorsAndUpdatePHIs(MBB); sinkMBB->transferSuccessorsAndUpdatePHIs(MBB);
MachineRegisterInfo &MRI = MF->getRegInfo();
unsigned DstReg = MI.getOperand(0).getReg();
const TargetRegisterClass *RC = MRI.getRegClass(DstReg);
unsigned mainDstReg = MRI.createVirtualRegister(RC);
unsigned fallDstReg = MRI.createVirtualRegister(RC);
// thisMBB: // thisMBB:
// xbegin sinkMBB // xbegin fallMBB
// # fallthrough to mainMBB // # fallthrough to mainMBB
// # abortion to sinkMBB // # abortion to fallMBB
BuildMI(thisMBB, DL, TII->get(X86::XBEGIN_4)).addMBB(sinkMBB); BuildMI(thisMBB, DL, TII->get(X86::XBEGIN_4)).addMBB(fallMBB);
thisMBB->addSuccessor(mainMBB); thisMBB->addSuccessor(mainMBB);
thisMBB->addSuccessor(sinkMBB); thisMBB->addSuccessor(fallMBB);
// mainMBB: // mainMBB:
// EAX = -1 // mainDstReg := -1
BuildMI(mainMBB, DL, TII->get(X86::MOV32ri), X86::EAX).addImm(-1); BuildMI(mainMBB, DL, TII->get(X86::MOV32ri), mainDstReg).addImm(-1);
BuildMI(mainMBB, DL, TII->get(X86::JMP_1)).addMBB(sinkMBB);
mainMBB->addSuccessor(sinkMBB); mainMBB->addSuccessor(sinkMBB);
// sinkMBB: // fallMBB:
// EAX is live into the sinkMBB // ; pseudo instruction to model hardware's definition from XABORT
sinkMBB->addLiveIn(X86::EAX); // EAX := XABORT_DEF
BuildMI(*sinkMBB, sinkMBB->begin(), DL, TII->get(TargetOpcode::COPY), // fallDstReg := EAX
MI.getOperand(0).getReg()) BuildMI(fallMBB, DL, TII->get(X86::XABORT_DEF));
BuildMI(fallMBB, DL, TII->get(TargetOpcode::COPY), fallDstReg)
.addReg(X86::EAX); .addReg(X86::EAX);
fallMBB->addSuccessor(sinkMBB);
// sinkMBB:
// DstReg := phi(mainDstReg/mainBB, fallDstReg/fallBB)
BuildMI(*sinkMBB, sinkMBB->begin(), DL, TII->get(X86::PHI), DstReg)
.addReg(mainDstReg).addMBB(mainMBB)
.addReg(fallDstReg).addMBB(fallMBB);
MI.eraseFromParent(); MI.eraseFromParent();
return sinkMBB; return sinkMBB;

View File

@ -30,6 +30,11 @@ def XBEGIN_4 : Ii32PCRel<0xc7, MRM_F8, (outs), (ins brtarget32:$dst),
"xbegin\t$dst", []>, OpSize32; "xbegin\t$dst", []>, OpSize32;
} }
// Psuedo instruction to fake the definition of EAX on the fallback code path.
let isPseudo = 1, Defs = [EAX] in {
def XABORT_DEF : I<0, Pseudo, (outs), (ins), "# XABORT DEF", []>;
}
def XEND : I<0x01, MRM_D5, (outs), (ins), def XEND : I<0x01, MRM_D5, (outs), (ins),
"xend", [(int_x86_xend)]>, TB, Requires<[HasRTM]>; "xend", [(int_x86_xend)]>, TB, Requires<[HasRTM]>;

View File

@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+rtm | FileCheck %s --check-prefix=X86 ; RUN: llc -verify-machineinstrs < %s -mtriple=i686-unknown-unknown -mattr=+rtm | FileCheck %s --check-prefix=X86
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+rtm | FileCheck %s --check-prefix=X64 ; RUN: llc -verify-machineinstrs < %s -mtriple=x86_64-unknown-unknown -mattr=+rtm | FileCheck %s --check-prefix=X64
declare i32 @llvm.x86.xbegin() nounwind declare i32 @llvm.x86.xbegin() nounwind
declare void @llvm.x86.xend() nounwind declare void @llvm.x86.xend() nounwind
@ -13,7 +13,8 @@ define i32 @test_xbegin() nounwind uwtable {
; X86-NEXT: xbegin .LBB0_2 ; X86-NEXT: xbegin .LBB0_2
; X86-NEXT: # BB#1: # %entry ; X86-NEXT: # BB#1: # %entry
; X86-NEXT: movl $-1, %eax ; X86-NEXT: movl $-1, %eax
; X86-NEXT: .LBB0_2: # %entry ; X86: .LBB0_2: # %entry
; X86-NEXT: # XABORT DEF
; X86-NEXT: retl ; X86-NEXT: retl
; ;
; X64-LABEL: test_xbegin: ; X64-LABEL: test_xbegin:
@ -21,7 +22,8 @@ define i32 @test_xbegin() nounwind uwtable {
; X64-NEXT: xbegin .LBB0_2 ; X64-NEXT: xbegin .LBB0_2
; X64-NEXT: # BB#1: # %entry ; X64-NEXT: # BB#1: # %entry
; X64-NEXT: movl $-1, %eax ; X64-NEXT: movl $-1, %eax
; X64-NEXT: .LBB0_2: # %entry ; X64: .LBB0_2: # %entry
; X64-NEXT: # XABORT DEF
; X64-NEXT: retq ; X64-NEXT: retq
entry: entry:
%0 = tail call i32 @llvm.x86.xbegin() nounwind %0 = tail call i32 @llvm.x86.xbegin() nounwind