xref: /llvm-project/llvm/test/Transforms/ObjCARC/opt-catchswitch.ll (revision 01e4f41b43b57dee751146fde9992c660bd7c714)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=objc-arc < %s | FileCheck %s
3
4target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
5target triple = "i686--windows-msvc"
6
7declare ptr @f(ptr, ptr)
8
9declare i32 @__CxxFrameHandler3(...)
10
11declare dllimport ptr @llvm.objc.autoreleaseReturnValue(ptr returned)
12declare dllimport ptr @llvm.objc.retain(ptr returned)
13declare dllimport ptr @llvm.objc.retainAutoreleasedReturnValue(ptr returned)
14declare dllimport void @llvm.objc.release(ptr)
15
16define ptr @g(ptr %p, ptr %q) local_unnamed_addr personality ptr @__CxxFrameHandler3 {
17; CHECK-LABEL: @g(
18; CHECK-NEXT:  entry:
19; CHECK-NEXT:    [[TMP0:%.*]] = tail call ptr @llvm.objc.retain(ptr [[P:%.*]]) #[[ATTR0:[0-9]+]]
20; CHECK-NEXT:    [[V1:%.*]] = call ptr @f(ptr null, ptr null)
21; CHECK-NEXT:    [[CALL:%.*]] = invoke ptr @f(ptr [[P]], ptr [[Q:%.*]])
22; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[CATCH_DISPATCH:%.*]], !clang.arc.no_objc_arc_exceptions !0
23; CHECK:       catch.dispatch:
24; CHECK-NEXT:    [[TMP1:%.*]] = catchswitch within none [label %catch] unwind to caller
25; CHECK:       catch:
26; CHECK-NEXT:    [[TMP2:%.*]] = catchpad within [[TMP1]] [ptr null, i32 64, ptr null]
27; CHECK-NEXT:    catchret from [[TMP2]] to label [[CLEANUP:%.*]]
28; CHECK:       invoke.cont:
29; CHECK-NEXT:    [[TMP3:%.*]] = tail call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr [[CALL]]) #[[ATTR0]]
30; CHECK-NEXT:    br label [[CLEANUP]]
31; CHECK:       cleanup:
32; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi ptr [ [[CALL]], [[INVOKE_CONT]] ], [ null, [[CATCH:%.*]] ]
33; CHECK-NEXT:    tail call void @llvm.objc.release(ptr [[P]]) #[[ATTR0]], !clang.imprecise_release !0
34; CHECK-NEXT:    [[TMP4:%.*]] = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr [[RETVAL_0]]) #[[ATTR0]]
35; CHECK-NEXT:    ret ptr [[RETVAL_0]]
36;
37entry:
38  %0 = tail call ptr @llvm.objc.retain(ptr %p) #0
39  ; the following call prevents ARC optimizer from removing the retain/release
40  ; pair on %p
41  %v1 = call ptr @f(ptr null, ptr null)
42  %1 = tail call ptr @llvm.objc.retain(ptr %q) #0
43  %call = invoke ptr @f(ptr %p, ptr %q)
44  to label %invoke.cont unwind label %catch.dispatch, !clang.arc.no_objc_arc_exceptions !0
45
46catch.dispatch:
47  %2 = catchswitch within none [label %catch] unwind to caller
48
49catch:
50  %3 = catchpad within %2 [ptr null, i32 64, ptr null]
51  catchret from %3 to label %cleanup
52
53invoke.cont:
54  %4 = tail call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %call) #0
55  br label %cleanup
56
57cleanup:
58  %retval.0 = phi ptr [ %call, %invoke.cont ], [ null, %catch ]
59  tail call void @llvm.objc.release(ptr %q) #0, !clang.imprecise_release !0
60  tail call void @llvm.objc.release(ptr %p) #0, !clang.imprecise_release !0
61  %5 = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr %retval.0) #0
62  ret ptr %retval.0
63}
64
65attributes #0 = { nounwind }
66
67!0 = !{}
68