• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt -mtriple x86_64-unknown-windows-msvc -objc-arc -S -o - %s | FileCheck %s
2
3; bool g();
4; id h();
5;
6; void f() {
7;   id a = nullptr;
8;   if (g())
9;     a = h();
10;   id b = nullptr;
11;   g();
12; }
13
14declare zeroext i1 @"\01?g@@YA_NXZ"() local_unnamed_addr
15declare i8* @"\01?h@@YAPEAUobjc_object@@XZ"() local_unnamed_addr
16
17declare dllimport void @objc_release(i8*) local_unnamed_addr
18declare dllimport i8* @objc_retainAutoreleasedReturnValue(i8* returned) local_unnamed_addr
19
20declare i32 @__CxxFrameHandler3(...)
21
22define void @"\01?f@@YAXXZ"() local_unnamed_addr personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
23entry:
24  %call = invoke zeroext i1 @"\01?g@@YA_NXZ"()
25          to label %invoke.cont unwind label %ehcleanup6
26
27invoke.cont:                                      ; preds = %entry
28  br i1 %call, label %if.then, label %if.end
29
30if.then:                                          ; preds = %invoke.cont
31  %call2 = invoke i8* @"\01?h@@YAPEAUobjc_object@@XZ"()
32          to label %invoke.cont1 unwind label %ehcleanup6
33
34invoke.cont1:                                     ; preds = %if.then
35  %0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call2)
36  tail call void @objc_release(i8* null), !clang.imprecise_release !1
37  br label %if.end
38
39if.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
43
44invoke.cont3:                                     ; preds = %if.end
45  tail call void @objc_release(i8* null), !clang.imprecise_release !1
46  tail call void @objc_release(i8* %a.0), !clang.imprecise_release !1
47  ret void
48
49ehcleanup:                                        ; preds = %if.end
50  %1 = cleanuppad within none []
51  call void @objc_release(i8* null) [ "funclet"(token %1) ], !clang.imprecise_release !1
52  cleanupret from %1 unwind label %ehcleanup6
53
54ehcleanup6:                                       ; 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 @objc_release(i8* %a.1) [ "funclet"(token %2) ], !clang.imprecise_release !1
58  cleanupret from %2 unwind to caller
59}
60
61; CHECK-LABEL: ?f@@YAXXZ
62; CHECK: call void @objc_release(i8* {{.*}}) {{.*}}[ "funclet"(token %1) ]
63; CHECK-NOT: call void @objc_release(i8* {{.*}}) {{.*}}[ "funclet"(token %2) ]
64
65define void @"\01?i@@YAXXZ"() local_unnamed_addr personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
66entry:
67  %call = invoke zeroext i1 @"\01?g@@YA_NXZ"()
68          to label %invoke.cont unwind label %ehcleanup6
69
70invoke.cont:                                      ; preds = %entry
71  br i1 %call, label %if.then, label %if.end
72
73if.then:                                          ; preds = %invoke.cont
74  %call2 = invoke i8* @"\01?h@@YAPEAUobjc_object@@XZ"()
75          to label %invoke.cont1 unwind label %ehcleanup6
76
77invoke.cont1:                                     ; preds = %if.then
78  %0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call2)
79  tail call void @objc_release(i8* null), !clang.imprecise_release !1
80  br label %if.end
81
82if.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
86
87invoke.cont3:                                     ; preds = %if.end
88  tail call void @objc_release(i8* null), !clang.imprecise_release !1
89  tail call void @objc_release(i8* %a.0), !clang.imprecise_release !1
90  ret void
91
92ehcleanup:                                        ; preds = %if.end
93  %1 = cleanuppad within none []
94  call void @objc_release(i8* null) [ "funclet"(token %1) ], !clang.imprecise_release !1
95  br label %ehcleanup.1
96
97ehcleanup.1:
98  cleanupret from %1 unwind label %ehcleanup6
99
100ehcleanup6:                                       ; 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 @objc_release(i8* %a.1) [ "funclet"(token %2) ], !clang.imprecise_release !1
104  cleanupret from %2 unwind to caller
105}
106
107; CHECK-LABEL: ?i@@YAXXZ
108; CHECK: call void @objc_release(i8* {{.*}}) {{.*}}[ "funclet"(token %1) ]
109; CHECK-NOT: call void @objc_release(i8* {{.*}}) {{.*}}[ "funclet"(token %2) ]
110
111!1 = !{}
112
113