diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index f0c603f0c8f..ec736a04bbd 100644 --- a/lib/CodeGen/BranchFolding.cpp +++ b/lib/CodeGen/BranchFolding.cpp @@ -801,9 +801,8 @@ bool BranchFolder::CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB, } static void -mergeMMOsFromMemoryOperations(MachineBasicBlock::iterator MBBIStartPos, - MachineBasicBlock &MBBCommon) { - // Merge MMOs from memory operations in the common block. +mergeOperations(MachineBasicBlock::iterator MBBIStartPos, + MachineBasicBlock &MBBCommon) { 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. diff --git a/test/CodeGen/X86/branchfolding-undef.mir b/test/CodeGen/X86/branchfolding-undef.mir new file mode 100644 index 00000000000..0da167b3325 --- /dev/null +++ b/test/CodeGen/X86/branchfolding-undef.mir @@ -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 +...