[PATCH] D48256: Fix bug to merge away entry block and update DT correctly.
Xin Tong via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 16 13:45:55 PDT 2018
trentxintong updated this revision to Diff 151627.
trentxintong added a comment.
Remove some duplicate code.
Repository:
rL LLVM
https://reviews.llvm.org/D48256
Files:
lib/Transforms/Utils/Local.cpp
unittests/Transforms/Utils/Local.cpp
Index: unittests/Transforms/Utils/Local.cpp
===================================================================
--- unittests/Transforms/Utils/Local.cpp
+++ unittests/Transforms/Utils/Local.cpp
@@ -176,6 +176,18 @@
TEST(Local, MergeBasicBlockIntoOnlyPred) {
LLVMContext C;
+ auto runMergeBasicBlockIntoOnlyPred = [&](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<BranchInst>(SinglePred->getTerminator());
+ if (Term && !Term->isConditional())
+ MergeBasicBlockIntoOnlyPred(BB, DT);
+ }
+ };
+
std::unique_ptr<Module> M = parseIR(C,
R"(
define i32 @f(i8* %str) {
@@ -194,18 +206,28 @@
ret i32 0
}
)");
- runWithDomTree(
- *M, "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<BranchInst>(SinglePred->getTerminator());
- if (Term && !Term->isConditional())
- MergeBasicBlockIntoOnlyPred(BB, DT);
- }
- EXPECT_TRUE(DT->verify());
- });
+ runWithDomTree(*M, "f", [&](Function &F, DominatorTree *DT) {
+ runMergeBasicBlockIntoOnlyPred(F, DT);
+ EXPECT_TRUE(DT->verify());
+ });
+
+ // Test we can merge away entry block and update DT correctly.
+ // entry block does not have IDom.
+ std::unique_ptr<Module> 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) {
+ runMergeBasicBlockIntoOnlyPred(F, DT);
+ EXPECT_TRUE(DT->verify());
+ });
}
TEST(Local, ConstantFoldTerminator) {
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()));
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48256.151627.patch
Type: text/x-patch
Size: 3333 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180616/62eb9290/attachment.bin>
More information about the llvm-commits
mailing list