r255731 - Reland "[SEH] Use llvm.x86.seh.recoverfp for SEH filters on x64 as well as 32bit"

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 15 16:26:38 PST 2015


Author: rnk
Date: Tue Dec 15 18:26:37 2015
New Revision: 255731

URL: http://llvm.org/viewvc/llvm-project?rev=255731&view=rev
Log:
Reland "[SEH] Use llvm.x86.seh.recoverfp for SEH filters on x64 as well as 32bit"

I forgot to initialize RecoverFP.

Modified:
    cfe/trunk/lib/CodeGen/CGException.cpp
    cfe/trunk/test/CodeGen/exceptions-seh.c
    cfe/trunk/test/CodeGenCXX/exceptions-seh-filter-captures.cpp

Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=255731&r1=255730&r2=255731&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Tue Dec 15 18:26:37 2015
@@ -1493,8 +1493,9 @@ struct CaptureFinder : ConstStmtVisitor<
 };
 } // end anonymous namespace
 
-Address CodeGenFunction::recoverAddrOfEscapedLocal(
-    CodeGenFunction &ParentCGF, Address ParentVar, llvm::Value *ParentFP) {
+Address CodeGenFunction::recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF,
+                                                   Address ParentVar,
+                                                   llvm::Value *ParentFP) {
   llvm::CallInst *RecoverCall = nullptr;
   CGBuilderTy Builder(*this, AllocaInsertPt);
   if (auto *ParentAlloca = dyn_cast<llvm::AllocaInst>(ParentVar.getPointer())) {
@@ -1548,27 +1549,32 @@ void CodeGenFunction::EmitCapturedLocals
     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 = EntryFP;
+  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.
@@ -1592,8 +1598,8 @@ void CodeGenFunction::EmitCapturedLocals
       continue;
 
     Address ParentVar = I->second;
-    setAddrOfLocalVar(VD,
-                  recoverAddrOfEscapedLocal(ParentCGF, ParentVar, ParentFP));
+    setAddrOfLocalVar(
+        VD, recoverAddrOfEscapedLocal(ParentCGF, ParentVar, ParentFP));
   }
 
   if (Finder.SEHCodeSlot.isValid()) {
@@ -1602,7 +1608,7 @@ void CodeGenFunction::EmitCapturedLocals
   }
 
   if (IsFilter)
-    EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryEBP);
+    EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryFP);
 }
 
 /// Arrange a function prototype that can be called by Windows exception
@@ -1718,7 +1724,7 @@ CodeGenFunction::GenerateSEHFinallyFunct
 
 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 +1737,7 @@ void CodeGenFunction::EmitSEHExceptionCo
     // 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(

Modified: cfe/trunk/test/CodeGen/exceptions-seh.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh.c?rev=255731&r1=255730&r2=255731&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/exceptions-seh.c (original)
+++ cfe/trunk/test/CodeGen/exceptions-seh.c Tue Dec 15 18:26:37 2015
@@ -89,7 +89,8 @@ int filter_expr_capture(void) {
 // CHECK: ret i32 %[[rv]]
 
 // X64-LABEL: define internal i32 @"\01?filt$0 at 0@filter_expr_capture@@"(i8* %exception_pointers, i8* %frame_pointer)
-// X64: call i8* @llvm.localrecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %frame_pointer, i32 0)
+// 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)
 //
 // X86-LABEL: define internal i32 @"\01?filt$0 at 0@filter_expr_capture@@"()
 // X86: %[[ebp:[^ ]*]] = call i8* @llvm.frameaddress(i32 1)

Modified: cfe/trunk/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/exceptions-seh-filter-captures.cpp?rev=255731&r1=255730&r2=255731&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/exceptions-seh-filter-captures.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/exceptions-seh-filter-captures.cpp Tue Dec 15 18:26:37 2015
@@ -21,9 +21,10 @@ extern "C" void test_freefunc(int p1) {
 // CHECK: invoke void @might_crash()
 
 // CHECK-LABEL: define internal i32 @"\01?filt$0 at 0@test_freefunc@@"(i8* %exception_pointers, i8* %frame_pointer)
-// CHECK: %[[p1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer, i32 0)
+// 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_ptr:[^ ]*]] = bitcast i8* %[[p1_i8]] to i32*
-// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer, i32 1)
+// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %[[fp]], i32 1)
 // CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32*
 // CHECK: %[[s1:[^ ]*]] = load i32, i32* @"\01?s1@?1??test_freefunc@@9 at 4HA", align 4
 // CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]]
@@ -50,7 +51,8 @@ void S::test_method() {
 // CHECK: invoke void @might_crash()
 
 // CHECK-LABEL: define internal i32 @"\01?filt$0 at 0@test_method at S@@"(i8* %exception_pointers, i8* %frame_pointer)
-// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%struct.S*)* @"\01?test_method at S@@QEAAXXZ" to i8*), i8* %frame_pointer, i32 0)
+// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void (%struct.S*)* @"\01?test_method at S@@QEAAXXZ" to i8*), i8* %frame_pointer)
+// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%struct.S*)* @"\01?test_method at S@@QEAAXXZ" to i8*), i8* %[[fp]], 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]])
@@ -74,7 +76,8 @@ void test_lambda() {
 // CHECK: invoke void @might_crash()
 
 // CHECK-LABEL: define internal i32 @"\01?filt$0 at 0@?R<lambda_0>@?test_lambda@@YAXXZ@"(i8* %exception_pointers, i8* %frame_pointer)
-// CHECK: %[[l2_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon*)* @"\01??R<lambda_0>@?test_lambda@@YAXXZ at QEBAXXZ" to i8*), i8* %frame_pointer, i32 0)
+// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void (%class.anon*)* @"\01??R<lambda_0>@?test_lambda@@YAXXZ at QEBAXXZ" to i8*), i8* %frame_pointer)
+// CHECK: %[[l2_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon*)* @"\01??R<lambda_0>@?test_lambda@@YAXXZ at QEBAXXZ" to i8*), i8* %[[fp]], 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]])




More information about the cfe-commits mailing list