r235553 - Revert "Revert r234581, it might have caused a few miscompiles in Chromium."

Alexey Samsonov vonosmas at gmail.com
Fri Jun 12 14:13:24 PDT 2015


I believe it's safe to fix this (http://reviews.llvm.org/D10418), but
please speak up if there's some aspect I'm missing.

On Fri, Jun 12, 2015 at 1:12 PM, Nico Weber <thakis at chromium.org> wrote:

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


-- 
Alexey Samsonov
vonosmas at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150612/4734ac56/attachment.html>


More information about the cfe-commits mailing list