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@H@Z"(%struct.A* %[[arg3]], i32 3) +// X86: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@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@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@H@Z"(%struct.A* %[[arg1]], i32 1) -// X86: invoke void @"\01?foo@@YAXUA@@00@Z"([[argmem_ty]]* inalloca %[[argmem]]) +// X86: call void @"\01?foo@@YAXUA@@00@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@Z" -// WIN32: call void @llvm.stackrestore(i8* %[[base]]) +// WIN32: call i32 @"\01?TakesTwo@@YAHUA@@0@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@XZ" +// WIN32: call x86_thiscallcc void @"\01??1A@@QAE@XZ" // WIN32-NOT: @"\01??1A@@QAE@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@XZ" +// WIN32: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" // WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" // // WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %[[arg1]]) @@ -54,10 +53,9 @@ int HasDeactivatedCleanups() { // WIN32: store i1 false, i1* %[[isactive]] // // WIN32: invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z"([[argmem_ty]]* inalloca %[[argmem]]) -// WIN32: call void @llvm.stackrestore // Destroy the two const ref temporaries. // WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ" -// WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ" +// WIN32: call x86_thiscallcc void @"\01??1A@@QAE@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@XZ"(%struct.A* %{{.*}}) +// WIN32: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %{{.*}}) // WIN32: store i1 true // WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %{{.*}}) -// WIN32: invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z" +// WIN32: call i32 @"\01?TakesTwo@@YAHUA@@0@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@XZ"({{.*}}) +// WIN32: call x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}}) // WIN32-NOT: invoke x86_thiscallcc void @"\01??1A@@QAE@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@XZ" +// WIN32: call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" // WIN32: store i1 true // WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" // WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@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@XZ" -// WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ" +// WIN32-NOT: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ" // WIN32: ret i32 // // Somewhere in the landing pad soup, we conditionally destroy arg1. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits