1; RUN: opt -pre-isel-intrinsic-lowering -S -o - %s | FileCheck %s
2
3; Make sure calls to the objc intrinsics are translated to calls in to the
4; runtime
5
6declare i8* @foo()
7declare i32 @__gxx_personality_v0(...)
8
9define i8* @test_objc_autorelease(i8* %arg0) {
10; CHECK-LABEL: test_objc_autorelease
11; CHECK-NEXT: entry
12; CHECK-NEXT: %0 = notail call i8* @objc_autorelease(i8* %arg0)
13; CHECK-NEXT: ret i8* %0
14entry:
15  %0 = call i8* @llvm.objc.autorelease(i8* %arg0)
16	ret i8* %0
17}
18
19define void @test_objc_autoreleasePoolPop(i8* %arg0) {
20; CHECK-LABEL: test_objc_autoreleasePoolPop
21; CHECK-NEXT: entry
22; CHECK-NEXT: call void @objc_autoreleasePoolPop(i8* %arg0)
23; CHECK-NEXT: ret void
24entry:
25  call void @llvm.objc.autoreleasePoolPop(i8* %arg0)
26  ret void
27}
28
29define i8* @test_objc_autoreleasePoolPush() {
30; CHECK-LABEL: test_objc_autoreleasePoolPush
31; CHECK-NEXT: entry
32; CHECK-NEXT: %0 = call i8* @objc_autoreleasePoolPush()
33; CHECK-NEXT: ret i8* %0
34entry:
35  %0 = call i8* @llvm.objc.autoreleasePoolPush()
36	ret i8* %0
37}
38
39define i8* @test_objc_autoreleaseReturnValue(i8* %arg0) {
40; CHECK-LABEL: test_objc_autoreleaseReturnValue
41; CHECK-NEXT: entry
42; CHECK-NEXT: %0 = tail call i8* @objc_autoreleaseReturnValue(i8* %arg0)
43; CHECK-NEXT: ret i8* %0
44entry:
45  %0 = call i8* @llvm.objc.autoreleaseReturnValue(i8* %arg0)
46	ret i8* %0
47}
48
49define void @test_objc_copyWeak(i8** %arg0, i8** %arg1) {
50; CHECK-LABEL: test_objc_copyWeak
51; CHECK-NEXT: entry
52; CHECK-NEXT: call void @objc_copyWeak(i8** %arg0, i8** %arg1)
53; CHECK-NEXT: ret void
54entry:
55  call void @llvm.objc.copyWeak(i8** %arg0, i8** %arg1)
56  ret void
57}
58
59define void @test_objc_destroyWeak(i8** %arg0) {
60; CHECK-LABEL: test_objc_destroyWeak
61; CHECK-NEXT: entry
62; CHECK-NEXT: call void @objc_destroyWeak(i8** %arg0)
63; CHECK-NEXT: ret void
64entry:
65  call void @llvm.objc.destroyWeak(i8** %arg0)
66  ret void
67}
68
69define i8* @test_objc_initWeak(i8** %arg0, i8* %arg1) {
70; CHECK-LABEL: test_objc_initWeak
71; CHECK-NEXT: entry
72; CHECK-NEXT: %0 = call i8* @objc_initWeak(i8** %arg0, i8* %arg1)
73; CHECK-NEXT: ret i8* %0
74entry:
75  %0 = call i8* @llvm.objc.initWeak(i8** %arg0, i8* %arg1)
76	ret i8* %0
77}
78
79define i8* @test_objc_loadWeak(i8** %arg0) {
80; CHECK-LABEL: test_objc_loadWeak
81; CHECK-NEXT: entry
82; CHECK-NEXT: %0 = call i8* @objc_loadWeak(i8** %arg0)
83; CHECK-NEXT: ret i8* %0
84entry:
85  %0 = call i8* @llvm.objc.loadWeak(i8** %arg0)
86	ret i8* %0
87}
88
89define i8* @test_objc_loadWeakRetained(i8** %arg0) {
90; CHECK-LABEL: test_objc_loadWeakRetained
91; CHECK-NEXT: entry
92; CHECK-NEXT: %0 = call i8* @objc_loadWeakRetained(i8** %arg0)
93; CHECK-NEXT: ret i8* %0
94entry:
95  %0 = call i8* @llvm.objc.loadWeakRetained(i8** %arg0)
96	ret i8* %0
97}
98
99define void @test_objc_moveWeak(i8** %arg0, i8** %arg1) {
100; CHECK-LABEL: test_objc_moveWeak
101; CHECK-NEXT: entry
102; CHECK-NEXT: call void @objc_moveWeak(i8** %arg0, i8** %arg1)
103; CHECK-NEXT: ret void
104entry:
105  call void @llvm.objc.moveWeak(i8** %arg0, i8** %arg1)
106  ret void
107}
108
109define void @test_objc_release(i8* %arg0) {
110; CHECK-LABEL: test_objc_release
111; CHECK-NEXT: entry
112; CHECK-NEXT: call void @objc_release(i8* %arg0)
113; CHECK-NEXT: ret void
114entry:
115  call void @llvm.objc.release(i8* %arg0)
116  ret void
117}
118
119define i8* @test_objc_retain(i8* %arg0) {
120; CHECK-LABEL: test_objc_retain
121; CHECK-NEXT: entry
122; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %arg0)
123; CHECK-NEXT: ret i8* %0
124entry:
125  %0 = call i8* @llvm.objc.retain(i8* %arg0)
126	ret i8* %0
127}
128
129define i8* @test_objc_retainAutorelease(i8* %arg0) {
130; CHECK-LABEL: test_objc_retainAutorelease
131; CHECK-NEXT: entry
132; CHECK-NEXT: %0 = call i8* @objc_retainAutorelease(i8* %arg0)
133; CHECK-NEXT: ret i8* %0
134entry:
135  %0 = call i8* @llvm.objc.retainAutorelease(i8* %arg0)
136	ret i8* %0
137}
138
139define i8* @test_objc_retainAutoreleaseReturnValue(i8* %arg0) {
140; CHECK-LABEL: test_objc_retainAutoreleaseReturnValue
141; CHECK-NEXT: entry
142; CHECK-NEXT: %0 = tail call i8* @objc_retainAutoreleaseReturnValue(i8* %arg0)
143; CHECK-NEXT: ret i8* %0
144entry:
145  %0 = tail call i8* @llvm.objc.retainAutoreleaseReturnValue(i8* %arg0)
146	ret i8* %0
147}
148
149define i8* @test_objc_retainAutoreleasedReturnValue(i8* %arg0) {
150; CHECK-LABEL: test_objc_retainAutoreleasedReturnValue
151; CHECK-NEXT: entry
152; CHECK-NEXT: %0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %arg0)
153; CHECK-NEXT: ret i8* %0
154entry:
155  %0 = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %arg0)
156	ret i8* %0
157}
158
159define void @test_objc_retainAutoreleasedReturnValue_bundle() {
160; CHECK-LABEL: test_objc_retainAutoreleasedReturnValue_bundle(
161; CHECK-NEXT: call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_retainAutoreleasedReturnValue) ]
162  call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
163  ret void
164}
165
166define void @test_objc_retainAutoreleasedReturnValue_bundle_invoke() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
167; CHECK-LABEL: test_objc_retainAutoreleasedReturnValue_bundle_invoke(
168; CHECK-NEXT: entry
169; CHECK-NEXT: invoke i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_retainAutoreleasedReturnValue) ]
170entry:
171  invoke i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
172      to label %invoke.cont unwind label %lpad
173
174invoke.cont:
175  ret void
176
177lpad:
178  %1 = landingpad { i8*, i32 }
179          cleanup
180  resume { i8*, i32 } %1
181}
182
183define i8* @test_objc_retainBlock(i8* %arg0) {
184; CHECK-LABEL: test_objc_retainBlock
185; CHECK-NEXT: entry
186; CHECK-NEXT: %0 = call i8* @objc_retainBlock(i8* %arg0)
187; CHECK-NEXT: ret i8* %0
188entry:
189  %0 = call i8* @llvm.objc.retainBlock(i8* %arg0)
190	ret i8* %0
191}
192
193define void @test_objc_storeStrong(i8** %arg0, i8* %arg1) {
194; CHECK-LABEL: test_objc_storeStrong
195; CHECK-NEXT: entry
196; CHECK-NEXT: call void @objc_storeStrong(i8** %arg0, i8* %arg1)
197; CHECK-NEXT: ret void
198entry:
199  call void @llvm.objc.storeStrong(i8** %arg0, i8* %arg1)
200	ret void
201}
202
203define i8* @test_objc_storeWeak(i8** %arg0, i8* %arg1) {
204; CHECK-LABEL: test_objc_storeWeak
205; CHECK-NEXT: entry
206; CHECK-NEXT: %0 = call i8* @objc_storeWeak(i8** %arg0, i8* %arg1)
207; CHECK-NEXT: ret i8* %0
208entry:
209  %0 = call i8* @llvm.objc.storeWeak(i8** %arg0, i8* %arg1)
210	ret i8* %0
211}
212
213define i8* @test_objc_unsafeClaimAutoreleasedReturnValue(i8* %arg0) {
214; CHECK-LABEL: test_objc_unsafeClaimAutoreleasedReturnValue
215; CHECK-NEXT: entry
216; CHECK-NEXT: %0 = tail call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* %arg0)
217; CHECK-NEXT: ret i8* %0
218entry:
219  %0 = call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* %arg0)
220  ret i8* %0
221}
222
223define void @test_objc_unsafeClaimAutoreleasedReturnValue_bundle() {
224; CHECK-LABEL: test_objc_unsafeClaimAutoreleasedReturnValue_bundle(
225; CHECK-NEXT: call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @objc_unsafeClaimAutoreleasedReturnValue) ]
226  call i8* @foo() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ]
227  ret void
228}
229
230define i8* @test_objc_retainedObject(i8* %arg0) {
231; CHECK-LABEL: test_objc_retainedObject
232; CHECK-NEXT: entry
233; CHECK-NEXT: %0 = call i8* @objc_retainedObject(i8* %arg0)
234; CHECK-NEXT: ret i8* %0
235entry:
236  %0 = call i8* @llvm.objc.retainedObject(i8* %arg0)
237  ret i8* %0
238}
239
240define i8* @test_objc_unretainedObject(i8* %arg0) {
241; CHECK-LABEL: test_objc_unretainedObject
242; CHECK-NEXT: entry
243; CHECK-NEXT: %0 = call i8* @objc_unretainedObject(i8* %arg0)
244; CHECK-NEXT: ret i8* %0
245entry:
246  %0 = call i8* @llvm.objc.unretainedObject(i8* %arg0)
247  ret i8* %0
248}
249
250define i8* @test_objc_unretainedPointer(i8* %arg0) {
251; CHECK-LABEL: test_objc_unretainedPointer
252; CHECK-NEXT: entry
253; CHECK-NEXT: %0 = call i8* @objc_unretainedPointer(i8* %arg0)
254; CHECK-NEXT: ret i8* %0
255entry:
256  %0 = call i8* @llvm.objc.unretainedPointer(i8* %arg0)
257  ret i8* %0
258}
259
260define i8* @test_objc_retain_autorelease(i8* %arg0) {
261; CHECK-LABEL: test_objc_retain_autorelease
262; CHECK-NEXT: entry
263; CHECK-NEXT: %0 = call i8* @objc_retain_autorelease(i8* %arg0)
264; CHECK-NEXT: ret i8* %0
265entry:
266  %0 = call i8* @llvm.objc.retain.autorelease(i8* %arg0)
267  ret i8* %0
268}
269
270define i32 @test_objc_sync_enter(i8* %arg0) {
271; CHECK-LABEL: test_objc_sync_enter
272; CHECK-NEXT: entry
273; CHECK-NEXT: %0 = call i32 @objc_sync_enter(i8* %arg0)
274; CHECK-NEXT: ret i32 %0
275entry:
276  %0 = call i32 @llvm.objc.sync.enter(i8* %arg0)
277  ret i32 %0
278}
279
280define i32 @test_objc_sync_exit(i8* %arg0) {
281; CHECK-LABEL: test_objc_sync_exit
282; CHECK-NEXT: entry
283; CHECK-NEXT: %0 = call i32 @objc_sync_exit(i8* %arg0)
284; CHECK-NEXT: ret i32 %0
285entry:
286  %0 = call i32 @llvm.objc.sync.exit(i8* %arg0)
287  ret i32 %0
288}
289
290declare i8* @llvm.objc.autorelease(i8*)
291declare void @llvm.objc.autoreleasePoolPop(i8*)
292declare i8* @llvm.objc.autoreleasePoolPush()
293declare i8* @llvm.objc.autoreleaseReturnValue(i8*)
294declare void @llvm.objc.copyWeak(i8**, i8**)
295declare void @llvm.objc.destroyWeak(i8**)
296declare extern_weak i8* @llvm.objc.initWeak(i8**, i8*)
297declare i8* @llvm.objc.loadWeak(i8**)
298declare i8* @llvm.objc.loadWeakRetained(i8**)
299declare void @llvm.objc.moveWeak(i8**, i8**)
300declare void @llvm.objc.release(i8*)
301declare i8* @llvm.objc.retain(i8*)
302declare i8* @llvm.objc.retainAutorelease(i8*)
303declare i8* @llvm.objc.retainAutoreleaseReturnValue(i8*)
304declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*)
305declare i8* @llvm.objc.retainBlock(i8*)
306declare void @llvm.objc.storeStrong(i8**, i8*)
307declare i8* @llvm.objc.storeWeak(i8**, i8*)
308declare i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8*)
309declare i8* @llvm.objc.retainedObject(i8*)
310declare i8* @llvm.objc.unretainedObject(i8*)
311declare i8* @llvm.objc.unretainedPointer(i8*)
312declare i8* @llvm.objc.retain.autorelease(i8*)
313declare i32 @llvm.objc.sync.enter(i8*)
314declare i32 @llvm.objc.sync.exit(i8*)
315
316attributes #0 = { nounwind }
317
318; CHECK: declare i8* @objc_autorelease(i8*)
319; CHECK: declare void @objc_autoreleasePoolPop(i8*)
320; CHECK: declare i8* @objc_autoreleasePoolPush()
321; CHECK: declare i8* @objc_autoreleaseReturnValue(i8*)
322; CHECK: declare void @objc_copyWeak(i8**, i8**)
323; CHECK: declare void @objc_destroyWeak(i8**)
324; CHECK: declare extern_weak i8* @objc_initWeak(i8**, i8*)
325; CHECK: declare i8* @objc_loadWeak(i8**)
326; CHECK: declare i8* @objc_loadWeakRetained(i8**)
327; CHECK: declare void @objc_moveWeak(i8**, i8**)
328; CHECK: declare void @objc_release(i8*) [[NLB:#[0-9]+]]
329; CHECK: declare i8* @objc_retain(i8*) [[NLB]]
330; CHECK: declare i8* @objc_retainAutorelease(i8*)
331; CHECK: declare i8* @objc_retainAutoreleaseReturnValue(i8*)
332; CHECK: declare i8* @objc_retainAutoreleasedReturnValue(i8*)
333; CHECK: declare i8* @objc_retainBlock(i8*)
334; CHECK: declare void @objc_storeStrong(i8**, i8*)
335; CHECK: declare i8* @objc_storeWeak(i8**, i8*)
336; CHECK: declare i8* @objc_unsafeClaimAutoreleasedReturnValue(i8*)
337; CHECK: declare i8* @objc_retainedObject(i8*)
338; CHECK: declare i8* @objc_unretainedObject(i8*)
339; CHECK: declare i8* @objc_unretainedPointer(i8*)
340; CHECK: declare i8* @objc_retain_autorelease(i8*)
341; CHECK: declare i32 @objc_sync_enter(i8*)
342; CHECK: declare i32 @objc_sync_exit(i8*)
343
344; CHECK: attributes #0 = { nounwind }
345; CHECK: attributes [[NLB]] = { nonlazybind }
346