diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 9ee3c8b..ebd0523 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -108,7 +108,13 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
   llvm::Value *Keys = 0;
   if (DLE)
     Keys = CreateMemTemp(ElementArrayType, "keys");
-  
+
+  // Objects to keep alive under ARC when optimizing.
+  SmallVector<llvm::Value *, 16> NeededObjects;
+  bool TrackNeededObjects =
+    (getLangOpts().ObjCAutoRefCount &&
+    CGM.getCodeGenOpts().OptimizationLevel != 0);
+
   // Perform the actual initialialization of the array(s).
   for (uint64_t i = 0; i < NumElements; i++) {
     if (ALE) {
@@ -118,8 +124,13 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
                                    ElementType,
                                    Context.getTypeAlignInChars(Rhs->getType()),
                                    Context);
-      EmitScalarInit(Rhs, /*D=*/0, LV, /*capturedByInit=*/false);
-    } else {      
+      
+      llvm::Value *Value = EmitScalarExpr(Rhs);
+      EmitStoreThroughLValue(RValue::get(Value), LV, true);
+      if (TrackNeededObjects) {
+        NeededObjects.push_back(Value);
+      }
+    } else {
       // Emit the key initializer.
       const Expr *Key = DLE->getKeyValueElement(i).Key;
       LValue KeyLV = LValue::MakeAddr(Builder.CreateStructGEP(Keys, i),
@@ -128,13 +139,21 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
                                       Context);
       EmitScalarInit(Key, /*D=*/0, KeyLV, /*capturedByInit=*/false);
 
+      llvm::Value *KeyResult = EmitScalarExpr(Key);
+      EmitStoreThroughLValue(RValue::get(KeyResult), KeyLV, /*isInit=*/true);
+
       // Emit the value initializer.
       const Expr *Value = DLE->getKeyValueElement(i).Value;  
       LValue ValueLV = LValue::MakeAddr(Builder.CreateStructGEP(Objects, i), 
                                         ElementType,
                                   Context.getTypeAlignInChars(Value->getType()),
                                         Context);
-      EmitScalarInit(Value, /*D=*/0, ValueLV, /*capturedByInit=*/false);
+      llvm::Value *ValueResult = EmitScalarExpr(Key);
+      EmitStoreThroughLValue(RValue::get(ValueResult), ValueLV, /*isInit=*/true);
+      if (TrackNeededObjects) {
+        NeededObjects.push_back(KeyResult);
+        NeededObjects.push_back(ValueResult);
+      }
     }
   }
   
@@ -166,14 +185,22 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
   llvm::Value *Receiver = Runtime.GetClass(*this, Class);
 
   // Generate the message send.
-  RValue result
-    = Runtime.GenerateMessageSend(*this, ReturnValueSlot(), 
-                                  MethodWithObjects->getResultType(),
-                                  Sel,
-                                  Receiver, Args, Class,
-                                  MethodWithObjects);
-  return Builder.CreateBitCast(result.getScalarVal(), 
-                               ConvertType(E->getType()));
+  RValue ResultRValue = Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
+                                MethodWithObjects->getResultType(),
+                                Sel,
+                                Receiver, Args, Class,
+                                MethodWithObjects);
+  llvm::Value *Result = Builder.CreateBitCast(ResultRValue.getScalarVal(),
+                                              ConvertType(E->getType()));
+  
+  // The above message send needs these objects, but since they are passed
+  // in a buffer without a lifetime, we must prevent the optimizer from
+  // releasing them until after that call by indicating they are used.
+  if (TrackNeededObjects) {
+    EmitARCIntrinsicUse(NeededObjects);
+  }
+  
+  return Result;
 }
 
 llvm::Value *CodeGenFunction::EmitObjCArrayLiteral(const ObjCArrayLiteral *E) {
diff --git a/test/CodeGenObjC/arc-literals.m b/test/CodeGenObjC/arc-literals.m
index 203c2ad..c070b58 100644
--- a/test/CodeGenObjC/arc-literals.m
+++ b/test/CodeGenObjC/arc-literals.m
@@ -49,6 +49,7 @@ void test_array(id a, id b) {
   // CHECK: call i8* @objc_retainAutoreleasedReturnValue
   id arr = @[a, b];
 
+  // CHECK: call void (...)* @clang.arc.use(i8* %{{[A-Za-z0-9]+}}, i8* %{{[A-Za-z0-9]+}})
   // CHECK: call void @objc_release
   // CHECK: call void @objc_release
   // CHECK: call void @objc_release
@@ -78,6 +79,7 @@ void test_dictionary(id k1, id o1, id k2, id o2) {
   // CHECK: call i8* @objc_retainAutoreleasedReturnValue
   id dict = @{ k1 : o1, k2 : o2 };
 
+  // CHECK: call void (...)* @clang.arc.use(i8* %{{[A-Za-z0-9]+}}, i8* %{{[A-Za-z0-9]+}}, i8* %{{[A-Za-z0-9]+}}, i8* %{{[A-Za-z0-9]+}})
   // CHECK: call void @objc_release
   // CHECK: call void @objc_release
   // CHECK: call void @objc_release
@@ -109,6 +111,8 @@ void test_property(B *b) {
   // CHECK: call i8* @objc_retainAutoreleasedReturnValue
   id arr = @[ b.prop ];
 
+  // CHECK: call void (...)* @clang.arc.use(i8* %{{[A-Za-z0-9]+}}) 
+
   // Release b.prop
   // CHECK: call void @objc_release
 
