<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 14 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-reply;
font-family:"Calibri","sans-serif";
color:#1F497D;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri","sans-serif";
mso-fareast-language:EN-US;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-GB link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Hi Nico,<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Thanks for letting me know. I’ll be at EuroLLVM Monday/Tuesday, but I would be very happy to investigate your repro after the event.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Cheers,<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Arnaud<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><b><span lang=EN-US style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>From:</span></b><span lang=EN-US style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> thakis@google.com [mailto:thakis@google.com] <b>On Behalf Of </b>Nico Weber<br><b>Sent:</b> 12 April 2015 01:56<br><b>To:</b> Arnaud De Grandmaison<br><b>Cc:</b> cfe-commits@cs.uiuc.edu<br><b>Subject:</b> Re: r234581 - Remove threshold for inserting lifetime markers for named temporaries<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><o:p> </o:p></p><div><p class=MsoNormal style='margin-left:36.0pt'>Hi Arnaud,<o:p></o:p></p><div><p class=MsoNormal style='margin-left:36.0pt'><o:p> </o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'>a few Chromium tests started failing after this commit (<a href="http://crbug.com/476316">http://crbug.com/476316</a>). I speculatively reverted this in r234700 – if it helps with our test failures, I'll get you a repro on Monday, else I'll reland your change.<o:p></o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'><o:p> </o:p></p></div><div><p class=MsoNormal style='margin-left:36.0pt'>Nico<o:p></o:p></p></div></div><div><p class=MsoNormal style='margin-left:36.0pt'><o:p> </o:p></p><div><p class=MsoNormal style='margin-left:36.0pt'>On Fri, Apr 10, 2015 at 3:13 AM, Arnaud A. de Grandmaison <<a href="mailto:arnaud.degrandmaison@arm.com" target="_blank">arnaud.degrandmaison@arm.com</a>> wrote:<o:p></o:p></p><p class=MsoNormal style='margin-left:36.0pt'>Author: aadg<br>Date: Fri Apr 10 05:13:52 2015<br>New Revision: 234581<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=234581&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=234581&view=rev</a><br>Log:<br>Remove threshold for inserting lifetime markers for named temporaries<br><br>Now that TailRecursionElimination has been fixed with r222354, the<br>threshold on size for lifetime marker insertion can be removed. This<br>only affects named temporary though, as the patch for unnamed temporaries<br>is still in progress.<br><br>My previous commit (r222993) was not handling debuginfo correctly, but<br>this could only be seen with some asan tests. Basically, lifetime markers<br>are just instrumentation for the compiler's usage and should not affect<br>debug information; however, the cleanup infrastructure was assuming it<br>contained only destructors, i.e. actual code to be executed, and was<br>setting the breakpoint for the end of the function to the closing '}', and<br>not the return statement, in order to show some destructors have been<br>called when leaving the function. This is wrong when the cleanups are only<br>lifetime markers, and this is now fixed.<br><br>Added:<br> cfe/trunk/test/CodeGen/cleanup-destslot-simple.c<br> cfe/trunk/test/CodeGen/lifetime-debuginfo-1.c<br> cfe/trunk/test/CodeGen/lifetime-debuginfo-2.c<br>Modified:<br> cfe/trunk/lib/CodeGen/CGCall.cpp<br> cfe/trunk/lib/CodeGen/CGCleanup.cpp<br> cfe/trunk/lib/CodeGen/CGCleanup.h<br> cfe/trunk/lib/CodeGen/CGDecl.cpp<br> cfe/trunk/lib/CodeGen/CodeGenFunction.cpp<br> cfe/trunk/lib/CodeGen/CodeGenFunction.h<br> cfe/trunk/lib/CodeGen/EHScopeStack.h<br> cfe/trunk/test/CodeGenCXX/destructors.cpp<br> cfe/trunk/test/CodeGenCXX/nrvo.cpp<br> cfe/trunk/test/CodeGenObjC/arc-blocks.m<br> cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m<br> cfe/trunk/test/CodeGenObjC/arc-literals.m<br> cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m<br> cfe/trunk/test/CodeGenObjC/arc-ternary-op.m<br> cfe/trunk/test/CodeGenObjC/arc.m<br> cfe/trunk/test/CodeGenObjC/exceptions.m<br> cfe/trunk/test/CodeGenObjCXX/<a href="http://arc-move.mm" target="_blank">arc-move.mm</a><br> cfe/trunk/test/CodeGenObjCXX/<a href="http://arc-references.mm" target="_blank">arc-references.mm</a><br> cfe/trunk/test/CodeGenObjCXX/<a href="http://arc.mm" target="_blank">arc.mm</a><br> cfe/trunk/test/CodeGenObjCXX/<a href="http://literals.mm" target="_blank">literals.mm</a><br><br>Modified: cfe/trunk/lib/CodeGen/CGCall.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)<br>+++ cfe/trunk/lib/CodeGen/CGCall.cpp Fri Apr 10 05:13:52 2015<br>@@ -30,6 +30,7 @@<br> #include "llvm/IR/DataLayout.h"<br> #include "llvm/IR/InlineAsm.h"<br> #include "llvm/IR/Intrinsics.h"<br>+#include "llvm/IR/IntrinsicInst.h"<br> #include "llvm/Transforms/Utils/Local.h"<br> #include <sstream><br> using namespace clang;<br>@@ -2216,7 +2217,29 @@ static llvm::StoreInst *findDominatingSt<br> if (!CGF.ReturnValue->hasOneUse()) {<br> llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock();<br> if (IP->empty()) return nullptr;<br>- llvm::StoreInst *store = dyn_cast<llvm::StoreInst>(&IP->back());<br>+ llvm::Instruction *I = &IP->back();<br>+<br>+ // Skip lifetime markers<br>+ for (llvm::BasicBlock::reverse_iterator II = IP->rbegin(),<br>+ IE = IP->rend();<br>+ II != IE; ++II) {<br>+ if (llvm::IntrinsicInst *Intrinsic =<br>+ dyn_cast<llvm::IntrinsicInst>(&*II)) {<br>+ if (Intrinsic->getIntrinsicID() == llvm::Intrinsic::lifetime_end) {<br>+ const llvm::Value *CastAddr = Intrinsic->getArgOperand(1);<br>+ ++II;<br>+ if (isa<llvm::BitCastInst>(&*II)) {<br>+ if (CastAddr == &*II) {<br>+ continue;<br>+ }<br>+ }<br>+ }<br>+ }<br>+ I = &*II;<br>+ break;<br>+ }<br>+<br>+ llvm::StoreInst *store = dyn_cast<llvm::StoreInst>(I);<br> if (!store) return nullptr;<br> if (store->getPointerOperand() != CGF.ReturnValue) return nullptr;<br> assert(!store->isAtomic() && !store->isVolatile()); // see below<br>@@ -2314,7 +2337,8 @@ void CodeGenFunction::EmitFunctionEpilog<br><br> // If there is a dominating store to ReturnValue, we can elide<br> // the load, zap the store, and usually zap the alloca.<br>- if (llvm::StoreInst *SI = findDominatingStoreToReturnValue(*this)) {<br>+ if (llvm::StoreInst *SI =<br>+ findDominatingStoreToReturnValue(*this)) {<br> // Reuse the debug location from the store unless there is<br> // cleanup code to be emitted between the store and return<br> // instruction.<br><br>Modified: cfe/trunk/lib/CodeGen/CGCleanup.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCleanup.cpp?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCleanup.cpp?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CGCleanup.cpp (original)<br>+++ cfe/trunk/lib/CodeGen/CGCleanup.cpp Fri Apr 10 05:13:52 2015<br>@@ -125,6 +125,17 @@ char *EHScopeStack::allocate(size_t Size<br> return StartOfData;<br> }<br><br>+bool EHScopeStack::containsOnlyLifetimeMarkers(<br>+ EHScopeStack::stable_iterator Old) const {<br>+ for (EHScopeStack::iterator it = begin(); stabilize(it) != Old; it++) {<br>+ EHCleanupScope *cleanup = dyn_cast<EHCleanupScope>(&*it);<br>+ if (!cleanup || !cleanup->isLifetimeMarker())<br>+ return false;<br>+ }<br>+<br>+ return true;<br>+}<br>+<br> EHScopeStack::stable_iterator<br> EHScopeStack::getInnermostActiveNormalCleanup() const {<br> for (stable_iterator si = getInnermostNormalCleanup(), se = stable_end();<br>@@ -748,7 +759,15 @@ void CodeGenFunction::PopCleanupBlock(bo<br> Scope.getNumBranchAfters() == 1) {<br> assert(!BranchThroughDest || !IsActive);<br><br>- // TODO: clean up the possibly dead stores to the cleanup dest slot.<br>+ // Clean up the possibly dead store to the cleanup dest slot.<br>+ llvm::Instruction *NormalCleanupDestSlot =<br>+ cast<llvm::Instruction>(getNormalCleanupDestSlot());<br>+ if (NormalCleanupDestSlot->hasOneUse()) {<br>+ NormalCleanupDestSlot->user_back()->eraseFromParent();<br>+ NormalCleanupDestSlot->eraseFromParent();<br>+ NormalCleanupDest = nullptr;<br>+ }<br>+<br> llvm::BasicBlock *BranchAfter = Scope.getBranchAfterBlock(0);<br> InstsToAppend.push_back(llvm::BranchInst::Create(BranchAfter));<br><br><br>Modified: cfe/trunk/lib/CodeGen/CGCleanup.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCleanup.h?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCleanup.h?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CGCleanup.h (original)<br>+++ cfe/trunk/lib/CodeGen/CGCleanup.h Fri Apr 10 05:13:52 2015<br>@@ -62,6 +62,9 @@ protected:<br> /// Whether this cleanup is currently active.<br> unsigned IsActive : 1;<br><br>+ /// Whether this cleanup is a lifetime marker<br>+ unsigned IsLifetimeMarker : 1;<br>+<br> /// Whether the normal cleanup should test the activation flag.<br> unsigned TestFlagInNormalCleanup : 1;<br><br>@@ -75,7 +78,7 @@ protected:<br> /// The number of fixups required by enclosing scopes (not including<br> /// this one). If this is the top cleanup scope, all the fixups<br> /// from this index onwards belong to this scope.<br>- unsigned FixupDepth : 32 - 17 - NumCommonBits; // currently 13<br>+ unsigned FixupDepth : 32 - 18 - NumCommonBits; // currently 13<br> };<br><br> class FilterBitFields {<br>@@ -272,6 +275,7 @@ public:<br> CleanupBits.IsNormalCleanup = isNormal;<br> CleanupBits.IsEHCleanup = isEH;<br> CleanupBits.IsActive = isActive;<br>+ CleanupBits.IsLifetimeMarker = false;<br> CleanupBits.TestFlagInNormalCleanup = false;<br> CleanupBits.TestFlagInEHCleanup = false;<br> CleanupBits.CleanupSize = cleanupSize;<br>@@ -295,6 +299,9 @@ public:<br> bool isActive() const { return CleanupBits.IsActive; }<br> void setActive(bool A) { CleanupBits.IsActive = A; }<br><br>+ bool isLifetimeMarker() const { return CleanupBits.IsLifetimeMarker; }<br>+ void setLifetimeMarker() { CleanupBits.IsLifetimeMarker = true; }<br>+<br> llvm::AllocaInst *getActiveFlag() const { return ActiveFlag; }<br> void setActiveFlag(llvm::AllocaInst *Var) { ActiveFlag = Var; }<br><br><br>Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)<br>+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Fri Apr 10 05:13:52 2015<br>@@ -12,6 +12,7 @@<br> //===----------------------------------------------------------------------===//<br><br> #include "CodeGenFunction.h"<br>+#include "CGCleanup.h"<br> #include "CGDebugInfo.h"<br> #include "CGOpenCLRuntime.h"<br> #include "CodeGenModule.h"<br>@@ -516,10 +517,7 @@ namespace {<br> : Addr(addr), Size(size) {}<br><br> void Emit(CodeGenFunction &CGF, Flags flags) override {<br>- llvm::Value *castAddr = CGF.Builder.CreateBitCast(Addr, CGF.Int8PtrTy);<br>- CGF.Builder.CreateCall2(CGF.CGM.getLLVMLifetimeEndFn(),<br>- Size, castAddr)<br>- ->setDoesNotThrow();<br>+ CGF.EmitLifetimeEnd(Size, Addr);<br> }<br> };<br> }<br>@@ -840,21 +838,6 @@ static bool shouldUseMemSetPlusStoresToI<br> canEmitInitWithFewStoresAfterMemset(Init, StoreBudget);<br> }<br><br>-/// Should we use the LLVM lifetime intrinsics for the given local variable?<br>-static bool shouldUseLifetimeMarkers(CodeGenFunction &CGF, const VarDecl &D,<br>- unsigned Size) {<br>- // For now, only in optimized builds.<br>- if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0)<br>- return false;<br>-<br>- // Limit the size of marked objects to 32 bytes. We don't want to increase<br>- // compile time by marking tiny objects.<br>- unsigned SizeThreshold = 32;<br>-<br>- return Size > SizeThreshold;<br>-}<br>-<br>-<br> /// EmitAutoVarDecl - Emit code and set up an entry in LocalDeclMap for a<br> /// variable declaration with auto, register, or no storage class specifier.<br> /// These turn into simple stack objects, or GlobalValues depending on target.<br>@@ -864,6 +847,33 @@ void CodeGenFunction::EmitAutoVarDecl(co<br> EmitAutoVarCleanups(emission);<br> }<br><br>+/// Emit a lifetime.begin marker if some criteria are satisfied.<br>+/// \return a pointer to the temporary size Value if a marker was emitted, null<br>+/// otherwise<br>+llvm::Value *CodeGenFunction::EmitLifetimeStart(uint64_t Size,<br>+ llvm::Value *Addr) {<br>+ // For now, only in optimized builds.<br>+ if (CGM.getCodeGenOpts().OptimizationLevel == 0)<br>+ return nullptr;<br>+<br>+ llvm::Value *SizeV = llvm::ConstantInt::get(Int64Ty, Size);<br>+ llvm::Value *Args[] = {<br>+ SizeV,<br>+ new llvm::BitCastInst(Addr, Int8PtrTy, "", Builder.GetInsertBlock())};<br>+ llvm::CallInst *C = llvm::CallInst::Create(CGM.getLLVMLifetimeStartFn(), Args,<br>+ "", Builder.GetInsertBlock());<br>+ C->setDoesNotThrow();<br>+ return SizeV;<br>+}<br>+<br>+void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {<br>+ llvm::Value *Args[] = {Size, new llvm::BitCastInst(Addr, Int8PtrTy, "",<br>+ Builder.GetInsertBlock())};<br>+ llvm::CallInst *C = llvm::CallInst::Create(CGM.getLLVMLifetimeEndFn(), Args,<br>+ "", Builder.GetInsertBlock());<br>+ C->setDoesNotThrow();<br>+}<br>+<br> /// EmitAutoVarAlloca - Emit the alloca and debug information for a<br> /// local variable. Does not emit initialization or destruction.<br> CodeGenFunction::AutoVarEmission<br>@@ -959,13 +969,8 @@ CodeGenFunction::EmitAutoVarAlloca(const<br> // Emit a lifetime intrinsic if meaningful. There's no point<br> // in doing this if we don't have a valid insertion point (?).<br> uint64_t size = CGM.getDataLayout().getTypeAllocSize(LTy);<br>- if (HaveInsertPoint() && shouldUseLifetimeMarkers(*this, D, size)) {<br>- llvm::Value *sizeV = llvm::ConstantInt::get(Int64Ty, size);<br>-<br>- emission.SizeForLifetimeMarkers = sizeV;<br>- llvm::Value *castAddr = Builder.CreateBitCast(Alloc, Int8PtrTy);<br>- Builder.CreateCall2(CGM.getLLVMLifetimeStartFn(), sizeV, castAddr)<br>- ->setDoesNotThrow();<br>+ if (HaveInsertPoint()) {<br>+ emission.SizeForLifetimeMarkers = EmitLifetimeStart(size, Alloc);<br> } else {<br> assert(!emission.useLifetimeMarkers());<br> }<br>@@ -1311,6 +1316,8 @@ void CodeGenFunction::EmitAutoVarCleanup<br> EHStack.pushCleanup<CallLifetimeEnd>(NormalCleanup,<br> emission.getAllocatedAddress(),<br> emission.getSizeForLifetimeMarkers());<br>+ EHCleanupScope &cleanup = cast<EHCleanupScope>(*EHStack.begin());<br>+ cleanup.setLifetimeMarker();<br> }<br><br> // Check the type for a cleanup.<br><br>Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)<br>+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Fri Apr 10 05:13:52 2015<br>@@ -12,6 +12,7 @@<br> //===----------------------------------------------------------------------===//<br><br> #include "CodeGenFunction.h"<br>+#include "CGCleanup.h"<br> #include "CGCUDARuntime.h"<br> #include "CGCXXABI.h"<br> #include "CGDebugInfo.h"<br>@@ -243,12 +244,13 @@ void CodeGenFunction::FinishFunction(Sou<br> // parameters. Do this in whatever block we're currently in; it's<br> // important to do this before we enter the return block or return<br> // edges will be *really* confused.<br>- bool EmitRetDbgLoc = true;<br>- if (EHStack.stable_begin() != PrologueCleanupDepth) {<br>+ bool HasCleanups = EHStack.stable_begin() != PrologueCleanupDepth;<br>+ bool HasOnlyLifetimeMarkers =<br>+ HasCleanups && EHStack.containsOnlyLifetimeMarkers(PrologueCleanupDepth);<br>+ bool EmitRetDbgLoc = !HasCleanups || HasOnlyLifetimeMarkers;<br>+ if (HasCleanups) {<br> // Make sure the line table doesn't jump back into the body for<br> // the ret after it's been at EndLoc.<br>- EmitRetDbgLoc = false;<br>-<br> if (CGDebugInfo *DI = getDebugInfo())<br> if (OnlySimpleReturnStmts)<br> DI->EmitLocation(Builder, EndLoc);<br><br>Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)<br>+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Apr 10 05:13:52 2015<br>@@ -1741,6 +1741,9 @@ public:<br> void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType,<br> llvm::Value *Ptr);<br><br>+ llvm::Value *EmitLifetimeStart(uint64_t Size, llvm::Value *Addr);<br>+ void EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr);<br>+<br> llvm::Value *EmitCXXNewExpr(const CXXNewExpr *E);<br> void EmitCXXDeleteExpr(const CXXDeleteExpr *E);<br><br><br>Modified: cfe/trunk/lib/CodeGen/EHScopeStack.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/EHScopeStack.h?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/EHScopeStack.h?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/CodeGen/EHScopeStack.h (original)<br>+++ cfe/trunk/lib/CodeGen/EHScopeStack.h Fri Apr 10 05:13:52 2015<br>@@ -319,6 +319,10 @@ public:<br> /// Pops a terminate handler off the stack.<br> void popTerminate();<br><br>+ // Returns true iff the current scope is either empty or contains only<br>+ // lifetime markers, i.e. no real cleanup code<br>+ bool containsOnlyLifetimeMarkers(stable_iterator Old) const;<br>+<br> /// Determines whether the exception-scopes stack is empty.<br> bool empty() const { return StartOfData == EndOfBuffer; }<br><br><br>Added: cfe/trunk/test/CodeGen/cleanup-destslot-simple.c<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/cleanup-destslot-simple.c?rev=234581&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/cleanup-destslot-simple.c?rev=234581&view=auto</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGen/cleanup-destslot-simple.c (added)<br>+++ cfe/trunk/test/CodeGen/cleanup-destslot-simple.c Fri Apr 10 05:13:52 2015<br>@@ -0,0 +1,15 @@<br>+// RUN: %clang_cc1 -O1 -triple x86_64-none-linux-gnu -emit-llvm -gline-tables-only %s -o - | FileCheck %s<br>+<br>+// There is no exception to handle here, lifetime.end is not a destructor,<br>+// so there is no need have cleanup dest slot related code<br>+// CHECK-LABEL: define i32 @test<br>+int test() {<br>+ int x = 3;<br>+ int *volatile p = &x;<br>+ return *p;<br>+// CHECK: [[X:%.*]] = alloca i32<br>+// CHECK: [[P:%.*]] = alloca i32*<br>+// CHECK: call void @llvm.lifetime.start(i64 4, i8* %{{.*}})<br>+// CHECK: call void @llvm.lifetime.start(i64 8, i8* %{{.*}})<br>+// CHECK-NOT: store i32 %{{.*}}, i32* %cleanup.dest.slot<br>+}<br><br>Added: cfe/trunk/test/CodeGen/lifetime-debuginfo-1.c<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/lifetime-debuginfo-1.c?rev=234581&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/lifetime-debuginfo-1.c?rev=234581&view=auto</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGen/lifetime-debuginfo-1.c (added)<br>+++ cfe/trunk/test/CodeGen/lifetime-debuginfo-1.c Fri Apr 10 05:13:52 2015<br>@@ -0,0 +1,13 @@<br>+// RUN: %clang_cc1 -O1 -triple x86_64-none-linux-gnu -emit-llvm -gline-tables-only %s -o - | FileCheck %s<br>+<br>+// Inserting lifetime markers should not affect debuginfo<br>+<br>+extern int x;<br>+<br>+// CHECK-LABEL: define i32 @f<br>+int f() {<br>+ int *p = &x;<br>+// CHECK: ret i32 %{{.*}}, !dbg [[DI:![0-9]*]]<br>+// CHECK: [[DI]] = !MDLocation(line: [[@LINE+1]]<br>+ return *p;<br>+}<br><br>Added: cfe/trunk/test/CodeGen/lifetime-debuginfo-2.c<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/lifetime-debuginfo-2.c?rev=234581&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/lifetime-debuginfo-2.c?rev=234581&view=auto</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGen/lifetime-debuginfo-2.c (added)<br>+++ cfe/trunk/test/CodeGen/lifetime-debuginfo-2.c Fri Apr 10 05:13:52 2015<br>@@ -0,0 +1,29 @@<br>+// RUN: %clang_cc1 -O1 -triple x86_64-none-linux-gnu -emit-llvm -gline-tables-only %s -o - | FileCheck %s<br>+<br>+// Inserting lifetime markers should not affect debuginfo: lifetime.end is not<br>+// a destructor, but instrumentation for the compiler. Ensure the debug info for<br>+// the return statement (in the IR) does not point to the function closing '}'<br>+// which is used to show some destructors have been called before leaving the<br>+// function.<br>+<br>+extern int f(int);<br>+extern int g(int);<br>+<br>+// CHECK-LABEL: define i32 @test<br>+int test(int a, int b) {<br>+ int res;<br>+<br>+ if (a==2) {<br>+ int r = f(b);<br>+ res = r + b;<br>+ a += 2;<br>+ } else {<br>+ int r = f(a);<br>+ res = r + a;<br>+ b += 1;<br>+ }<br>+<br>+ return res;<br>+// CHECK: ret i32 %{{.*}}, !dbg [[DI:![0-9]+]]<br>+// CHECK: [[DI]] = !MDLocation(line: [[@LINE-2]]<br>+}<br><br>Modified: cfe/trunk/test/CodeGenCXX/destructors.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/destructors.cpp?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/destructors.cpp?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenCXX/destructors.cpp (original)<br>+++ cfe/trunk/test/CodeGenCXX/destructors.cpp Fri Apr 10 05:13:52 2015<br>@@ -279,6 +279,8 @@ namespace test5 {<br> // CHECK5: [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align<br> // CHECK5-NEXT: [[EXN:%.*]] = alloca i8*<br> // CHECK5-NEXT: [[SEL:%.*]] = alloca i32<br>+ // CHECK5-NEXT: [[PELEMS:%.*]] = bitcast [5 x [[A]]]* [[ELEMS]] to i8*<br>+ // CHECK5-NEXT: call void @llvm.lifetime.start(i64 5, i8* [[PELEMS]])<br> // CHECK5-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x [[A]]], [5 x [[A]]]* [[ELEMS]], i32 0, i32 0<br> // CHECK5-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 5<br> // CHECK5-NEXT: br label<br>@@ -287,7 +289,8 @@ namespace test5 {<br> // CHECK5-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[ELT]])<br> // CHECK5: [[T0:%.*]] = icmp eq [[A]]* [[ELT]], [[BEGIN]]<br> // CHECK5-NEXT: br i1 [[T0]],<br>- // CHECK5: ret void<br>+ // CHECK5: call void @llvm.lifetime.end<br>+ // CHECK5-NEXT: ret void<br> // lpad<br> // CHECK5: [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[ELT]]<br> // CHECK5-NEXT: br i1 [[EMPTY]]<br><br>Modified: cfe/trunk/test/CodeGenCXX/nrvo.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/nrvo.cpp?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/nrvo.cpp?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenCXX/nrvo.cpp (original)<br>+++ cfe/trunk/test/CodeGenCXX/nrvo.cpp Fri Apr 10 05:13:52 2015<br>@@ -54,16 +54,22 @@ X test2(bool B) {<br> return x;<br><br> // CHECK: call {{.*}} @_ZN1XC1Ev<br>+ // CHECK-NEXT: {{.*}} getelementptr inbounds %class.X, %class.X* %y, i32 0, i32 0<br>+ // CHECK-NEXT: call void @llvm.lifetime.start<br> // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev<br> // CHECK: call {{.*}} @_ZN1XC1ERKS_<br> // CHECK: call {{.*}} @_ZN1XC1ERKS_<br> // CHECK: call {{.*}} @_ZN1XD1Ev<br>+ // CHECK-NEXT: call void @llvm.lifetime.end<br> // CHECK: call {{.*}} @_ZN1XD1Ev<br>+ // CHECK-NEXT: call void @llvm.lifetime.end<br> // CHECK: ret void<br><br> // The block ordering in the -fexceptions IR is unfortunate.<br><br>- // CHECK-EH: call {{.*}} @_ZN1XC1Ev<br>+ // CHECK-EH: call void @llvm.lifetime.start<br>+ // CHECK-EH-NEXT: call {{.*}} @_ZN1XC1Ev<br>+ // CHECK-EH: call void @llvm.lifetime.start<br> // CHECK-EH-NEXT: invoke {{.*}} @_ZN1XC1Ev<br> // -> %invoke.cont, %lpad<br><br>@@ -96,7 +102,9 @@ X test2(bool B) {<br> // -> %invoke.cont11, %lpad<br><br> // %invoke.cont11: normal cleanup for 'x'<br>- // CHECK-EH: call {{.*}} @_ZN1XD1Ev<br>+ // CHECK-EH: call void @llvm.lifetime.end<br>+ // CHECK-EH-NEXT: call {{.*}} @_ZN1XD1Ev<br>+ // CHECK-EH-NEXT: call void @llvm.lifetime.end<br> // CHECK-EH-NEXT: ret void<br><br> // %eh.cleanup: EH cleanup for 'x'<br>@@ -168,9 +176,12 @@ X test6() {<br> X a __attribute__((aligned(8)));<br> return a;<br> // CHECK: [[A:%.*]] = alloca [[X:%.*]], align 8<br>+ // CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds %class.X, %class.X* [[A]], i32 0, i32 0<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 1, i8* [[PTR]])<br> // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* [[A]])<br> // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* dereferenceable({{[0-9]+}}) [[A]])<br> // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* [[A]])<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 1, i8* [[PTR]])<br> // CHECK-NEXT: ret void<br> }<br><br><br>Modified: cfe/trunk/test/CodeGenObjC/arc-blocks.m<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-blocks.m?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-blocks.m?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenObjC/arc-blocks.m (original)<br>+++ cfe/trunk/test/CodeGenObjC/arc-blocks.m Fri Apr 10 05:13:52 2015<br>@@ -74,6 +74,8 @@ void test3(void (^sink)(id*)) {<br> // CHECK-NEXT: call i8* @objc_retain(<br> // CHECK-NEXT: bitcast i8*<br> // CHECK-NEXT: store void (i8**)* {{%.*}}, void (i8**)** [[SINK]]<br>+ // CHECK-NEXT: [[STRONGPTR1:%.*]] = bitcast i8** [[STRONG]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[STRONGPTR1]])<br> // CHECK-NEXT: store i8* null, i8** [[STRONG]]<br><br> // CHECK-NEXT: load void (i8**)*, void (i8**)** [[SINK]]<br>@@ -94,6 +96,8 @@ void test3(void (^sink)(id*)) {<br><br> // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[STRONG]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T0]])<br>+ // CHECK-NEXT: [[STRONGPTR2:%.*]] = bitcast i8** [[STRONG]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[STRONGPTR2]])<br><br> // CHECK-NEXT: load void (i8**)*, void (i8**)** [[SINK]]<br> // CHECK-NEXT: bitcast<br>@@ -167,6 +171,8 @@ void test5(void) {<br> // CHECK-LABEL: define void @test5()<br> // CHECK: [[VAR:%.*]] = alloca i8*<br> // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],<br>+ // CHECK-NEXT: [[VARPTR1:%.*]] = bitcast i8** [[VAR]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[VARPTR1]])<br> // CHECK: [[T0:%.*]] = call i8* @test5_source()<br> // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])<br> // CHECK-NEXT: store i8* [[T1]], i8** [[VAR]],<br>@@ -178,6 +184,8 @@ void test5(void) {<br> // CHECK-NEXT: store i8* [[T0]], i8** [[CAPTURE]]<br> // CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to<br> // CHECK: call void @test5_helper<br>+ // CHECK-NEXT: [[VARPTR2:%.*]] = bitcast i8** [[VAR]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[VARPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -190,6 +198,8 @@ void test6(void) {<br> // CHECK-LABEL: define void @test6()<br> // CHECK: [[VAR:%.*]] = alloca [[BYREF_T:%.*]],<br> // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],<br>+ // CHECK-NEXT: [[VARPTR1:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 48, i8* [[VARPTR1]])<br> // CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 2<br> // 0x02000000 - has copy/dispose helpers weak<br> // CHECK-NEXT: store i32 1107296256, i32* [[T0]]<br>@@ -207,7 +217,9 @@ void test6(void) {<br> // CHECK: [[T0:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*<br> // CHECK-NEXT: call void @_Block_object_dispose(i8* [[T0]], i32 8)<br> // CHECK-NEXT: call void @objc_destroyWeak(i8** [[SLOT]])<br>- // CHECK: ret void<br>+ // CHECK-NEXT: [[VARPTR2:%.*]] = bitcast [[BYREF_T]]* [[VAR]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 48, i8* [[VARPTR2]])<br>+ // CHECK-NEXT: ret void<br><br> // CHECK-LABEL: define internal void @__Block_byref_object_copy_<br> // CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* {{%.*}}, i32 0, i32 6<br>@@ -494,6 +506,8 @@ void test13(id x) {<br> // CHECK-NEXT: [[CLEANUP_ACTIVE:%.*]] = alloca i1<br> // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* {{%.*}})<br> // CHECK-NEXT: store i8* [[T0]], i8** [[X]], align 8<br>+ // CHECK-NEXT: [[BPTR1:%.*]] = bitcast void ()** [[B]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[BPTR1]])<br> // CHECK-NEXT: [[CLEANUP_ADDR:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5<br> // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]], align 8<br> // CHECK-NEXT: [[T1:%.*]] = icmp ne i8* [[T0]], null<br>@@ -519,6 +533,8 @@ void test13(id x) {<br> // CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[B]]<br> // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*<br> // CHECK-NEXT: call void @objc_release(i8* [[T1]])<br>+ // CHECK-NEXT: [[BPTR2:%.*]] = bitcast void ()** [[B]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[BPTR2]])<br><br> // CHECK-NEXT: [[T0:%.*]] = load i1, i1* [[CLEANUP_ACTIVE]]<br> // CHECK-NEXT: br i1 [[T0]]<br>@@ -550,6 +566,8 @@ void test16() {<br> // CHECK-LABEL: define void @test16(<br> // CHECK: [[BLKVAR:%.*]] = alloca void ()*, align 8<br> // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],<br>+ // CHECK-NEXT: [[BLKVARPTR1:%.*]] = bitcast void ()** [[BLKVAR]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[BLKVARPTR1]])<br> // CHECK-NEXT: [[SLOTREL:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5<br> // CHECK-NEXT: store void ()* null, void ()** [[BLKVAR]], align 8<br> }<br><br>Modified: cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m (original)<br>+++ cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m Fri Apr 10 05:13:52 2015<br>@@ -31,6 +31,8 @@ void bridge_transfer_from_cf(int *i) {<br> // CHECK: store i32 17<br> *i = 17;<br> // CHECK: call void @objc_release<br>+ // CHECK-NEXT: bitcast<br>+ // CHECK-NEXT: call void @llvm.lifetime.end<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -50,6 +52,8 @@ void bridge_from_cf(int *i) {<br> // CHECK: store i32 17<br> *i = 17;<br> // CHECK: call void @objc_release<br>+ // CHECK-NEXT: bitcast<br>+ // CHECK-NEXT: call void @llvm.lifetime.end<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -67,6 +71,8 @@ void bridge_retained_of_cf(int *i) {<br> // CHECK: store i32 13<br> // CHECK: store i32 17<br> *i = 17;<br>+ // CHECK-NEXT: bitcast<br>+ // CHECK-NEXT: call void @llvm.lifetime.end<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -74,7 +80,8 @@ void bridge_retained_of_cf(int *i) {<br> void bridge_of_cf(int *i) {<br> // CHECK: store i32 7<br> *i = 7;<br>- // CHECK: call i8* @CreateSomething()<br>+ // CHECK: call void @llvm.lifetime.start<br>+ // CHECK-NEXT: call i8* @CreateSomething()<br> CFTypeRef cf1 = (__bridge CFTypeRef)CreateSomething();<br> // CHECK-NOT: retain<br> // CHECK: store i32 11<br>@@ -85,6 +92,8 @@ void bridge_of_cf(int *i) {<br> // CHECK-NOT: release<br> // CHECK: store i32 17<br> *i = 17;<br>+ // CHECK-NEXT: bitcast<br>+ // CHECK-NEXT: call void @llvm.lifetime.end<br> // CHECK-NEXT: ret void<br> }<br><br><br>Modified: cfe/trunk/test/CodeGenObjC/arc-literals.m<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-literals.m?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-literals.m?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenObjC/arc-literals.m (original)<br>+++ cfe/trunk/test/CodeGenObjC/arc-literals.m Fri Apr 10 05:13:52 2015<br>@@ -27,9 +27,13 @@ void test_numeric() {<br> // CHECK: call i8* @objc_retainAutoreleasedReturnValue<br> id charlit = @'a';<br> // CHECK: call void @objc_release<br>+ // CHECK: call void @llvm.lifetime.end<br> // CHECK: call void @objc_release<br>+ // CHECK: call void @llvm.lifetime.end<br> // CHECK: call void @objc_release<br>+ // CHECK: call void @llvm.lifetime.end<br> // CHECK: call void @objc_release<br>+ // CHECK: call void @llvm.lifetime.end<br> // CHECK-NEXT: ret void<br> }<br><br><br>Modified: cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m (original)<br>+++ cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m Fri Apr 10 05:13:52 2015<br>@@ -7,6 +7,8 @@ void test0() {<br> PRECISE_LIFETIME id x = test0_helper();<br> x = 0;<br> // CHECK: [[X:%.*]] = alloca i8*<br>+ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br> // CHECK-NEXT: [[CALL:%.*]] = call i8* @test0_helper()<br> // CHECK-NEXT: store i8* [[CALL]], i8** [[X]]<br><br>@@ -19,6 +21,8 @@ void test0() {<br> // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW:#[0-9]+]]<br> // CHECK-NOT: clang.imprecise_release<br><br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -32,11 +36,17 @@ extern Test1 *test1_helper(void);<br><br> // CHECK-LABEL: define void @test1a()<br> void test1a(void) {<br>+ // CHECK: [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8<br>+ // CHECK: [[C:%.*]] = alloca i8*, align 8<br>+ // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*<br>+ // CHECK: call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])<br> // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()<br> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*<br> // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])<br> // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*<br> // CHECK-NEXT: store [[TEST1]]* [[T3]]<br>+ // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[CPTR1]])<br> // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**<br> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*<br> // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]])<br>@@ -45,9 +55,13 @@ void test1a(void) {<br> // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*<br> // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast<br> // CHECK-NEXT: store i8* [[T6]], i8**<br>+ // CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[CPTR2]])<br> // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**<br> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*<br> // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release<br>+ // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])<br> // CHECK-NEXT: ret void<br> Test1 *ptr = test1_helper();<br> char *c = [(ptr) interior];<br>@@ -55,31 +69,47 @@ void test1a(void) {<br><br> // CHECK-LABEL: define void @test1b()<br> void test1b(void) {<br>+ // CHECK: [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8<br>+ // CHECK: [[C:%.*]] = alloca i8*, align 8<br>+ // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*<br>+ // CHECK: call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])<br> // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()<br> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*<br> // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])<br> // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*<br> // CHECK-NEXT: store [[TEST1]]* [[T3]]<br>+ // CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[CPTR1]])<br> // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**<br> // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_<br> // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*<br> // CHECK-NEXT: [[T3:%.*]] = call i8* bitcast<br> // CHECK-NEXT: store i8* [[T3]], i8**<br>+ // CHECK-NEXT: [[CPTR2:%.*]] = bitcast i8** [[C]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[CPTR2]])<br> // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**<br> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*<br> // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]]<br> // CHECK-NOT: clang.imprecise_release<br>+ // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])<br> // CHECK-NEXT: ret void<br> __attribute__((objc_precise_lifetime)) Test1 *ptr = test1_helper();<br> char *c = [ptr interior];<br> }<br><br> void test1c(void) {<br>+ // CHECK: [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8<br>+ // CHECK: [[PC:%.*]] = alloca i8*, align 8<br>+ // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*<br>+ // CHECK: call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])<br> // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()<br> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*<br> // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])<br> // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*<br> // CHECK-NEXT: store [[TEST1]]* [[T3]]<br>+ // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[PCPTR1]])<br> // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**<br> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*<br> // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]])<br>@@ -88,20 +118,30 @@ void test1c(void) {<br> // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8*<br> // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast<br> // CHECK-NEXT: store i8* [[T6]], i8**<br>+ // CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PCPTR2]])<br> // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**<br> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*<br> // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release<br>+ // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])<br> // CHECK-NEXT: ret void<br> Test1 *ptr = test1_helper();<br> char *pc = ptr.PropertyReturnsInnerPointer;<br> }<br><br> void test1d(void) {<br>+ // CHECK: [[PTR:%.*]] = alloca [[PTR_T:%.*]]*, align 8<br>+ // CHECK: [[PC:%.*]] = alloca i8*, align 8<br>+ // CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*<br>+ // CHECK: call void @llvm.lifetime.start(i64 8, i8* [[PTRPTR1]])<br> // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()<br> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*<br> // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])<br> // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*<br> // CHECK-NEXT: store [[TEST1]]* [[T3]]<br>+ // CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[PCPTR1]])<br> // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**<br> // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*<br> // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retainAutorelease<br>@@ -110,9 +150,13 @@ void test1d(void) {<br> // CHECK-NEXT: [[EIGHT:%.*]] = bitcast [[TEST1]]* [[SIX]] to i8*<br> // CHECK-NEXT: [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* [[EIGHT]], i8* [[SEVEN]])<br> // CHECK-NEXT: store i8* [[CALL1]], i8**<br>+ // CHECK-NEXT: [[PCPTR2:%.*]] = bitcast i8** [[PC]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PCPTR2]])<br> // CHECK-NEXT: [[NINE:%.*]] = load [[TEST1]]*, [[TEST1]]**<br> // CHECK-NEXT: [[TEN:%.*]] = bitcast [[TEST1]]* [[NINE]] to i8*<br> // CHECK-NEXT: call void @objc_release(i8* [[TEN]])<br>+ // CHECK-NEXT: [[PTRPTR2:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTRPTR2]])<br> // CHECK-NEXT: ret void<br> __attribute__((objc_precise_lifetime)) Test1 *ptr = test1_helper();<br> char *pc = ptr.PropertyReturnsInnerPointer;<br><br>Modified: cfe/trunk/test/CodeGenObjC/arc-ternary-op.m<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-ternary-op.m?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-ternary-op.m?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenObjC/arc-ternary-op.m (original)<br>+++ cfe/trunk/test/CodeGenObjC/arc-ternary-op.m Fri Apr 10 05:13:52 2015<br>@@ -10,6 +10,8 @@ void test0(_Bool cond) {<br> // CHECK-NEXT: [[RELCOND:%.*]] = alloca i1<br> // CHECK-NEXT: zext<br> // CHECK-NEXT: store<br>+ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br> // CHECK-NEXT: [[T0:%.*]] = load i8, i8* [[COND]]<br> // CHECK-NEXT: [[T1:%.*]] = trunc i8 [[T0]] to i1<br> // CHECK-NEXT: store i1 false, i1* [[RELCOND]]<br>@@ -29,6 +31,8 @@ void test0(_Bool cond) {<br> // CHECK-NEXT: br label<br> // CHECK: [[T0:%.*]] = load i8*, i8** [[X]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]]<br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> id x = (cond ? 0 : test0_helper());<br> }<br>@@ -49,7 +53,11 @@ void test1(int cond) {<br> // CHECK-NEXT: [[CONDCLEANUPSAVE:%.*]] = alloca i8*<br> // CHECK-NEXT: [[CONDCLEANUP:%.*]] = alloca i1<br> // CHECK-NEXT: store i32<br>+ // CHECK-NEXT: [[STRONGPTR1:%.*]] = bitcast i8** [[STRONG]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[STRONGPTR1]])<br> // CHECK-NEXT: store i8* null, i8** [[STRONG]]<br>+ // CHECK-NEXT: [[WEAKPTR1:%.*]] = bitcast i8** [[WEAK]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[WEAKPTR1]])<br> // CHECK-NEXT: call i8* @objc_initWeak(i8** [[WEAK]], i8* null)<br><br> // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[COND]]<br>@@ -93,6 +101,10 @@ void test1(int cond) {<br> // CHECK-NEXT: br label<br><br> // CHECK: call void @objc_destroyWeak(i8** [[WEAK]])<br>+ // CHECK: [[WEAKPTR2:%.*]] = bitcast i8** [[WEAK]] to i8*<br>+ // CHECK: call void @llvm.lifetime.end(i64 8, i8* [[WEAKPTR2]])<br>+ // CHECK: [[STRONGPTR2:%.*]] = bitcast i8** [[STRONG]] to i8*<br>+ // CHECK: call void @llvm.lifetime.end(i64 8, i8* [[STRONGPTR2]])<br> // CHECK: ret void<br> }<br><br><br>Modified: cfe/trunk/test/CodeGenObjC/arc.m<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc.m?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc.m?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenObjC/arc.m (original)<br>+++ cfe/trunk/test/CodeGenObjC/arc.m Fri Apr 10 05:13:52 2015<br>@@ -46,15 +46,17 @@ void test0(id x) {<br> id test1(id x) {<br> // CHECK: [[X:%.*]] = alloca i8*<br> // CHECK-NEXT: [[Y:%.*]] = alloca i8*<br>- // CHECK-NEXT: alloca i32<br> // CHECK-NEXT: [[PARM:%.*]] = call i8* @objc_retain(i8* {{%.*}})<br> // CHECK-NEXT: store i8* [[PARM]], i8** [[X]]<br>+ // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[YPTR1]])<br> // CHECK-NEXT: store i8* null, i8** [[Y]]<br> // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]<br> // CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T0]])<br>- // CHECK-NEXT: store i32<br> // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T0]])<br>+ // CHECK-NEXT: [[YPTR2:%.*]] = bitcast i8** [[Y]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[YPTR2]])<br> // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T1]])<br> // CHECK-NEXT: [[T1:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[RET]])<br>@@ -99,6 +101,8 @@ void test3_unelided() {<br> extern void test3_helper(void);<br><br> // CHECK: [[X:%.*]] = alloca [[TEST3:%.*]]*<br>+ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast [[TEST3]]** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br> // CHECK-NEXT: store [[TEST3]]* null, [[TEST3]]** [[X]], align<br> Test3 *x;<br><br>@@ -122,12 +126,16 @@ void test3_unelided() {<br> // CHECK-NEXT: [[T0:%.*]] = load [[TEST3]]*, [[TEST3]]** [[X]]<br> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8*<br> // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]]<br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast [[TEST3]]** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br> // CHECK-LABEL: define void @test3()<br> void test3() {<br> // CHECK: [[X:%.*]] = alloca i8*<br>+ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br><br> id x = [[Test3 alloc] initWith: 5];<br><br>@@ -162,7 +170,8 @@ void test3() {<br> // Cleanup for x.<br> // CHECK-NEXT: [[TMP:%.*]] = load i8*, i8** [[X]]<br> // CHECK-NEXT: call void @objc_release(i8* [[TMP]]) [[NUW]]<br>-<br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -244,10 +253,14 @@ id test6_helper(void) __attribute__((ns_<br> // CHECK-LABEL: define void @test6()<br> void test6() {<br> // CHECK: [[X:%.*]] = alloca i8*<br>+ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br> // CHECK-NEXT: [[CALL:%.*]] = call i8* @test6_helper()<br> // CHECK-NEXT: store i8* [[CALL]], i8** [[X]]<br> // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release<br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> id x = test6_helper();<br> }<br>@@ -256,12 +269,16 @@ void test7_helper(id __attribute__((ns_c<br> // CHECK-LABEL: define void @test7()<br> void test7() {<br> // CHECK: [[X:%.*]] = alloca i8*<br>+ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br> // CHECK-NEXT: store i8* null, i8** [[X]]<br> // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]<br> // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]]) [[NUW]]<br> // CHECK-NEXT: call void @test7_helper(i8* [[T1]])<br> // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], !clang.imprecise_release<br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> id x;<br> test7_helper(x);<br>@@ -271,9 +288,13 @@ id test8_helper(void) __attribute__((ns_<br> void test8() {<br> __unsafe_unretained id x = test8_helper();<br> // CHECK: [[X:%.*]] = alloca i8*<br>+ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br> // CHECK-NEXT: [[T0:%.*]] = call i8* @test8_helper()<br> // CHECK-NEXT: store i8* [[T0]], i8** [[X]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]], !clang.imprecise_release<br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -287,7 +308,11 @@ void test10() {<br> // CHECK-LABEL: define void @test10()<br> // CHECK: [[X:%.*]] = alloca [[TEST10:%.*]]*, align<br> // CHECK-NEXT: [[Y:%.*]] = alloca i8*, align<br>+ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast [[TEST10]]** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br> // CHECK-NEXT: store [[TEST10]]* null, [[TEST10]]** [[X]]<br>+ // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[YPTR1]])<br> // CHECK-NEXT: load [[TEST10]]*, [[TEST10]]** [[X]], align<br> // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_{{[0-9]*}}<br> // CHECK-NEXT: bitcast<br>@@ -307,9 +332,13 @@ void test10() {<br> // CHECK-NEXT: call void @objc_release(i8* [[T0]])<br> // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T0]])<br>+ // CHECK-NEXT: [[YPTR2:%.*]] = bitcast i8** [[Y]] to i8*<br>+ // CHECK-NEXT: void @llvm.lifetime.end(i64 8, i8* [[YPTR2]])<br> // CHECK-NEXT: [[T0:%.*]] = load [[TEST10]]*, [[TEST10]]** [[X]]<br> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST10]]* [[T0]] to i8*<br> // CHECK-NEXT: call void @objc_release(i8* [[T1]])<br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast [[TEST10]]** [[X]] to i8*<br>+ // CHECK-NEXT: void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -318,11 +347,15 @@ void test11(id (*f)(void) __attribute__(<br> // CHECK: [[F:%.*]] = alloca i8* ()*, align<br> // CHECK-NEXT: [[X:%.*]] = alloca i8*, align<br> // CHECK-NEXT: store i8* ()* {{%.*}}, i8* ()** [[F]], align<br>+ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br> // CHECK-NEXT: [[T0:%.*]] = load i8* ()*, i8* ()** [[F]], align<br> // CHECK-NEXT: [[T1:%.*]] = call i8* [[T0]]()<br> // CHECK-NEXT: store i8* [[T1]], i8** [[X]], align<br> // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** [[X]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T3]]) [[NUW]], !clang.imprecise_release<br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> id x = f();<br> }<br>@@ -335,6 +368,8 @@ void test12(void) {<br> // CHECK-NEXT: [[Y:%.*]] = alloca i8*, align<br><br> __weak id x = test12_helper();<br>+ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br> // CHECK-NEXT: [[T0:%.*]] = call i8* @test12_helper()<br> // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])<br> // CHECK-NEXT: call i8* @objc_initWeak(i8** [[X]], i8* [[T1]])<br>@@ -347,12 +382,18 @@ void test12(void) {<br> // CHECK-NEXT: call void @objc_release(i8* [[T1]])<br><br> id y = x;<br>+ // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[YPTR1]])<br> // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_loadWeakRetained(i8** [[X]])<br> // CHECK-NEXT: store i8* [[T2]], i8** [[Y]], align<br><br> // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[Y]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T4]]) [[NUW]], !clang.imprecise_release<br>+ // CHECK-NEXT: [[YPTR2:%.*]] = bitcast i8** [[Y]] to i8*<br>+ // CHECK-NEXT: void @llvm.lifetime.end(i64 8, i8* [[YPTR2]])<br> // CHECK-NEXT: call void @objc_destroyWeak(i8** [[X]])<br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK: ret void<br> }<br><br>@@ -360,6 +401,8 @@ void test12(void) {<br> void test13(void) {<br> // CHECK-LABEL: define void @test13()<br> // CHECK: [[X:%.*]] = alloca i8*, align<br>+ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br> // CHECK-NEXT: store i8* null, i8** [[X]], align<br> id x;<br><br>@@ -385,6 +428,8 @@ void test13(void) {<br><br> // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T0]]) [[NUW]]<br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -617,7 +662,6 @@ void test21(unsigned n) {<br> // CHECK: define internal i8* @"\01-[Test27 init]"<br> // CHECK: [[SELF:%.*]] = alloca [[TEST27:%.*]]*,<br> // CHECK-NEXT: [[CMD:%.*]] = alloca i8*,<br>-// CHECK-NEXT: [[DEST:%.*]] = alloca i32<br> // CHECK-NEXT: store [[TEST27]]* {{%.*}}, [[TEST27]]** [[SELF]]<br> // CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]]<br> // CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]*, [[TEST27]]** [[SELF]]<br>@@ -625,7 +669,6 @@ void test21(unsigned n) {<br> // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])<br> // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST27]]*<br> // CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST27]]* [[T3]] to i8*<br>-// CHECK-NEXT: store i32 {{[0-9]+}}, i32* [[DEST]]<br> // CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]*, [[TEST27]]** [[SELF]]<br> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8*<br> // CHECK-NEXT: call void @objc_release(i8* [[T1]])<br>@@ -662,7 +705,6 @@ static id _test29_allocator = 0;<br> // CHECK: define internal i8* @"\01-[Test29 init]"([[TEST29:%[^*]*]]* {{%.*}},<br> // CHECK: [[SELF:%.*]] = alloca [[TEST29]]*, align 8<br> // CHECK-NEXT: [[CMD:%.*]] = alloca i8*, align 8<br>-// CHECK-NEXT: [[CLEANUP:%.*]] = alloca i32<br> // CHECK-NEXT: store [[TEST29]]* {{%.*}}, [[TEST29]]** [[SELF]]<br> // CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]]<br><br>@@ -691,7 +733,6 @@ static id _test29_allocator = 0;<br> // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[CALL]]) [[NUW]]<br> // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST29]]*<br> // CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST29]]* [[T1]] to i8*<br>-// CHECK-NEXT: store i32 1, i32* [[CLEANUP]]<br><br> // Cleanup.<br> // CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]*, [[TEST29]]** [[SELF]]<br>@@ -708,7 +749,6 @@ static id _test29_allocator = 0;<br> // CHECK-NEXT: [[CMD:%.*]] = alloca i8*, align 8<br> // CHECK-NEXT: [[ALLOCATOR:%.*]] = alloca i8*, align 8<br> // CHECK-NEXT: alloca<br>-// CHECK-NEXT: [[CLEANUP:%.*]] = alloca i32<br> // CHECK-NEXT: store [[TEST29]]* {{%.*}}, [[TEST29]]** [[SELF]]<br> // CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]]<br> // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* {{%.*}})<br>@@ -747,7 +787,6 @@ static id _test29_allocator = 0;<br> // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[T1]]) [[NUW]]<br> // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST29]]*<br> // CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST29]]* [[T1]] to i8*<br>-// CHECK-NEXT: store i32 1, i32* [[CLEANUP]]<br><br> // Cleanup.<br> // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[ALLOCATOR]]<br>@@ -776,7 +815,6 @@ char *helper;<br> // CHECK: define internal i8* @"\01-[Test30 init]"([[TEST30:%[^*]*]]* {{%.*}},<br> // CHECK: [[RET:%.*]] = alloca [[TEST30]]*<br> // CHECK-NEXT: alloca i8*<br>-// CHECK-NEXT: alloca i32<br> // CHECK-NEXT: store [[TEST30]]* {{%.*}}, [[TEST30]]** [[SELF]]<br> // CHECK-NEXT: store<br><br>@@ -804,7 +842,6 @@ char *helper;<br> // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[T1]])<br> // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[TEST30]]*<br> // CHECK-NEXT: [[RET:%.*]] = bitcast [[TEST30]]* [[T1]] to i8*<br>-// CHECK-NEXT: store i32 1<br><br> // Cleanup.<br> // CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]*, [[TEST30]]** [[SELF]]<br>@@ -863,6 +900,8 @@ void test33(Test33 *ptr) {<br> // CHECK-NEXT: objc_retain<br> // CHECK-NEXT: bitcast<br> // CHECK-NEXT: store<br>+ // CHECK-NEXT: bitcast<br>+ // CHECK-NEXT: call void @llvm.lifetime.start<br> // CHECK-NEXT: store [[A_T]]* null, [[A_T]]** [[A]]<br><br> // CHECK-NEXT: load [[TEST33]]*, [[TEST33]]** [[PTR]]<br>@@ -925,6 +964,8 @@ void test33(Test33 *ptr) {<br> // CHECK-NEXT: load<br> // CHECK-NEXT: bitcast<br> // CHECK-NEXT: objc_release<br>+ // CHECK-NEXT: bitcast<br>+ // CHECK-NEXT: call void @llvm.lifetime.end<br> // CHECK-NEXT: load<br> // CHECK-NEXT: bitcast<br> // CHECK-NEXT: objc_release<br>@@ -963,6 +1004,8 @@ void test37(void) {<br> // CHECK-LABEL: define void @test37()<br> // CHECK: [[VAR:%.*]] = alloca [[TEST37:%.*]]*,<br> // CHECK-NEXT: [[TEMP:%.*]] = alloca i8*<br>+ // CHECK-NEXT: [[VARPTR1:%.*]] = bitcast [[TEST37]]** [[VAR]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[VARPTR1]])<br> // CHECK-NEXT: store [[TEST37]]* null, [[TEST37]]** [[VAR]]<br><br> // CHECK-NEXT: [[W0:%.*]] = load [[TEST37]]*, [[TEST37]]** [[VAR]]<br>@@ -983,6 +1026,8 @@ void test37(void) {<br> // CHECK-NEXT: [[T0:%.*]] = load [[TEST37]]*, [[TEST37]]** [[VAR]]<br> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST37]]* [[T0]] to i8*<br> // CHECK-NEXT: call void @objc_release(i8* [[T1]])<br>+ // CHECK-NEXT: [[VARPTR2:%.*]] = bitcast [[TEST37]]** [[VAR]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[VARPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -1039,6 +1084,8 @@ void test47(void) {<br><br> // CHECK-LABEL: define void @test47()<br> // CHECK: [[X:%.*]] = alloca i8*<br>+ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br> // CHECK-NEXT: store i8* null, i8** [[X]]<br> // CHECK-NEXT: [[CALL:%.*]] = call i8* @test47_helper()<br> // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[CALL]])<br>@@ -1051,6 +1098,8 @@ void test47(void) {<br> // CHECK-NEXT: call void @objc_release(i8* [[T3]])<br> // CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[X]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T4]])<br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -1059,6 +1108,8 @@ void test48(void) {<br> __weak id x = x = test48_helper();<br> // CHECK-LABEL: define void @test48()<br> // CHECK: [[X:%.*]] = alloca i8*<br>+ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br> // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_initWeak(i8** [[X]], i8* null)<br> // CHECK-NEXT: [[T1:%.*]] = call i8* @test48_helper()<br> // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T1]])<br>@@ -1066,6 +1117,8 @@ void test48(void) {<br> // CHECK-NEXT: [[T4:%.*]] = call i8* @objc_storeWeak(i8** [[X]], i8* [[T3]])<br> // CHECK-NEXT: call void @objc_release(i8* [[T2]])<br> // CHECK-NEXT: call void @objc_destroyWeak(i8** [[X]])<br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -1074,6 +1127,8 @@ void test49(void) {<br> __autoreleasing id x = x = test49_helper();<br> // CHECK-LABEL: define void @test49()<br> // CHECK: [[X:%.*]] = alloca i8*<br>+ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br> // CHECK-NEXT: store i8* null, i8** [[X]]<br> // CHECK-NEXT: [[CALL:%.*]] = call i8* @test49_helper()<br> // CHECK-NEXT: [[T0:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[CALL]])<br>@@ -1081,6 +1136,8 @@ void test49(void) {<br> // CHECK-NEXT: store i8* [[T2]], i8** [[X]]<br> // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]])<br> // CHECK-NEXT: store i8* [[T3]], i8** [[X]]<br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -1116,10 +1173,14 @@ id test52(void) {<br> // CHECK-LABEL: define i8* @test52()<br> // CHECK: [[X:%.*]] = alloca i32<br> // CHECK-NEXT: [[TMPALLOCA:%.*]] = alloca i8*<br>+// CHECK-NEXT: [[XPTR1:%.*]] = bitcast i32* [[X]] to i8*<br>+// CHECK-NEXT: call void @llvm.lifetime.start(i64 4, i8* [[XPTR1]])<br> // CHECK-NEXT: store i32 5, i32* [[X]],<br> // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[X]],<br> // CHECK-NEXT: [[T1:%.*]] = call i8* @test52_helper(i32 [[T0]])<br> // CHECK-NEXT: store i8* [[T1]], i8** [[TMPALLOCA]]<br>+// CHECK-NEXT: [[XPTR2:%.*]] = bitcast i32* [[X]] to i8*<br>+// CHECK-NEXT: call void @llvm.lifetime.end(i64 4, i8* [[XPTR2]])<br> // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[TMPALLOCA]]<br> // CHECK-NEXT: [[T3:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[T2]])<br> // CHECK-NEXT: ret i8* [[T3]]<br>@@ -1134,6 +1195,10 @@ void test53(void) {<br> // CHECK: [[X:%.*]] = alloca i8*,<br> // CHECK-NEXT: [[Y:%.*]] = alloca i8*,<br> // CHECK-NEXT: [[TMPALLOCA:%.*]] = alloca i8*,<br>+// CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*<br>+// CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br>+// CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8*<br>+// CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[YPTR1]])<br> // CHECK-NEXT: [[T0:%.*]] = call i8* @test53_helper()<br> // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])<br> // CHECK-NEXT: store i8* [[T1]], i8** [[Y]],<br>@@ -1142,11 +1207,15 @@ void test53(void) {<br> // CHECK-NEXT: store i8* [[T1]], i8** [[TMPALLOCA]]<br> // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[Y]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T2]])<br>+// CHECK-NEXT: [[YPTR2:%.*]] = bitcast i8** [[Y]] to i8*<br>+// CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[YPTR2]])<br> // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** [[TMPALLOCA]]<br> // CHECK-NEXT: store i8* [[T3]], i8** [[X]],<br> // CHECK-NEXT: load i8*, i8** [[X]],<br> // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T0]])<br>+// CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*<br>+// CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -1193,10 +1262,14 @@ void test56_test(void) {<br> id x = [Test56 make];<br> // CHECK-LABEL: define void @test56_test()<br> // CHECK: [[X:%.*]] = alloca i8*, align 8<br>+ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br> // CHECK: [[T0:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(<br> // CHECK-NEXT: store i8* [[T0]], i8** [[X]]<br> // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T0]])<br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -1276,6 +1349,8 @@ void test61(void) {<br> // CHECK-NEXT: call void @objc_release(i8* [[T1]])<br> [test61_make() performSelector: @selector(test61_void)];<br><br>+ // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[YPTR1]])<br> // CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make()<br> // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])<br> // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_<br>@@ -1288,6 +1363,8 @@ void test61(void) {<br><br> // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T0]])<br>+ // CHECK-NEXT: [[YPTR2:%.*]] = bitcast i8** [[Y]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[YPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -1300,6 +1377,8 @@ void test62(void) {<br> extern id test62_make(void);<br> extern void test62_body(void);<br><br>+ // CHECK-NEXT: [[IPTR:%.*]] = bitcast i32* [[I]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 4, i8* [[IPTR]])<br> // CHECK-NEXT: store i32 0, i32* [[I]], align 4<br> // CHECK-NEXT: br label<br><br>@@ -1391,8 +1470,12 @@ void test67(void) {<br> }<br> // CHECK-LABEL: define void @test67()<br> // CHECK: [[CL:%.*]] = alloca i8*, align 8<br>+// CHECK-NEXT: [[CLPTR1:%.*]] = bitcast i8** [[CL]] to i8*<br>+// CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[CLPTR1]])<br> // CHECK-NEXT: [[T0:%.*]] = call i8* @test67_helper()<br> // CHECK-NEXT: store i8* [[T0]], i8** [[CL]], align 8<br>+// CHECK-NEXT: [[CLPTR2:%.*]] = bitcast i8** [[CL]] to i8*<br>+// CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[CLPTR2]])<br> // CHECK-NEXT: ret void<br><br> Class test68_helper(void);<br>@@ -1401,11 +1484,15 @@ void test68(void) {<br> }<br> // CHECK-LABEL: define void @test68()<br> // CHECK: [[CL:%.*]] = alloca i8*, align 8<br>+// CHECK-NEXT: [[CLPTR1:%.*]] = bitcast i8** [[CL]] to i8*<br>+// CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[CLPTR1]])<br> // CHECK-NEXT: [[T0:%.*]] = call i8* @test67_helper()<br> // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])<br> // CHECK-NEXT: store i8* [[T1]], i8** [[CL]], align 8<br> // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[CL]]<br> // CHECK-NEXT: call void @objc_release(i8* [[T2]])<br>+// CHECK-NEXT: [[CLPTR2:%.*]] = bitcast i8** [[CL]] to i8*<br>+// CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[CLPTR2]])<br> // CHECK-NEXT: ret void<br><br> // rdar://problem/10564852<br><br>Modified: cfe/trunk/test/CodeGenObjC/exceptions.m<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/exceptions.m?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/exceptions.m?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenObjC/exceptions.m (original)<br>+++ cfe/trunk/test/CodeGenObjC/exceptions.m Fri Apr 10 05:13:52 2015<br>@@ -82,6 +82,8 @@ void f3() {<br> extern void f3_helper(int, int*);<br><br> // CHECK: [[X:%.*]] = alloca i32<br>+ // CHECK: [[XPTR:%.*]] = bitcast i32* [[X]] to i8*<br>+ // CHECK: call void @llvm.lifetime.start(i64 4, i8* [[XPTR]])<br> // CHECK: store i32 0, i32* [[X]]<br> int x = 0;<br><br>@@ -122,6 +124,7 @@ void f3() {<br> }<br><br> // CHECK: call void @f3_helper(i32 4, i32* [[X]])<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 4, i8* [[XPTR]])<br> // CHECK-NEXT: ret void<br> f3_helper(4, &x);<br> }<br><br>Modified: cfe/trunk/test/CodeGenObjCXX/<a href="http://arc-move.mm" target="_blank">arc-move.mm</a><br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-move.mm?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-move.mm?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenObjCXX/<a href="http://arc-move.mm" target="_blank">arc-move.mm</a> (original)<br>+++ cfe/trunk/test/CodeGenObjCXX/<a href="http://arc-move.mm" target="_blank">arc-move.mm</a> Fri Apr 10 05:13:52 2015<br>@@ -46,6 +46,10 @@ void library_move(__strong id &x, __stro<br><br> // CHECK-LABEL: define void @_Z12library_moveRU8__strongP11objc_object<br> void library_move(__strong id &y) {<br>+ // CHECK: [[X:%.*]] = alloca i8*, align 8<br>+ // CHECK: [[I:%.*]] = alloca i32, align 4<br>+ // CHECK: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XPTR1]])<br> // CHECK: [[Y:%[a-zA-Z0-9]+]] = call dereferenceable({{[0-9]+}}) i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_<br> // Load the object<br> // CHECK-NEXT: [[OBJ:%[a-zA-Z0-9]+]] = load i8*, i8** [[Y]]<br>@@ -55,10 +59,16 @@ void library_move(__strong id &y) {<br> // CHECK-NEXT: store i8* [[OBJ]], i8** [[X:%[a-zA-Z0-9]+]]<br> id x = move(y);<br><br>+ // CHECK-NEXT: [[IPTR1:%.*]] = bitcast i32* [[I]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 4, i8* [[IPTR1]])<br> // CHECK-NEXT: store i32 17<br> int i = 17;<br>+ // CHECK-NEXT: [[IPTR2:%.*]] = bitcast i32* [[I]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 4, i8* [[IPTR2]])<br> // CHECK-NEXT: [[OBJ:%[a-zA-Z0-9]+]] = load i8*, i8** [[X]]<br> // CHECK-NEXT: call void @objc_release(i8* [[OBJ]])<br>+ // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br><br>Modified: cfe/trunk/test/CodeGenObjCXX/<a href="http://arc-references.mm" target="_blank">arc-references.mm</a><br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-references.mm?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-references.mm?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenObjCXX/<a href="http://arc-references.mm" target="_blank">arc-references.mm</a> (original)<br>+++ cfe/trunk/test/CodeGenObjCXX/<a href="http://arc-references.mm" target="_blank">arc-references.mm</a> Fri Apr 10 05:13:52 2015<br>@@ -38,11 +38,14 @@ typedef __strong id strong_id;<br><br> //CHECK: define void @_Z5test3v<br> void test3() {<br>+ // CHECK: [[REF:%.*]] = alloca i8**, align 8<br> // CHECK: call i8* @objc_initWeak<br> // CHECK-NEXT: store i8**<br> const __weak id &ref = strong_id();<br> // CHECK-NEXT: call void @_Z6calleev()<br> callee();<br>+ // CHECK-NEXT: [[PTR:%.*]] = bitcast i8*** [[REF]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTR]])<br> // CHECK-NEXT: call void @objc_destroyWeak<br> // CHECK-NEXT: ret void<br> }<br>@@ -62,6 +65,7 @@ void sink(__strong A* &&);<br> // CHECK-LABEL: define void @_Z5test5RU8__strongP11objc_object<br> void test5(__strong id &x) {<br> // CHECK: [[REFTMP:%.*]] = alloca {{%.*}}*, align 8<br>+ // CHECK: [[I:%.*]] = alloca i32, align 4<br> // CHECK: [[OBJ_ID:%.*]] = call i8* @objc_retain(<br> // CHECK-NEXT: [[OBJ_A:%.*]] = bitcast i8* [[OBJ_ID]] to [[A:%[a-zA-Z0-9]+]]*<br> // CHECK-NEXT: store [[A]]* [[OBJ_A]], [[A]]** [[REFTMP:%[a-zA-Z0-9]+]]<br>@@ -70,8 +74,12 @@ void test5(__strong id &x) {<br> // CHECK-NEXT: [[OBJ_A:%[a-zA-Z0-9]+]] = load [[A]]*, [[A]]** [[REFTMP]]<br> // CHECK-NEXT: [[OBJ_ID:%[a-zA-Z0-9]+]] = bitcast [[A]]* [[OBJ_A]] to i8*<br> // CHECK-NEXT: call void @objc_release<br>+ // CHECK-NEXT: [[IPTR1:%.*]] = bitcast i32* [[I]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 4, i8* [[IPTR1]])<br> // CHECK-NEXT: store i32 17, i32<br> int i = 17;<br>+ // CHECK-NEXT: [[IPTR2:%.*]] = bitcast i32* [[I]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 4, i8* [[IPTR2]])<br> // CHECK-NEXT: ret void<br> }<br><br><br>Modified: cfe/trunk/test/CodeGenObjCXX/<a href="http://arc.mm" target="_blank">arc.mm</a><br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc.mm?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc.mm?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenObjCXX/<a href="http://arc.mm" target="_blank">arc.mm</a> (original)<br>+++ cfe/trunk/test/CodeGenObjCXX/<a href="http://arc.mm" target="_blank">arc.mm</a> Fri Apr 10 05:13:52 2015<br>@@ -64,7 +64,11 @@ void test34(int cond) {<br> // CHECK-NEXT: [[CONDCLEANUPSAVE:%.*]] = alloca i8*<br> // CHECK-NEXT: [[CONDCLEANUP:%.*]] = alloca i1<br> // CHECK-NEXT: store i32<br>+ // CHECK-NEXT: [[STRONGP:%.*]] = bitcast i8** [[STRONG]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[STRONGP]])<br> // CHECK-NEXT: store i8* null, i8** [[STRONG]]<br>+ // CHECK-NEXT: [[WEAKP:%.*]] = bitcast i8** [[WEAK]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[WEAKP]])<br> // CHECK-NEXT: call i8* @objc_initWeak(i8** [[WEAK]], i8* null)<br><br> // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[COND]]<br>@@ -120,56 +124,77 @@ struct Test35_Helper {<br><br> // CHECK-LABEL: define void @_Z6test3513Test35_HelperPS_<br> void test35(Test35_Helper x0, Test35_Helper *x0p) {<br>+ // CHECK: call void @llvm.lifetime.start<br> // CHECK: call i8* @_ZN13Test35_Helper11makeObject1Ev<br> // CHECK-NOT: call i8* @objc_retain<br> id obj1 = Test35_Helper::makeObject1();<br>+ // CHECK: call void @llvm.lifetime.start<br> // CHECK: call i8* @_ZN13Test35_Helper11makeObject2Ev<br> // CHECK-NOT: call i8* @objc_retain<br> id obj2 = x0.makeObject2();<br>+ // CHECK: call void @llvm.lifetime.start<br> // CHECK: call i8* @_ZN13Test35_Helper11makeObject2Ev<br> // CHECK-NOT: call i8* @objc_retain<br> id obj3 = x0p->makeObject2();<br> id (Test35_Helper::*pmf)() __attribute__((ns_returns_retained))<br> = &Test35_Helper::makeObject2;<br>+ // CHECK: call void @llvm.lifetime.start<br> // CHECK: call i8* %<br> // CHECK-NOT: call i8* @objc_retain<br> id obj4 = (x0.*pmf)();<br>+ // CHECK: call void @llvm.lifetime.start<br> // CHECK: call i8* %<br> // CHECK-NOT: call i8* @objc_retain<br> id obj5 = (x0p->*pmf)();<br><br> // CHECK: call void @objc_release<br>+ // CHECK: call void @llvm.lifetime.end<br> // CHECK: call void @objc_release<br>+ // CHECK: call void @llvm.lifetime.end<br> // CHECK: call void @objc_release<br>+ // CHECK: call void @llvm.lifetime.end<br> // CHECK: call void @objc_release<br>+ // CHECK: call void @llvm.lifetime.end<br> // CHECK: call void @objc_release<br>+ // CHECK: call void @llvm.lifetime.end<br> // CHECK-NEXT: ret void<br> }<br><br> // CHECK-LABEL: define void @_Z7test35b13Test35_HelperPS_<br> void test35b(Test35_Helper x0, Test35_Helper *x0p) {<br>+ // CHECK: call void @llvm.lifetime.start<br> // CHECK: call i8* @_ZN13Test35_Helper11makeObject3Ev<br> // CHECK: call i8* @objc_retain<br> id obj1 = Test35_Helper::makeObject3();<br>+ // CHECK: call void @llvm.lifetime.start<br> // CHECK: call i8* @_ZN13Test35_Helper11makeObject4Ev<br> // CHECK: call i8* @objc_retain<br> id obj2 = x0.makeObject4();<br>+ // CHECK: call void @llvm.lifetime.start<br> // CHECK: call i8* @_ZN13Test35_Helper11makeObject4Ev<br> // CHECK: call i8* @objc_retain<br> id obj3 = x0p->makeObject4();<br> id (Test35_Helper::*pmf)() = &Test35_Helper::makeObject4;<br>+ // CHECK: call void @llvm.lifetime.start<br> // CHECK: call i8* %<br> // CHECK: call i8* @objc_retain<br> id obj4 = (x0.*pmf)();<br>+ // CHECK: call void @llvm.lifetime.start<br> // CHECK: call i8* %<br> // CHECK: call i8* @objc_retain<br> id obj5 = (x0p->*pmf)();<br><br> // CHECK: call void @objc_release<br>+ // CHECK: call void @llvm.lifetime.end<br> // CHECK: call void @objc_release<br>+ // CHECK: call void @llvm.lifetime.end<br>+ // CHECK: call void @llvm.lifetime.end<br> // CHECK: call void @objc_release<br>+ // CHECK: call void @llvm.lifetime.end<br> // CHECK: call void @objc_release<br>+ // CHECK: call void @llvm.lifetime.end<br> // CHECK: call void @objc_release<br>+ // CHECK: call void @llvm.lifetime.end<br> // CHECK-NEXT: ret void<br> }<br><br>@@ -290,6 +315,8 @@ template void test40_helper<int>();<br> // CHECK-LABEL: define weak_odr void @_Z13test40_helperIiEvv()<br> // CHECK: [[X:%.*]] = alloca i8*<br> // CHECK-NEXT: [[TEMP:%.*]] = alloca i8*<br>+// CHECK-NEXT: [[XP:%.*]] = bitcast i8** [[X]] to i8*<br>+// CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XP]])<br> // CHECK-NEXT: store i8* null, i8** [[X]]<br> // CHECK: [[T0:%.*]] = load i8*, i8** [[X]]<br> // CHECK-NEXT: store i8* [[T0]], i8** [[TEMP]]<br><br>Modified: cfe/trunk/test/CodeGenObjCXX/<a href="http://literals.mm" target="_blank">literals.mm</a><br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/literals.mm?rev=234581&r1=234580&r2=234581&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/literals.mm?rev=234581&r1=234580&r2=234581&view=diff</a><br>==============================================================================<br>--- cfe/trunk/test/CodeGenObjCXX/<a href="http://literals.mm" target="_blank">literals.mm</a> (original)<br>+++ cfe/trunk/test/CodeGenObjCXX/<a href="http://literals.mm" target="_blank">literals.mm</a> Fri Apr 10 05:13:52 2015<br>@@ -16,9 +16,12 @@ struct Y {<br><br> // CHECK-LABEL: define void @_Z10test_arrayv<br> void test_array() {<br>+ // CHECK: [[ARR:%[a-zA-Z0-9.]+]] = alloca i8*<br> // CHECK: [[OBJECTS:%[a-zA-Z0-9.]+]] = alloca [2 x i8*]<br><br> // Initializing first element<br>+ // CHECK: [[PTR1:%.*]] = bitcast i8** [[ARR]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[PTR1]])<br> // CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i32 0, i32 0<br> // CHECK-NEXT: call void @_ZN1XC1Ev<br> // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv<br>@@ -47,6 +50,8 @@ void test_array() {<br> // CHECK-NEXT: call void @_ZN1XD1Ev<br> // CHECK-NOT: ret void<br> // CHECK: call void @objc_release<br>+ // CHECK-NEXT: [[PTR2:%.*]] = bitcast i8** [[ARR]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTR2]])<br> // CHECK-NEXT: ret void<br><br> // Check cleanups<br>@@ -63,9 +68,12 @@ void test_array() {<br> // CHECK-LABEL: define weak_odr void @_Z24test_array_instantiationIiEvv<br> template<typename T><br> void test_array_instantiation() {<br>+ // CHECK: [[ARR:%[a-zA-Z0-9.]+]] = alloca i8*<br> // CHECK: [[OBJECTS:%[a-zA-Z0-9.]+]] = alloca [2 x i8*]<br><br> // Initializing first element<br>+ // CHECK: [[PTR1:%.*]] = bitcast i8** [[ARR]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[PTR1]])<br> // CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i32 0, i32 0<br> // CHECK-NEXT: call void @_ZN1XC1Ev<br> // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv<br>@@ -94,6 +102,8 @@ void test_array_instantiation() {<br> // CHECK-NEXT: call void @_ZN1XD1Ev<br> // CHECK-NOT: ret void<br> // CHECK: call void @objc_release<br>+ // CHECK-NEXT: [[PTR2]] = bitcast i8** [[ARR]] to i8*<br>+ // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTR2]])<br> // CHECK-NEXT: ret void<br><br> // Check cleanups<br><br><br>_______________________________________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><o:p></o:p></p></div><p class=MsoNormal style='margin-left:36.0pt'><o:p> </o:p></p></div></div></body></html>