// 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) {
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());
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.
--- /dev/null
+; 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
+}