From 2f485a10cdae37cc154692255892c7244fbf3fd4 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Wed, 16 Dec 2015 00:20:21 +0000 Subject: [PATCH] Revert "[SEH] Use llvm.x86.seh.recoverfp for SEH filters on x64 as well as 32bit" This reverts commit r255710. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@255728 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGException.cpp | 35 ++++++++----------- test/CodeGen/exceptions-seh.c | 3 +- .../exceptions-seh-filter-captures.cpp | 11 +++--- 3 files changed, 20 insertions(+), 29 deletions(-) diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index bd95cdeff3..a064e6246a 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -1548,32 +1548,27 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF, return; } - llvm::Value *EntryFP = nullptr; - CGBuilderTy Builder(CGM, AllocaInsertPt); + llvm::Value *EntryEBP = nullptr; + llvm::Value *ParentFP; 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). - EntryFP = Builder.CreateCall( + // recover that with llvm.frameaddress(1), and adjust that to recover the + // parent's true frame pointer. + CGBuilderTy Builder(CGM, AllocaInsertPt); + EntryEBP = 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; - 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}); + ParentFP = &*AI; } // Create llvm.localrecover calls for all captures. @@ -1607,7 +1602,7 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF, } if (IsFilter) - EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryFP); + EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryEBP); } /// Arrange a function prototype that can be called by Windows exception @@ -1723,7 +1718,7 @@ CodeGenFunction::GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF, void CodeGenFunction::EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF, llvm::Value *ParentFP, - llvm::Value *EntryFP) { + llvm::Value *EntryEBP) { // Get the pointer to the EXCEPTION_POINTERS struct. This is returned by the // __exception_info intrinsic. if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) { @@ -1736,7 +1731,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, EntryFP, -20); + SEHInfo = Builder.CreateConstInBoundsGEP1_32(Int8Ty, EntryEBP, -20); SEHInfo = Builder.CreateBitCast(SEHInfo, Int8PtrTy->getPointerTo()); SEHInfo = Builder.CreateAlignedLoad(Int8PtrTy, SEHInfo, getPointerAlign()); SEHCodeSlotStack.push_back(recoverAddrOfEscapedLocal( diff --git a/test/CodeGen/exceptions-seh.c b/test/CodeGen/exceptions-seh.c index b027bd844b..0829117fbe 100644 --- a/test/CodeGen/exceptions-seh.c +++ b/test/CodeGen/exceptions-seh.c @@ -89,8 +89,7 @@ int filter_expr_capture(void) { // CHECK: ret i32 %[[rv]] // X64-LABEL: define internal i32 @"\01?filt$0@0@filter_expr_capture@@"(i8* %exception_pointers, i8* %frame_pointer) -// X64: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %frame_pointer) -// X64: call i8* @llvm.localrecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[fp]], i32 0) +// X64: call i8* @llvm.localrecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %frame_pointer, i32 0) // // X86-LABEL: define internal i32 @"\01?filt$0@0@filter_expr_capture@@"() // X86: %[[ebp:[^ ]*]] = call i8* @llvm.frameaddress(i32 1) diff --git a/test/CodeGenCXX/exceptions-seh-filter-captures.cpp b/test/CodeGenCXX/exceptions-seh-filter-captures.cpp index 4e8be72089..26ef90f5a6 100644 --- a/test/CodeGenCXX/exceptions-seh-filter-captures.cpp +++ b/test/CodeGenCXX/exceptions-seh-filter-captures.cpp @@ -21,10 +21,9 @@ extern "C" void test_freefunc(int p1) { // CHECK: invoke void @might_crash() // CHECK-LABEL: define internal i32 @"\01?filt$0@0@test_freefunc@@"(i8* %exception_pointers, i8* %frame_pointer) -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer) -// CHECK: %[[p1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %[[fp]], i32 0) +// CHECK: %[[p1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer, i32 0) // CHECK: %[[p1_ptr:[^ ]*]] = bitcast i8* %[[p1_i8]] to i32* -// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %[[fp]], i32 1) +// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer, i32 1) // CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32* // CHECK: %[[s1:[^ ]*]] = load i32, i32* @"\01?s1@?1??test_freefunc@@9@4HA", align 4 // CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]] @@ -51,8 +50,7 @@ void S::test_method() { // CHECK: invoke void @might_crash() // CHECK-LABEL: define internal i32 @"\01?filt$0@0@test_method@S@@"(i8* %exception_pointers, i8* %frame_pointer) -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void (%struct.S*)* @"\01?test_method@S@@QEAAXXZ" to i8*), i8* %frame_pointer) -// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%struct.S*)* @"\01?test_method@S@@QEAAXXZ" to i8*), i8* %[[fp]], i32 0) +// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%struct.S*)* @"\01?test_method@S@@QEAAXXZ" to i8*), i8* %frame_pointer, i32 0) // CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32* // CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]] // CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l1]]) @@ -76,8 +74,7 @@ void test_lambda() { // CHECK: invoke void @might_crash() // CHECK-LABEL: define internal i32 @"\01?filt$0@0@?R@?test_lambda@@YAXXZ@"(i8* %exception_pointers, i8* %frame_pointer) -// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void (%class.anon*)* @"\01??R@?test_lambda@@YAXXZ@QEBAXXZ" to i8*), i8* %frame_pointer) -// CHECK: %[[l2_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon*)* @"\01??R@?test_lambda@@YAXXZ@QEBAXXZ" to i8*), i8* %[[fp]], i32 0) +// CHECK: %[[l2_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon*)* @"\01??R@?test_lambda@@YAXXZ@QEBAXXZ" to i8*), i8* %frame_pointer, i32 0) // CHECK: %[[l2_ptr:[^ ]*]] = bitcast i8* %[[l2_i8]] to i32* // CHECK: %[[l2:[^ ]*]] = load i32, i32* %[[l2_ptr]] // CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l2]]) -- 2.40.0