1//   Make sure it works on x86-64.
2// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime=macosx-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED
3
4//   Make sure it works on x86-32.
5// RUN: %clang_cc1 -triple i386-apple-darwin11 -fobjc-runtime=macosx-fragile-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED
6
7//   Make sure it works on ARM.
8// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED
9// 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 -check-prefix=CHECK-OPTIMIZED
10
11//   Make sure it works on ARM64.
12// RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED
13// RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED
14
15//   Make sure that it's implicitly disabled if the runtime version isn't high enough.
16// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-10.10 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=DISABLED
17// RUN: %clang_cc1 -triple arm64-apple-ios8 -fobjc-runtime=ios-8 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=DISABLED -check-prefix=DISABLED-MARKED
18
19@class A;
20
21A *makeA(void);
22
23void test_assign() {
24  __unsafe_unretained id x;
25  x = makeA();
26}
27// CHECK-LABEL:        define void @test_assign()
28// CHECK:                [[X:%.*]] = alloca i8*
29// CHECK:                [[T0:%.*]] = call [[A:.*]]* @makeA()
30// CHECK-MARKED-NEXT:    call void asm sideeffect
31// CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
32// CHECK-NEXT:           [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
33// CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
34// CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
35// CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
36// CHECK-OPTIMIZED-NEXT: bitcast
37// CHECK-OPTIMIZED-NEXT: lifetime.end
38// CHECK-NEXT:           ret void
39
40// DISABLED-LABEL:     define void @test_assign()
41// DISABLED:             [[T0:%.*]] = call [[A:.*]]* @makeA()
42// DISABLED-MARKED-NEXT: call void asm sideeffect
43// DISABLED-NEXT:        [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
44// DISABLED-NEXT:        [[T2:%.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
45
46void test_assign_assign() {
47  __unsafe_unretained id x, y;
48  x = y = makeA();
49}
50// CHECK-LABEL:        define void @test_assign_assign()
51// CHECK:                [[X:%.*]] = alloca i8*
52// CHECK:                [[Y:%.*]] = alloca i8*
53// CHECK:                [[T0:%.*]] = call [[A]]* @makeA()
54// CHECK-MARKED-NEXT:    call void asm sideeffect
55// CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
56// CHECK-NEXT:           [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
57// CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
58// CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
59// CHECK-NEXT:           store i8* [[T4]], i8** [[Y]]
60// CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
61// CHECK-OPTIMIZED-NEXT: bitcast
62// CHECK-OPTIMIZED-NEXT: lifetime.end
63// CHECK-OPTIMIZED-NEXT: bitcast
64// CHECK-OPTIMIZED-NEXT: lifetime.end
65// CHECK-NEXT:           ret void
66
67void test_strong_assign_assign() {
68  __strong id x;
69  __unsafe_unretained id y;
70  x = y = makeA();
71}
72// CHECK-LABEL:        define void @test_strong_assign_assign()
73// CHECK:                [[X:%.*]] = alloca i8*
74// CHECK:                [[Y:%.*]] = alloca i8*
75// CHECK:                [[T0:%.*]] = call [[A]]* @makeA()
76// CHECK-MARKED-NEXT:    call void asm sideeffect
77// CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
78// CHECK-NEXT:           [[T2:%.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
79// CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
80// CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
81// CHECK-NEXT:           store i8* [[T4]], i8** [[Y]]
82// CHECK-NEXT:           [[OLD:%.*]] = load i8*, i8** [[X]]
83// CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
84// CHECK-NEXT:           call void @llvm.objc.release(i8* [[OLD]]
85// CHECK-OPTIMIZED-NEXT: bitcast
86// CHECK-OPTIMIZED-NEXT: lifetime.end
87// CHECK-UNOPTIMIZED-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], i8* null)
88// CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]
89// CHECK-OPTIMIZED-NEXT: call void @llvm.objc.release(i8* [[T0]])
90// CHECK-OPTIMIZED-NEXT: bitcast
91// CHECK-OPTIMIZED-NEXT: lifetime.end
92// CHECK-NEXT:           ret void
93
94void test_assign_strong_assign() {
95  __unsafe_unretained id x;
96  __strong id y;
97  x = y = makeA();
98}
99// CHECK-LABEL:        define void @test_assign_strong_assign()
100// CHECK:                [[X:%.*]] = alloca i8*
101// CHECK:                [[Y:%.*]] = alloca i8*
102// CHECK:                [[T0:%.*]] = call [[A]]* @makeA()
103// CHECK-MARKED-NEXT:    call void asm sideeffect
104// CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
105// CHECK-NEXT:           [[T2:%.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
106// CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
107// CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
108// CHECK-NEXT:           [[OLD:%.*]] = load i8*, i8** [[Y]]
109// CHECK-NEXT:           store i8* [[T4]], i8** [[Y]]
110// CHECK-NEXT:           call void @llvm.objc.release(i8* [[OLD]]
111// CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
112// CHECK-UNOPTIMIZED-NEXT: call void @llvm.objc.storeStrong(i8** [[Y]], i8* null)
113// CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]
114// CHECK-OPTIMIZED-NEXT: call void @llvm.objc.release(i8* [[T0]])
115// CHECK-OPTIMIZED-NEXT: bitcast
116// CHECK-OPTIMIZED-NEXT: lifetime.end
117// CHECK-OPTIMIZED-NEXT: bitcast
118// CHECK-OPTIMIZED-NEXT: lifetime.end
119// CHECK-NEXT:           ret void
120
121void test_init() {
122  __unsafe_unretained id x = makeA();
123}
124// CHECK-LABEL:        define void @test_init()
125// CHECK:                [[X:%.*]] = alloca i8*
126// CHECK:                [[T0:%.*]] = call [[A]]* @makeA()
127// CHECK-MARKED-NEXT:    call void asm sideeffect
128// CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
129// CHECK-NEXT:           [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
130// CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
131// CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
132// CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
133// CHECK-OPTIMIZED-NEXT: bitcast
134// CHECK-OPTIMIZED-NEXT: lifetime.end
135// CHECK-NEXT:           ret void
136
137void test_init_assignment() {
138  __unsafe_unretained id x;
139  __unsafe_unretained id y = x = makeA();
140}
141// CHECK-LABEL:        define void @test_init_assignment()
142// CHECK:                [[X:%.*]] = alloca i8*
143// CHECK:                [[Y:%.*]] = alloca i8*
144// CHECK:                [[T0:%.*]] = call [[A]]* @makeA()
145// CHECK-MARKED-NEXT:    call void asm sideeffect
146// CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
147// CHECK-NEXT:           [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
148// CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
149// CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
150// CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
151// CHECK-NEXT:           store i8* [[T4]], i8** [[Y]]
152// CHECK-OPTIMIZED-NEXT: bitcast
153// CHECK-OPTIMIZED-NEXT: lifetime.end
154// CHECK-OPTIMIZED-NEXT: bitcast
155// CHECK-OPTIMIZED-NEXT: lifetime.end
156// CHECK-NEXT: ret void
157
158void test_strong_init_assignment() {
159  __unsafe_unretained id x;
160  __strong id y = x = makeA();
161}
162// CHECK-LABEL:        define void @test_strong_init_assignment()
163// CHECK:                [[X:%.*]] = alloca i8*
164// CHECK:                [[Y:%.*]] = alloca i8*
165// CHECK:                [[T0:%.*]] = call [[A]]* @makeA()
166// CHECK-MARKED-NEXT:    call void asm sideeffect
167// CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
168// CHECK-NEXT:           [[T2:%.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
169// CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
170// CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
171// CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
172// CHECK-NEXT:           store i8* [[T4]], i8** [[Y]]
173// CHECK-UNOPTIMIZED-NEXT: call void @llvm.objc.storeStrong(i8** [[Y]], i8* null)
174// CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]
175// CHECK-OPTIMIZED-NEXT: call void @llvm.objc.release(i8* [[T0]])
176// CHECK-OPTIMIZED-NEXT: bitcast
177// CHECK-OPTIMIZED-NEXT: lifetime.end
178// CHECK-OPTIMIZED-NEXT: bitcast
179// CHECK-OPTIMIZED-NEXT: lifetime.end
180// CHECK-NEXT: ret void
181
182void test_init_strong_assignment() {
183  __strong id x;
184  __unsafe_unretained id y = x = makeA();
185}
186// CHECK-LABEL:        define void @test_init_strong_assignment()
187// CHECK:                [[X:%.*]] = alloca i8*
188// CHECK:                [[Y:%.*]] = alloca i8*
189// CHECK:                [[T0:%.*]] = call [[A]]* @makeA()
190// CHECK-MARKED-NEXT:    call void asm sideeffect
191// CHECK-NEXT:           [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
192// CHECK-NEXT:           [[T2:%.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
193// CHECK-NEXT:           [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
194// CHECK-NEXT:           [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
195// CHECK-NEXT:           [[OLD:%.*]] = load i8*, i8** [[X]]
196// CHECK-NEXT:           store i8* [[T4]], i8** [[X]]
197// CHECK-NEXT:           call void @llvm.objc.release(i8* [[OLD]])
198// CHECK-NEXT:           store i8* [[T4]], i8** [[Y]]
199// CHECK-OPTIMIZED-NEXT: bitcast
200// CHECK-OPTIMIZED-NEXT: lifetime.end
201// CHECK-UNOPTIMIZED-NEXT: call void @llvm.objc.storeStrong(i8** [[X]], i8* null)
202// CHECK-OPTIMIZED-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]
203// CHECK-OPTIMIZED-NEXT: call void @llvm.objc.release(i8* [[T0]])
204// CHECK-OPTIMIZED-NEXT: bitcast
205// CHECK-OPTIMIZED-NEXT: lifetime.end
206// CHECK-NEXT: ret void
207
208void test_ignored() {
209  makeA();
210}
211// CHECK-LABEL:     define void @test_ignored()
212// CHECK:             [[T0:%.*]] = call [[A]]* @makeA()
213// CHECK-MARKED-NEXT: call void asm sideeffect
214// CHECK-NEXT:        [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
215// CHECK-NEXT:        [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
216// CHECK-NEXT:        bitcast i8* [[T2]] to [[A]]*
217// CHECK-NEXT:        ret void
218
219void test_cast_to_void() {
220  (void) makeA();
221}
222// CHECK-LABEL:     define void @test_cast_to_void()
223// CHECK:             [[T0:%.*]] = call [[A]]* @makeA()
224// CHECK-MARKED-NEXT: call void asm sideeffect
225// CHECK-NEXT:        [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
226// CHECK-NEXT:        [[T2:%.*]] = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* [[T1]])
227// CHECK-NEXT:        bitcast i8* [[T2]] to [[A]]*
228// CHECK-NEXT:        ret void
229
230
231
232// This is always at the end of the module.
233
234// CHECK-OPTIMIZED: !llvm.module.flags = !{!0,
235// CHECK-OPTIMIZED: !0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov{{.*}}marker for objc_retainAutoreleaseReturnValue"}
236