summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp12
-rw-r--r--llvm/lib/CodeGen/WinEHPrepare.cpp10
-rw-r--r--llvm/lib/IR/Verifier.cpp7
3 files changed, 28 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 6c14e7969c5..6a08fff09cd 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -5446,13 +5446,23 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
case Intrinsic::eh_begincatch:
case Intrinsic::eh_endcatch:
llvm_unreachable("begin/end catch intrinsics not lowered in codegen");
+ case Intrinsic::eh_parentframe: {
+ AllocaInst *Slot =
+ cast<AllocaInst>(I.getArgOperand(0)->stripPointerCasts());
+ assert(FuncInfo.StaticAllocaMap.count(Slot) &&
+ "can only use static allocas with llvm.eh.parentframe");
+ int FI = FuncInfo.StaticAllocaMap[Slot];
+ // TODO: Save this in the not-yet-existent WinEHFuncInfo struct.
+ (void)FI;
+ return nullptr;
+ }
case Intrinsic::eh_unwindhelp: {
AllocaInst *Slot =
cast<AllocaInst>(I.getArgOperand(0)->stripPointerCasts());
assert(FuncInfo.StaticAllocaMap.count(Slot) &&
"can only use static allocas with llvm.eh.unwindhelp");
int FI = FuncInfo.StaticAllocaMap[Slot];
- // TODO: Save this in the not-yet-existant WinEHFuncInfo struct.
+ // TODO: Save this in the not-yet-existent WinEHFuncInfo struct.
(void)FI;
return nullptr;
}
diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp
index ab0f96ef05f..3f9aaec366e 100644
--- a/llvm/lib/CodeGen/WinEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -695,6 +695,16 @@ bool WinEHPrepare::outlineHandler(ActionHandler *Action, Function *SrcFn,
if (!LPadMap.isInitialized())
LPadMap.mapLandingPad(LPad);
if (auto *CatchAction = dyn_cast<CatchHandler>(Action)) {
+ // Insert an alloca for the object which holds the address of the parent's
+ // frame pointer. The stack offset of this object needs to be encoded in
+ // xdata.
+ AllocaInst *ParentFrame = new AllocaInst(Int8PtrType, "parentframe", Entry);
+ Builder.CreateStore(&Handler->getArgumentList().back(), ParentFrame,
+ /*isStore=*/true);
+ Function *ParentFrameFn =
+ Intrinsic::getDeclaration(M, Intrinsic::eh_parentframe);
+ Builder.CreateCall(ParentFrameFn, ParentFrame);
+
Constant *Sel = CatchAction->getSelector();
Director.reset(new WinEHCatchDirector(Handler, Sel, VarInfo, LPadMap));
LPadMap.remapSelector(VMap, ConstantInt::get(Type::getInt32Ty(Context), 1));
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index fcf48c452e2..248d1279eaf 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2909,6 +2909,13 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
break;
}
+ case Intrinsic::eh_parentframe: {
+ auto *AI = dyn_cast<AllocaInst>(CI.getArgOperand(0)->stripPointerCasts());
+ Assert(AI && AI->isStaticAlloca(),
+ "llvm.eh.parentframe requires a static alloca", &CI);
+ break;
+ }
+
case Intrinsic::eh_unwindhelp: {
auto *AI = dyn_cast<AllocaInst>(CI.getArgOperand(0)->stripPointerCasts());
Assert(AI && AI->isStaticAlloca(),
OpenPOWER on IntegriCloud