BranchFolder: Fix invalid undef flags after merge.

It is legal to merge instructions with different undef flags; However we
must drop the undef flag from the merged instruction if it isn't present
everywhere.

This fixes http://llvm.org/PR30199

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281957 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Matthias Braun 2016-09-20 01:14:42 +00:00
parent 34c557c690
commit b72235f318
2 changed files with 43 additions and 5 deletions

View File

@ -801,9 +801,8 @@ bool BranchFolder::CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB,
}
static void
mergeMMOsFromMemoryOperations(MachineBasicBlock::iterator MBBIStartPos,
mergeOperations(MachineBasicBlock::iterator MBBIStartPos,
MachineBasicBlock &MBBCommon) {
// Merge MMOs from memory operations in the common block.
MachineBasicBlock *MBB = MBBIStartPos->getParent();
// Note CommonTailLen does not necessarily matches the size of
// the common BB nor all its instructions because of debug
@ -833,8 +832,18 @@ mergeMMOsFromMemoryOperations(MachineBasicBlock::iterator MBBIStartPos,
"Reached BB end within common tail length!");
assert(MBBICommon->isIdenticalTo(*MBBI) && "Expected matching MIIs!");
// Merge MMOs from memory operations in the common block.
if (MBBICommon->mayLoad() || MBBICommon->mayStore())
MBBICommon->setMemRefs(MBBICommon->mergeMemRefsWith(*MBBI));
// Drop undef flags if they aren't present in all merged instructions.
for (unsigned I = 0, E = MBBICommon->getNumOperands(); I != E; ++I) {
MachineOperand &MO = MBBICommon->getOperand(I);
if (MO.isReg() && MO.isUndef()) {
const MachineOperand &OtherMO = MBBI->getOperand(I);
if (!OtherMO.isUndef())
MO.setIsUndef(false);
}
}
++MBBI;
++MBBICommon;
@ -952,8 +961,8 @@ bool BranchFolder::TryTailMergeBlocks(MachineBasicBlock *SuccBB,
continue;
DEBUG(dbgs() << "BB#" << SameTails[i].getBlock()->getNumber()
<< (i == e-1 ? "" : ", "));
// Merge MMOs from memory operations as needed.
mergeMMOsFromMemoryOperations(SameTails[i].getTailStartPos(), *MBB);
// Merge operations (MMOs, undef flags)
mergeOperations(SameTails[i].getTailStartPos(), *MBB);
// Hack the end off BB i, making it jump to BB commonTailIndex instead.
ReplaceTailWithBranchTo(SameTails[i].getTailStartPos(), MBB);
// BB i is no longer a predecessor of SuccBB; remove it from the worklist.

View File

@ -0,0 +1,29 @@
# RUN: llc -o - %s -march=x86 -run-pass branch-folder | FileCheck %s
# Test that tail merging drops undef flags that aren't present on all
# instructions to be merged.
--- |
define void @func() { ret void }
...
---
# CHECK-LABEL: name: func
# CHECK: bb.1:
# CHECK: %eax = MOV32ri 2
# CHECK-NOT: RET
# CHECK: bb.2:
# CHECK-NOT: RET 0, undef %eax
# CHECK: RET 0, %eax
name: func
tracksRegLiveness: true
body: |
bb.0:
successors: %bb.1, %bb.2
JE_1 %bb.1, implicit undef %eflags
JMP_1 %bb.2
bb.1:
%eax = MOV32ri 2
RET 0, %eax
bb.2:
RET 0, undef %eax
...