aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2020-07-27 21:11:54 -0700
committerHans Wennborg <hans@chromium.org>2020-07-28 13:43:23 +0200
commite47a6a224a4b6d0ce98028f560a8b3806d145907 (patch)
treefddb61a9814efcad14c011142625e8b200fe5f0c
parentbf2c0fb8a254345e62f18d61ed8c3ca84307b0d8 (diff)
downloadllvm-e47a6a224a4b6d0ce98028f560a8b3806d145907.zip
llvm-e47a6a224a4b6d0ce98028f560a8b3806d145907.tar.gz
llvm-e47a6a224a4b6d0ce98028f560a8b3806d145907.tar.bz2
[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 (cherry picked from commit 647e861e080382593648b234668ad2f5a376ac5e)
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp57
-rw-r--r--llvm/test/CodeGen/X86/pr46827.ll39
2 files changed, 75 insertions, 21 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index f8b6b7e..7d846e4 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -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) {
@@ -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());
@@ -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.
diff --git a/llvm/test/CodeGen/X86/pr46827.ll b/llvm/test/CodeGen/X86/pr46827.ll
new file mode 100644
index 0000000..438b13c
--- /dev/null
+++ b/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
+}