<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jun 12, 2015 at 1:03 PM, Alexey Samsonov <span dir="ltr"><<a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On Wed, Apr 22, 2015 at 2:38 PM, David Majnemer <span dir="ltr"><<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: majnemer<br>
Date: Wed Apr 22 16:38:15 2015<br>
New Revision: 235553<br>
<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D235553-26view-3Drev&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=F23Mc0ASEwwsJh1Jd3odrnKKOW5kafbc2pM5CDCsyx4&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=235553&view=rev</a><br>
Log:<br>
Revert "Revert r234581, it might have caused a few miscompiles in Chromium."<br>
<br>
This reverts commit r234700.  It turns out that the lifetime markers<br>
were not the cause of Chromium failing but a bug which was uncovered by<br>
optimizations exposed by the markers.<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="https://urldefense.proofpoint.com/v2/url?u=http-3A__arc-2Dmove.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=TysMitYpqcz82cAywg2eQAsRTgDObLHbzmejeyxv2fA&e=" rel="noreferrer" target="_blank">arc-move.mm</a><br>
    cfe/trunk/test/CodeGenObjCXX/<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__arc-2Dreferences.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=jZKxkJjGVzFG_ESHrtaR9s-r-viYoemHGX-ydYnDlCY&e=" rel="noreferrer" target="_blank">arc-references.mm</a><br>
    cfe/trunk/test/CodeGenObjCXX/<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__arc.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=M8ROBtYC9r-cYoMMRz9VwqCJ7ra4MqM5GuhzWqm_3Ro&e=" rel="noreferrer" target="_blank">arc.mm</a><br>
    cfe/trunk/test/CodeGenObjCXX/<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__literals.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=b7Nt4lvl4VsxqJlBOVS0BlHIO2Q9Zx_oAxzkrmHOYyE&e=" rel="noreferrer" target="_blank">literals.mm</a><br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_CodeGen_CGCall.cpp-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=F4a-OYRn2cLGFi2Aiilc8d4BuYKXltVEZAgX2Hlc3Ew&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_CodeGen_CGCleanup.cpp-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=Ohqdo3FS3CHwmygQHt2C_I6oxAce1_ASe0P7kn8ILFM&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCleanup.cpp?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGCleanup.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGCleanup.cpp Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_CodeGen_CGCleanup.h-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=Y0WXHA3j5AgglGYLjtsPGBH2q96uFENOFpaRBcR5kD0&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCleanup.h?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGCleanup.h (original)<br>
+++ cfe/trunk/lib/CodeGen/CGCleanup.h Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_CodeGen_CGDecl.cpp-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=WMNB66ap8710Ieb_eGC38a3ez7FFrq--QOM4KZ501XM&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Wed Apr 22 16:38:15 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></blockquote><div><br></div></div></div><div>^^</div><div>Why do you create BitCast and CallInst manually, instead of using the Builder methods?</div><div>Looks like we are losing debug locations of these newly added instructions, which might actually be helpful.</div></div></div></div></blockquote><div><br>Side note: CallInst without debug locations are particularly problematic. If:<br><br>* you have a call inst with no location<br>* in a function with debug info<br>* calling another function with debug info<br>* and you inline that call site<br><br><badness> (assertion failures and if not that, then weirdly broken debug info where the inline scope is never created, etc)<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5"><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+  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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_CodeGen_CodeGenFunction.cpp-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=LOmG0zH0muti84DMBQp0U39kX1bAw70jb5vOUGcGJfE&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_CodeGen_CodeGenFunction.h-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=z-dnK4s4qCPImfON1clLuDgv_59qfMi6yAcPTUSeYfE&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Apr 22 16:38:15 2015<br>
@@ -1730,6 +1730,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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_CodeGen_EHScopeStack.h-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=trm_isnhy-aVG3PIIVXOVQeHixnrhTFfcDfeAn3j7gs&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/EHScopeStack.h?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/EHScopeStack.h (original)<br>
+++ cfe/trunk/lib/CodeGen/EHScopeStack.h Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGen_cleanup-2Ddestslot-2Dsimple.c-3Frev-3D235553-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=8w4BncwBDOAfS1qqf9H9fIKRW6RMe6-Qc8hb2SMK930&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/cleanup-destslot-simple.c?rev=235553&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/cleanup-destslot-simple.c (added)<br>
+++ cfe/trunk/test/CodeGen/cleanup-destslot-simple.c Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGen_lifetime-2Ddebuginfo-2D1.c-3Frev-3D235553-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=XEdwgKUWwjw0--lRsNQp_G6rXz4mxS1_S6EJIshVHd8&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/lifetime-debuginfo-1.c?rev=235553&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/lifetime-debuginfo-1.c (added)<br>
+++ cfe/trunk/test/CodeGen/lifetime-debuginfo-1.c Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGen_lifetime-2Ddebuginfo-2D2.c-3Frev-3D235553-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=l_XA50WmMKntYeccZ-FRIUgUg7o5uTqT_3TQ2rw9Z-E&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/lifetime-debuginfo-2.c?rev=235553&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/lifetime-debuginfo-2.c (added)<br>
+++ cfe/trunk/test/CodeGen/lifetime-debuginfo-2.c Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenCXX_destructors.cpp-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=ojs4gBPZW6cl6wx3Edt-_CqFa3hDExsAPCtgqJ-z0KE&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/destructors.cpp?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/destructors.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/destructors.cpp Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenCXX_nrvo.cpp-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=ue49EkLAFS4yuZ8UP1BpbD-nzkLRnNbCAreee5mJrLE&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/nrvo.cpp?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/nrvo.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/nrvo.cpp Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenObjC_arc-2Dblocks.m-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=ttFIVqMSxIbjFahECRp0_umABynVSln9YjU6m34MS14&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-blocks.m?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjC/arc-blocks.m (original)<br>
+++ cfe/trunk/test/CodeGenObjC/arc-blocks.m Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenObjC_arc-2Dbridged-2Dcast.m-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=WP5a7c4n_68UZD_Tp5UcXyDaW-EOHsMntHjiIU5ZjcA&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m (original)<br>
+++ cfe/trunk/test/CodeGenObjC/arc-bridged-cast.m Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenObjC_arc-2Dliterals.m-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=9Ns_IzrcSeoIM8gw2b6SurXM2gnEUJRNsH0rSyw8Heg&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-literals.m?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjC/arc-literals.m (original)<br>
+++ cfe/trunk/test/CodeGenObjC/arc-literals.m Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenObjC_arc-2Dprecise-2Dlifetime.m-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=ctwcOC8C8tSx9_Wxu-f53Gov6UcgTh6liAy77j-YZzE&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m (original)<br>
+++ cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenObjC_arc-2Dternary-2Dop.m-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=SbF0jJ09wG-hhOAa-WsUJHaaKXKitERAOk1AtoORawk&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-ternary-op.m?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjC/arc-ternary-op.m (original)<br>
+++ cfe/trunk/test/CodeGenObjC/arc-ternary-op.m Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenObjC_arc.m-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=wbzlTsRfts98xpOS8dwL1alfZ84iINZWognsRUk6UWo&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc.m?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjC/arc.m (original)<br>
+++ cfe/trunk/test/CodeGenObjC/arc.m Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenObjC_exceptions.m-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=EnNylpdF6_1JTdDmY3G1c71GthheDlnZh_9rF2BXGjE&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/exceptions.m?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjC/exceptions.m (original)<br>
+++ cfe/trunk/test/CodeGenObjC/exceptions.m Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__arc-2Dmove.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=TysMitYpqcz82cAywg2eQAsRTgDObLHbzmejeyxv2fA&e=" rel="noreferrer" target="_blank">arc-move.mm</a><br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenObjCXX_arc-2Dmove.mm-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=_XYpk6izllNt_Tshtk2dCjzDrqasdX71T99mqK1zHSk&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-move.mm?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjCXX/<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__arc-2Dmove.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=TysMitYpqcz82cAywg2eQAsRTgDObLHbzmejeyxv2fA&e=" rel="noreferrer" target="_blank">arc-move.mm</a> (original)<br>
+++ cfe/trunk/test/CodeGenObjCXX/<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__arc-2Dmove.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=TysMitYpqcz82cAywg2eQAsRTgDObLHbzmejeyxv2fA&e=" rel="noreferrer" target="_blank">arc-move.mm</a> Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__arc-2Dreferences.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=jZKxkJjGVzFG_ESHrtaR9s-r-viYoemHGX-ydYnDlCY&e=" rel="noreferrer" target="_blank">arc-references.mm</a><br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenObjCXX_arc-2Dreferences.mm-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=xun2MsOYzmFLEUFenrPY6IIE0gxubcEByUiC1uxl2GA&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-references.mm?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjCXX/<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__arc-2Dreferences.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=jZKxkJjGVzFG_ESHrtaR9s-r-viYoemHGX-ydYnDlCY&e=" rel="noreferrer" target="_blank">arc-references.mm</a> (original)<br>
+++ cfe/trunk/test/CodeGenObjCXX/<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__arc-2Dreferences.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=jZKxkJjGVzFG_ESHrtaR9s-r-viYoemHGX-ydYnDlCY&e=" rel="noreferrer" target="_blank">arc-references.mm</a> Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__arc.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=M8ROBtYC9r-cYoMMRz9VwqCJ7ra4MqM5GuhzWqm_3Ro&e=" rel="noreferrer" target="_blank">arc.mm</a><br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenObjCXX_arc.mm-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=ktnvZA3nK5kZDOei2Zm0Td4LTmWy8qQmKA6wUBkCpA8&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc.mm?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjCXX/<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__arc.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=M8ROBtYC9r-cYoMMRz9VwqCJ7ra4MqM5GuhzWqm_3Ro&e=" rel="noreferrer" target="_blank">arc.mm</a> (original)<br>
+++ cfe/trunk/test/CodeGenObjCXX/<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__arc.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=M8ROBtYC9r-cYoMMRz9VwqCJ7ra4MqM5GuhzWqm_3Ro&e=" rel="noreferrer" target="_blank">arc.mm</a> Wed Apr 22 16:38:15 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="https://urldefense.proofpoint.com/v2/url?u=http-3A__literals.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=b7Nt4lvl4VsxqJlBOVS0BlHIO2Q9Zx_oAxzkrmHOYyE&e=" rel="noreferrer" target="_blank">literals.mm</a><br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_test_CodeGenObjCXX_literals.mm-3Frev-3D235553-26r1-3D235552-26r2-3D235553-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=Nd8obGk52NBvKS0M7yTRo6AFlRpmPbXmVr8ZWZffFQE&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/literals.mm?rev=235553&r1=235552&r2=235553&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjCXX/<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__literals.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=b7Nt4lvl4VsxqJlBOVS0BlHIO2Q9Zx_oAxzkrmHOYyE&e=" rel="noreferrer" target="_blank">literals.mm</a> (original)<br>
+++ cfe/trunk/test/CodeGenObjCXX/<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__literals.mm&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=4-mrr1rofeToV-1uTZkKBq2IVTNBwRpljtFn9EgJFvU&s=b7Nt4lvl4VsxqJlBOVS0BlHIO2Q9Zx_oAxzkrmHOYyE&e=" rel="noreferrer" target="_blank">literals.mm</a> Wed Apr 22 16:38:15 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" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div></div></div><span class="HOEnZb"><font color="#888888"><br><br clear="all"><div><br></div>-- <br><div><div dir="ltr">Alexey Samsonov<br><a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a></div></div>
</font></span></div></div>
<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" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div><br></div></div>