forked from OSchip/llvm-project
[SimplifyCFG] `markAliveBlocks()`: recognize that normal dest of `invoke`d `noreturn` function is `unreachable`
As per LangRef's definition of `noreturn` attribute: ``` noreturn This function attribute indicates that the function never returns normally, hence through a return instruction. This produces undefined behavior at runtime if the function ever does dynamically return. nnotated functions may still raise an exception, i.a., nounwind is not implied. ```
This commit is contained in:
parent
75c1d1dab4
commit
598833c987
|
@ -2349,19 +2349,32 @@ static bool markAliveBlocks(Function &F,
|
|||
isa<UndefValue>(Callee)) {
|
||||
changeToUnreachable(II, false, DTU);
|
||||
Changed = true;
|
||||
} else if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(&F)) {
|
||||
if (II->use_empty() && II->onlyReadsMemory()) {
|
||||
// jump to the normal destination branch.
|
||||
BasicBlock *NormalDestBB = II->getNormalDest();
|
||||
BasicBlock *UnwindDestBB = II->getUnwindDest();
|
||||
BranchInst::Create(NormalDestBB, II);
|
||||
UnwindDestBB->removePredecessor(II->getParent());
|
||||
II->eraseFromParent();
|
||||
if (DTU)
|
||||
DTU->applyUpdates({{DominatorTree::Delete, BB, UnwindDestBB}});
|
||||
} else
|
||||
changeToCall(II, DTU);
|
||||
Changed = true;
|
||||
} else {
|
||||
if (II->doesNotReturn()) {
|
||||
// If we found an invoke of a no-return function,
|
||||
// insert an unreachable instruction after it (on the normal dest).
|
||||
// Make sure there isn't *already* one there though.
|
||||
Instruction *FirstNormalInst = &II->getNormalDest()->front();
|
||||
if (!isa<UnreachableInst>(FirstNormalInst)) {
|
||||
// Don't insert a call to llvm.trap right before the unreachable.
|
||||
changeToUnreachable(FirstNormalInst, false, DTU);
|
||||
Changed = true;
|
||||
}
|
||||
}
|
||||
if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(&F)) {
|
||||
if (II->use_empty() && II->onlyReadsMemory()) {
|
||||
// jump to the normal destination branch.
|
||||
BasicBlock *NormalDestBB = II->getNormalDest();
|
||||
BasicBlock *UnwindDestBB = II->getUnwindDest();
|
||||
BranchInst::Create(NormalDestBB, II);
|
||||
UnwindDestBB->removePredecessor(II->getParent());
|
||||
II->eraseFromParent();
|
||||
if (DTU)
|
||||
DTU->applyUpdates({{DominatorTree::Delete, BB, UnwindDestBB}});
|
||||
} else
|
||||
changeToCall(II, DTU);
|
||||
Changed = true;
|
||||
}
|
||||
}
|
||||
} else if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(Terminator)) {
|
||||
// Remove catchpads which cannot be reached.
|
||||
|
|
|
@ -4,7 +4,7 @@ target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
|||
target triple = "x86_64-pc-windows-msvc"
|
||||
|
||||
declare i32 @__CxxFrameHandler3(...)
|
||||
declare void @throw() noreturn uwtable
|
||||
declare void @throw() uwtable
|
||||
declare i8* @getval()
|
||||
declare void @llvm.trap()
|
||||
|
||||
|
|
|
@ -198,8 +198,7 @@ define void @invoke_of_noreturn() personality i8* bitcast (i32 (...)* @__gxx_per
|
|||
; CHECK-NEXT: invoke void @simple_throw()
|
||||
; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
|
||||
; CHECK: invoke.cont:
|
||||
; CHECK-NEXT: call void @sideeffect(i32 0)
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK-NEXT: unreachable
|
||||
; CHECK: lpad:
|
||||
; CHECK-NEXT: [[EH:%.*]] = landingpad { i8*, i32 }
|
||||
; CHECK-NEXT: cleanup
|
||||
|
|
Loading…
Reference in New Issue