r241199 - [SEH] Update EmitCapturedLocals to match r241187

Reid Kleckner reid at kleckner.net
Wed Jul 1 15:33:46 PDT 2015


Author: rnk
Date: Wed Jul  1 17:33:45 2015
New Revision: 241199

URL: http://llvm.org/viewvc/llvm-project?rev=241199&view=rev
Log:
[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.

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

Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=241199&r1=241198&r2=241199&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Wed Jul  1 17:33:45 2015
@@ -1447,15 +1447,11 @@ void CodeGenFunction::EmitCapturedLocals
 
   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
     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.

Modified: cfe/trunk/test/CodeGen/exceptions-seh.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh.c?rev=241199&r1=241198&r2=241199&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/exceptions-seh.c (original)
+++ cfe/trunk/test/CodeGen/exceptions-seh.c Wed Jul  1 17:33:45 2015
@@ -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 at 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 at 0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
 // CHECK: resume
 
-// CHECK: define internal void @"\01?fin$0 at 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 at 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);





More information about the cfe-commits mailing list