Index: lib/Transforms/Utils/Local.cpp =================================================================== --- lib/Transforms/Utils/Local.cpp +++ lib/Transforms/Utils/Local.cpp @@ -714,7 +714,8 @@ if (ReplaceEntryBB) DestBB->moveAfter(PredBB); - if (DT) { + // Entry block does not have IDom. + if (DT && !ReplaceEntryBB) { // For some irreducible CFG we end up having forward-unreachable blocks // so check if getNode returns a valid node before updating the domtree. if (DomTreeNode *DTN = DT->getNode(PredBB)) { @@ -735,6 +736,11 @@ DDT->applyUpdates(Updates); } else { PredBB->eraseFromParent(); // Nuke BB. + // The entry block was removed and there is no external interface for the + // dominator tree to be notified of this change. In this corner-case we + // recalculate the entire tree. + if (DT && ReplaceEntryBB) + DT->recalculate(*(DestBB->getParent())); } } Index: unittests/Transforms/Utils/Local.cpp =================================================================== --- unittests/Transforms/Utils/Local.cpp +++ unittests/Transforms/Utils/Local.cpp @@ -206,6 +206,33 @@ } EXPECT_TRUE(DT->verify()); }); + + // Test we can merge away entry block and update DT correctly. + // entry block does not have IDom. + std::unique_ptr M2 = parseIR(C, + R"( + define i32 @f(i8* %str) { + entry: + br label %bb2.i + bb2.i: ; preds = %bb4.i, %entry + br label %base2flt.exit204 + base2flt.exit204: ; preds = %bb7.i197, %bb7.i197, %bb2.i, %bb4.i + ret i32 0 + } + )"); + runWithDomTree( + *M2, "f", [&](Function &F, DominatorTree *DT) { + for (Function::iterator I = F.begin(), E = F.end(); I != E;) { + BasicBlock *BB = &*I++; + BasicBlock *SinglePred = BB->getSinglePredecessor(); + if (!SinglePred || SinglePred == BB || BB->hasAddressTaken()) continue; + BranchInst *Term = dyn_cast(SinglePred->getTerminator()); + if (Term && !Term->isConditional()) + MergeBasicBlockIntoOnlyPred(BB, DT); + } + EXPECT_TRUE(DT->verify()); + }); + } TEST(Local, ConstantFoldTerminator) {