Unverified Commit ed83797f authored by Jon Roelofs's avatar Jon Roelofs
Browse files

[Intrinsics][ObjC] Mark objc_retain and friends as thisreturn.

parent 19784825
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -3404,9 +3404,9 @@ static llvm::Value *tryRemoveRetainOfSelf(CodeGenFunction &CGF,
  const VarDecl *self = method->getSelfDecl();
  if (!self->getType().isConstQualified()) return nullptr;

  // Look for a retain call.
  llvm::CallInst *retainCall =
    dyn_cast<llvm::CallInst>(result->stripPointerCasts());
  // Look for a retain call. Note: stripPointerCasts looks through returned arg
  // functions, which would cause us to miss the retain.
  llvm::CallInst *retainCall = dyn_cast<llvm::CallInst>(result);
  if (!retainCall || retainCall->getCalledOperand() !=
                         CGF.CGM.getObjCEntrypoints().objc_retain)
    return nullptr;
+10 −10
Original line number Diff line number Diff line
@@ -7,30 +7,30 @@
// RUN: %clang_cc1 -fobjc-runtime=macosx-10.7.0 -triple x86_64-apple-darwin11 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-NATIVE %s

// ARC-ALIEN: declare extern_weak void @llvm.objc.storeStrong(ptr, ptr)
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.retain(ptr)
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.autoreleaseReturnValue(ptr)
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.retain(ptr returned)
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.autoreleaseReturnValue(ptr returned)
// ARC-ALIEN: declare ptr @objc_msgSend(ptr, ptr, ...) [[NLB:#[0-9]+]]
// ARC-ALIEN: declare extern_weak void @llvm.objc.release(ptr)
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.retainAutoreleasedReturnValue(ptr)
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.retainAutoreleasedReturnValue(ptr returned)
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.initWeak(ptr, ptr)
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.storeWeak(ptr, ptr)
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.loadWeakRetained(ptr)
// ARC-ALIEN: declare extern_weak void @llvm.objc.destroyWeak(ptr)
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.autorelease(ptr)
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.retainAutorelease(ptr)
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.autorelease(ptr returned)
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.retainAutorelease(ptr returned)

// ARC-NATIVE: declare void @llvm.objc.storeStrong(ptr, ptr)
// ARC-NATIVE: declare ptr @llvm.objc.retain(ptr)
// ARC-NATIVE: declare ptr @llvm.objc.autoreleaseReturnValue(ptr)
// ARC-NATIVE: declare ptr @llvm.objc.retain(ptr returned)
// ARC-NATIVE: declare ptr @llvm.objc.autoreleaseReturnValue(ptr returned)
// ARC-NATIVE: declare ptr @objc_msgSend(ptr, ptr, ...) [[NLB:#[0-9]+]]
// ARC-NATIVE: declare void @llvm.objc.release(ptr)
// ARC-NATIVE: declare ptr @llvm.objc.retainAutoreleasedReturnValue(ptr)
// ARC-NATIVE: declare ptr @llvm.objc.retainAutoreleasedReturnValue(ptr returned)
// ARC-NATIVE: declare ptr @llvm.objc.initWeak(ptr, ptr)
// ARC-NATIVE: declare ptr @llvm.objc.storeWeak(ptr, ptr)
// ARC-NATIVE: declare ptr @llvm.objc.loadWeakRetained(ptr)
// ARC-NATIVE: declare void @llvm.objc.destroyWeak(ptr)
// ARC-NATIVE: declare ptr @llvm.objc.autorelease(ptr)
// ARC-NATIVE: declare ptr @llvm.objc.retainAutorelease(ptr)
// ARC-NATIVE: declare ptr @llvm.objc.autorelease(ptr returned)
// ARC-NATIVE: declare ptr @llvm.objc.retainAutorelease(ptr returned)

// CHECK-LABEL: define{{.*}} void @test0
void test0(id x) {
+5 −0
Original line number Diff line number Diff line
@@ -28,6 +28,11 @@ void test1(id x) {
  // MSGS: {{call.*@objc_msgSend}}
  // CALLS: {{call.*@objc_alloc}}
  // CALLS: {{call.*@objc_allocWithZone}}

  // Note that calls to the intrinsics are not allowed for
  // retain/release/autorelease they're marked `thisreturn`, which isn't
  // guaranteed to be true for classes that define their own `-retain`, for
  // example. Be sure to keep these as normal function calls:
  // CALLS: {{call.*@objc_retain}}
  // CALLS: {{call.*@objc_release}}
  // CALLS: {{tail call.*@objc_autorelease}}
+16 −8
Original line number Diff line number Diff line
@@ -720,11 +720,13 @@ def int_gcwrite : Intrinsic<[],
// eliminate retain and releases where possible.

def int_objc_autorelease                    : Intrinsic<[llvm_ptr_ty],
                                                        [llvm_ptr_ty]>;
                                                        [llvm_ptr_ty],
                                                        [Returned<ArgIndex<0>>]>;
def int_objc_autoreleasePoolPop             : Intrinsic<[], [llvm_ptr_ty]>;
def int_objc_autoreleasePoolPush            : Intrinsic<[llvm_ptr_ty], []>;
def int_objc_autoreleaseReturnValue         : Intrinsic<[llvm_ptr_ty],
                                                        [llvm_ptr_ty]>;
                                                        [llvm_ptr_ty],
                                                        [Returned<ArgIndex<0>>]>;
def int_objc_copyWeak                       : Intrinsic<[],
                                                        [llvm_ptr_ty,
                                                         llvm_ptr_ty]>;
@@ -741,13 +743,17 @@ def int_objc_moveWeak : Intrinsic<[],
                                                         llvm_ptr_ty]>;
def int_objc_release                        : Intrinsic<[], [llvm_ptr_ty]>;
def int_objc_retain                         : Intrinsic<[llvm_ptr_ty],
                                                        [llvm_ptr_ty]>;
                                                        [llvm_ptr_ty],
                                                        [Returned<ArgIndex<0>>]>;
def int_objc_retainAutorelease              : Intrinsic<[llvm_ptr_ty],
                                                        [llvm_ptr_ty]>;
                                                        [llvm_ptr_ty],
                                                        [Returned<ArgIndex<0>>]>;
def int_objc_retainAutoreleaseReturnValue   : Intrinsic<[llvm_ptr_ty],
                                                        [llvm_ptr_ty]>;
                                                        [llvm_ptr_ty],
                                                        [Returned<ArgIndex<0>>]>;
def int_objc_retainAutoreleasedReturnValue  : Intrinsic<[llvm_ptr_ty],
                                                        [llvm_ptr_ty]>;
                                                        [llvm_ptr_ty],
                                                        [Returned<ArgIndex<0>>]>;
def int_objc_retainBlock                    : Intrinsic<[llvm_ptr_ty],
                                                        [llvm_ptr_ty]>;
def int_objc_storeStrong                    : Intrinsic<[],
@@ -762,7 +768,8 @@ def int_objc_clang_arc_noop_use : DefaultAttrsIntrinsic<[],
                                                        [llvm_vararg_ty],
                                                        [IntrInaccessibleMemOnly]>;
def int_objc_unsafeClaimAutoreleasedReturnValue : Intrinsic<[llvm_ptr_ty],
                                                            [llvm_ptr_ty]>;
                                                            [llvm_ptr_ty],
                                                            [Returned<ArgIndex<0>>]>;
def int_objc_retainedObject                 : Intrinsic<[llvm_ptr_ty],
                                                        [llvm_ptr_ty]>;
def int_objc_unretainedObject               : Intrinsic<[llvm_ptr_ty],
@@ -770,7 +777,8 @@ def int_objc_unretainedObject : Intrinsic<[llvm_ptr_ty],
def int_objc_unretainedPointer              : Intrinsic<[llvm_ptr_ty],
                                                        [llvm_ptr_ty]>;
def int_objc_retain_autorelease             : Intrinsic<[llvm_ptr_ty],
                                                        [llvm_ptr_ty]>;
                                                        [llvm_ptr_ty],
                                                        [Returned<ArgIndex<0>>]>;
def int_objc_sync_enter                     : Intrinsic<[llvm_i32_ty],
                                                        [llvm_ptr_ty]>;
def int_objc_sync_exit                      : Intrinsic<[llvm_i32_ty],
+10 −0
Original line number Diff line number Diff line
@@ -162,6 +162,16 @@ static bool lowerObjCCall(Function &F, const char *NewFn,
    CallInst::TailCallKind TCK = CI->getTailCallKind();
    NewCI->setTailCallKind(std::max(TCK, OverridingTCK));

    // Transfer the 'returned' attribute from the intrinsic to the call site.
    // By applying this only to intrinsic call sites, we avoid applying it to
    // non-ARC explicit calls to things like objc_retain which have not been
    // auto-upgraded to use the intrinsics.
    unsigned Index;
    if (F.getAttributes().hasAttrSomewhere(Attribute::Returned, &Index) &&
        Index)
      NewCI->addParamAttr(Index - AttributeList::FirstArgIndex,
                          Attribute::Returned);

    if (!CI->use_empty())
      CI->replaceAllUsesWith(NewCI);
    CI->eraseFromParent();
Loading