summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-10-13 22:08:17 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-10-13 22:08:17 +0000
commiteba62796cb9bb9e4856b4067a0d0117033cb3c1d (patch)
treeb5fa7004ad484f89e78ee39e04639aa41e5d6169
parentac93f649fa9449e56527ba8d3b10bf1c73d92af4 (diff)
downloadbcm5719-llvm-eba62796cb9bb9e4856b4067a0d0117033cb3c1d.tar.gz
bcm5719-llvm-eba62796cb9bb9e4856b4067a0d0117033cb3c1d.zip
[InlineFunction] Correctly inline TerminatePadInst
We forgot to append the terminatepad's arguments which resulted in us treating the old terminatepad as an argument to the new terminatepad causing us to crash immediately. Instead, add the old terminatepad's arguments to the new terminatepad. This fixes PR25155. llvm-svn: 250234
-rw-r--r--llvm/lib/Transforms/Utils/InlineFunction.cpp15
-rw-r--r--llvm/test/Transforms/Inline/PR25155.ll54
2 files changed, 64 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 9d45788d94b..5539a26b3f3 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -341,9 +341,10 @@ static void HandleInlinedEHPad(InvokeInst *II, BasicBlock *FirstNewBlock,
} else if (auto *TPI = dyn_cast<TerminatePadInst>(I)) {
if (TPI->unwindsToCaller()) {
SmallVector<Value *, 3> TerminatePadArgs;
- for (Value *Operand : TPI->operands())
- TerminatePadArgs.push_back(Operand);
- TerminatePadInst::Create(TPI->getContext(), UnwindDest, TPI);
+ for (Value *ArgOperand : TPI->arg_operands())
+ TerminatePadArgs.push_back(ArgOperand);
+ TerminatePadInst::Create(TPI->getContext(), UnwindDest,
+ TerminatePadArgs, TPI);
TPI->eraseFromParent();
UpdatePHINodes(&*BB);
}
@@ -1048,13 +1049,17 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
// Get the personality function from the callee if it contains a landing pad.
Constant *CalledPersonality =
- CalledFunc->hasPersonalityFn() ? CalledFunc->getPersonalityFn() : nullptr;
+ CalledFunc->hasPersonalityFn()
+ ? CalledFunc->getPersonalityFn()->stripPointerCasts()
+ : nullptr;
// Find the personality function used by the landing pads of the caller. If it
// exists, then check to see that it matches the personality function used in
// the callee.
Constant *CallerPersonality =
- Caller->hasPersonalityFn() ? Caller->getPersonalityFn() : nullptr;
+ Caller->hasPersonalityFn()
+ ? Caller->getPersonalityFn()->stripPointerCasts()
+ : nullptr;
if (CalledPersonality) {
if (!CallerPersonality)
Caller->setPersonalityFn(CalledPersonality);
diff --git a/llvm/test/Transforms/Inline/PR25155.ll b/llvm/test/Transforms/Inline/PR25155.ll
new file mode 100644
index 00000000000..f2a9ec32fda
--- /dev/null
+++ b/llvm/test/Transforms/Inline/PR25155.ll
@@ -0,0 +1,54 @@
+; RUN: opt < %s -inline -S | FileCheck %s
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc18.0.0"
+
+define void @f() personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+ invoke void @g()
+ to label %try.cont unwind label %catch.dispatch
+
+catch.dispatch: ; preds = %entry
+ %0 = catchpad [i8* null, i32 64, i8* null]
+ to label %catch unwind label %catchendblock
+
+catch: ; preds = %catch.dispatch
+ invoke void @dtor()
+ to label %invoke.cont.1 unwind label %catchendblock
+
+invoke.cont.1: ; preds = %catch
+ catchret %0 to label %try.cont
+
+try.cont: ; preds = %entry, %invoke.cont.1
+ ret void
+
+catchendblock: ; preds = %catch, %catch.dispatch
+ catchendpad unwind to caller
+}
+
+; CHECK-LABEL: define void @f(
+
+; CHECK: invoke void @g()
+; CHECK: to label %dtor.exit unwind label %terminate.i
+
+; CHECK: terminate.i:
+; CHECK-NEXT: terminatepad [void ()* @terminate] unwind label %catchendblock
+
+; CHECK: catchendblock:
+; CHECK-NEXT: catchendpad unwind to caller
+
+declare i32 @__CxxFrameHandler3(...)
+
+define internal void @dtor() personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+ invoke void @g()
+ to label %invoke.cont unwind label %terminate
+
+invoke.cont: ; preds = %entry
+ ret void
+
+terminate: ; preds = %entry
+ terminatepad [void ()* @terminate] unwind to caller
+}
+
+declare void @g()
+declare void @terminate()
OpenPOWER on IntegriCloud