diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index 92b1335843d..6fd7d7bf9ae 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1860,33 +1860,26 @@ bool llvm::SimplifyCFG(BasicBlock *BB) { } else if (isa(BB->begin())) { // Check to see if the first instruction in this block is just an unwind. // If so, replace any invoke instructions which use this as an exception - // destination with call instructions, and any unconditional branch - // predecessor with an unwind. + // destination with call instructions. // SmallVector Preds(pred_begin(BB), pred_end(BB)); while (!Preds.empty()) { BasicBlock *Pred = Preds.back(); - if (BranchInst *BI = dyn_cast(Pred->getTerminator())) { - if (BI->isUnconditional()) { - Pred->getInstList().pop_back(); // nuke uncond branch - new UnwindInst(Pred->getContext(), Pred); // Use unwind. - Changed = true; - } - } else if (InvokeInst *II = dyn_cast(Pred->getTerminator())) + if (InvokeInst *II = dyn_cast(Pred->getTerminator())) if (II->getUnwindDest() == BB) { // Insert a new branch instruction before the invoke, because this - // is now a fall through... + // is now a fall through. BranchInst *BI = BranchInst::Create(II->getNormalDest(), II); Pred->getInstList().remove(II); // Take out of symbol table - // Insert the call now... + // Insert the call now. SmallVector Args(II->op_begin()+3, II->op_end()); CallInst *CI = CallInst::Create(II->getCalledValue(), Args.begin(), Args.end(), II->getName(), BI); CI->setCallingConv(II->getCallingConv()); CI->setAttributes(II->getAttributes()); - // If the invoke produced a value, the Call now does instead + // If the invoke produced a value, the Call now does instead. II->replaceAllUsesWith(CI); delete II; Changed = true; diff --git a/test/Transforms/SimplifyCFG/invoke_unwind.ll b/test/Transforms/SimplifyCFG/invoke_unwind.ll index da6e3db2f8a..bbd779beb48 100644 --- a/test/Transforms/SimplifyCFG/invoke_unwind.ll +++ b/test/Transforms/SimplifyCFG/invoke_unwind.ll @@ -1,10 +1,9 @@ -; This testcase checks to see if the simplifycfg pass is converting invoke -; instructions to call instructions if the handler just rethrows the exception. - ; RUN: opt < %s -simplifycfg -S | FileCheck %s declare void @bar() +; This testcase checks to see if the simplifycfg pass is converting invoke +; instructions to call instructions if the handler just rethrows the exception. define i32 @test1() { ; CHECK: @test1 ; CHECK-NEXT: call void @bar() @@ -16,3 +15,19 @@ Ok: ; preds = %0 Rethrow: ; preds = %0 unwind } + + +; Verify that simplifycfg isn't duplicating 'unwind' instructions. Doing this +; is bad because it discourages commoning. +define i32 @test2(i1 %c) { +; CHECK: @test2 +; CHECK: T: +; CHECK-NEXT: call void @bar() +; CHECK-NEXT: br label %F + br i1 %c, label %T, label %F +T: + call void @bar() + br label %F +F: + unwind +}