xref: /aosp_15_r20/external/llvm/test/Transforms/ObjCARC/rv.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -objc-arc -S < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-p:64:64:64"
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retain(i8*)
6*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retainAutoreleasedReturnValue(i8*)
7*9880d681SAndroid Build Coastguard Workerdeclare void @objc_release(i8*)
8*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_autorelease(i8*)
9*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_autoreleaseReturnValue(i8*)
10*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retainAutoreleaseReturnValue(i8*)
11*9880d681SAndroid Build Coastguard Workerdeclare void @objc_autoreleasePoolPop(i8*)
12*9880d681SAndroid Build Coastguard Workerdeclare void @objc_autoreleasePoolPush()
13*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retainBlock(i8*)
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retainedObject(i8*)
16*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_unretainedObject(i8*)
17*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_unretainedPointer(i8*)
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Workerdeclare void @use_pointer(i8*)
20*9880d681SAndroid Build Coastguard Workerdeclare void @callee()
21*9880d681SAndroid Build Coastguard Workerdeclare void @callee_fnptr(void ()*)
22*9880d681SAndroid Build Coastguard Workerdeclare void @invokee()
23*9880d681SAndroid Build Coastguard Workerdeclare i8* @returner()
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker; Test that retain+release elimination is suppressed when the
26*9880d681SAndroid Build Coastguard Worker; retain is an objc_retainAutoreleasedReturnValue, since it's
27*9880d681SAndroid Build Coastguard Worker; better to do the RV optimization.
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL:      define void @test0(
30*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
31*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   %x = call i8* @returner
32*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   %0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %x) [[NUW:#[0-9]+]]
33*9880d681SAndroid Build Coastguard Worker; CHECK: t:
34*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_
35*9880d681SAndroid Build Coastguard Worker; CHECK: return:
36*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @objc_release(i8* %x)
37*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
38*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
39*9880d681SAndroid Build Coastguard Workerdefine void @test0(i1 %p) nounwind {
40*9880d681SAndroid Build Coastguard Workerentry:
41*9880d681SAndroid Build Coastguard Worker  %x = call i8* @returner()
42*9880d681SAndroid Build Coastguard Worker  %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %x)
43*9880d681SAndroid Build Coastguard Worker  br i1 %p, label %t, label %return
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Workert:
46*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %x)
47*9880d681SAndroid Build Coastguard Worker  store i8 0, i8* %x
48*9880d681SAndroid Build Coastguard Worker  br label %return
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Workerreturn:
51*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %x) nounwind
52*9880d681SAndroid Build Coastguard Worker  ret void
53*9880d681SAndroid Build Coastguard Worker}
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker; Delete no-ops.
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test2(
58*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_
59*9880d681SAndroid Build Coastguard Worker; CHECK: }
60*9880d681SAndroid Build Coastguard Workerdefine void @test2() {
61*9880d681SAndroid Build Coastguard Worker  call i8* @objc_retainAutoreleasedReturnValue(i8* null)
62*9880d681SAndroid Build Coastguard Worker  call i8* @objc_autoreleaseReturnValue(i8* null)
63*9880d681SAndroid Build Coastguard Worker  ; call i8* @objc_retainAutoreleaseReturnValue(i8* null) ; TODO
64*9880d681SAndroid Build Coastguard Worker  ret void
65*9880d681SAndroid Build Coastguard Worker}
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker; Delete a redundant retainRV,autoreleaseRV when forwaring a call result
68*9880d681SAndroid Build Coastguard Worker; directly to a return value.
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8* @test3(
71*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @returner()
72*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i8* %call
73*9880d681SAndroid Build Coastguard Workerdefine i8* @test3() {
74*9880d681SAndroid Build Coastguard Workerentry:
75*9880d681SAndroid Build Coastguard Worker  %call = call i8* @returner()
76*9880d681SAndroid Build Coastguard Worker  %0 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
77*9880d681SAndroid Build Coastguard Worker  %1 = call i8* @objc_autoreleaseReturnValue(i8* %0) nounwind
78*9880d681SAndroid Build Coastguard Worker  ret i8* %1
79*9880d681SAndroid Build Coastguard Worker}
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker; Delete a redundant retain,autoreleaseRV when forwaring a call result
82*9880d681SAndroid Build Coastguard Worker; directly to a return value.
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8* @test4(
85*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @returner()
86*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i8* %call
87*9880d681SAndroid Build Coastguard Workerdefine i8* @test4() {
88*9880d681SAndroid Build Coastguard Workerentry:
89*9880d681SAndroid Build Coastguard Worker  %call = call i8* @returner()
90*9880d681SAndroid Build Coastguard Worker  %0 = call i8* @objc_retain(i8* %call) nounwind
91*9880d681SAndroid Build Coastguard Worker  %1 = call i8* @objc_autoreleaseReturnValue(i8* %0) nounwind
92*9880d681SAndroid Build Coastguard Worker  ret i8* %1
93*9880d681SAndroid Build Coastguard Worker}
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker; Delete a redundant fused retain+autoreleaseRV when forwaring a call result
96*9880d681SAndroid Build Coastguard Worker; directly to a return value.
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker; TODO
99*9880d681SAndroid Build Coastguard Worker; HECK: define i8* @test5
100*9880d681SAndroid Build Coastguard Worker; HECK: call i8* @returner()
101*9880d681SAndroid Build Coastguard Worker; HECK-NEXT: ret i8* %call
102*9880d681SAndroid Build Coastguard Worker;define i8* @test5() {
103*9880d681SAndroid Build Coastguard Worker;entry:
104*9880d681SAndroid Build Coastguard Worker;  %call = call i8* @returner()
105*9880d681SAndroid Build Coastguard Worker;  %0 = call i8* @objc_retainAutoreleaseReturnValue(i8* %call) nounwind
106*9880d681SAndroid Build Coastguard Worker;  ret i8* %0
107*9880d681SAndroid Build Coastguard Worker;}
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker; Don't eliminate objc_retainAutoreleasedReturnValue by merging it into
110*9880d681SAndroid Build Coastguard Worker; an objc_autorelease.
111*9880d681SAndroid Build Coastguard Worker; TODO? Merge objc_retainAutoreleasedReturnValue and objc_autorelease into
112*9880d681SAndroid Build Coastguard Worker; objc_retainAutoreleasedReturnValueAutorelease and merge
113*9880d681SAndroid Build Coastguard Worker; objc_retainAutoreleasedReturnValue and objc_autoreleaseReturnValue
114*9880d681SAndroid Build Coastguard Worker; into objc_retainAutoreleasedReturnValueAutoreleaseReturnValue?
115*9880d681SAndroid Build Coastguard Worker; Those entrypoints don't exist yet though.
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8* @test7(
118*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retainAutoreleasedReturnValue(i8* %p)
119*9880d681SAndroid Build Coastguard Worker; CHECK: %t = tail call i8* @objc_autoreleaseReturnValue(i8* %p)
120*9880d681SAndroid Build Coastguard Workerdefine i8* @test7() {
121*9880d681SAndroid Build Coastguard Worker  %p = call i8* @returner()
122*9880d681SAndroid Build Coastguard Worker  call i8* @objc_retainAutoreleasedReturnValue(i8* %p)
123*9880d681SAndroid Build Coastguard Worker  %t = call i8* @objc_autoreleaseReturnValue(i8* %p)
124*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %p)
125*9880d681SAndroid Build Coastguard Worker  ret i8* %t
126*9880d681SAndroid Build Coastguard Worker}
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8* @test7b(
129*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_retain(i8* %p)
130*9880d681SAndroid Build Coastguard Worker; CHECK: %t = tail call i8* @objc_autoreleaseReturnValue(i8* %p)
131*9880d681SAndroid Build Coastguard Workerdefine i8* @test7b() {
132*9880d681SAndroid Build Coastguard Worker  %p = call i8* @returner()
133*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %p)
134*9880d681SAndroid Build Coastguard Worker  call i8* @objc_retainAutoreleasedReturnValue(i8* %p)
135*9880d681SAndroid Build Coastguard Worker  %t = call i8* @objc_autoreleaseReturnValue(i8* %p)
136*9880d681SAndroid Build Coastguard Worker  ret i8* %p
137*9880d681SAndroid Build Coastguard Worker}
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Worker; Don't apply the RV optimization to autorelease if there's no retain.
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker; CHECK: define i8* @test9(i8* %p)
142*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_autorelease(i8* %p)
143*9880d681SAndroid Build Coastguard Workerdefine i8* @test9(i8* %p) {
144*9880d681SAndroid Build Coastguard Worker  call i8* @objc_autorelease(i8* %p)
145*9880d681SAndroid Build Coastguard Worker  ret i8* %p
146*9880d681SAndroid Build Coastguard Worker}
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker; Do not apply the RV optimization.
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Worker; CHECK: define i8* @test10(i8* %p)
151*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %p) [[NUW]]
152*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_autorelease(i8* %p) [[NUW]]
153*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i8* %p
154*9880d681SAndroid Build Coastguard Workerdefine i8* @test10(i8* %p) {
155*9880d681SAndroid Build Coastguard Worker  %1 = call i8* @objc_retain(i8* %p)
156*9880d681SAndroid Build Coastguard Worker  %2 = call i8* @objc_autorelease(i8* %p)
157*9880d681SAndroid Build Coastguard Worker  ret i8* %p
158*9880d681SAndroid Build Coastguard Worker}
159*9880d681SAndroid Build Coastguard Worker
160*9880d681SAndroid Build Coastguard Worker; Don't do the autoreleaseRV optimization because @use_pointer
161*9880d681SAndroid Build Coastguard Worker; could undo the retain.
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker; CHECK: define i8* @test11(i8* %p)
164*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %p)
165*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @use_pointer(i8* %p)
166*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_autorelease(i8* %p)
167*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i8* %p
168*9880d681SAndroid Build Coastguard Workerdefine i8* @test11(i8* %p) {
169*9880d681SAndroid Build Coastguard Worker  %1 = call i8* @objc_retain(i8* %p)
170*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %p)
171*9880d681SAndroid Build Coastguard Worker  %2 = call i8* @objc_autorelease(i8* %p)
172*9880d681SAndroid Build Coastguard Worker  ret i8* %p
173*9880d681SAndroid Build Coastguard Worker}
174*9880d681SAndroid Build Coastguard Worker
175*9880d681SAndroid Build Coastguard Worker; Don't spoil the RV optimization.
176*9880d681SAndroid Build Coastguard Worker
177*9880d681SAndroid Build Coastguard Worker; CHECK: define i8* @test12(i8* %p)
178*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retain(i8* %p)
179*9880d681SAndroid Build Coastguard Worker; CHECK: call void @use_pointer(i8* %p)
180*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_autoreleaseReturnValue(i8* %p)
181*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8* %p
182*9880d681SAndroid Build Coastguard Workerdefine i8* @test12(i8* %p) {
183*9880d681SAndroid Build Coastguard Worker  %1 = call i8* @objc_retain(i8* %p)
184*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %p)
185*9880d681SAndroid Build Coastguard Worker  %2 = call i8* @objc_autoreleaseReturnValue(i8* %p)
186*9880d681SAndroid Build Coastguard Worker  ret i8* %p
187*9880d681SAndroid Build Coastguard Worker}
188*9880d681SAndroid Build Coastguard Worker
189*9880d681SAndroid Build Coastguard Worker; Don't zap the objc_retainAutoreleasedReturnValue.
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8* @test13(
192*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_retainAutoreleasedReturnValue(i8* %p)
193*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_autorelease(i8* %p)
194*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8* %p
195*9880d681SAndroid Build Coastguard Workerdefine i8* @test13() {
196*9880d681SAndroid Build Coastguard Worker  %p = call i8* @returner()
197*9880d681SAndroid Build Coastguard Worker  %1 = call i8* @objc_retainAutoreleasedReturnValue(i8* %p)
198*9880d681SAndroid Build Coastguard Worker  call void @callee()
199*9880d681SAndroid Build Coastguard Worker  %2 = call i8* @objc_autorelease(i8* %p)
200*9880d681SAndroid Build Coastguard Worker  ret i8* %p
201*9880d681SAndroid Build Coastguard Worker}
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Worker; Convert objc_retainAutoreleasedReturnValue to objc_retain if its
204*9880d681SAndroid Build Coastguard Worker; argument is not a return value.
205*9880d681SAndroid Build Coastguard Worker
206*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test14(
207*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tail call i8* @objc_retain(i8* %p) [[NUW]]
208*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
209*9880d681SAndroid Build Coastguard Workerdefine void @test14(i8* %p) {
210*9880d681SAndroid Build Coastguard Worker  call i8* @objc_retainAutoreleasedReturnValue(i8* %p)
211*9880d681SAndroid Build Coastguard Worker  ret void
212*9880d681SAndroid Build Coastguard Worker}
213*9880d681SAndroid Build Coastguard Worker
214*9880d681SAndroid Build Coastguard Worker; Don't convert objc_retainAutoreleasedReturnValue to objc_retain if its
215*9880d681SAndroid Build Coastguard Worker; argument is a return value.
216*9880d681SAndroid Build Coastguard Worker
217*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test15(
218*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %y = call i8* @returner()
219*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tail call i8* @objc_retainAutoreleasedReturnValue(i8* %y) [[NUW]]
220*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void
221*9880d681SAndroid Build Coastguard Workerdefine void @test15() {
222*9880d681SAndroid Build Coastguard Worker  %y = call i8* @returner()
223*9880d681SAndroid Build Coastguard Worker  call i8* @objc_retainAutoreleasedReturnValue(i8* %y)
224*9880d681SAndroid Build Coastguard Worker  ret void
225*9880d681SAndroid Build Coastguard Worker}
226*9880d681SAndroid Build Coastguard Worker
227*9880d681SAndroid Build Coastguard Worker; Delete autoreleaseRV+retainRV pairs.
228*9880d681SAndroid Build Coastguard Worker
229*9880d681SAndroid Build Coastguard Worker; CHECK: define i8* @test19(i8* %p) {
230*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i8* %p
231*9880d681SAndroid Build Coastguard Workerdefine i8* @test19(i8* %p) {
232*9880d681SAndroid Build Coastguard Worker  call i8* @objc_autoreleaseReturnValue(i8* %p)
233*9880d681SAndroid Build Coastguard Worker  call i8* @objc_retainAutoreleasedReturnValue(i8* %p)
234*9880d681SAndroid Build Coastguard Worker  ret i8* %p
235*9880d681SAndroid Build Coastguard Worker}
236*9880d681SAndroid Build Coastguard Worker
237*9880d681SAndroid Build Coastguard Worker; Like test19 but with plain autorelease.
238*9880d681SAndroid Build Coastguard Worker
239*9880d681SAndroid Build Coastguard Worker; CHECK: define i8* @test20(i8* %p) {
240*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_autorelease(i8* %p)
241*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_retain(i8* %p)
242*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i8* %p
243*9880d681SAndroid Build Coastguard Workerdefine i8* @test20(i8* %p) {
244*9880d681SAndroid Build Coastguard Worker  call i8* @objc_autorelease(i8* %p)
245*9880d681SAndroid Build Coastguard Worker  call i8* @objc_retainAutoreleasedReturnValue(i8* %p)
246*9880d681SAndroid Build Coastguard Worker  ret i8* %p
247*9880d681SAndroid Build Coastguard Worker}
248*9880d681SAndroid Build Coastguard Worker
249*9880d681SAndroid Build Coastguard Worker; Like test19 but with plain retain.
250*9880d681SAndroid Build Coastguard Worker
251*9880d681SAndroid Build Coastguard Worker; CHECK: define i8* @test21(i8* %p) {
252*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_autoreleaseReturnValue(i8* %p)
253*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_retain(i8* %p)
254*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i8* %p
255*9880d681SAndroid Build Coastguard Workerdefine i8* @test21(i8* %p) {
256*9880d681SAndroid Build Coastguard Worker  call i8* @objc_autoreleaseReturnValue(i8* %p)
257*9880d681SAndroid Build Coastguard Worker  call i8* @objc_retain(i8* %p)
258*9880d681SAndroid Build Coastguard Worker  ret i8* %p
259*9880d681SAndroid Build Coastguard Worker}
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Worker; Like test19 but with plain retain and autorelease.
262*9880d681SAndroid Build Coastguard Worker
263*9880d681SAndroid Build Coastguard Worker; CHECK: define i8* @test22(i8* %p) {
264*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_autorelease(i8* %p)
265*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call i8* @objc_retain(i8* %p)
266*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret i8* %p
267*9880d681SAndroid Build Coastguard Workerdefine i8* @test22(i8* %p) {
268*9880d681SAndroid Build Coastguard Worker  call i8* @objc_autorelease(i8* %p)
269*9880d681SAndroid Build Coastguard Worker  call i8* @objc_retain(i8* %p)
270*9880d681SAndroid Build Coastguard Worker  ret i8* %p
271*9880d681SAndroid Build Coastguard Worker}
272*9880d681SAndroid Build Coastguard Worker
273*9880d681SAndroid Build Coastguard Worker; Convert autoreleaseRV to autorelease.
274*9880d681SAndroid Build Coastguard Worker
275*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @test23(
276*9880d681SAndroid Build Coastguard Worker; CHECK: call i8* @objc_autorelease(i8* %p) [[NUW]]
277*9880d681SAndroid Build Coastguard Workerdefine void @test23(i8* %p) {
278*9880d681SAndroid Build Coastguard Worker  store i8 0, i8* %p
279*9880d681SAndroid Build Coastguard Worker  call i8* @objc_autoreleaseReturnValue(i8* %p)
280*9880d681SAndroid Build Coastguard Worker  ret void
281*9880d681SAndroid Build Coastguard Worker}
282*9880d681SAndroid Build Coastguard Worker
283*9880d681SAndroid Build Coastguard Worker; Don't convert autoreleaseRV to autorelease if the result is returned,
284*9880d681SAndroid Build Coastguard Worker; even through a bitcast.
285*9880d681SAndroid Build Coastguard Worker
286*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define {}* @test24(
287*9880d681SAndroid Build Coastguard Worker; CHECK: tail call i8* @objc_autoreleaseReturnValue(i8* %p)
288*9880d681SAndroid Build Coastguard Workerdefine {}* @test24(i8* %p) {
289*9880d681SAndroid Build Coastguard Worker  %t = call i8* @objc_autoreleaseReturnValue(i8* %p)
290*9880d681SAndroid Build Coastguard Worker  %s = bitcast i8* %p to {}*
291*9880d681SAndroid Build Coastguard Worker  ret {}* %s
292*9880d681SAndroid Build Coastguard Worker}
293*9880d681SAndroid Build Coastguard Worker
294*9880d681SAndroid Build Coastguard Worker; CHECK: attributes [[NUW]] = { nounwind }
295