[cfe-commits] r166085 - in /cfe/trunk: lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGObjC.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenObjC/arc-arm.m test/CodeGenObjC/arc-blocks.m test/CodeGenObjC/arc-exceptions.m test/CodeGenObjC/arc-foreach.m test/CodeGenObjC/arc-no-runtime.m test/CodeGenObjC/arc-property.m test/CodeGenObjC/arc-related-result-type.m test/CodeGenObjC/objc-arc-container-subscripting.m test/CodeGenObjCXX/arc-exceptions.mm test/CodeGenObjCXX/arc-new-delete.mm test/CodeGenObjCXX/arc-special-member-functions.mm

John McCall rjmccall at apple.com
Tue Oct 16 19:28:38 PDT 2012


Author: rjmccall
Date: Tue Oct 16 21:28:37 2012
New Revision: 166085

URL: http://llvm.org/viewvc/llvm-project?rev=166085&view=rev
Log:
At -O0, prefer objc_storeStrong with a null new value to the
combination of a load+objc_release;  this is generally better
for tools that try to track why values are retained and
released.  Also use objc_storeStrong when copying a block
(again, only at -O0), which requires us to do a preliminary
store of null in order to compensate for objc_storeStrong's
assign semantics.

Modified:
    cfe/trunk/lib/CodeGen/CGBlocks.cpp
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/test/CodeGenObjC/arc-arm.m
    cfe/trunk/test/CodeGenObjC/arc-blocks.m
    cfe/trunk/test/CodeGenObjC/arc-exceptions.m
    cfe/trunk/test/CodeGenObjC/arc-foreach.m
    cfe/trunk/test/CodeGenObjC/arc-no-runtime.m
    cfe/trunk/test/CodeGenObjC/arc-property.m
    cfe/trunk/test/CodeGenObjC/arc-related-result-type.m
    cfe/trunk/test/CodeGenObjC/objc-arc-container-subscripting.m
    cfe/trunk/test/CodeGenObjCXX/arc-exceptions.mm
    cfe/trunk/test/CodeGenObjCXX/arc-new-delete.mm
    cfe/trunk/test/CodeGenObjCXX/arc-special-member-functions.mm

Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=166085&r1=166084&r2=166085&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Tue Oct 16 21:28:37 2012
@@ -1241,7 +1241,8 @@
     const Expr *copyExpr = ci->getCopyExpr();
     BlockFieldFlags flags;
 
-    bool isARCWeakCapture = false;
+    bool useARCWeakCopy = false;
+    bool useARCStrongCopy = false;
 
     if (copyExpr) {
       assert(!ci->isByRef());
@@ -1254,21 +1255,35 @@
 
     } else if (type->isObjCRetainableType()) {
       flags = BLOCK_FIELD_IS_OBJECT;
-      if (type->isBlockPointerType())
+      bool isBlockPointer = type->isBlockPointerType();
+      if (isBlockPointer)
         flags = BLOCK_FIELD_IS_BLOCK;
 
       // Special rules for ARC captures:
       if (getLangOpts().ObjCAutoRefCount) {
         Qualifiers qs = type.getQualifiers();
 
-        // Don't generate special copy logic for a captured object
-        // unless it's __strong or __weak.
-        if (!qs.hasStrongOrWeakObjCLifetime())
+        // We need to register __weak direct captures with the runtime.
+        if (qs.getObjCLifetime() == Qualifiers::OCL_Weak) {
+          useARCWeakCopy = true;
+
+        // We need to retain the copied value for __strong direct captures.
+        } else if (qs.getObjCLifetime() == Qualifiers::OCL_Strong) {
+          // If it's a block pointer, we have to copy the block and
+          // assign that to the destination pointer, so we might as
+          // well use _Block_object_assign.  Otherwise we can avoid that.
+          if (!isBlockPointer)
+            useARCStrongCopy = true;
+
+        // Otherwise the memcpy is fine.
+        } else {
           continue;
+        }
 
-        // Support __weak direct captures.
-        if (qs.getObjCLifetime() == Qualifiers::OCL_Weak)
-          isARCWeakCapture = true;
+      // Non-ARC captures of retainable pointers are strong and
+      // therefore require a call to _Block_object_assign.
+      } else {
+        // fall through
       }
     } else {
       continue;
@@ -1281,14 +1296,36 @@
     // If there's an explicit copy expression, we do that.
     if (copyExpr) {
       EmitSynthesizedCXXCopyCtor(dstField, srcField, copyExpr);
-    } else if (isARCWeakCapture) {
+    } else if (useARCWeakCopy) {
       EmitARCCopyWeak(dstField, srcField);
     } else {
       llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src");
-      srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy);
-      llvm::Value *dstAddr = Builder.CreateBitCast(dstField, VoidPtrTy);
-      Builder.CreateCall3(CGM.getBlockObjectAssign(), dstAddr, srcValue,
-                          llvm::ConstantInt::get(Int32Ty, flags.getBitMask()));
+      if (useARCStrongCopy) {
+        // At -O0, store null into the destination field (so that the
+        // storeStrong doesn't over-release) and then call storeStrong.
+        // This is a workaround to not having an initStrong call.
+        if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
+          llvm::PointerType *ty = cast<llvm::PointerType>(srcValue->getType());
+          llvm::Value *null = llvm::ConstantPointerNull::get(ty);
+          Builder.CreateStore(null, dstField);
+          EmitARCStoreStrongCall(dstField, srcValue, true);
+
+        // With optimization enabled, take advantage of the fact that
+        // the blocks runtime guarantees a memcpy of the block data, and
+        // just emit a retain of the src field.
+        } else {
+          EmitARCRetainNonBlock(srcValue);
+
+          // We don't need this anymore, so kill it.  It's not quite
+          // worth the annoyance to avoid creating it in the first place.
+          cast<llvm::Instruction>(dstField)->eraseFromParent();
+        }
+      } else {
+        srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy);
+        llvm::Value *dstAddr = Builder.CreateBitCast(dstField, VoidPtrTy);
+        Builder.CreateCall3(CGM.getBlockObjectAssign(), dstAddr, srcValue,
+                            llvm::ConstantInt::get(Int32Ty, flags.getBitMask()));
+      }
     }
   }
 
@@ -1353,7 +1390,8 @@
     BlockFieldFlags flags;
     const CXXDestructorDecl *dtor = 0;
 
-    bool isARCWeakCapture = false;
+    bool useARCWeakDestroy = false;
+    bool useARCStrongDestroy = false;
 
     if (ci->isByRef()) {
       flags = BLOCK_FIELD_IS_BYREF;
@@ -1379,7 +1417,11 @@
 
         // Support __weak direct captures.
         if (qs.getObjCLifetime() == Qualifiers::OCL_Weak)
-          isARCWeakCapture = true;
+          useARCWeakDestroy = true;
+
+        // Tools really want us to use objc_storeStrong here.
+        else
+          useARCStrongDestroy = true;
       }
     } else {
       continue;
@@ -1393,9 +1435,13 @@
       PushDestructorCleanup(dtor, srcField);
 
     // If this is a __weak capture, emit the release directly.
-    } else if (isARCWeakCapture) {
+    } else if (useARCWeakDestroy) {
       EmitARCDestroyWeak(srcField);
 
+    // Destroy strong objects with a call if requested.
+    } else if (useARCStrongDestroy) {
+      EmitARCDestroyStrong(srcField, /*precise*/ false);
+
     // Otherwise we call _Block_object_dispose.  It wouldn't be too
     // hard to just emit this as a cleanup if we wanted to make sure
     // that things were done in reverse.
@@ -1494,10 +1540,7 @@
   }
 
   void emitDispose(CodeGenFunction &CGF, llvm::Value *field) {
-    llvm::LoadInst *value = CGF.Builder.CreateLoad(field);
-    value->setAlignment(Alignment.getQuantity());
-
-    CGF.EmitARCRelease(value, /*precise*/ false);
+    CGF.EmitARCDestroyStrong(field, /*precise*/ false);
   }
 
   void profileImpl(llvm::FoldingSetNodeID &id) const {
@@ -1527,10 +1570,7 @@
   }
 
   void emitDispose(CodeGenFunction &CGF, llvm::Value *field) {
-    llvm::LoadInst *value = CGF.Builder.CreateLoad(field);
-    value->setAlignment(Alignment.getQuantity());
-
-    CGF.EmitARCRelease(value, /*precise*/ false);
+    CGF.EmitARCDestroyStrong(field, /*precise*/ false);
   }
 
   void profileImpl(llvm::FoldingSetNodeID &id) const {

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=166085&r1=166084&r2=166085&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Tue Oct 16 21:28:37 2012
@@ -1949,6 +1949,28 @@
   }
 }
 
+/// Destroy a __strong variable.
+///
+/// At -O0, emit a call to store 'null' into the address;
+/// instrumenting tools prefer this because the address is exposed,
+/// but it's relatively cumbersome to optimize.
+///
+/// At -O1 and above, just load and call objc_release.
+///
+///   call void \@objc_storeStrong(i8** %addr, i8* null)
+void CodeGenFunction::EmitARCDestroyStrong(llvm::Value *addr, bool precise) {
+  if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
+    llvm::PointerType *addrTy = cast<llvm::PointerType>(addr->getType());
+    llvm::Value *null = llvm::ConstantPointerNull::get(
+                          cast<llvm::PointerType>(addrTy->getElementType()));
+    EmitARCStoreStrongCall(addr, null, /*ignored*/ true);
+    return;
+  }
+
+  llvm::Value *value = Builder.CreateLoad(addr);
+  EmitARCRelease(value, precise);
+}
+
 /// Store into a strong object.  Always calls this:
 ///   call void \@objc_storeStrong(i8** %addr, i8* %value)
 llvm::Value *CodeGenFunction::EmitARCStoreStrongCall(llvm::Value *addr,
@@ -2222,15 +2244,13 @@
 void CodeGenFunction::destroyARCStrongPrecise(CodeGenFunction &CGF,
                                               llvm::Value *addr,
                                               QualType type) {
-  llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy");
-  CGF.EmitARCRelease(ptr, /*precise*/ true);
+  CGF.EmitARCDestroyStrong(addr, /*precise*/ true);
 }
 
 void CodeGenFunction::destroyARCStrongImprecise(CodeGenFunction &CGF,
                                                 llvm::Value *addr,
                                                 QualType type) {
-  llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy");
-  CGF.EmitARCRelease(ptr, /*precise*/ false);  
+  CGF.EmitARCDestroyStrong(addr, /*precise*/ false);
 }
 
 void CodeGenFunction::destroyARCWeak(CodeGenFunction &CGF,

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=166085&r1=166084&r2=166085&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Oct 16 21:28:37 2012
@@ -2353,6 +2353,7 @@
   llvm::Value *EmitARCRetain(QualType type, llvm::Value *value);
   llvm::Value *EmitARCRetainNonBlock(llvm::Value *value);
   llvm::Value *EmitARCRetainBlock(llvm::Value *value, bool mandatory);
+  void EmitARCDestroyStrong(llvm::Value *addr, bool precise);
   void EmitARCRelease(llvm::Value *value, bool precise);
   llvm::Value *EmitARCAutorelease(llvm::Value *value);
   llvm::Value *EmitARCAutoreleaseReturnValue(llvm::Value *value);

Modified: cfe/trunk/test/CodeGenObjC/arc-arm.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-arm.m?rev=166085&r1=166084&r2=166085&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-arm.m (original)
+++ cfe/trunk/test/CodeGenObjC/arc-arm.m Tue Oct 16 21:28:37 2012
@@ -13,8 +13,7 @@
   // CHECK-NEXT: call void asm sideeffect "mov\09r7, r7
   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
   // CHECK-NEXT: store i8* [[T1]],
-  // CHECK-NEXT: load
-  // CHECK-NEXT: call void @objc_release
+  // CHECK-NEXT: call void @objc_storeStrong(
   // CHECK-NEXT: ret void
   id x = test1_helper();
 }

Modified: cfe/trunk/test/CodeGenObjC/arc-blocks.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-blocks.m?rev=166085&r1=166084&r2=166085&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-blocks.m (original)
+++ cfe/trunk/test/CodeGenObjC/arc-blocks.m Tue Oct 16 21:28:37 2012
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-UNOPT %s
 
 // This shouldn't crash.
 void test0(id (^maker)(void)) {
@@ -41,6 +42,24 @@
 // CHECK-NEXT: ret void
   extern void test2_helper(id (^)(void));
   test2_helper(^{ return x; });
+
+// CHECK:    define internal void @__copy_helper_block_
+// CHECK:      [[T0:%.*]] = load i8**
+// CHECK-NEXT: [[SRC:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
+// CHECK-NEXT: [[T0:%.*]] = load i8**
+// CHECK-NEXT: [[DST:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
+// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[SRC]], i32 0, i32 5
+// CHECK-NEXT: [[T1:%.*]] = load i8** [[T0]]
+// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) nounwind
+// CHECK-NEXT: ret void
+
+// CHECK:    define internal void @__destroy_helper_block_
+// CHECK:      [[T0:%.*]] = load i8**
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
+// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[T1]], i32 0, i32 5
+// CHECK-NEXT: [[T3:%.*]] = load i8** [[T2]]
+// CHECK-NEXT: call void @objc_release(i8* [[T3]])
+// CHECK-NEXT: ret void
 }
 
 void test3(void (^sink)(id*)) {
@@ -359,7 +378,7 @@
 // CHECK:      [[T0:%.*]] = load i8** {{%.*}}
 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[BYREF_T]]*
 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[BYREF_T]]* [[T1]], i32 0, i32 6
-// CHECK-NEXT: [[T3:%.*]] = load void ()** [[T2]], align 8
+// CHECK-NEXT: [[T3:%.*]] = load void ()** [[T2]]
 // CHECK-NEXT: [[T4:%.*]] = bitcast void ()* [[T3]] to i8*
 // CHECK-NEXT: call void @objc_release(i8* [[T4]])
 // CHECK-NEXT: ret void
@@ -589,3 +608,42 @@
 // CHECK-NEXT: call void @objc_release(i8* [[T0]])
 // CHECK-NEXT: store i32
 // CHECK-NEXT: br label
+
+void test18(id x) {
+// CHECK-UNOPT:    define void @test18(
+// CHECK-UNOPT:      [[X:%.*]] = alloca i8*,
+// CHECK-UNOPT-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
+// CHECK-UNOPT-NEXT: [[PARM:%.*]] = call i8* @objc_retain(i8* {{%.*}})
+// CHECK-UNOPT-NEXT: store i8* [[PARM]], i8** [[X]]
+// CHECK-UNOPT-NEXT: [[SLOTREL:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
+// CHECK-UNOPT:      [[SLOT:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
+// CHECK-UNOPT-NEXT: [[T0:%.*]] = load i8** [[X]],
+// CHECK-UNOPT-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
+// CHECK-UNOPT-NEXT: store i8* [[T1]], i8** [[SLOT]],
+// CHECK-UNOPT-NEXT: bitcast
+// CHECK-UNOPT-NEXT: call void @test18_helper(
+// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[SLOTREL]], i8* null) nounwind
+// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null) nounwind
+// CHECK-UNOPT-NEXT: ret void
+  extern void test18_helper(id (^)(void));
+  test18_helper(^{ return x; });
+
+// CHECK-UNOPT:    define internal void @__copy_helper_block_
+// CHECK-UNOPT:      [[T0:%.*]] = load i8**
+// CHECK-UNOPT-NEXT: [[SRC:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
+// CHECK-UNOPT-NEXT: [[T0:%.*]] = load i8**
+// CHECK-UNOPT-NEXT: [[DST:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
+// CHECK-UNOPT-NEXT: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[SRC]], i32 0, i32 5
+// CHECK-UNOPT-NEXT: [[T1:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[DST]], i32 0, i32 5
+// CHECK-UNOPT-NEXT: [[T2:%.*]] = load i8** [[T0]]
+// CHECK-UNOPT-NEXT: store i8* null, i8** [[T1]]
+// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[T1]], i8* [[T2]]) nounwind
+// CHECK-UNOPT-NEXT: ret void
+
+// CHECK-UNOPT:    define internal void @__destroy_helper_block_
+// CHECK-UNOPT:      [[T0:%.*]] = load i8**
+// CHECK-UNOPT-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[BLOCK_T]]*
+// CHECK-UNOPT-NEXT: [[T2:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[T1]], i32 0, i32 5
+// CHECK-UNOPT-NEXT: call void @objc_storeStrong(i8** [[T2]], i8* null)
+// CHECK-UNOPT-NEXT: ret void
+}

Modified: cfe/trunk/test/CodeGenObjC/arc-exceptions.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-exceptions.m?rev=166085&r1=166084&r2=166085&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-exceptions.m (original)
+++ cfe/trunk/test/CodeGenObjC/arc-exceptions.m Tue Oct 16 21:28:37 2012
@@ -20,9 +20,8 @@
 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) nounwind
 // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
 // CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
-// CHECK-NEXT: [[T0:%.*]] = load [[ETY]]** [[E]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[ETY]]* [[T0]] to i8*
-// CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) nounwind
 // CHECK-NEXT: call void @objc_end_catch() nounwind
 
 void test1_helper(void);

Modified: cfe/trunk/test/CodeGenObjC/arc-foreach.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-foreach.m?rev=166085&r1=166084&r2=166085&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-foreach.m (original)
+++ cfe/trunk/test/CodeGenObjC/arc-foreach.m Tue Oct 16 21:28:37 2012
@@ -67,8 +67,7 @@
 // CHECK-LP64-NEXT: store i8* [[T2]], i8** [[T0]]
 // CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] 
 // CHECK-LP64: call void @use_block(
-// CHECK-LP64-NEXT: [[T1:%.*]] = load i8** [[D0]]
-// CHECK-LP64-NEXT: call void @objc_release(i8* [[T1]])
+// CHECK-LP64-NEXT: call void @objc_storeStrong(i8** [[D0]], i8* null)
 
 // CHECK-LP64:      [[T0:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_
 // CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[ARRAY_T]]* [[SAVED_ARRAY]] to i8*
@@ -79,9 +78,8 @@
 // CHECK-LP64-NEXT: call void @objc_release(i8* [[T0]])
 
 // Destroy 'array'.
-// CHECK-LP64:      [[T0:%.*]] = load [[ARRAY_T]]** [[ARRAY]]
-// CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[ARRAY_T]]* [[T0]] to i8*
-// CHECK-LP64-NEXT: call void @objc_release(i8* [[T1]])
+// CHECK-LP64:      [[T0:%.*]] = bitcast [[ARRAY_T]]** [[ARRAY]] to i8**
+// CHECK-LP64-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null)
 // CHECK-LP64-NEXT: ret void
 
 // CHECK-LP64:    define internal void @__test0_block_invoke

Modified: cfe/trunk/test/CodeGenObjC/arc-no-runtime.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-no-runtime.m?rev=166085&r1=166084&r2=166085&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-no-runtime.m (original)
+++ cfe/trunk/test/CodeGenObjC/arc-no-runtime.m Tue Oct 16 21:28:37 2012
@@ -1,9 +1,13 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc -emit-llvm %s -o - | FileCheck %s
 
 // rdar://problem/9224855
+id make(void) __attribute__((ns_returns_retained));
 void test0() {
+  make();
   id x = 0;
   // CHECK: call void @objc_release(
+  // CHECK: call void @objc_storeStrong(
 }
 
 // CHECK: declare extern_weak void @objc_release(
+// CHECK: declare extern_weak void @objc_storeStrong(

Modified: cfe/trunk/test/CodeGenObjC/arc-property.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-property.m?rev=166085&r1=166084&r2=166085&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-property.m (original)
+++ cfe/trunk/test/CodeGenObjC/arc-property.m Tue Oct 16 21:28:37 2012
@@ -11,8 +11,8 @@
 // CHECK: call i8* @objc_retain(
 // CHECK: call i8* @objc_retain(
 // CHECK: @objc_msgSend
-// CHECK: call void @objc_release(
-// CHECK: call void @objc_release(
+// CHECK: call void @objc_storeStrong(
+// CHECK: call void @objc_storeStrong(
 
 struct S1 { Class isa; };
 @interface Test1

Modified: cfe/trunk/test/CodeGenObjC/arc-related-result-type.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-related-result-type.m?rev=166085&r1=166084&r2=166085&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-related-result-type.m (original)
+++ cfe/trunk/test/CodeGenObjC/arc-related-result-type.m Tue Oct 16 21:28:37 2012
@@ -20,11 +20,9 @@
 // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
 // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[TEST0]]*
 // CHECK-NEXT: store [[TEST0]]* [[T2]], [[TEST0]]** [[X]]
-// CHECK-NEXT: [[T0:%.*]] = load [[TEST0]]** [[X]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST0]]* [[T0]] to i8*
-// CHECK-NEXT: call void @objc_release(i8* [[T1]])
-// CHECK-NEXT: [[T0:%.*]] = load [[TEST0]]** [[VAL]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST0]]* [[T0]] to i8*
-// CHECK-NEXT: call void @objc_release(i8* [[T1]])
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST0]]** [[X]] to i8**
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null)
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST0]]** [[VAL]] to i8**
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null)
 // CHECK-NEXT: ret void
 }

Modified: cfe/trunk/test/CodeGenObjC/objc-arc-container-subscripting.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/objc-arc-container-subscripting.m?rev=166085&r1=166084&r2=166085&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/objc-arc-container-subscripting.m (original)
+++ cfe/trunk/test/CodeGenObjC/objc-arc-container-subscripting.m Tue Oct 16 21:28:37 2012
@@ -13,9 +13,8 @@
 
 // CHECK: [[call:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
 // CHECK: [[SIX:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[call]]) nounwind
-// CHECK: [[ARRAY:%.*]] = load %0** 
-// CHECK: [[ARRAY_CASTED:%.*]] = bitcast{{.*}}[[ARRAY]] to i8*
-// CHECK: call void @objc_release(i8* [[ARRAY_CASTED]])
+// CHECK: [[ARRAY_CASTED:%.*]] = bitcast %0** {{%.*}} to i8**
+// CHECK: call void @objc_storeStrong(i8** [[ARRAY_CASTED]], i8* null)
 // CHECK: [[EIGHT:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[SIX]]) nounwind
 // CHECK: ret i8* [[EIGHT]]
 

Modified: cfe/trunk/test/CodeGenObjCXX/arc-exceptions.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-exceptions.mm?rev=166085&r1=166084&r2=166085&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/arc-exceptions.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/arc-exceptions.mm Tue Oct 16 21:28:37 2012
@@ -20,9 +20,8 @@
 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) nounwind
 // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
 // CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
-// CHECK-NEXT: [[T0:%.*]] = load [[ETY]]** [[E]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[ETY]]* [[T0]] to i8*
-// CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) nounwind
 // CHECK-NEXT: call void @objc_end_catch() nounwind
 
 void test1_helper(void);
@@ -60,9 +59,8 @@
 // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) nounwind
 // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
 // CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
-// CHECK-NEXT: [[T0:%.*]] = load [[ETY]]** [[E]]
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[ETY]]* [[T0]] to i8*
-// CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null) nounwind
 // CHECK-NEXT: call void @__cxa_end_catch() nounwind
 
 void test3_helper(void);

Modified: cfe/trunk/test/CodeGenObjCXX/arc-new-delete.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-new-delete.mm?rev=166085&r1=166084&r2=166085&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/arc-new-delete.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/arc-new-delete.mm Tue Oct 16 21:28:37 2012
@@ -35,7 +35,7 @@
   // CHECK: call i8* @objc_initWeak
   new __weak id(invalue);
 
-  // CHECK: call void @objc_release
+  // CHECK: call void @objc_storeStrong
   // CHECK: ret void
 }
 
@@ -76,8 +76,7 @@
   // CHECK-NEXT: icmp eq i8** [[BEGIN]], [[END]]
   // CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]],
   // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8** [[PAST]], i64 -1
-  // CHECK-NEXT: [[T0:%.*]] = load i8** [[CUR]]
-  // CHECK-NEXT: call void @objc_release(i8* [[T0]])
+  // CHECK-NEXT: call void @objc_storeStrong(i8** [[CUR]], i8* null)
   // CHECK-NEXT: icmp eq i8** [[CUR]], [[BEGIN]]
   // CHECK: call void @_ZdaPv
   delete [] sptr;

Modified: cfe/trunk/test/CodeGenObjCXX/arc-special-member-functions.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-special-member-functions.mm?rev=166085&r1=166084&r2=166085&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/arc-special-member-functions.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/arc-special-member-functions.mm Tue Oct 16 21:28:37 2012
@@ -111,7 +111,7 @@
 
 // Implicitly-generated destructor for ObjCBlockMember
 // CHECK: define linkonce_odr void @_ZN15ObjCBlockMemberD2Ev
-// CHECK: call void @objc_release(i8*
+// CHECK: call void @objc_storeStrong(i8*
 // CHECK: ret
 
 // Implicitly-generated default constructor for ObjCBlockMember
@@ -134,8 +134,7 @@
 // CHECK-NEXT: br label
 // CHECK:      [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
 // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8** [[PAST]], i64 -1
-// CHECK-NEXT: [[T0:%.*]] = load i8** [[CUR]]
-// CHECK-NEXT: call void @objc_release(i8* [[T0]])
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[CUR]], i8* null)
 // CHECK-NEXT: [[T1:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]]
 // CHECK-NEXT: br i1 [[T1]], 
 // CHECK:      ret void
@@ -154,7 +153,7 @@
 
 // Implicitly-generated destructor for ObjCMember
 // CHECK: define linkonce_odr void @_ZN10ObjCMemberD2Ev
-// CHECK: call void @objc_release
+// CHECK: call void @objc_storeStrong
 // CHECK: ret void
 
 // Implicitly-generated default constructor for ObjCMember





More information about the cfe-commits mailing list