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