forked from OSchip/llvm-project
[SEH] Update EmitCapturedLocals to match r241187
It was still using frameaddress(1) to get the parent FP, even though it had the value it wanted as a parameter. llvm-svn: 241199
This commit is contained in:
parent
4897596728
commit
698310b004
|
@ -1447,15 +1447,11 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF,
|
|||
|
||||
llvm::Value *EntryEBP = nullptr;
|
||||
llvm::Value *ParentFP;
|
||||
if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
|
||||
// On x64, the parent FP is passed as the second argument.
|
||||
auto AI = CurFn->arg_begin();
|
||||
++AI;
|
||||
ParentFP = AI;
|
||||
} else {
|
||||
// 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.
|
||||
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(AllocaInsertPt);
|
||||
EntryEBP = Builder.CreateCall(
|
||||
CGM.getIntrinsic(llvm::Intrinsic::frameaddress), {Builder.getInt32(1)});
|
||||
|
@ -1464,11 +1460,12 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF,
|
|||
llvm::Constant *ParentI8Fn =
|
||||
llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
|
||||
ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryEBP});
|
||||
|
||||
// Inlining will break llvm.frameaddress(1), so disable it.
|
||||
// FIXME: We could teach the inliner about the special meaning of
|
||||
// frameaddress, framerecover, and frameescape to remove this limitation.
|
||||
CurFn->addFnAttr(llvm::Attribute::NoInline);
|
||||
} else {
|
||||
// Otherwise, for x64 and 32-bit finally functions, the parent FP is the
|
||||
// second parameter.
|
||||
auto AI = CurFn->arg_begin();
|
||||
++AI;
|
||||
ParentFP = AI;
|
||||
}
|
||||
|
||||
// Create llvm.framerecover calls for all captures.
|
||||
|
|
|
@ -168,21 +168,20 @@ int nested_try(void) {
|
|||
// CHECK: load i32, i32*
|
||||
// CHECK: icmp eq i32 %{{.*}}, 123
|
||||
|
||||
static unsigned g = 0;
|
||||
void basic_finally(void) {
|
||||
++g;
|
||||
int basic_finally(int g) {
|
||||
__try {
|
||||
j();
|
||||
} __finally {
|
||||
--g;
|
||||
++g;
|
||||
}
|
||||
return g;
|
||||
}
|
||||
// CHECK-LABEL: define void @basic_finally()
|
||||
// CHECK-LABEL: define i32 @basic_finally(i32 %g)
|
||||
// X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
|
||||
// X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
|
||||
// CHECK: load i32, i32* @g
|
||||
// CHECK: add i32 %{{.*}}, 1
|
||||
// CHECK: store i32 %{{.*}}, i32* @g
|
||||
// CHECK: %[[g_addr:[^ ]*]] = alloca i32, align 4
|
||||
// CHECK: call void (...) @llvm.frameescape(i32* %[[g_addr]])
|
||||
// CHECK: store i32 %g, i32* %[[g_addr]]
|
||||
//
|
||||
// CHECK: invoke void @j()
|
||||
// CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
|
||||
|
@ -190,7 +189,8 @@ void basic_finally(void) {
|
|||
// CHECK: [[cont]]
|
||||
// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
|
||||
// CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]])
|
||||
// CHECK: ret void
|
||||
// CHECK: load i32, i32* %[[g_addr]], align 4
|
||||
// CHECK: ret i32
|
||||
//
|
||||
// CHECK: [[lpad]]
|
||||
// CHECK: landingpad { i8*, i32 }
|
||||
|
@ -199,10 +199,11 @@ void basic_finally(void) {
|
|||
// CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
|
||||
// CHECK: resume
|
||||
|
||||
// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"({{.*}})
|
||||
// CHECK: load i32, i32* @g, align 4
|
||||
// CHECK: add i32 %{{.*}}, -1
|
||||
// CHECK: store i32 %{{.*}}, i32* @g, align 4
|
||||
// CHECK: define internal void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} %abnormal_termination, i8* %frame_pointer)
|
||||
// CHECK: call i8* @llvm.framerecover(i8* bitcast (i32 (i32)* @basic_finally to i8*), i8* %frame_pointer, i32 0)
|
||||
// CHECK: load i32, i32* %{{.*}}, align 4
|
||||
// CHECK: add nsw i32 %{{.*}}, 1
|
||||
// CHECK: store i32 %{{.*}}, i32* %{{.*}}, align 4
|
||||
// CHECK: ret void
|
||||
|
||||
int returns_int(void);
|
||||
|
|
Loading…
Reference in New Issue