From: Jakub Kuderski Date: Wed, 12 Jul 2017 18:42:16 +0000 (+0000) Subject: [LoopRotate] Fix DomTree update logic for unreachable nodes. Fix PR33701. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7c78172bced2d22d612794febda988d2c9551e58;p=llvm [LoopRotate] Fix DomTree update logic for unreachable nodes. Fix PR33701. Summary: LoopRotate manually updates the DoomTree by iterating over all predecessors of a basic block and computing the Nearest Common Dominator. When a predecessor happens to be unreachable, `DT.findNearestCommonDominator` returns nullptr. This patch teaches LoopRotate to handle this case and fixes [[ https://bugs.llvm.org/show_bug.cgi?id=33701 | PR33701 ]]. In the future, LoopRotate should be taught to use the new incremental API for updating the DomTree. Reviewers: dberlin, davide, uabelho, grosser Subscribers: efriedma, mzolotukhin Differential Revision: https://reviews.llvm.org/D35074 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307828 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/LoopRotation.cpp b/lib/Transforms/Scalar/LoopRotation.cpp index 7312d97f8ef..3506ac343d5 100644 --- a/lib/Transforms/Scalar/LoopRotation.cpp +++ b/lib/Transforms/Scalar/LoopRotation.cpp @@ -485,10 +485,22 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) { DomTreeNode *Node = HeaderChildren[I]; BasicBlock *BB = Node->getBlock(); - pred_iterator PI = pred_begin(BB); - BasicBlock *NearestDom = *PI; - for (pred_iterator PE = pred_end(BB); PI != PE; ++PI) - NearestDom = DT->findNearestCommonDominator(NearestDom, *PI); + BasicBlock *NearestDom = nullptr; + for (BasicBlock *Pred : predecessors(BB)) { + // Consider only reachable basic blocks. + if (!DT->getNode(Pred)) + continue; + + if (!NearestDom) { + NearestDom = Pred; + continue; + } + + NearestDom = DT->findNearestCommonDominator(NearestDom, Pred); + assert(NearestDom && "No NearestCommonDominator found"); + } + + assert(NearestDom && "Nearest dominator not found"); // Remember if this changes the DomTree. if (Node->getIDom()->getBlock() != NearestDom) { diff --git a/test/Transforms/LoopRotate/pr33701.ll b/test/Transforms/LoopRotate/pr33701.ll new file mode 100644 index 00000000000..ed162b12098 --- /dev/null +++ b/test/Transforms/LoopRotate/pr33701.ll @@ -0,0 +1,27 @@ +; RUN: opt < %s -loop-rotate -verify-dom-info -verify-loop-info -disable-output + +define void @func() { +bb0: + br label %bb1 + +bb1: ; preds = %bb4, %bb0 + %0 = phi i16 [ %2, %bb4 ], [ 0, %bb0 ] + %1 = icmp sle i16 %0, 2 + br i1 %1, label %bb2, label %bb5 + +bb2: ; preds = %bb1 + br i1 undef, label %bb6, label %bb4 + +bb3: ; No predecessors! + br label %bb6 + +bb4: ; preds = %bb2 + %2 = add i16 undef, 1 + br label %bb1 + +bb5: ; preds = %bb1 + br label %bb6 + +bb6: ; preds = %bb5, %bb3, %bb2 + unreachable +}