xref: /llvm-project/llvm/test/Transforms/ObjCARC/contract-catchswitch.ll (revision 01e4f41b43b57dee751146fde9992c660bd7c714)
1; RUN: opt -S -passes=objc-arc-contract < %s | FileCheck %s
2
3target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
4target triple = "i686--windows-msvc19.11.0"
5
6%0 = type opaque
7
8declare i32 @__CxxFrameHandler3(...)
9declare dllimport void @llvm.objc.release(ptr) local_unnamed_addr
10declare dllimport ptr @llvm.objc.retain(ptr returned) local_unnamed_addr
11
12@p = global ptr null, align 4
13
14declare void @f() local_unnamed_addr
15
16define void @g() local_unnamed_addr personality ptr @__CxxFrameHandler3 {
17entry:
18  %tmp = load ptr, ptr @p, align 4
19  %tmp1 = tail call ptr @llvm.objc.retain(ptr %tmp) #0
20  ; Split the basic block to ensure bitcast ends up in entry.split.
21  br label %entry.split
22
23entry.split:
24  invoke void @f()
25          to label %invoke.cont unwind label %catch.dispatch
26
27; Dummy nested catchswitch to test looping through the dominator tree.
28catch.dispatch:
29  %tmp2 = catchswitch within none [label %catch] unwind label %catch.dispatch1
30
31catch:
32  %tmp3 = catchpad within %tmp2 [ptr null, i32 64, ptr null]
33  catchret from %tmp3 to label %invoke.cont
34
35catch.dispatch1:
36  %tmp4 = catchswitch within none [label %catch1] unwind label %ehcleanup
37
38catch1:
39  %tmp5 = catchpad within %tmp4 [ptr null, i32 64, ptr null]
40  catchret from %tmp5 to label %invoke.cont
41
42invoke.cont:
43  %tmp6 = load ptr, ptr @p, align 4
44  %tmp7 = tail call ptr @llvm.objc.retain(ptr %tmp6) #0
45  call void @llvm.objc.release(ptr %tmp) #0, !clang.imprecise_release !0
46  ; Split the basic block to ensure bitcast ends up in invoke.cont.split.
47  br label %invoke.cont.split
48
49invoke.cont.split:
50  invoke void @f()
51          to label %invoke.cont1 unwind label %ehcleanup
52
53invoke.cont1:
54  ret void
55
56ehcleanup:
57  %tmp8 = phi ptr [ %tmp, %catch.dispatch1 ], [ %tmp6, %invoke.cont.split ]
58  %tmp9 = cleanuppad within none []
59  call void @llvm.objc.release(ptr %tmp8) #0 [ "funclet"(token %tmp9) ]
60  cleanupret from %tmp9 unwind to caller
61}
62
63; CHECK-LABEL: entry.split:
64; CHECK-NEXT:    invoke void @f()
65; CHECK-NEXT:            to label %invoke.cont unwind label %catch.dispatch
66
67; CHECK-LABEL: invoke.cont.split:
68; CHECK-NEXT:    invoke void @f()
69; CHECK-NEXT:            to label %invoke.cont1 unwind label %ehcleanup
70
71; CHECK-LABEL: ehcleanup:
72; CHECK-NEXT:    %tmp8 = phi ptr [ %tmp1, %catch.dispatch1 ], [ %tmp7, %invoke.cont.split ]
73
74attributes #0 = { nounwind }
75
76!0 = !{}
77