return getOrEnforceKnownAlignment(V, 0, DL, CxtI, AC, DT);
}
+/// Create a call that matches the invoke \p II in terms of arguments,
+/// attributes, debug information, etc. The call is not placed in a block and it
+/// will not have a name. The invoke instruction is not removed, nor are the
+/// uses replaced by the new call.
+CallInst *createCallMatchingInvoke(InvokeInst *II);
+
/// This function converts the specified invoek into a normall call.
void changeToCall(InvokeInst *II, DomTreeUpdater *DTU = nullptr);
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.
(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;
return NumInstrsRemoved;
}
-/// changeToCall - Convert the specified invoke into a normal call.
-void llvm::changeToCall(InvokeInst *II, DomTreeUpdater *DTU) {
- SmallVector<Value*, 8> Args(II->arg_begin(), II->arg_end());
+CallInst *llvm::createCallMatchingInvoke(InvokeInst *II) {
+ SmallVector<Value *, 8> Args(II->arg_begin(), II->arg_end());
SmallVector<OperandBundleDef, 1> OpBundles;
II->getOperandBundlesAsDefs(OpBundles);
- CallInst *NewCall = CallInst::Create(
- II->getFunctionType(), II->getCalledValue(), Args, OpBundles, "", II);
- NewCall->takeName(II);
+ CallInst *NewCall = CallInst::Create(II->getFunctionType(),
+ II->getCalledValue(), Args, OpBundles);
NewCall->setCallingConv(II->getCallingConv());
NewCall->setAttributes(II->getAttributes());
NewCall->setDebugLoc(II->getDebugLoc());
NewCall->copyMetadata(*II);
+ return NewCall;
+}
+
+/// changeToCall - Convert the specified invoke into a normal call.
+void llvm::changeToCall(InvokeInst *II, DomTreeUpdater *DTU) {
+ CallInst *NewCall = createCallMatchingInvoke(II);
+ NewCall->takeName(II);
+ NewCall->insertBefore(II);
II->replaceAllUsesWith(NewCall);
// Follow the call by a branch to the normal destination.
call void @normal_call()
%call = invoke i32 @foo_noreturn_nounwind() to label %continue
unwind label %cleanup
- ; CHECK: call i32 @foo_noreturn_nounwind()
+ ; CHECK: call void @normal_call()
+ ; CHECK-NEXT: call i32 @foo_noreturn_nounwind()
; CHECK-NEXT: unreachable
+ ; We keep the invoke around as other attributes might have references to it.
+ ; CHECK: cond.true.split: ; No predecessors!
+ ; CHECK-NEXT: invoke i32 @foo_noreturn_nounwind()
+
cond.false: ; preds = %entry
call void @normal_call()
%call1 = call i32 @bar()