Just like in regular escape analysis, loads and stores through
(but not of) a block pointer do not cause the block pointer to
escape. This fixes rdar://10803830.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150424 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Transforms/Scalar/ObjCARC.cpp b/lib/Transforms/Scalar/ObjCARC.cpp
index 9284401..673e1a4 100644
--- a/lib/Transforms/Scalar/ObjCARC.cpp
+++ b/lib/Transforms/Scalar/ObjCARC.cpp
@@ -618,11 +618,21 @@
       // to be an escape.
       if (isa<CallInst>(UUser) || isa<InvokeInst>(UUser))
         continue;
+      // Use by an instruction which copies the value is an escape if the
+      // result is an escape.
       if (isa<BitCastInst>(UUser) || isa<GetElementPtrInst>(UUser) ||
           isa<PHINode>(UUser) || isa<SelectInst>(UUser)) {
         Worklist.push_back(UUser);
         continue;
       }
+      // Use by a load is not an escape.
+      if (isa<LoadInst>(UUser))
+        continue;
+      // Use by a store is not an escape if the use is the address.
+      if (const StoreInst *SI = dyn_cast<StoreInst>(UUser))
+        if (V != SI->getValueOperand())
+          continue;
+      // Otherwise, conservatively assume an escape.
       return true;
     }
   } while (!Worklist.empty());