diff options
Diffstat (limited to 'llvm/lib/Transforms/IPO/Attributor.cpp')
| -rw-r--r-- | llvm/lib/Transforms/IPO/Attributor.cpp | 26 | 
1 files changed, 20 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 1ae8ac77de0..3ecad8b03eb 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -1577,6 +1577,11 @@ struct AAIsDeadFunction : AAIsDead, BooleanState {        Instruction *SplitPos = I->getNextNode();        if (auto *II = dyn_cast<InvokeInst>(I)) { +        // If we keep the invoke the split position is at the beginning of the +        // normal desitination block (it invokes a noreturn function after all). +        BasicBlock *NormalDestBB = II->getNormalDest(); +        SplitPos = &NormalDestBB->front(); +          /// Invoke is replaced with a call and unreachable is placed after it if          /// the callee is nounwind and noreturn. Otherwise, we keep the invoke          /// and only place an unreachable in the normal successor. @@ -1587,17 +1592,26 @@ struct AAIsDeadFunction : AAIsDead, BooleanState {                  (AANoUnw && AANoUnw->isAssumedNoUnwind())) {                LLVM_DEBUG(dbgs()                           << "[AAIsDead] Replace invoke with call inst\n"); -              changeToCall(II); -              changeToUnreachable(BB->getTerminator(), /* UseLLVMTrap */ false); -              continue; +              // We do not need an invoke (II) but instead want a call followed +              // by an unreachable. However, we do not remove II as other +              // abstract attributes might have it cached as part of their +              // results. Given that we modify the CFG anyway, we simply keep II +              // around but in a new dead block. To avoid II being live through +              // a different edge we have to ensure the block we place it in is +              // only reached from the current block of II and then not reached +              // at all when we insert the unreachable. +              SplitBlockPredecessors(NormalDestBB, {BB}, ".i2c"); +              CallInst *CI = createCallMatchingInvoke(II); +              CI->insertBefore(II); +              CI->takeName(II); +              II->replaceAllUsesWith(CI); +              SplitPos = CI->getNextNode();              }            }          } - -        BB = II->getNormalDest(); -        SplitPos = &BB->front();        } +      BB = SplitPos->getParent();        SplitBlock(BB, SplitPos);        changeToUnreachable(BB->getTerminator(), /* UseLLVMTrap */ false);        HasChanged = ChangeStatus::CHANGED;  | 

