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 -buildExtractionBlockSet(ArrayRef BBs) { - auto BBBegin = BBs.begin(); - auto BBEnd = BBs.end(); - assert(BBBegin != BBEnd && "The set of blocks to extract must be non-empty"); - +buildExtractionBlockSet(ArrayRef BBs, DominatorTree *DT) { + assert(!BBs.empty() && "The set of blocks to extract must be non-empty"); SetVector 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::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 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 +}