[PATCH] D32335: [PartialInliner] Fix crash when inlining functions with unreachable blocks

Davide Italiano via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 20 20:36:50 PDT 2017


davide created this revision.

CodeExtractor looks up the dominator node corresponding to return blocks when splitting them. If one of these blocks is unreachable, there's no node in the Dom and CodeExtractor crashes because it doesn't check for domtree node validity.
In theory, we could add just a check for skipping DTNode == nullptr in `splitReturnBlock` but the fix I propose here is slightly different. To the best of my knowledge, unreachable blocks are irrelevant for the algorithm, therefore we can just skip them when building the candidate set in the constructor.
I'm not 100% sure if any pass using CodeExtractor could make use of extracting an unreachable block (including bugpoint), in which case my fix would need to be adjusted.


https://reviews.llvm.org/D32335

Files:
  lib/Transforms/Utils/CodeExtractor.cpp
  test/Transforms/CodeExtractor/unreachable-block.ll


Index: test/Transforms/CodeExtractor/unreachable-block.ll
===================================================================
--- /dev/null
+++ test/Transforms/CodeExtractor/unreachable-block.ll
@@ -0,0 +1,38 @@
+; RUN: opt -S -partial-inliner %s | FileCheck %s
+
+; CHECK-LABEL: define void @dipsy(
+; CHECK-NEXT:   call void @tinkywinky.1_ontrue()
+; CHECK-NEXT:   call void @patatuccio()
+; CHECK-NEXT:   ret void
+; CHECK-NEXT: }
+
+; CHECK-LABEL: define internal void @tinkywinky.1_ontrue() {
+; CHECK-NEXT: newFuncRoot:
+; CHECK-NEXT:   br label %ontrue
+; CHECK: .exitStub:
+; CHECK-NEXT:   ret void
+; CHECK: ontrue:
+; CHECK-NEXT:   call void @patatino()
+; CHECK-NEXT:   br label %onfalse
+; CHECK: onfalse:
+; CHECK-NEXT:   br label %.exitStub
+; CHECK-NEXT: }
+
+declare void @patatino()
+declare void @patatuccio()
+
+define fastcc void @tinkywinky() {
+  br i1 true, label %ontrue, label %onfalse
+ontrue:
+  call void @patatino()
+  br label %onfalse
+onfalse:
+  call void @patatuccio()
+  ret void
+cantreachme:
+  ret void
+}
+define void @dipsy() {
+  call fastcc void @tinkywinky()
+  ret void
+}
Index: lib/Transforms/Utils/CodeExtractor.cpp
===================================================================
--- lib/Transforms/Utils/CodeExtractor.cpp
+++ lib/Transforms/Utils/CodeExtractor.cpp
@@ -74,24 +74,25 @@
 
 /// \brief Build a set of blocks to extract if the input blocks are viable.
 static SetVector<BasicBlock *>
-buildExtractionBlockSet(ArrayRef<BasicBlock *> BBs) {
-  auto BBBegin = BBs.begin();
-  auto BBEnd = BBs.end();
-  assert(BBBegin != BBEnd && "The set of blocks to extract must be non-empty");
-
+buildExtractionBlockSet(ArrayRef<BasicBlock *> BBs, DominatorTree *DT) {
+  assert(!BBs.empty() && "The set of blocks to extract must be non-empty");
   SetVector<BasicBlock *> Result;
 
   // Loop over the blocks, adding them to our set-vector, and aborting with an
   // empty set if we encounter invalid blocks.
-  do {
-    if (!Result.insert(*BBBegin))
-      llvm_unreachable("Repeated basic blocks in extraction input");
+  for (BasicBlock *BB : BBs) {
+
+    // If this block is dead, don't process it.
+    if (DT && !DT->isReachableFromEntry(BB))
+      continue;
 
-    if (!CodeExtractor::isBlockValidForExtraction(**BBBegin)) {
+    if (!Result.insert(BB))
+      llvm_unreachable("Repeated basic blocks in extraction input");
+    if (!CodeExtractor::isBlockValidForExtraction(*BB)) {
       Result.clear();
       return Result;
     }
-  } while (++BBBegin != BBEnd);
+  }
 
 #ifndef NDEBUG
   for (SetVector<BasicBlock *>::iterator I = std::next(Result.begin()),
@@ -111,13 +112,13 @@
                              bool AggregateArgs, BlockFrequencyInfo *BFI,
                              BranchProbabilityInfo *BPI)
     : DT(DT), AggregateArgs(AggregateArgs || AggregateArgsOpt), BFI(BFI),
-      BPI(BPI), Blocks(buildExtractionBlockSet(BBs)), NumExitBlocks(~0U) {}
+      BPI(BPI), Blocks(buildExtractionBlockSet(BBs, DT)), NumExitBlocks(~0U) {}
 
 CodeExtractor::CodeExtractor(DominatorTree &DT, Loop &L, bool AggregateArgs,
                              BlockFrequencyInfo *BFI,
                              BranchProbabilityInfo *BPI)
     : DT(&DT), AggregateArgs(AggregateArgs || AggregateArgsOpt), BFI(BFI),
-      BPI(BPI), Blocks(buildExtractionBlockSet(L.getBlocks())),
+      BPI(BPI), Blocks(buildExtractionBlockSet(L.getBlocks(), &DT)),
       NumExitBlocks(~0U) {}
 
 /// definedInRegion - Return true if the specified value is defined in the


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32335.96087.patch
Type: text/x-patch
Size: 3524 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170421/11d98189/attachment.bin>


More information about the llvm-commits mailing list