diff options
| author | John McCall <rjmccall@apple.com> | 2011-06-01 02:17:11 +0000 | 
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2011-06-01 02:17:11 +0000 | 
| commit | fca778626755d862b3a09a2473a76828d2c5aaa2 (patch) | |
| tree | 39bc32d64167f19582f59d124af5757a396fd179 | |
| parent | 48581a64547a14475cf3ba7c9ccc1f073d081e6e (diff) | |
| download | bcm5719-llvm-fca778626755d862b3a09a2473a76828d2c5aaa2.tar.gz bcm5719-llvm-fca778626755d862b3a09a2473a76828d2c5aaa2.zip  | |
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.
llvm-svn: 132382
| -rw-r--r-- | llvm/lib/Transforms/Utils/InlineFunction.cpp | 22 | ||||
| -rw-r--r-- | llvm/test/Transforms/Inline/inline_invoke.ll | 31 | 
2 files changed, 47 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index d2fd07aed10..4a829874832 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -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;  } diff --git a/llvm/test/Transforms/Inline/inline_invoke.ll b/llvm/test/Transforms/Inline/inline_invoke.ll index 110a82823e1..5f657387c21 100644 --- a/llvm/test/Transforms/Inline/inline_invoke.ll +++ b/llvm/test/Transforms/Inline/inline_invoke.ll @@ -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]]  | 

