xref: /llvm-project/llvm/test/Transforms/ObjCARC/retain-not-declared.ll (revision 01e4f41b43b57dee751146fde9992c660bd7c714)
1; RUN: opt -S -passes=objc-arc,objc-arc-contract < %s | FileCheck %s
2
3target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
4declare ptr @llvm.objc.unretainedObject(ptr)
5declare ptr @llvm.objc.retainAutoreleasedReturnValue(ptr)
6declare ptr @llvm.objc.autoreleaseReturnValue(ptr)
7declare ptr @objc_msgSend(ptr, ptr, ...)
8declare void @llvm.objc.release(ptr)
9
10; Test that the optimizer can create an objc_retainAutoreleaseReturnValue
11; declaration even if no objc_retain declaration exists.
12; rdar://9401303
13
14; CHECK:      define ptr @test0(ptr %p) {
15; CHECK-NEXT: entry:
16; CHECK-NEXT:   %0 = tail call ptr @llvm.objc.retainAutoreleaseReturnValue(ptr %p) [[NUW:#[0-9]+]]
17; CHECK-NEXT:   ret ptr %0
18; CHECK-NEXT: }
19
20define ptr @test0(ptr %p) {
21entry:
22  %call = tail call ptr @llvm.objc.unretainedObject(ptr %p)
23  %0 = tail call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %call) nounwind
24  %1 = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr %call) nounwind
25  ret ptr %call
26}
27
28; Properly create the @llvm.objc.retain declaration when it doesn't already exist.
29; rdar://9825114
30
31; CHECK-LABEL: @test1(
32; CHECK: @llvm.objc.retain
33; CHECK: @llvm.objc.retainAutoreleasedReturnValue(
34; CHECK: @llvm.objc.release
35; CHECK: @llvm.objc.release
36; CHECK: }
37define void @test1(ptr %call88) nounwind personality ptr @__gxx_personality_v0 {
38entry:
39  %tmp1 = call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %call88) nounwind
40  %call94 = invoke ptr @objc_msgSend(ptr %tmp1)
41          to label %invoke.cont93 unwind label %lpad91
42
43invoke.cont93:                                    ; preds = %entry
44  %tmp2 = call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %call94) nounwind
45  call void @llvm.objc.release(ptr %tmp1) nounwind
46  invoke void @objc_msgSend(ptr %tmp2)
47          to label %invoke.cont102 unwind label %lpad100
48
49invoke.cont102:                                   ; preds = %invoke.cont93
50  call void @llvm.objc.release(ptr %tmp2) nounwind, !clang.imprecise_release !0
51  unreachable
52
53lpad91:                                           ; preds = %entry
54  %exn91 = landingpad {ptr, i32}
55              cleanup
56  unreachable
57
58lpad100:                                          ; preds = %invoke.cont93
59  %exn100 = landingpad {ptr, i32}
60              cleanup
61  call void @llvm.objc.release(ptr %tmp2) nounwind, !clang.imprecise_release !0
62  unreachable
63}
64
65declare i32 @__gxx_personality_v0(...)
66
67!0 = !{}
68
69; CHECK: attributes [[NUW]] = { nounwind }
70