Skip to content

Commit

Permalink
[X86] Detect if EFLAGs is live across XBEGIN pseudo instruction. Add …
Browse files Browse the repository at this point in the history
…it as livein to the basic blocks created when expanding the pseudo

XBEGIN causes several based blocks to be inserted. If flags are live across it we need to make eflags live in the new basic blocks to avoid machine verifier errors.

Fixes PR46827

Reviewed By: ivanbaev

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

(cherry picked from commit 647e861)
  • Loading branch information
topperc authored and zmodem committed Jul 28, 2020
1 parent bf2c0fb commit e47a6a2
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 21 deletions.
57 changes: 36 additions & 21 deletions llvm/lib/Target/X86/X86ISelLowering.cpp
Expand Up @@ -30953,6 +30953,34 @@ bool X86TargetLowering::areJTsAllowed(const Function *Fn) const {
// X86 Scheduler Hooks
//===----------------------------------------------------------------------===//

// Returns true if EFLAG is consumed after this iterator in the rest of the
// basic block or any successors of the basic block.
static bool isEFLAGSLiveAfter(MachineBasicBlock::iterator Itr,
MachineBasicBlock *BB) {
// Scan forward through BB for a use/def of EFLAGS.
for (MachineBasicBlock::iterator miI = std::next(Itr), miE = BB->end();
miI != miE; ++miI) {
const MachineInstr& mi = *miI;
if (mi.readsRegister(X86::EFLAGS))
return true;
// If we found a def, we can stop searching.
if (mi.definesRegister(X86::EFLAGS))
return false;
}

// If we hit the end of the block, check whether EFLAGS is live into a
// successor.
for (MachineBasicBlock::succ_iterator sItr = BB->succ_begin(),
sEnd = BB->succ_end();
sItr != sEnd; ++sItr) {
MachineBasicBlock* succ = *sItr;
if (succ->isLiveIn(X86::EFLAGS))
return true;
}

return false;
}

/// Utility function to emit xbegin specifying the start of an RTM region.
static MachineBasicBlock *emitXBegin(MachineInstr &MI, MachineBasicBlock *MBB,
const TargetInstrInfo *TII) {
Expand Down Expand Up @@ -30985,6 +31013,12 @@ static MachineBasicBlock *emitXBegin(MachineInstr &MI, MachineBasicBlock *MBB,
MF->insert(I, fallMBB);
MF->insert(I, sinkMBB);

if (isEFLAGSLiveAfter(MI, MBB)) {
mainMBB->addLiveIn(X86::EFLAGS);
fallMBB->addLiveIn(X86::EFLAGS);
sinkMBB->addLiveIn(X86::EFLAGS);
}

// Transfer the remainder of BB and its successor edges to sinkMBB.
sinkMBB->splice(sinkMBB->begin(), MBB,
std::next(MachineBasicBlock::iterator(MI)), MBB->end());
Expand Down Expand Up @@ -31373,27 +31407,8 @@ MachineBasicBlock *X86TargetLowering::EmitVAStartSaveXMMRegsWithCustomInserter(
static bool checkAndUpdateEFLAGSKill(MachineBasicBlock::iterator SelectItr,
MachineBasicBlock* BB,
const TargetRegisterInfo* TRI) {
// Scan forward through BB for a use/def of EFLAGS.
MachineBasicBlock::iterator miI(std::next(SelectItr));
for (MachineBasicBlock::iterator miE = BB->end(); miI != miE; ++miI) {
const MachineInstr& mi = *miI;
if (mi.readsRegister(X86::EFLAGS))
return false;
if (mi.definesRegister(X86::EFLAGS))
break; // Should have kill-flag - update below.
}

// If we hit the end of the block, check whether EFLAGS is live into a
// successor.
if (miI == BB->end()) {
for (MachineBasicBlock::succ_iterator sItr = BB->succ_begin(),
sEnd = BB->succ_end();
sItr != sEnd; ++sItr) {
MachineBasicBlock* succ = *sItr;
if (succ->isLiveIn(X86::EFLAGS))
return false;
}
}
if (isEFLAGSLiveAfter(SelectItr, BB))
return false;

// We found a def, or hit the end of the basic block and EFLAGS wasn't live
// out. SelectMI should have a kill flag on EFLAGS.
Expand Down
39 changes: 39 additions & 0 deletions llvm/test/CodeGen/X86/pr46827.ll
@@ -0,0 +1,39 @@
; RUN: llc < %s -mtriple=i686-pc-linux -mattr=+rtm -verify-machineinstrs -stop-after=finalize-isel | FileCheck %s

; CHECK: body: |
; CHECK: bb.0.bb107:
; CHECK: successors: %bb.3(0x40000000), %bb.4(0x40000000)
; CHECK: %0:gr32 = MOV32rm %fixed-stack.0, 1, $noreg, 0, $noreg :: (load 4 from %fixed-stack.0, align 16)
; CHECK: %1:gr32 = SUB32ri8 %0, 1, implicit-def $eflags
; CHECK: XBEGIN_4 %bb.4, implicit-def $eax
; CHECK: bb.3.bb107:
; CHECK: successors: %bb.5(0x80000000)
; CHECK: liveins: $eflags
; CHECK: %3:gr32 = MOV32ri -1
; CHECK: JMP_1 %bb.5
; CHECK: bb.4.bb107:
; CHECK: successors: %bb.5(0x80000000)
; CHECK: liveins: $eflags
; CHECK: XABORT_DEF implicit-def $eax
; CHECK: %4:gr32 = COPY $eax
; CHECK: bb.5.bb107:
; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
; CHECK: liveins: $eflags
; CHECK: %2:gr32 = PHI %3, %bb.3, %4, %bb.4
; CHECK: JCC_1 %bb.2, 5, implicit $eflags
; CHECK: JMP_1 %bb.1

declare i32 @llvm.x86.xbegin() #0

define void @wobble.12(i32 %tmp116) {
bb107: ; preds = %bb42
%tmp117 = icmp eq i32 %tmp116, 1
%tmp127 = tail call i32 @llvm.x86.xbegin() #0
br i1 %tmp117, label %bb129, label %bb250

bb129: ; preds = %bb107
unreachable

bb250: ; preds = %bb107
unreachable
}

0 comments on commit e47a6a2

Please sign in to comment.