xref: /aosp_15_r20/external/llvm/test/Transforms/ObjCARC/invoke.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -objc-arc < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retain(i8*)
4*9880d681SAndroid Build Coastguard Workerdeclare void @objc_release(i8*)
5*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retainAutoreleasedReturnValue(i8*)
6*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_msgSend(i8*, i8*, ...)
7*9880d681SAndroid Build Coastguard Workerdeclare void @use_pointer(i8*)
8*9880d681SAndroid Build Coastguard Workerdeclare void @callee()
9*9880d681SAndroid Build Coastguard Workerdeclare i8* @returner()
10*9880d681SAndroid Build Coastguard Worker
11*9880d681SAndroid Build Coastguard Worker; ARCOpt shouldn't try to move the releases to the block containing the invoke.
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test0(
14*9880d681SAndroid Build Coastguard Worker; CHECK: invoke.cont:
15*9880d681SAndroid Build Coastguard Worker; CHECK:   call void @objc_release(i8* %zipFile) [[NUW:#[0-9]+]], !clang.imprecise_release !0
16*9880d681SAndroid Build Coastguard Worker; CHECK:   ret void
17*9880d681SAndroid Build Coastguard Worker; CHECK: lpad:
18*9880d681SAndroid Build Coastguard Worker; CHECK:   call void @objc_release(i8* %zipFile) [[NUW]], !clang.imprecise_release !0
19*9880d681SAndroid Build Coastguard Worker; CHECK:   ret void
20*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
21*9880d681SAndroid Build Coastguard Workerdefine void @test0(i8* %zipFile) personality i32 (...)* @__gxx_personality_v0 {
22*9880d681SAndroid Build Coastguard Workerentry:
23*9880d681SAndroid Build Coastguard Worker  call i8* @objc_retain(i8* %zipFile) nounwind
24*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %zipFile)
25*9880d681SAndroid Build Coastguard Worker  invoke void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*)*)(i8* %zipFile)
26*9880d681SAndroid Build Coastguard Worker          to label %invoke.cont unwind label %lpad
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Workerinvoke.cont:                                      ; preds = %entry
29*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
30*9880d681SAndroid Build Coastguard Worker  ret void
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Workerlpad:                                             ; preds = %entry
33*9880d681SAndroid Build Coastguard Worker  %exn = landingpad {i8*, i32}
34*9880d681SAndroid Build Coastguard Worker           cleanup
35*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
36*9880d681SAndroid Build Coastguard Worker  ret void
37*9880d681SAndroid Build Coastguard Worker}
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker; ARCOpt should move the release before the callee calls.
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test1(
42*9880d681SAndroid Build Coastguard Worker; CHECK: invoke.cont:
43*9880d681SAndroid Build Coastguard Worker; CHECK:   call void @objc_release(i8* %zipFile) [[NUW]], !clang.imprecise_release !0
44*9880d681SAndroid Build Coastguard Worker; CHECK:   call void @callee()
45*9880d681SAndroid Build Coastguard Worker; CHECK:   br label %done
46*9880d681SAndroid Build Coastguard Worker; CHECK: lpad:
47*9880d681SAndroid Build Coastguard Worker; CHECK:   call void @objc_release(i8* %zipFile) [[NUW]], !clang.imprecise_release !0
48*9880d681SAndroid Build Coastguard Worker; CHECK:   call void @callee()
49*9880d681SAndroid Build Coastguard Worker; CHECK:   br label %done
50*9880d681SAndroid Build Coastguard Worker; CHECK: done:
51*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
52*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
53*9880d681SAndroid Build Coastguard Workerdefine void @test1(i8* %zipFile) personality i32 (...)* @__gxx_personality_v0 {
54*9880d681SAndroid Build Coastguard Workerentry:
55*9880d681SAndroid Build Coastguard Worker  call i8* @objc_retain(i8* %zipFile) nounwind
56*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %zipFile)
57*9880d681SAndroid Build Coastguard Worker  invoke void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*)*)(i8* %zipFile)
58*9880d681SAndroid Build Coastguard Worker          to label %invoke.cont unwind label %lpad
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Workerinvoke.cont:                                      ; preds = %entry
61*9880d681SAndroid Build Coastguard Worker  call void @callee()
62*9880d681SAndroid Build Coastguard Worker  br label %done
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Workerlpad:                                             ; preds = %entry
65*9880d681SAndroid Build Coastguard Worker  %exn = landingpad {i8*, i32}
66*9880d681SAndroid Build Coastguard Worker           cleanup
67*9880d681SAndroid Build Coastguard Worker  call void @callee()
68*9880d681SAndroid Build Coastguard Worker  br label %done
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Workerdone:
71*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
72*9880d681SAndroid Build Coastguard Worker  ret void
73*9880d681SAndroid Build Coastguard Worker}
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker; The optimizer should ignore invoke unwind paths consistently.
76*9880d681SAndroid Build Coastguard Worker; PR12265
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test2() personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*) {
79*9880d681SAndroid Build Coastguard Worker; CHECK: invoke.cont:
80*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_retain
81*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_r
82*9880d681SAndroid Build Coastguard Worker; CHECK: finally.cont:
83*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release
84*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc
85*9880d681SAndroid Build Coastguard Worker; CHECK: finally.rethrow:
86*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc
87*9880d681SAndroid Build Coastguard Worker; CHECK: }
88*9880d681SAndroid Build Coastguard Workerdefine void @test2() personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*) {
89*9880d681SAndroid Build Coastguard Workerentry:
90*9880d681SAndroid Build Coastguard Worker  %call = invoke i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* ()*)()
91*9880d681SAndroid Build Coastguard Worker          to label %invoke.cont unwind label %finally.rethrow, !clang.arc.no_objc_arc_exceptions !0
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Workerinvoke.cont:                                      ; preds = %entry
94*9880d681SAndroid Build Coastguard Worker  %tmp1 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
95*9880d681SAndroid Build Coastguard Worker  call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void ()*)(), !clang.arc.no_objc_arc_exceptions !0
96*9880d681SAndroid Build Coastguard Worker  invoke void @use_pointer(i8* %call)
97*9880d681SAndroid Build Coastguard Worker          to label %finally.cont unwind label %finally.rethrow, !clang.arc.no_objc_arc_exceptions !0
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Workerfinally.cont:                                     ; preds = %invoke.cont
100*9880d681SAndroid Build Coastguard Worker  tail call void @objc_release(i8* %call) nounwind, !clang.imprecise_release !0
101*9880d681SAndroid Build Coastguard Worker  ret void
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Workerfinally.rethrow:                                  ; preds = %invoke.cont, %entry
104*9880d681SAndroid Build Coastguard Worker  %tmp2 = landingpad { i8*, i32 }
105*9880d681SAndroid Build Coastguard Worker          catch i8* null
106*9880d681SAndroid Build Coastguard Worker  unreachable
107*9880d681SAndroid Build Coastguard Worker}
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker; Don't try to place code on invoke critical edges.
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test3(
112*9880d681SAndroid Build Coastguard Worker; CHECK: if.end:
113*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %p) [[NUW]]
114*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
115*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
116*9880d681SAndroid Build Coastguard Workerdefine void @test3(i8* %p, i1 %b) personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*) {
117*9880d681SAndroid Build Coastguard Workerentry:
118*9880d681SAndroid Build Coastguard Worker  %0 = call i8* @objc_retain(i8* %p)
119*9880d681SAndroid Build Coastguard Worker  call void @callee()
120*9880d681SAndroid Build Coastguard Worker  br i1 %b, label %if.else, label %if.then
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Workerif.then:
123*9880d681SAndroid Build Coastguard Worker  invoke void @use_pointer(i8* %p)
124*9880d681SAndroid Build Coastguard Worker          to label %if.end unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Workerif.else:
127*9880d681SAndroid Build Coastguard Worker  invoke void @use_pointer(i8* %p)
128*9880d681SAndroid Build Coastguard Worker          to label %if.end unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Workerlpad:
131*9880d681SAndroid Build Coastguard Worker  %r = landingpad { i8*, i32 }
132*9880d681SAndroid Build Coastguard Worker       cleanup
133*9880d681SAndroid Build Coastguard Worker  ret void
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Workerif.end:
136*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %p)
137*9880d681SAndroid Build Coastguard Worker  ret void
138*9880d681SAndroid Build Coastguard Worker}
139*9880d681SAndroid Build Coastguard Worker
140*9880d681SAndroid Build Coastguard Worker; Like test3, but with ARC-relevant exception handling.
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test4(
143*9880d681SAndroid Build Coastguard Worker; CHECK: lpad:
144*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %r = landingpad { i8*, i32 }
145*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cleanup
146*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %p) [[NUW]]
147*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
148*9880d681SAndroid Build Coastguard Worker; CHECK: if.end:
149*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %p) [[NUW]]
150*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
151*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
152*9880d681SAndroid Build Coastguard Workerdefine void @test4(i8* %p, i1 %b) personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*) {
153*9880d681SAndroid Build Coastguard Workerentry:
154*9880d681SAndroid Build Coastguard Worker  %0 = call i8* @objc_retain(i8* %p)
155*9880d681SAndroid Build Coastguard Worker  call void @callee()
156*9880d681SAndroid Build Coastguard Worker  br i1 %b, label %if.else, label %if.then
157*9880d681SAndroid Build Coastguard Worker
158*9880d681SAndroid Build Coastguard Workerif.then:
159*9880d681SAndroid Build Coastguard Worker  invoke void @use_pointer(i8* %p)
160*9880d681SAndroid Build Coastguard Worker          to label %if.end unwind label %lpad
161*9880d681SAndroid Build Coastguard Worker
162*9880d681SAndroid Build Coastguard Workerif.else:
163*9880d681SAndroid Build Coastguard Worker  invoke void @use_pointer(i8* %p)
164*9880d681SAndroid Build Coastguard Worker          to label %if.end unwind label %lpad
165*9880d681SAndroid Build Coastguard Worker
166*9880d681SAndroid Build Coastguard Workerlpad:
167*9880d681SAndroid Build Coastguard Worker  %r = landingpad { i8*, i32 }
168*9880d681SAndroid Build Coastguard Worker       cleanup
169*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %p)
170*9880d681SAndroid Build Coastguard Worker  ret void
171*9880d681SAndroid Build Coastguard Worker
172*9880d681SAndroid Build Coastguard Workerif.end:
173*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %p)
174*9880d681SAndroid Build Coastguard Worker  ret void
175*9880d681SAndroid Build Coastguard Worker}
176*9880d681SAndroid Build Coastguard Worker
177*9880d681SAndroid Build Coastguard Worker; Don't turn the retainAutoreleaseReturnValue into retain, because it's
178*9880d681SAndroid Build Coastguard Worker; for an invoke which we can assume codegen will put immediately prior.
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test5(
181*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retainAutoreleasedReturnValue(i8* %z)
182*9880d681SAndroid Build Coastguard Worker; CHECK: }
183*9880d681SAndroid Build Coastguard Workerdefine void @test5() personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*) {
184*9880d681SAndroid Build Coastguard Workerentry:
185*9880d681SAndroid Build Coastguard Worker  %z = invoke i8* @returner()
186*9880d681SAndroid Build Coastguard Worker          to label %if.end unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0
187*9880d681SAndroid Build Coastguard Worker
188*9880d681SAndroid Build Coastguard Workerlpad:
189*9880d681SAndroid Build Coastguard Worker  %r13 = landingpad { i8*, i32 }
190*9880d681SAndroid Build Coastguard Worker          cleanup
191*9880d681SAndroid Build Coastguard Worker  ret void
192*9880d681SAndroid Build Coastguard Worker
193*9880d681SAndroid Build Coastguard Workerif.end:
194*9880d681SAndroid Build Coastguard Worker  call i8* @objc_retainAutoreleasedReturnValue(i8* %z)
195*9880d681SAndroid Build Coastguard Worker  ret void
196*9880d681SAndroid Build Coastguard Worker}
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Worker; Like test5, but there's intervening code.
199*9880d681SAndroid Build Coastguard Worker
200*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test6(
201*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain(i8* %z)
202*9880d681SAndroid Build Coastguard Worker; CHECK: }
203*9880d681SAndroid Build Coastguard Workerdefine void @test6() personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*) {
204*9880d681SAndroid Build Coastguard Workerentry:
205*9880d681SAndroid Build Coastguard Worker  %z = invoke i8* @returner()
206*9880d681SAndroid Build Coastguard Worker          to label %if.end unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Workerlpad:
209*9880d681SAndroid Build Coastguard Worker  %r13 = landingpad { i8*, i32 }
210*9880d681SAndroid Build Coastguard Worker          cleanup
211*9880d681SAndroid Build Coastguard Worker  ret void
212*9880d681SAndroid Build Coastguard Worker
213*9880d681SAndroid Build Coastguard Workerif.end:
214*9880d681SAndroid Build Coastguard Worker  call void @callee()
215*9880d681SAndroid Build Coastguard Worker  call i8* @objc_retainAutoreleasedReturnValue(i8* %z)
216*9880d681SAndroid Build Coastguard Worker  ret void
217*9880d681SAndroid Build Coastguard Worker}
218*9880d681SAndroid Build Coastguard Worker
219*9880d681SAndroid Build Coastguard Workerdeclare i32 @__gxx_personality_v0(...)
220*9880d681SAndroid Build Coastguard Workerdeclare i32 @__objc_personality_v0(...)
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker; CHECK: attributes [[NUW]] = { nounwind }
223*9880d681SAndroid Build Coastguard Worker
224*9880d681SAndroid Build Coastguard Worker!0 = !{}
225