r249640 - Don't emit exceptional stackrestore cleanups around inalloca functions

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 7 17:17:46 PDT 2015


Author: rnk
Date: Wed Oct  7 19:17:45 2015
New Revision: 249640

URL: http://llvm.org/viewvc/llvm-project?rev=249640&view=rev
Log:
Don't emit exceptional stackrestore cleanups around inalloca functions

The backend restores the stack pointer after recovering from an
exception.  This is similar to r245879, but it doesn't try to use the
normal cleanup mechanism, so hopefully it won't cause the same breakage.

Modified:
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/lib/CodeGen/CGCall.h
    cfe/trunk/test/CodeGenCXX/microsoft-abi-arg-order.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=249640&r1=249639&r2=249640&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Wed Oct  7 19:17:45 2015
@@ -2752,25 +2752,12 @@ void CallArgList::allocateArgumentMemory
   // Save the stack.
   llvm::Function *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stacksave);
   StackBase = CGF.Builder.CreateCall(F, {}, "inalloca.save");
-
-  // Control gets really tied up in landing pads, so we have to spill the
-  // stacksave to an alloca to avoid violating SSA form.
-  // TODO: This is dead if we never emit the cleanup.  We should create the
-  // alloca and store lazily on the first cleanup emission.
-  StackBaseMem = CGF.CreateTempAlloca(CGF.Int8PtrTy, CGF.getPointerAlign(),
-                                      "inalloca.spmem");
-  CGF.Builder.CreateStore(StackBase, StackBaseMem);
-  CGF.pushStackRestore(EHCleanup, StackBaseMem);
-  StackCleanup = CGF.EHStack.getInnermostEHScope();
-  assert(StackCleanup.isValid());
 }
 
 void CallArgList::freeArgumentMemory(CodeGenFunction &CGF) const {
   if (StackBase) {
-    CGF.DeactivateCleanupBlock(StackCleanup, StackBase);
+    // Restore the stack after the call.
     llvm::Value *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
-    // We could load StackBase from StackBaseMem, but in the non-exceptional
-    // case we can skip it.
     CGF.Builder.CreateCall(F, StackBase);
   }
 }

Modified: cfe/trunk/lib/CodeGen/CGCall.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.h?rev=249640&r1=249639&r2=249640&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.h (original)
+++ cfe/trunk/lib/CodeGen/CGCall.h Wed Oct  7 19:17:45 2015
@@ -56,7 +56,7 @@ namespace CodeGen {
   class CallArgList :
     public SmallVector<CallArg, 16> {
   public:
-    CallArgList() : StackBase(nullptr), StackBaseMem(Address::invalid()) {}
+    CallArgList() : StackBase(nullptr) {}
 
     struct Writeback {
       /// The original argument.  Note that the argument l-value
@@ -134,9 +134,6 @@ namespace CodeGen {
     /// The stacksave call.  It dominates all of the argument evaluation.
     llvm::CallInst *StackBase;
 
-    /// The alloca holding the stackbase.  We need it to maintain SSA form.
-    Address StackBaseMem;
-
     /// The iterator pointing to the stack restore cleanup.  We manually run and
     /// deactivate this cleanup after the call in the unexceptional case because
     /// it doesn't run in the normal order.

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-arg-order.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-arg-order.cpp?rev=249640&r1=249639&r2=249640&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-arg-order.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-arg-order.cpp Wed Oct  7 19:17:45 2015
@@ -42,12 +42,12 @@ void call_foo() {
 // X86: call i8* @llvm.stacksave()
 // X86: %[[argmem:[^ ]*]] = alloca inalloca [[argmem_ty]]
 // X86: %[[arg3:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 2
-// X86: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE at H@Z"(%struct.A* %[[arg3]], i32 3)
+// X86: call x86_thiscallcc %struct.A* @"\01??0A@@QAE at H@Z"(%struct.A* %[[arg3]], i32 3)
 // X86: %[[arg2:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 1
 // X86: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE at H@Z"(%struct.A* %[[arg2]], i32 2)
 // X86: %[[arg1:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0
 // X86: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE at H@Z"(%struct.A* %[[arg1]], i32 1)
-// X86: invoke void @"\01?foo@@YAXUA@@00 at Z"([[argmem_ty]]* inalloca %[[argmem]])
+// X86: call void @"\01?foo@@YAXUA@@00 at Z"([[argmem_ty]]* inalloca %[[argmem]])
 // X86: call void @llvm.stackrestore
 // X86: ret void
 //

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp?rev=249640&r1=249639&r2=249640&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp Wed Oct  7 19:17:45 2015
@@ -17,18 +17,17 @@ void HasEHCleanup() {
 // WIN32-LABEL: define void @"\01?HasEHCleanup@@YAXXZ"() {{.*}} {
 // WIN32:   %[[base:.*]] = call i8* @llvm.stacksave()
 //    If this call throws, we have to restore the stack.
-// WIN32:   invoke void @"\01?getA@@YA?AUA@@XZ"(%struct.A* sret %{{.*}})
+// WIN32:   call void @"\01?getA@@YA?AUA@@XZ"(%struct.A* sret %{{.*}})
 //    If this call throws, we have to cleanup the first temporary.
 // WIN32:   invoke void @"\01?getA@@YA?AUA@@XZ"(%struct.A* sret %{{.*}})
 //    If this call throws, we have to cleanup the stacksave.
-// WIN32:   invoke i32 @"\01?TakesTwo@@YAHUA@@0 at Z"
-// WIN32:   call void @llvm.stackrestore(i8* %[[base]])
+// WIN32:   call i32 @"\01?TakesTwo@@YAHUA@@0 at Z"
+// WIN32:   call void @llvm.stackrestore
 // WIN32:   ret void
 //
 //    There should be one dtor call for unwinding from the second getA.
-// WIN32:   invoke x86_thiscallcc void @"\01??1A@@QAE at XZ"
+// WIN32:   call x86_thiscallcc void @"\01??1A@@QAE at XZ"
 // WIN32-NOT: @"\01??1A@@QAE at XZ"
-// WIN32:   call void @llvm.stackrestore
 // WIN32: }
 
 void TakeRef(const A &a);
@@ -41,7 +40,7 @@ int HasDeactivatedCleanups() {
 // WIN32:   call i8* @llvm.stacksave()
 // WIN32:   %[[argmem:.*]] = alloca inalloca [[argmem_ty:<{ %struct.A, %struct.A }>]]
 // WIN32:   %[[arg1:.*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 1
-// WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE at XZ"
+// WIN32:   call x86_thiscallcc %struct.A* @"\01??0A@@QAE at XZ"
 // WIN32:   invoke void @"\01?TakeRef@@YAXABUA@@@Z"
 //
 // WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE at XZ"(%struct.A* %[[arg1]])
@@ -54,10 +53,9 @@ int HasDeactivatedCleanups() {
 // WIN32:   store i1 false, i1* %[[isactive]]
 //
 // WIN32:   invoke i32 @"\01?TakesTwo@@YAHUA@@0 at Z"([[argmem_ty]]* inalloca %[[argmem]])
-// WIN32:   call void @llvm.stackrestore
 //        Destroy the two const ref temporaries.
 // WIN32:   invoke x86_thiscallcc void @"\01??1A@@QAE at XZ"
-// WIN32:   invoke x86_thiscallcc void @"\01??1A@@QAE at XZ"
+// WIN32:   call x86_thiscallcc void @"\01??1A@@QAE at XZ"
 // WIN32:   ret i32
 //
 //        Conditionally destroy arg1.
@@ -76,18 +74,18 @@ int HasConditionalCleanup(bool cond) {
 // WIN32:   store i1 false
 // WIN32:   br i1
 // WIN32:   call i8* @llvm.stacksave()
-// WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE at XZ"(%struct.A* %{{.*}})
+// WIN32:   call x86_thiscallcc %struct.A* @"\01??0A@@QAE at XZ"(%struct.A* %{{.*}})
 // WIN32:   store i1 true
 // WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE at XZ"(%struct.A* %{{.*}})
-// WIN32:   invoke i32 @"\01?TakesTwo@@YAHUA@@0 at Z"
+// WIN32:   call i32 @"\01?TakesTwo@@YAHUA@@0 at Z"
+//
 // WIN32:   call void @llvm.stackrestore
 //
 // WIN32:   call i32 @"\01?CouldThrow@@YAHXZ"()
 //
 //        Only one dtor in the invoke for arg1
-// WIN32:   invoke x86_thiscallcc void @"\01??1A@@QAE at XZ"({{.*}})
+// WIN32:   call x86_thiscallcc void @"\01??1A@@QAE at XZ"({{.*}})
 // WIN32-NOT: invoke x86_thiscallcc void @"\01??1A@@QAE at XZ"
-// WIN32:   call void @llvm.stackrestore
 // WIN32: }
 
 // Now test both.
@@ -105,7 +103,7 @@ int HasConditionalDeactivatedCleanups(bo
 // WIN32:   store i1 false
 // WIN32:   br i1
 //        True condition.
-// WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE at XZ"
+// WIN32:   call x86_thiscallcc %struct.A* @"\01??0A@@QAE at XZ"
 // WIN32:   store i1 true
 // WIN32:   invoke void @"\01?TakeRef@@YAXABUA@@@Z"
 // WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE at XZ"
@@ -121,7 +119,7 @@ int HasConditionalDeactivatedCleanups(bo
 // WIN32:   invoke i32 @"\01?CouldThrow@@YAHXZ"()
 //        Two normal cleanups for TakeRef args.
 // WIN32:   invoke x86_thiscallcc void @"\01??1A@@QAE at XZ"
-// WIN32:   invoke x86_thiscallcc void @"\01??1A@@QAE at XZ"
+// WIN32-NOT:   invoke x86_thiscallcc void @"\01??1A@@QAE at XZ"
 // WIN32:   ret i32
 //
 //        Somewhere in the landing pad soup, we conditionally destroy arg1.




More information about the cfe-commits mailing list