diff --git a/llvm/lib/Transforms/IPO/PartialInlining.cpp b/llvm/lib/Transforms/IPO/PartialInlining.cpp --- a/llvm/lib/Transforms/IPO/PartialInlining.cpp +++ b/llvm/lib/Transforms/IPO/PartialInlining.cpp @@ -50,6 +50,7 @@ #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/CodeExtractor.h" #include "llvm/Transforms/Utils/ValueMapper.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" #include #include #include @@ -1440,6 +1441,13 @@ if (CurrFunc->use_empty()) continue; + // Try to eliminate unreachable blocks in the function, having unreachable + // blocks leads to incorrect costing because while evaluating the costs + // incase of outlining a function, such unreachable basic blocks might be + // taken into consideration, but the code extractor simply eliminates them + // while the outlined function is being constructed. + Changed |= EliminateUnreachableBlocks(*CurrFunc); + std::pair Result = unswitchFunction(*CurrFunc); if (Result.second) Worklist.push_back(Result.second); diff --git a/llvm/test/Transforms/PartialInlining/unreachable_basic_block.ll b/llvm/test/Transforms/PartialInlining/unreachable_basic_block.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/PartialInlining/unreachable_basic_block.ll @@ -0,0 +1,29 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -passes=partial-inliner -S < %s | FileCheck %s +declare i1 @llvm.public.type.test(ptr, metadata) + +define void @dummy() { +; CHECK-LABEL: @dummy( +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 false, label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]] +; CHECK: while.body: +; CHECK-NEXT: call void @dummy.1.while.body() +; CHECK-NEXT: br label [[WHILE_END]] +; CHECK: while.end: +; CHECK-NEXT: ret void +; +entry: + br i1 false, label %while.end, label %while.body + +while.body: ; preds = %entry + call void @dummy() + br label %while.end + +unreachable.block: ; No predecessors! + %0 = tail call i1 @llvm.public.type.test(ptr null, metadata !"test-function") + %result = getelementptr ptr, ptr null, i64 1 + br label %while.end + +while.end: ; preds = %unreachable.block, %while.body, %entry + ret void +}