[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / test / Transforms / ObjCARC / funclet.ll
blob346a690bc046ae2cffdcb2f664e77ebe9296f21e
1 ; RUN: opt -mtriple x86_64-unknown-windows-msvc -objc-arc -S -o - %s | FileCheck %s
3 ; bool g();
4 ; id h();
6 ; void f() {
7 ;   id a = nullptr;
8 ;   if (g())
9 ;     a = h();
10 ;   id b = nullptr;
11 ;   g();
12 ; }
14 declare zeroext i1 @"\01?g@@YA_NXZ"() local_unnamed_addr
15 declare i8* @"\01?h@@YAPEAUobjc_object@@XZ"() local_unnamed_addr
17 declare dllimport void @llvm.objc.release(i8*) local_unnamed_addr
18 declare dllimport i8* @llvm.objc.retainAutoreleasedReturnValue(i8* returned) local_unnamed_addr
20 declare i32 @__CxxFrameHandler3(...)
22 define void @"\01?f@@YAXXZ"() local_unnamed_addr personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
23 entry:
24   %call = invoke zeroext i1 @"\01?g@@YA_NXZ"()
25           to label %invoke.cont unwind label %ehcleanup6
27 invoke.cont:                                      ; preds = %entry
28   br i1 %call, label %if.then, label %if.end
30 if.then:                                          ; preds = %invoke.cont
31   %call2 = invoke i8* @"\01?h@@YAPEAUobjc_object@@XZ"()
32           to label %invoke.cont1 unwind label %ehcleanup6
34 invoke.cont1:                                     ; preds = %if.then
35   %0 = tail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %call2)
36   tail call void @llvm.objc.release(i8* null), !clang.imprecise_release !1
37   br label %if.end
39 if.end:                                           ; preds = %invoke.cont1, %invoke.cont
40   %a.0 = phi i8* [ %call2, %invoke.cont1 ], [ null, %invoke.cont ]
41   %call4 = invoke zeroext i1 @"\01?g@@YA_NXZ"()
42           to label %invoke.cont3 unwind label %ehcleanup
44 invoke.cont3:                                     ; preds = %if.end
45   tail call void @llvm.objc.release(i8* null), !clang.imprecise_release !1
46   tail call void @llvm.objc.release(i8* %a.0), !clang.imprecise_release !1
47   ret void
49 ehcleanup:                                        ; preds = %if.end
50   %1 = cleanuppad within none []
51   call void @llvm.objc.release(i8* null) [ "funclet"(token %1) ], !clang.imprecise_release !1
52   cleanupret from %1 unwind label %ehcleanup6
54 ehcleanup6:                                       ; preds = %ehcleanup, %if.then, %entry
55   %a.1 = phi i8* [ %a.0, %ehcleanup ], [ null, %if.then ], [ null, %entry ]
56   %2 = cleanuppad within none []
57   call void @llvm.objc.release(i8* %a.1) [ "funclet"(token %2) ], !clang.imprecise_release !1
58   cleanupret from %2 unwind to caller
61 ; CHECK-LABEL: ?f@@YAXXZ
62 ; CHECK: call void @llvm.objc.release(i8* {{.*}}) {{.*}}[ "funclet"(token %1) ]
63 ; CHECK-NOT: call void @llvm.objc.release(i8* {{.*}}) {{.*}}[ "funclet"(token %2) ]
65 define void @"\01?i@@YAXXZ"() local_unnamed_addr personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
66 entry:
67   %call = invoke zeroext i1 @"\01?g@@YA_NXZ"()
68           to label %invoke.cont unwind label %ehcleanup6
70 invoke.cont:                                      ; preds = %entry
71   br i1 %call, label %if.then, label %if.end
73 if.then:                                          ; preds = %invoke.cont
74   %call2 = invoke i8* @"\01?h@@YAPEAUobjc_object@@XZ"()
75           to label %invoke.cont1 unwind label %ehcleanup6
77 invoke.cont1:                                     ; preds = %if.then
78   %0 = tail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %call2)
79   tail call void @llvm.objc.release(i8* null), !clang.imprecise_release !1
80   br label %if.end
82 if.end:                                           ; preds = %invoke.cont1, %invoke.cont
83   %a.0 = phi i8* [ %call2, %invoke.cont1 ], [ null, %invoke.cont ]
84   %call4 = invoke zeroext i1 @"\01?g@@YA_NXZ"()
85           to label %invoke.cont3 unwind label %ehcleanup
87 invoke.cont3:                                     ; preds = %if.end
88   tail call void @llvm.objc.release(i8* null), !clang.imprecise_release !1
89   tail call void @llvm.objc.release(i8* %a.0), !clang.imprecise_release !1
90   ret void
92 ehcleanup:                                        ; preds = %if.end
93   %1 = cleanuppad within none []
94   call void @llvm.objc.release(i8* null) [ "funclet"(token %1) ], !clang.imprecise_release !1
95   br label %ehcleanup.1
97 ehcleanup.1:
98   cleanupret from %1 unwind label %ehcleanup6
100 ehcleanup6:                                       ; preds = %ehcleanup, %if.then, %entry
101   %a.1 = phi i8* [ %a.0, %ehcleanup.1 ], [ null, %if.then ], [ null, %entry ]
102   %2 = cleanuppad within none []
103   call void @llvm.objc.release(i8* %a.1) [ "funclet"(token %2) ], !clang.imprecise_release !1
104   cleanupret from %2 unwind to caller
107 ; CHECK-LABEL: ?i@@YAXXZ
108 ; CHECK: call void @llvm.objc.release(i8* {{.*}}) {{.*}}[ "funclet"(token %1) ]
109 ; CHECK-NOT: call void @llvm.objc.release(i8* {{.*}}) {{.*}}[ "funclet"(token %2) ]
111 !1 = !{}