Don't convert objc_autoreleaseReturnValue to objc_autorelease if the result
is returned through a bitcast.

llvm-svn: 137402
diff --git a/llvm/lib/Transforms/Scalar/ObjCARC.cpp b/llvm/lib/Transforms/Scalar/ObjCARC.cpp
index f2cda41..c74c353 100644
--- a/llvm/lib/Transforms/Scalar/ObjCARC.cpp
+++ b/llvm/lib/Transforms/Scalar/ObjCARC.cpp
@@ -1925,12 +1925,19 @@
 ObjCARCOpt::OptimizeAutoreleaseRVCall(Function &F, Instruction *AutoreleaseRV) {
   // Check for a return of the pointer value.
   const Value *Ptr = GetObjCArg(AutoreleaseRV);
-  for (Value::const_use_iterator UI = Ptr->use_begin(), UE = Ptr->use_end();
-       UI != UE; ++UI) {
-    const User *I = *UI;
-    if (isa<ReturnInst>(I) || GetBasicInstructionClass(I) == IC_RetainRV)
-      return;
-  }
+  SmallVector<const Value *, 2> Users;
+  Users.push_back(Ptr);
+  do {
+    Ptr = Users.pop_back_val();
+    for (Value::const_use_iterator UI = Ptr->use_begin(), UE = Ptr->use_end();
+         UI != UE; ++UI) {
+      const User *I = *UI;
+      if (isa<ReturnInst>(I) || GetBasicInstructionClass(I) == IC_RetainRV)
+        return;
+      if (isa<BitCastInst>(I))
+        Users.push_back(I);
+    }
+  } while (!Users.empty());
 
   Changed = true;
   ++NumPeeps;
diff --git a/llvm/test/Transforms/ObjCARC/rv.ll b/llvm/test/Transforms/ObjCARC/rv.ll
index da53a86..9353a19 100644
--- a/llvm/test/Transforms/ObjCARC/rv.ll
+++ b/llvm/test/Transforms/ObjCARC/rv.ll
@@ -329,3 +329,14 @@
   call i8* @objc_autoreleaseReturnValue(i8* %p)
   ret void
 }
+
+; Don't convert autoreleaseRV to autorelease if the result is returned,
+; even through a bitcast.
+
+; CHECK: define {}* @test24(
+; CHECK: tail call i8* @objc_autoreleaseReturnValue(i8* %p)
+define {}* @test24(i8* %p) {
+  %t = call i8* @objc_autoreleaseReturnValue(i8* %p)
+  %s = bitcast i8* %p to {}*
+  ret {}* %s
+}