summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGException.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2015-12-15 23:47:40 +0000
committerReid Kleckner <rnk@google.com>2015-12-15 23:47:40 +0000
commitcf2626600cdece9ed17f0ec76bb506f01db78508 (patch)
tree6143bc5f334222c146effea45462a50f613c5ef1 /clang/lib/CodeGen/CGException.cpp
parent8f3118f4499cb7a6d086a1d55dac3fe1485ab7ce (diff)
downloadbcm5719-llvm-cf2626600cdece9ed17f0ec76bb506f01db78508.tar.gz
bcm5719-llvm-cf2626600cdece9ed17f0ec76bb506f01db78508.zip
[SEH] Use llvm.x86.seh.recoverfp for SEH filters on x64 as well as 32bit
llvm-svn: 255710
Diffstat (limited to 'clang/lib/CodeGen/CGException.cpp')
-rw-r--r--clang/lib/CodeGen/CGException.cpp35
1 files changed, 20 insertions, 15 deletions
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index a064e6246a7..bd95cdeff39 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -1548,27 +1548,32 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF,
return;
}
- llvm::Value *EntryEBP = nullptr;
- llvm::Value *ParentFP;
+ llvm::Value *EntryFP = nullptr;
+ CGBuilderTy Builder(CGM, AllocaInsertPt);
if (IsFilter && CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
// 32-bit SEH filters need to be careful about FP recovery. The end of the
// EH registration is passed in as the EBP physical register. We can
- // recover that with llvm.frameaddress(1), and adjust that to recover the
- // parent's true frame pointer.
- CGBuilderTy Builder(CGM, AllocaInsertPt);
- EntryEBP = Builder.CreateCall(
+ // recover that with llvm.frameaddress(1).
+ EntryFP = Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::frameaddress), {Builder.getInt32(1)});
- llvm::Function *RecoverFPIntrin =
- CGM.getIntrinsic(llvm::Intrinsic::x86_seh_recoverfp);
- llvm::Constant *ParentI8Fn =
- llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
- ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryEBP});
} else {
// Otherwise, for x64 and 32-bit finally functions, the parent FP is the
// second parameter.
auto AI = CurFn->arg_begin();
++AI;
- ParentFP = &*AI;
+ EntryFP = &*AI;
+ }
+
+ llvm::Value *ParentFP;
+ if (IsFilter) {
+ // Given whatever FP the runtime provided us in EntryFP, recover the true
+ // frame pointer of the parent function. We only need to do this in filters,
+ // since finally funclets recover the parent FP for us.
+ llvm::Function *RecoverFPIntrin =
+ CGM.getIntrinsic(llvm::Intrinsic::x86_seh_recoverfp);
+ llvm::Constant *ParentI8Fn =
+ llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
+ ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryFP});
}
// Create llvm.localrecover calls for all captures.
@@ -1602,7 +1607,7 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF,
}
if (IsFilter)
- EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryEBP);
+ EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryFP);
}
/// Arrange a function prototype that can be called by Windows exception
@@ -1718,7 +1723,7 @@ CodeGenFunction::GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF,
void CodeGenFunction::EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF,
llvm::Value *ParentFP,
- llvm::Value *EntryEBP) {
+ llvm::Value *EntryFP) {
// Get the pointer to the EXCEPTION_POINTERS struct. This is returned by the
// __exception_info intrinsic.
if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
@@ -1731,7 +1736,7 @@ void CodeGenFunction::EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF,
// exception registration object. It contains 6 32-bit fields, and the info
// pointer is stored in the second field. So, GEP 20 bytes backwards and
// load the pointer.
- SEHInfo = Builder.CreateConstInBoundsGEP1_32(Int8Ty, EntryEBP, -20);
+ SEHInfo = Builder.CreateConstInBoundsGEP1_32(Int8Ty, EntryFP, -20);
SEHInfo = Builder.CreateBitCast(SEHInfo, Int8PtrTy->getPointerTo());
SEHInfo = Builder.CreateAlignedLoad(Int8PtrTy, SEHInfo, getPointerAlign());
SEHCodeSlotStack.push_back(recoverAddrOfEscapedLocal(
OpenPOWER on IntegriCloud