Skip to content

Commit 647e861

Browse files
committed
[X86] Detect if EFLAGs is live across XBEGIN pseudo instruction. Add 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
1 parent 25f193f commit 647e861

File tree

2 files changed

+75
-21
lines changed

2 files changed

+75
-21
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30954,6 +30954,34 @@ bool X86TargetLowering::areJTsAllowed(const Function *Fn) const {
3095430954
// X86 Scheduler Hooks
3095530955
//===----------------------------------------------------------------------===//
3095630956

30957+
// Returns true if EFLAG is consumed after this iterator in the rest of the
30958+
// basic block or any successors of the basic block.
30959+
static bool isEFLAGSLiveAfter(MachineBasicBlock::iterator Itr,
30960+
MachineBasicBlock *BB) {
30961+
// Scan forward through BB for a use/def of EFLAGS.
30962+
for (MachineBasicBlock::iterator miI = std::next(Itr), miE = BB->end();
30963+
miI != miE; ++miI) {
30964+
const MachineInstr& mi = *miI;
30965+
if (mi.readsRegister(X86::EFLAGS))
30966+
return true;
30967+
// If we found a def, we can stop searching.
30968+
if (mi.definesRegister(X86::EFLAGS))
30969+
return false;
30970+
}
30971+
30972+
// If we hit the end of the block, check whether EFLAGS is live into a
30973+
// successor.
30974+
for (MachineBasicBlock::succ_iterator sItr = BB->succ_begin(),
30975+
sEnd = BB->succ_end();
30976+
sItr != sEnd; ++sItr) {
30977+
MachineBasicBlock* succ = *sItr;
30978+
if (succ->isLiveIn(X86::EFLAGS))
30979+
return true;
30980+
}
30981+
30982+
return false;
30983+
}
30984+
3095730985
/// Utility function to emit xbegin specifying the start of an RTM region.
3095830986
static MachineBasicBlock *emitXBegin(MachineInstr &MI, MachineBasicBlock *MBB,
3095930987
const TargetInstrInfo *TII) {
@@ -30986,6 +31014,12 @@ static MachineBasicBlock *emitXBegin(MachineInstr &MI, MachineBasicBlock *MBB,
3098631014
MF->insert(I, fallMBB);
3098731015
MF->insert(I, sinkMBB);
3098831016

31017+
if (isEFLAGSLiveAfter(MI, MBB)) {
31018+
mainMBB->addLiveIn(X86::EFLAGS);
31019+
fallMBB->addLiveIn(X86::EFLAGS);
31020+
sinkMBB->addLiveIn(X86::EFLAGS);
31021+
}
31022+
3098931023
// Transfer the remainder of BB and its successor edges to sinkMBB.
3099031024
sinkMBB->splice(sinkMBB->begin(), MBB,
3099131025
std::next(MachineBasicBlock::iterator(MI)), MBB->end());
@@ -31374,27 +31408,8 @@ MachineBasicBlock *X86TargetLowering::EmitVAStartSaveXMMRegsWithCustomInserter(
3137431408
static bool checkAndUpdateEFLAGSKill(MachineBasicBlock::iterator SelectItr,
3137531409
MachineBasicBlock* BB,
3137631410
const TargetRegisterInfo* TRI) {
31377-
// Scan forward through BB for a use/def of EFLAGS.
31378-
MachineBasicBlock::iterator miI(std::next(SelectItr));
31379-
for (MachineBasicBlock::iterator miE = BB->end(); miI != miE; ++miI) {
31380-
const MachineInstr& mi = *miI;
31381-
if (mi.readsRegister(X86::EFLAGS))
31382-
return false;
31383-
if (mi.definesRegister(X86::EFLAGS))
31384-
break; // Should have kill-flag - update below.
31385-
}
31386-
31387-
// If we hit the end of the block, check whether EFLAGS is live into a
31388-
// successor.
31389-
if (miI == BB->end()) {
31390-
for (MachineBasicBlock::succ_iterator sItr = BB->succ_begin(),
31391-
sEnd = BB->succ_end();
31392-
sItr != sEnd; ++sItr) {
31393-
MachineBasicBlock* succ = *sItr;
31394-
if (succ->isLiveIn(X86::EFLAGS))
31395-
return false;
31396-
}
31397-
}
31411+
if (isEFLAGSLiveAfter(SelectItr, BB))
31412+
return false;
3139831413

3139931414
// We found a def, or hit the end of the basic block and EFLAGS wasn't live
3140031415
// out. SelectMI should have a kill flag on EFLAGS.

llvm/test/CodeGen/X86/pr46827.ll

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
; RUN: llc < %s -mtriple=i686-pc-linux -mattr=+rtm -verify-machineinstrs -stop-after=finalize-isel | FileCheck %s
2+
3+
; CHECK: body: |
4+
; CHECK: bb.0.bb107:
5+
; CHECK: successors: %bb.3(0x40000000), %bb.4(0x40000000)
6+
; CHECK: %0:gr32 = MOV32rm %fixed-stack.0, 1, $noreg, 0, $noreg :: (load 4 from %fixed-stack.0, align 16)
7+
; CHECK: %1:gr32 = SUB32ri8 %0, 1, implicit-def $eflags
8+
; CHECK: XBEGIN_4 %bb.4, implicit-def $eax
9+
; CHECK: bb.3.bb107:
10+
; CHECK: successors: %bb.5(0x80000000)
11+
; CHECK: liveins: $eflags
12+
; CHECK: %3:gr32 = MOV32ri -1
13+
; CHECK: JMP_1 %bb.5
14+
; CHECK: bb.4.bb107:
15+
; CHECK: successors: %bb.5(0x80000000)
16+
; CHECK: liveins: $eflags
17+
; CHECK: XABORT_DEF implicit-def $eax
18+
; CHECK: %4:gr32 = COPY $eax
19+
; CHECK: bb.5.bb107:
20+
; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
21+
; CHECK: liveins: $eflags
22+
; CHECK: %2:gr32 = PHI %3, %bb.3, %4, %bb.4
23+
; CHECK: JCC_1 %bb.2, 5, implicit $eflags
24+
; CHECK: JMP_1 %bb.1
25+
26+
declare i32 @llvm.x86.xbegin() #0
27+
28+
define void @wobble.12(i32 %tmp116) {
29+
bb107: ; preds = %bb42
30+
%tmp117 = icmp eq i32 %tmp116, 1
31+
%tmp127 = tail call i32 @llvm.x86.xbegin() #0
32+
br i1 %tmp117, label %bb129, label %bb250
33+
34+
bb129: ; preds = %bb107
35+
unreachable
36+
37+
bb250: ; preds = %bb107
38+
unreachable
39+
}

0 commit comments

Comments
 (0)