Skip to content

Commit 158043c

Browse files
authored
Add support for "clang.arc.attachedcall" on x86-64 (#3528)
* [ObjC][ARC] Handle operand bundle "clang.arc.attachedcall" on targets that don't use the inline asm marker This patch makes the changes to the ARC middle-end passes that are needed to handle operand bundle "clang.arc.attachedcall" on targets that don't use the inline asm marker for the retainRV/autoreleaseRV handshake (e.g., x86-64). Note that anyone who wants to use the operand bundle on their target has to teach their backend to handle the operand bundle. The x86-64 backend already knows about the operand bundle (see https://reviews.llvm.org/D94597). Differential Revision: https://reviews.llvm.org/D111334 (cherry picked from commit 8f8d9f7) * [ObjC][ARC] Use operand bundle "clang.arc.attachedcall" on x86-64 https://reviews.llvm.org/D92808 made clang use the operand bundle instead of emitting retainRV/claimRV calls on arm64. This commit makes changes to clang that are needed to use the operand bundle on x86-64. Differential Revision: https://reviews.llvm.org/D111331 (cherry picked from commit d61eb6c) * [ObjC][ARC] Replace uses of ObjC intrinsics that are arguments of operand bundle "clang.arc.attachedcall" with ObjC runtime functions The existing code only handles the case where the intrinsic being rewritten is used as the called function pointer of a call/invoke. (cherry picked from commit 1fe8993) (cherry picked from commit 807732b)
1 parent 496955f commit 158043c

23 files changed

+316
-232
lines changed

clang/lib/CodeGen/CGObjC.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2354,9 +2354,12 @@ static llvm::Value *emitOptimizedARCReturnCall(llvm::Value *value,
23542354
: llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue;
23552355
EP = getARCIntrinsic(IID, CGF.CGM);
23562356

2357-
// FIXME: Do this when the target isn't aarch64.
2357+
llvm::Triple::ArchType Arch = CGF.CGM.getTriple().getArch();
2358+
2359+
// FIXME: Do this on all targets and at -O0 too. This can be enabled only if
2360+
// the target backend knows how to handle the operand bundle.
23582361
if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2359-
CGF.CGM.getTarget().getTriple().isAArch64()) {
2362+
(Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::x86_64)) {
23602363
llvm::Value *bundleArgs[] = {EP};
23612364
llvm::OperandBundleDef OB("clang.arc.attachedcall", bundleArgs);
23622365
auto *oldCall = cast<llvm::CallBase>(value);

clang/test/CodeGenObjC/arc-blocks.m

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,9 @@ void test4(void) {
126126
// 0x02000000 - has copy/dispose helpers strong
127127
// CHECK-NEXT: store i32 838860800, i32* [[T0]]
128128
// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
129-
// CHECK-NEXT: [[T0:%.*]] = call i8* @test4_source()
130-
// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
131-
// CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]]
129+
// CHECK-NEXT: [[T0:%.*]] = call i8* @test4_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
130+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]])
131+
// CHECK-NEXT: store i8* [[T0]], i8** [[SLOT]]
132132
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
133133
// 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT
134134
// CHECK: store i32 -1040187392,
@@ -180,8 +180,8 @@ void test5(void) {
180180
// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
181181
// CHECK-NEXT: [[VARPTR1:%.*]] = bitcast i8** [[VAR]] to i8*
182182
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[VARPTR1]])
183-
// CHECK: [[T0:%.*]] = call i8* @test5_source()
184-
// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
183+
// CHECK: [[T1:%.*]] = call i8* @test5_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
184+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
185185
// CHECK-NEXT: store i8* [[T1]], i8** [[VAR]],
186186
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
187187
// 0x40800000 - has signature but no copy/dispose, as well as BLOCK_HAS_EXTENDED_LAYOUT
@@ -211,8 +211,8 @@ void test6(void) {
211211
// 0x02000000 - has copy/dispose helpers weak
212212
// CHECK-NEXT: store i32 1107296256, i32* [[T0]]
213213
// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
214-
// CHECK-NEXT: [[T0:%.*]] = call i8* @test6_source()
215-
// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
214+
// CHECK-NEXT: [[T1:%.*]] = call i8* @test6_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
215+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
216216
// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[SLOT]], i8* [[T1]])
217217
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
218218
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
@@ -257,8 +257,8 @@ void test7(void) {
257257
// CHECK-LABEL: define{{.*}} void @test7()
258258
// CHECK: [[VAR:%.*]] = alloca i8*,
259259
// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
260-
// CHECK: [[T0:%.*]] = call i8* @test7_source()
261-
// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
260+
// CHECK: [[T1:%.*]] = call i8* @test7_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
261+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
262262
// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[VAR]], i8* [[T1]])
263263
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
264264
// 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT
@@ -325,8 +325,8 @@ id test9(void) {
325325
// CHECK-NEXT: tail call i8* @llvm.objc.autoreleaseReturnValue
326326
// CHECK-NEXT: ret i8*
327327

328-
// CHECK: call i8* @test9_produce()
329-
// CHECK-NEXT: call i8* @llvm.objc.retain
328+
// CHECK: call i8* @test9_produce() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
329+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(
330330
// CHECK-NEXT: ret i8*
331331
}
332332

clang/test/CodeGenObjC/arc-bridged-cast.m

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,8 @@ void bridge_transfer_from_cf(int *i) {
4040
void bridge_from_cf(int *i) {
4141
// CHECK: store i32 7
4242
*i = 7;
43-
// CHECK: call i8* @CFCreateSomething()
43+
// CHECK: call i8* @CFCreateSomething() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
4444
id obj1 = (__bridge id)CFCreateSomething();
45-
// CHECK: llvm.objc.retainAutoreleasedReturnValue
4645
// CHECK: store i32 11
4746
*i = 11;
4847
// CHECK: call i8* @CFCreateSomething()
@@ -60,14 +59,12 @@ void bridge_from_cf(int *i) {
6059
// CHECK-LABEL: define{{.*}} void @bridge_retained_of_cf
6160
void bridge_retained_of_cf(int *i) {
6261
*i = 7;
63-
// CHECK: call i8* @CreateSomething()
62+
// CHECK: call i8* @CreateSomething() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
6463
CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething();
65-
// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue
6664
// CHECK: store i32 11
6765
*i = 11;
68-
// CHECK: call i8* @CreateSomething()
66+
// CHECK: call i8* @CreateSomething() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
6967
(__bridge_retained CFTypeRef)CreateSomething(), *i = 13;
70-
// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue
7168
// CHECK: store i32 13
7269
// CHECK: store i32 17
7370
*i = 17;
@@ -99,8 +96,7 @@ void bridge_of_cf(int *i) {
9996

10097
// CHECK-LABEL: define{{.*}} %struct.__CFString* @bridge_of_paren_expr()
10198
CFStringRef bridge_of_paren_expr() {
102-
// CHECK-NOT: call i8* @llvm.objc.retainAutoreleasedReturnValue(
103-
// CHECK-NOT: call void @llvm.objc.release(
99+
// CHECK-NOT: "@llvm.objc"
104100
CFStringRef r = (__bridge CFStringRef)(CreateNSString());
105101
r = (__bridge CFStringRef)((NSString *)(CreateNSString()));
106102
return r;

clang/test/CodeGenObjC/arc-literals.m

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,13 @@
1414

1515
// CHECK-LABEL: define{{.*}} void @test_numeric()
1616
void test_numeric() {
17-
// CHECK: {{call.*objc_msgSend.*i32 17}}
18-
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
17+
// CHECK: {{call.*objc_msgSend.*i32 17.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}}
1918
id ilit = @17;
20-
// CHECK: {{call.*objc_msgSend.*i32 25}}
21-
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
19+
// CHECK: {{call.*objc_msgSend.*i32 25.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}}
2220
id ulit = @25u;
23-
// CHECK: {{call.*objc_msgSend.*i64 42}}
24-
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
21+
// CHECK: {{call.*objc_msgSend.*i64 42.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}}
2522
id ulllit = @42ull;
26-
// CHECK: {{call.*objc_msgSend.*i8 signext 97}}
27-
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
23+
// CHECK: {{call.*objc_msgSend.*i8 signext 97.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}}
2824
id charlit = @'a';
2925
// CHECK: call void @llvm.objc.release
3026
// CHECK: call void @llvm.lifetime.end
@@ -58,8 +54,7 @@ void test_array(id a, id b) {
5854
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
5955
// CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
6056
// CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
61-
// CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 2)
62-
// CHECK-NEXT: [[T4:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]])
57+
// CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 2) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
6358
// CHECK: call void (...) @llvm.objc.clang.arc.use(i8* [[V0]], i8* [[V1]])
6459
id arr = @[a, b];
6560

@@ -102,8 +97,8 @@ void test_dictionary(id k1, id o1, id k2, id o2) {
10297
// CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
10398
// CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
10499
// CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8*]* [[KEYS]] to i8**
105-
// CHECK-NEXT: [[T4:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i8** [[T3]], i64 2)
106-
// CHECK-NEXT: [[T5:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]])
100+
// CHECK-NEXT: [[T4:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i8** [[T3]], i64 2) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
101+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T4]])
107102
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[V0]], i8* [[V1]], i8* [[V2]], i8* [[V3]])
108103

109104
id dict = @{ k1 : o1, k2 : o2 };
@@ -133,10 +128,8 @@ void test_property(B *b) {
133128
// Invoke 'prop'
134129
// CHECK: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
135130
// CHECK-NEXT: [[T1:%.*]] = bitcast
136-
// CHECK-NEXT: [[T2:%.*]] = call [[B:%.*]]* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]])
137-
// CHECK-NEXT: [[T3:%.*]] = bitcast [[B]]* [[T2]] to i8*
138-
// CHECK-NEXT: [[T4:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]])
139-
// CHECK-NEXT: [[V0:%.*]] = bitcast i8* [[T4]] to [[B]]*
131+
// CHECK-NEXT: [[V0:%.*]] = call [[B:%.*]]* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]]) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
132+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[B]]* [[V0]])
140133
// CHECK-NEXT: [[V1:%.*]] = bitcast [[B]]* [[V0]] to i8*
141134

142135
// Store to array.
@@ -147,8 +140,8 @@ void test_property(B *b) {
147140
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
148141
// CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
149142
// CHECK-NEXT: [[T2:%.*]] = bitcast [1 x i8*]* [[OBJECTS]] to i8**
150-
// CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}}(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 1)
151-
// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]])
143+
// CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}}(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 1) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
144+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T3]])
152145
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[V1]])
153146
// CHECK-NEXT: bitcast
154147
// CHECK-NEXT: bitcast

clang/test/CodeGenObjC/arc-precise-lifetime.m

Lines changed: 24 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,9 @@ void test1a_message(void) {
4141
// CHECK: [[C:%.*]] = alloca i8*, align 8
4242
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
4343
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
44-
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
45-
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
46-
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
47-
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
48-
// CHECK-NEXT: store [[TEST1]]* [[T3]]
44+
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
45+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
46+
// CHECK-NEXT: store [[TEST1]]* [[T0]]
4947
// CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
5048
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]])
5149
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
@@ -75,11 +73,9 @@ void test1a_property(void) {
7573
// CHECK: [[C:%.*]] = alloca i8*, align 8
7674
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
7775
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
78-
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
79-
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
80-
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
81-
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
82-
// CHECK-NEXT: store [[TEST1]]* [[T3]]
76+
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
77+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
78+
// CHECK-NEXT: store [[TEST1]]* [[T0]]
8379
// CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
8480
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]])
8581
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
@@ -109,11 +105,9 @@ void test1b_message(void) {
109105
// CHECK: [[C:%.*]] = alloca i8*, align 8
110106
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
111107
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
112-
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
113-
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
114-
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
115-
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
116-
// CHECK-NEXT: store [[TEST1]]* [[T3]]
108+
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
109+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
110+
// CHECK-NEXT: store [[TEST1]]* [[T0]]
117111
// CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
118112
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]])
119113
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
@@ -140,11 +134,9 @@ void test1b_property(void) {
140134
// CHECK: [[C:%.*]] = alloca i8*, align 8
141135
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
142136
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
143-
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
144-
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
145-
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
146-
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
147-
// CHECK-NEXT: store [[TEST1]]* [[T3]]
137+
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
138+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
139+
// CHECK-NEXT: store [[TEST1]]* [[T0]]
148140
// CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
149141
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]])
150142
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
@@ -171,11 +163,9 @@ void test1c_message(void) {
171163
// CHECK: [[PC:%.*]] = alloca i8*, align 8
172164
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
173165
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
174-
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
175-
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
176-
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
177-
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
178-
// CHECK-NEXT: store [[TEST1]]* [[T3]]
166+
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
167+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
168+
// CHECK-NEXT: store [[TEST1]]* [[T0]]
179169
// CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
180170
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]])
181171
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
@@ -204,11 +194,9 @@ void test1c_property(void) {
204194
// CHECK: [[PC:%.*]] = alloca i8*, align 8
205195
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
206196
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
207-
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
208-
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
209-
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
210-
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
211-
// CHECK-NEXT: store [[TEST1]]* [[T3]]
197+
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
198+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
199+
// CHECK-NEXT: store [[TEST1]]* [[T0]]
212200
// CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
213201
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]])
214202
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
@@ -237,11 +225,9 @@ void test1d_message(void) {
237225
// CHECK: [[PC:%.*]] = alloca i8*, align 8
238226
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
239227
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
240-
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
241-
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
242-
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
243-
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
244-
// CHECK-NEXT: store [[TEST1]]* [[T3]]
228+
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
229+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
230+
// CHECK-NEXT: store [[TEST1]]* [[T0]]
245231
// CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
246232
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]])
247233
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
@@ -267,11 +253,9 @@ void test1d_property(void) {
267253
// CHECK: [[PC:%.*]] = alloca i8*, align 8
268254
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
269255
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
270-
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
271-
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
272-
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
273-
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
274-
// CHECK-NEXT: store [[TEST1]]* [[T3]]
256+
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
257+
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
258+
// CHECK-NEXT: store [[TEST1]]* [[T0]]
275259
// CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
276260
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]])
277261
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**

clang/test/CodeGenObjC/arc-rv-attr.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK
2+
// RUN: %clang_cc1 -triple x86_64-apple-macosx10 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK
23

34
@class A;
45

0 commit comments

Comments
 (0)