mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-26 13:10:34 +00:00
First, do no harm -- even if we can't find a selector for an enclosing
landing pad, forward llvm.eh.resume calls to it instead of turning them invalidly into invokes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132382 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
edac4923dc
commit
1edbd6f3f0
@ -214,13 +214,24 @@ BasicBlock *InvokeInliningInfo::getInnerUnwindDest() {
|
||||
/// at the end of the given block, as a branch to the inner unwind
|
||||
/// block. Returns true if the call was forwarded.
|
||||
bool InvokeInliningInfo::forwardEHResume(CallInst *call, BasicBlock *src) {
|
||||
// First, check whether this is a call to the intrinsic.
|
||||
Function *fn = dyn_cast<Function>(call->getCalledValue());
|
||||
if (!fn || fn->getName() != "llvm.eh.resume")
|
||||
return false;
|
||||
|
||||
// At this point, we need to return true on all paths, because
|
||||
// otherwise we'll construct an invoke of the intrinsic, which is
|
||||
// not well-formed.
|
||||
|
||||
// If this fails, maybe it should be a fatal error.
|
||||
// Try to find or make an inner unwind dest, which will fail if we
|
||||
// can't find a selector call for the outer unwind dest.
|
||||
BasicBlock *dest = getInnerUnwindDest();
|
||||
if (!dest) return false;
|
||||
bool hasSelector = (dest != 0);
|
||||
|
||||
// If we failed, just use the outer unwind dest, dropping the
|
||||
// exception and selector on the floor.
|
||||
if (!hasSelector)
|
||||
dest = OuterUnwindDest;
|
||||
|
||||
// Make a branch.
|
||||
BranchInst::Create(dest, src);
|
||||
@ -228,8 +239,11 @@ bool InvokeInliningInfo::forwardEHResume(CallInst *call, BasicBlock *src) {
|
||||
// Update the phis in the destination. They were inserted in an
|
||||
// order which makes this work.
|
||||
addIncomingPHIValuesForInto(src, dest);
|
||||
InnerExceptionPHI->addIncoming(call->getArgOperand(0), src);
|
||||
InnerSelectorPHI->addIncoming(call->getArgOperand(1), src);
|
||||
|
||||
if (hasSelector) {
|
||||
InnerExceptionPHI->addIncoming(call->getArgOperand(0), src);
|
||||
InnerSelectorPHI->addIncoming(call->getArgOperand(1), src);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
; by appending selectors and forwarding _Unwind_Resume directly to the
|
||||
; enclosing landing pad.
|
||||
|
||||
;; Test 1 - basic functionality.
|
||||
;; Test 0 - basic functionality.
|
||||
|
||||
%struct.A = type { i8 }
|
||||
|
||||
@ -112,7 +112,7 @@ eh.resume:
|
||||
; CHECK-NEXT: call i32 @llvm.eh.typeid.for(
|
||||
|
||||
|
||||
;; Test 2 - Correctly handle phis in outer landing pads.
|
||||
;; Test 1 - Correctly handle phis in outer landing pads.
|
||||
|
||||
define void @test1_out() uwtable ssp {
|
||||
entry:
|
||||
@ -216,3 +216,30 @@ eh.resume:
|
||||
; CHECK: call void @use(i32 [[YJ1]])
|
||||
|
||||
; CHECK: call void @llvm.eh.resume(i8* [[EXNJ1]], i32 [[SELJ1]])
|
||||
|
||||
;; Test 2 - Don't make invalid IR for inlines into landing pads without eh.exception calls
|
||||
|
||||
define void @test2_out() uwtable ssp {
|
||||
entry:
|
||||
invoke void @test0_in()
|
||||
to label %ret unwind label %lpad
|
||||
|
||||
ret:
|
||||
ret void
|
||||
|
||||
lpad:
|
||||
call void @_ZSt9terminatev()
|
||||
unreachable
|
||||
}
|
||||
|
||||
; CHECK: define void @test2_out()
|
||||
; CHECK: [[A:%.*]] = alloca %struct.A,
|
||||
; CHECK: [[B:%.*]] = alloca %struct.A,
|
||||
; CHECK: invoke void @_ZN1AC1Ev(%struct.A* [[A]])
|
||||
; CHECK-NEXT: unwind label %[[LPAD:[^\s]+]]
|
||||
; CHECK: invoke void @_ZN1AC1Ev(%struct.A* [[B]])
|
||||
; CHECK-NEXT: unwind label %[[LPAD2:[^\s]+]]
|
||||
; CHECK: invoke void @_ZN1AD1Ev(%struct.A* [[B]])
|
||||
; CHECK-NEXT: unwind label %[[LPAD2]]
|
||||
; CHECK: invoke void @_ZN1AD1Ev(%struct.A* [[A]])
|
||||
; CHECK-NEXT: unwind label %[[LPAD]]
|
||||
|
Loading…
Reference in New Issue
Block a user