Skip to content

Commit d61eb6c

Browse files
committed
[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
1 parent 8f8d9f7 commit d61eb6c

16 files changed

+211
-216
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)