Skip to content

Commit ed83797

Browse files
committed
[Intrinsics][ObjC] Mark objc_retain and friends as thisreturn.
https://clang.llvm.org/docs/AutomaticReferenceCounting.html#arc-runtime-objc-retain rdar://79869679 Differential revision: https://reviews.llvm.org/D105671
1 parent 1978482 commit ed83797

File tree

6 files changed

+52
-29
lines changed

6 files changed

+52
-29
lines changed

clang/lib/CodeGen/CGCall.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3404,9 +3404,9 @@ static llvm::Value *tryRemoveRetainOfSelf(CodeGenFunction &CGF,
34043404
const VarDecl *self = method->getSelfDecl();
34053405
if (!self->getType().isConstQualified()) return nullptr;
34063406

3407-
// Look for a retain call.
3408-
llvm::CallInst *retainCall =
3409-
dyn_cast<llvm::CallInst>(result->stripPointerCasts());
3407+
// Look for a retain call. Note: stripPointerCasts looks through returned arg
3408+
// functions, which would cause us to miss the retain.
3409+
llvm::CallInst *retainCall = dyn_cast<llvm::CallInst>(result);
34103410
if (!retainCall || retainCall->getCalledOperand() !=
34113411
CGF.CGM.getObjCEntrypoints().objc_retain)
34123412
return nullptr;

clang/test/CodeGenObjC/arc.m

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,30 @@
77
// 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
88

99
// ARC-ALIEN: declare extern_weak void @llvm.objc.storeStrong(ptr, ptr)
10-
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.retain(ptr)
11-
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.autoreleaseReturnValue(ptr)
10+
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.retain(ptr returned)
11+
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.autoreleaseReturnValue(ptr returned)
1212
// ARC-ALIEN: declare ptr @objc_msgSend(ptr, ptr, ...) [[NLB:#[0-9]+]]
1313
// ARC-ALIEN: declare extern_weak void @llvm.objc.release(ptr)
14-
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.retainAutoreleasedReturnValue(ptr)
14+
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.retainAutoreleasedReturnValue(ptr returned)
1515
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.initWeak(ptr, ptr)
1616
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.storeWeak(ptr, ptr)
1717
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.loadWeakRetained(ptr)
1818
// ARC-ALIEN: declare extern_weak void @llvm.objc.destroyWeak(ptr)
19-
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.autorelease(ptr)
20-
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.retainAutorelease(ptr)
19+
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.autorelease(ptr returned)
20+
// ARC-ALIEN: declare extern_weak ptr @llvm.objc.retainAutorelease(ptr returned)
2121

2222
// ARC-NATIVE: declare void @llvm.objc.storeStrong(ptr, ptr)
23-
// ARC-NATIVE: declare ptr @llvm.objc.retain(ptr)
24-
// ARC-NATIVE: declare ptr @llvm.objc.autoreleaseReturnValue(ptr)
23+
// ARC-NATIVE: declare ptr @llvm.objc.retain(ptr returned)
24+
// ARC-NATIVE: declare ptr @llvm.objc.autoreleaseReturnValue(ptr returned)
2525
// ARC-NATIVE: declare ptr @objc_msgSend(ptr, ptr, ...) [[NLB:#[0-9]+]]
2626
// ARC-NATIVE: declare void @llvm.objc.release(ptr)
27-
// ARC-NATIVE: declare ptr @llvm.objc.retainAutoreleasedReturnValue(ptr)
27+
// ARC-NATIVE: declare ptr @llvm.objc.retainAutoreleasedReturnValue(ptr returned)
2828
// ARC-NATIVE: declare ptr @llvm.objc.initWeak(ptr, ptr)
2929
// ARC-NATIVE: declare ptr @llvm.objc.storeWeak(ptr, ptr)
3030
// ARC-NATIVE: declare ptr @llvm.objc.loadWeakRetained(ptr)
3131
// ARC-NATIVE: declare void @llvm.objc.destroyWeak(ptr)
32-
// ARC-NATIVE: declare ptr @llvm.objc.autorelease(ptr)
33-
// ARC-NATIVE: declare ptr @llvm.objc.retainAutorelease(ptr)
32+
// ARC-NATIVE: declare ptr @llvm.objc.autorelease(ptr returned)
33+
// ARC-NATIVE: declare ptr @llvm.objc.retainAutorelease(ptr returned)
3434

3535
// CHECK-LABEL: define{{.*}} void @test0
3636
void test0(id x) {

clang/test/CodeGenObjC/convert-messages-to-runtime-calls.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ void test1(id x) {
2828
// MSGS: {{call.*@objc_msgSend}}
2929
// CALLS: {{call.*@objc_alloc}}
3030
// CALLS: {{call.*@objc_allocWithZone}}
31+
32+
// Note that calls to the intrinsics are not allowed for
33+
// retain/release/autorelease they're marked `thisreturn`, which isn't
34+
// guaranteed to be true for classes that define their own `-retain`, for
35+
// example. Be sure to keep these as normal function calls:
3136
// CALLS: {{call.*@objc_retain}}
3237
// CALLS: {{call.*@objc_release}}
3338
// CALLS: {{tail call.*@objc_autorelease}}

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -720,11 +720,13 @@ def int_gcwrite : Intrinsic<[],
720720
// eliminate retain and releases where possible.
721721

722722
def int_objc_autorelease : Intrinsic<[llvm_ptr_ty],
723-
[llvm_ptr_ty]>;
723+
[llvm_ptr_ty],
724+
[Returned<ArgIndex<0>>]>;
724725
def int_objc_autoreleasePoolPop : Intrinsic<[], [llvm_ptr_ty]>;
725726
def int_objc_autoreleasePoolPush : Intrinsic<[llvm_ptr_ty], []>;
726727
def int_objc_autoreleaseReturnValue : Intrinsic<[llvm_ptr_ty],
727-
[llvm_ptr_ty]>;
728+
[llvm_ptr_ty],
729+
[Returned<ArgIndex<0>>]>;
728730
def int_objc_copyWeak : Intrinsic<[],
729731
[llvm_ptr_ty,
730732
llvm_ptr_ty]>;
@@ -741,13 +743,17 @@ def int_objc_moveWeak : Intrinsic<[],
741743
llvm_ptr_ty]>;
742744
def int_objc_release : Intrinsic<[], [llvm_ptr_ty]>;
743745
def int_objc_retain : Intrinsic<[llvm_ptr_ty],
744-
[llvm_ptr_ty]>;
746+
[llvm_ptr_ty],
747+
[Returned<ArgIndex<0>>]>;
745748
def int_objc_retainAutorelease : Intrinsic<[llvm_ptr_ty],
746-
[llvm_ptr_ty]>;
749+
[llvm_ptr_ty],
750+
[Returned<ArgIndex<0>>]>;
747751
def int_objc_retainAutoreleaseReturnValue : Intrinsic<[llvm_ptr_ty],
748-
[llvm_ptr_ty]>;
752+
[llvm_ptr_ty],
753+
[Returned<ArgIndex<0>>]>;
749754
def int_objc_retainAutoreleasedReturnValue : Intrinsic<[llvm_ptr_ty],
750-
[llvm_ptr_ty]>;
755+
[llvm_ptr_ty],
756+
[Returned<ArgIndex<0>>]>;
751757
def int_objc_retainBlock : Intrinsic<[llvm_ptr_ty],
752758
[llvm_ptr_ty]>;
753759
def int_objc_storeStrong : Intrinsic<[],
@@ -762,15 +768,17 @@ def int_objc_clang_arc_noop_use : DefaultAttrsIntrinsic<[],
762768
[llvm_vararg_ty],
763769
[IntrInaccessibleMemOnly]>;
764770
def int_objc_unsafeClaimAutoreleasedReturnValue : Intrinsic<[llvm_ptr_ty],
765-
[llvm_ptr_ty]>;
771+
[llvm_ptr_ty],
772+
[Returned<ArgIndex<0>>]>;
766773
def int_objc_retainedObject : Intrinsic<[llvm_ptr_ty],
767774
[llvm_ptr_ty]>;
768775
def int_objc_unretainedObject : Intrinsic<[llvm_ptr_ty],
769776
[llvm_ptr_ty]>;
770777
def int_objc_unretainedPointer : Intrinsic<[llvm_ptr_ty],
771778
[llvm_ptr_ty]>;
772779
def int_objc_retain_autorelease : Intrinsic<[llvm_ptr_ty],
773-
[llvm_ptr_ty]>;
780+
[llvm_ptr_ty],
781+
[Returned<ArgIndex<0>>]>;
774782
def int_objc_sync_enter : Intrinsic<[llvm_i32_ty],
775783
[llvm_ptr_ty]>;
776784
def int_objc_sync_exit : Intrinsic<[llvm_i32_ty],

llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,16 @@ static bool lowerObjCCall(Function &F, const char *NewFn,
162162
CallInst::TailCallKind TCK = CI->getTailCallKind();
163163
NewCI->setTailCallKind(std::max(TCK, OverridingTCK));
164164

165+
// Transfer the 'returned' attribute from the intrinsic to the call site.
166+
// By applying this only to intrinsic call sites, we avoid applying it to
167+
// non-ARC explicit calls to things like objc_retain which have not been
168+
// auto-upgraded to use the intrinsics.
169+
unsigned Index;
170+
if (F.getAttributes().hasAttrSomewhere(Attribute::Returned, &Index) &&
171+
Index)
172+
NewCI->addParamAttr(Index - AttributeList::FirstArgIndex,
173+
Attribute::Returned);
174+
165175
if (!CI->use_empty())
166176
CI->replaceAllUsesWith(NewCI);
167177
CI->eraseFromParent();

llvm/test/Transforms/PreISelIntrinsicLowering/objc-arc.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ declare i32 @__gxx_personality_v0(...)
99
define ptr @test_objc_autorelease(ptr %arg0) {
1010
; CHECK-LABEL: test_objc_autorelease
1111
; CHECK-NEXT: entry
12-
; CHECK-NEXT: %0 = notail call ptr @objc_autorelease(ptr %arg0)
12+
; CHECK-NEXT: %0 = notail call ptr @objc_autorelease(ptr returned %arg0)
1313
; CHECK-NEXT: ret ptr %0
1414
entry:
1515
%0 = call ptr @llvm.objc.autorelease(ptr %arg0)
@@ -39,7 +39,7 @@ entry:
3939
define ptr @test_objc_autoreleaseReturnValue(ptr %arg0) {
4040
; CHECK-LABEL: test_objc_autoreleaseReturnValue
4141
; CHECK-NEXT: entry
42-
; CHECK-NEXT: %0 = tail call ptr @objc_autoreleaseReturnValue(ptr %arg0)
42+
; CHECK-NEXT: %0 = tail call ptr @objc_autoreleaseReturnValue(ptr returned %arg0)
4343
; CHECK-NEXT: ret ptr %0
4444
entry:
4545
%0 = call ptr @llvm.objc.autoreleaseReturnValue(ptr %arg0)
@@ -119,7 +119,7 @@ entry:
119119
define ptr @test_objc_retain(ptr %arg0) {
120120
; CHECK-LABEL: test_objc_retain
121121
; CHECK-NEXT: entry
122-
; CHECK-NEXT: %0 = tail call ptr @objc_retain(ptr %arg0)
122+
; CHECK-NEXT: %0 = tail call ptr @objc_retain(ptr returned %arg0)
123123
; CHECK-NEXT: ret ptr %0
124124
entry:
125125
%0 = call ptr @llvm.objc.retain(ptr %arg0)
@@ -129,7 +129,7 @@ entry:
129129
define ptr @test_objc_retainAutorelease(ptr %arg0) {
130130
; CHECK-LABEL: test_objc_retainAutorelease
131131
; CHECK-NEXT: entry
132-
; CHECK-NEXT: %0 = call ptr @objc_retainAutorelease(ptr %arg0)
132+
; CHECK-NEXT: %0 = call ptr @objc_retainAutorelease(ptr returned %arg0)
133133
; CHECK-NEXT: ret ptr %0
134134
entry:
135135
%0 = call ptr @llvm.objc.retainAutorelease(ptr %arg0)
@@ -139,7 +139,7 @@ entry:
139139
define ptr @test_objc_retainAutoreleaseReturnValue(ptr %arg0) {
140140
; CHECK-LABEL: test_objc_retainAutoreleaseReturnValue
141141
; CHECK-NEXT: entry
142-
; CHECK-NEXT: %0 = tail call ptr @objc_retainAutoreleaseReturnValue(ptr %arg0)
142+
; CHECK-NEXT: %0 = tail call ptr @objc_retainAutoreleaseReturnValue(ptr returned %arg0)
143143
; CHECK-NEXT: ret ptr %0
144144
entry:
145145
%0 = tail call ptr @llvm.objc.retainAutoreleaseReturnValue(ptr %arg0)
@@ -149,7 +149,7 @@ entry:
149149
define ptr @test_objc_retainAutoreleasedReturnValue(ptr %arg0) {
150150
; CHECK-LABEL: test_objc_retainAutoreleasedReturnValue
151151
; CHECK-NEXT: entry
152-
; CHECK-NEXT: %0 = tail call ptr @objc_retainAutoreleasedReturnValue(ptr %arg0)
152+
; CHECK-NEXT: %0 = tail call ptr @objc_retainAutoreleasedReturnValue(ptr returned %arg0)
153153
; CHECK-NEXT: ret ptr %0
154154
entry:
155155
%0 = call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %arg0)
@@ -213,7 +213,7 @@ entry:
213213
define ptr @test_objc_unsafeClaimAutoreleasedReturnValue(ptr %arg0) {
214214
; CHECK-LABEL: test_objc_unsafeClaimAutoreleasedReturnValue
215215
; CHECK-NEXT: entry
216-
; CHECK-NEXT: %0 = tail call ptr @objc_unsafeClaimAutoreleasedReturnValue(ptr %arg0)
216+
; CHECK-NEXT: %0 = tail call ptr @objc_unsafeClaimAutoreleasedReturnValue(ptr returned %arg0)
217217
; CHECK-NEXT: ret ptr %0
218218
entry:
219219
%0 = call ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue(ptr %arg0)
@@ -260,7 +260,7 @@ entry:
260260
define ptr @test_objc_retain_autorelease(ptr %arg0) {
261261
; CHECK-LABEL: test_objc_retain_autorelease
262262
; CHECK-NEXT: entry
263-
; CHECK-NEXT: %0 = call ptr @objc_retain_autorelease(ptr %arg0)
263+
; CHECK-NEXT: %0 = call ptr @objc_retain_autorelease(ptr returned %arg0)
264264
; CHECK-NEXT: ret ptr %0
265265
entry:
266266
%0 = call ptr @llvm.objc.retain.autorelease(ptr %arg0)

0 commit comments

Comments
 (0)