xref: /aosp_15_r20/external/llvm/test/Transforms/ObjCARC/allocas.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 Workerdeclare i8* @objc_retain(i8*)
4*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retainAutoreleasedReturnValue(i8*)
5*9880d681SAndroid Build Coastguard Workerdeclare void @objc_release(i8*)
6*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_autorelease(i8*)
7*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_autoreleaseReturnValue(i8*)
8*9880d681SAndroid Build Coastguard Workerdeclare void @objc_autoreleasePoolPop(i8*)
9*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_autoreleasePoolPush()
10*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retainBlock(i8*)
11*9880d681SAndroid Build Coastguard Worker
12*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_retainedObject(i8*)
13*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_unretainedObject(i8*)
14*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_unretainedPointer(i8*)
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Workerdeclare void @use_pointer(i8*)
17*9880d681SAndroid Build Coastguard Workerdeclare void @callee()
18*9880d681SAndroid Build Coastguard Workerdeclare void @callee_fnptr(void ()*)
19*9880d681SAndroid Build Coastguard Workerdeclare void @invokee()
20*9880d681SAndroid Build Coastguard Workerdeclare i8* @returner()
21*9880d681SAndroid Build Coastguard Workerdeclare i8* @returner1()
22*9880d681SAndroid Build Coastguard Workerdeclare i8* @returner2()
23*9880d681SAndroid Build Coastguard Workerdeclare void @bar(i32 ()*)
24*9880d681SAndroid Build Coastguard Workerdeclare void @use_alloca(i8**)
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.dbg.value(metadata, i64, metadata, metadata)
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Workerdeclare i8* @objc_msgSend(i8*, i8*, ...)
29*9880d681SAndroid Build Coastguard Worker
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker; In the presence of allocas, unconditionally remove retain/release pairs only
32*9880d681SAndroid Build Coastguard Worker; if they are known safe in both directions. This prevents matching up an inner
33*9880d681SAndroid Build Coastguard Worker; retain with the boundary guarding release in the following situation:
34*9880d681SAndroid Build Coastguard Worker;
35*9880d681SAndroid Build Coastguard Worker; %A = alloca
36*9880d681SAndroid Build Coastguard Worker; retain(%x)
37*9880d681SAndroid Build Coastguard Worker; retain(%x) <--- Inner Retain
38*9880d681SAndroid Build Coastguard Worker; store %x, %A
39*9880d681SAndroid Build Coastguard Worker; %y = load %A
40*9880d681SAndroid Build Coastguard Worker; ... DO STUFF ...
41*9880d681SAndroid Build Coastguard Worker; release(%y)
42*9880d681SAndroid Build Coastguard Worker; release(%x) <--- Guarding Release
43*9880d681SAndroid Build Coastguard Worker;
44*9880d681SAndroid Build Coastguard Worker; rdar://13750319
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1a(i8* %x)
47*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
48*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
49*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y)
50*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x)
51*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
52*9880d681SAndroid Build Coastguard Worker; CHECK: }
53*9880d681SAndroid Build Coastguard Workerdefine void @test1a(i8* %x) {
54*9880d681SAndroid Build Coastguard Workerentry:
55*9880d681SAndroid Build Coastguard Worker  %A = alloca i8*
56*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
57*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
58*9880d681SAndroid Build Coastguard Worker  store i8* %x, i8** %A, align 8
59*9880d681SAndroid Build Coastguard Worker  %y = load i8*, i8** %A
60*9880d681SAndroid Build Coastguard Worker  call void @use_alloca(i8** %A)
61*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %y), !clang.imprecise_release !0
62*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %x)
63*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %x), !clang.imprecise_release !0
64*9880d681SAndroid Build Coastguard Worker  ret void
65*9880d681SAndroid Build Coastguard Worker}
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1b(i8* %x)
68*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
69*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
70*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y)
71*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x)
72*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
73*9880d681SAndroid Build Coastguard Worker; CHECK: }
74*9880d681SAndroid Build Coastguard Workerdefine void @test1b(i8* %x) {
75*9880d681SAndroid Build Coastguard Workerentry:
76*9880d681SAndroid Build Coastguard Worker  %A = alloca i8*
77*9880d681SAndroid Build Coastguard Worker  %gep = getelementptr i8*, i8** %A, i32 0
78*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
79*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
80*9880d681SAndroid Build Coastguard Worker  store i8* %x, i8** %gep, align 8
81*9880d681SAndroid Build Coastguard Worker  %y = load i8*, i8** %A
82*9880d681SAndroid Build Coastguard Worker  call void @use_alloca(i8** %A)
83*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %y), !clang.imprecise_release !0
84*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %x)
85*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %x), !clang.imprecise_release !0
86*9880d681SAndroid Build Coastguard Worker  ret void
87*9880d681SAndroid Build Coastguard Worker}
88*9880d681SAndroid Build Coastguard Worker
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1c(i8* %x)
91*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
92*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
93*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y)
94*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x)
95*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
96*9880d681SAndroid Build Coastguard Worker; CHECK: }
97*9880d681SAndroid Build Coastguard Workerdefine void @test1c(i8* %x) {
98*9880d681SAndroid Build Coastguard Workerentry:
99*9880d681SAndroid Build Coastguard Worker  %A = alloca i8*, i32 3
100*9880d681SAndroid Build Coastguard Worker  %gep = getelementptr i8*, i8** %A, i32 2
101*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
102*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
103*9880d681SAndroid Build Coastguard Worker  store i8* %x, i8** %gep, align 8
104*9880d681SAndroid Build Coastguard Worker  %y = load i8*, i8** %gep
105*9880d681SAndroid Build Coastguard Worker  call void @use_alloca(i8** %A)
106*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %y), !clang.imprecise_release !0
107*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %x)
108*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %x), !clang.imprecise_release !0
109*9880d681SAndroid Build Coastguard Worker  ret void
110*9880d681SAndroid Build Coastguard Worker}
111*9880d681SAndroid Build Coastguard Worker
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1d(i8* %x)
114*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
115*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
116*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y)
117*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x)
118*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
119*9880d681SAndroid Build Coastguard Worker; CHECK: }
120*9880d681SAndroid Build Coastguard Workerdefine void @test1d(i8* %x) {
121*9880d681SAndroid Build Coastguard Workerentry:
122*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %use_allocaA, label %use_allocaB
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Workeruse_allocaA:
125*9880d681SAndroid Build Coastguard Worker  %allocaA = alloca i8*
126*9880d681SAndroid Build Coastguard Worker  br label %exit
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Workeruse_allocaB:
129*9880d681SAndroid Build Coastguard Worker  %allocaB = alloca i8*
130*9880d681SAndroid Build Coastguard Worker  br label %exit
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Workerexit:
133*9880d681SAndroid Build Coastguard Worker  %A = phi i8** [ %allocaA, %use_allocaA ], [ %allocaB, %use_allocaB ]
134*9880d681SAndroid Build Coastguard Worker  %gep = getelementptr i8*, i8** %A, i32 0
135*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
136*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
137*9880d681SAndroid Build Coastguard Worker  store i8* %x, i8** %gep, align 8
138*9880d681SAndroid Build Coastguard Worker  %y = load i8*, i8** %gep
139*9880d681SAndroid Build Coastguard Worker  call void @use_alloca(i8** %A)
140*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %y), !clang.imprecise_release !0
141*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %x)
142*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %x), !clang.imprecise_release !0
143*9880d681SAndroid Build Coastguard Worker  ret void
144*9880d681SAndroid Build Coastguard Worker}
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1e(i8* %x)
147*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
148*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
149*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y)
150*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x)
151*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
152*9880d681SAndroid Build Coastguard Worker; CHECK: }
153*9880d681SAndroid Build Coastguard Workerdefine void @test1e(i8* %x) {
154*9880d681SAndroid Build Coastguard Workerentry:
155*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %use_allocaA, label %use_allocaB
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Workeruse_allocaA:
158*9880d681SAndroid Build Coastguard Worker  %allocaA = alloca i8*, i32 4
159*9880d681SAndroid Build Coastguard Worker  br label %exit
160*9880d681SAndroid Build Coastguard Worker
161*9880d681SAndroid Build Coastguard Workeruse_allocaB:
162*9880d681SAndroid Build Coastguard Worker  %allocaB = alloca i8*, i32 4
163*9880d681SAndroid Build Coastguard Worker  br label %exit
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Workerexit:
166*9880d681SAndroid Build Coastguard Worker  %A = phi i8** [ %allocaA, %use_allocaA ], [ %allocaB, %use_allocaB ]
167*9880d681SAndroid Build Coastguard Worker  %gep = getelementptr i8*, i8** %A, i32 2
168*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
169*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
170*9880d681SAndroid Build Coastguard Worker  store i8* %x, i8** %gep, align 8
171*9880d681SAndroid Build Coastguard Worker  %y = load i8*, i8** %gep
172*9880d681SAndroid Build Coastguard Worker  call void @use_alloca(i8** %A)
173*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %y), !clang.imprecise_release !0
174*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %x)
175*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %x), !clang.imprecise_release !0
176*9880d681SAndroid Build Coastguard Worker  ret void
177*9880d681SAndroid Build Coastguard Worker}
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1f(i8* %x)
180*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
181*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
182*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y)
183*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x)
184*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
185*9880d681SAndroid Build Coastguard Worker; CHECK: }
186*9880d681SAndroid Build Coastguard Workerdefine void @test1f(i8* %x) {
187*9880d681SAndroid Build Coastguard Workerentry:
188*9880d681SAndroid Build Coastguard Worker  %allocaOne = alloca i8*
189*9880d681SAndroid Build Coastguard Worker  %allocaTwo = alloca i8*
190*9880d681SAndroid Build Coastguard Worker  %A = select i1 undef, i8** %allocaOne, i8** %allocaTwo
191*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
192*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
193*9880d681SAndroid Build Coastguard Worker  store i8* %x, i8** %A, align 8
194*9880d681SAndroid Build Coastguard Worker  %y = load i8*, i8** %A
195*9880d681SAndroid Build Coastguard Worker  call void @use_alloca(i8** %A)
196*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %y), !clang.imprecise_release !0
197*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %x)
198*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %x), !clang.imprecise_release !0
199*9880d681SAndroid Build Coastguard Worker  ret void
200*9880d681SAndroid Build Coastguard Worker}
201*9880d681SAndroid Build Coastguard Worker
202*9880d681SAndroid Build Coastguard Worker; Make sure that if a store is in a different basic block we handle known safe
203*9880d681SAndroid Build Coastguard Worker; conservatively.
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Worker
206*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test2a(i8* %x)
207*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
208*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
209*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y)
210*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x)
211*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
212*9880d681SAndroid Build Coastguard Worker; CHECK: }
213*9880d681SAndroid Build Coastguard Workerdefine void @test2a(i8* %x) {
214*9880d681SAndroid Build Coastguard Workerentry:
215*9880d681SAndroid Build Coastguard Worker  %A = alloca i8*
216*9880d681SAndroid Build Coastguard Worker  store i8* %x, i8** %A, align 8
217*9880d681SAndroid Build Coastguard Worker  %y = load i8*, i8** %A
218*9880d681SAndroid Build Coastguard Worker  br label %bb1
219*9880d681SAndroid Build Coastguard Worker
220*9880d681SAndroid Build Coastguard Workerbb1:
221*9880d681SAndroid Build Coastguard Worker  br label %bb2
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Workerbb2:
224*9880d681SAndroid Build Coastguard Worker  br label %bb3
225*9880d681SAndroid Build Coastguard Worker
226*9880d681SAndroid Build Coastguard Workerbb3:
227*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
228*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
229*9880d681SAndroid Build Coastguard Worker  call void @use_alloca(i8** %A)
230*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %y), !clang.imprecise_release !0
231*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %x)
232*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %x), !clang.imprecise_release !0
233*9880d681SAndroid Build Coastguard Worker  ret void
234*9880d681SAndroid Build Coastguard Worker}
235*9880d681SAndroid Build Coastguard Worker
236*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test2b(i8* %x)
237*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
238*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
239*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y)
240*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x)
241*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
242*9880d681SAndroid Build Coastguard Worker; CHECK: }
243*9880d681SAndroid Build Coastguard Workerdefine void @test2b(i8* %x) {
244*9880d681SAndroid Build Coastguard Workerentry:
245*9880d681SAndroid Build Coastguard Worker  %A = alloca i8*
246*9880d681SAndroid Build Coastguard Worker  %gep1 = getelementptr i8*, i8** %A, i32 0
247*9880d681SAndroid Build Coastguard Worker  store i8* %x, i8** %gep1, align 8
248*9880d681SAndroid Build Coastguard Worker  %gep2 = getelementptr i8*, i8** %A, i32 0
249*9880d681SAndroid Build Coastguard Worker  %y = load i8*, i8** %gep2
250*9880d681SAndroid Build Coastguard Worker  br label %bb1
251*9880d681SAndroid Build Coastguard Worker
252*9880d681SAndroid Build Coastguard Workerbb1:
253*9880d681SAndroid Build Coastguard Worker  br label %bb2
254*9880d681SAndroid Build Coastguard Worker
255*9880d681SAndroid Build Coastguard Workerbb2:
256*9880d681SAndroid Build Coastguard Worker  br label %bb3
257*9880d681SAndroid Build Coastguard Worker
258*9880d681SAndroid Build Coastguard Workerbb3:
259*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
260*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
261*9880d681SAndroid Build Coastguard Worker  call void @use_alloca(i8** %A)
262*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %y), !clang.imprecise_release !0
263*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %x)
264*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %x), !clang.imprecise_release !0
265*9880d681SAndroid Build Coastguard Worker  ret void
266*9880d681SAndroid Build Coastguard Worker}
267*9880d681SAndroid Build Coastguard Worker
268*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test2c(i8* %x)
269*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
270*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
271*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y)
272*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x)
273*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
274*9880d681SAndroid Build Coastguard Worker; CHECK: }
275*9880d681SAndroid Build Coastguard Workerdefine void @test2c(i8* %x) {
276*9880d681SAndroid Build Coastguard Workerentry:
277*9880d681SAndroid Build Coastguard Worker  %A = alloca i8*, i32 3
278*9880d681SAndroid Build Coastguard Worker  %gep1 = getelementptr i8*, i8** %A, i32 2
279*9880d681SAndroid Build Coastguard Worker  store i8* %x, i8** %gep1, align 8
280*9880d681SAndroid Build Coastguard Worker  %gep2 = getelementptr i8*, i8** %A, i32 2
281*9880d681SAndroid Build Coastguard Worker  %y = load i8*, i8** %gep2
282*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
283*9880d681SAndroid Build Coastguard Worker  br label %bb1
284*9880d681SAndroid Build Coastguard Worker
285*9880d681SAndroid Build Coastguard Workerbb1:
286*9880d681SAndroid Build Coastguard Worker  br label %bb2
287*9880d681SAndroid Build Coastguard Worker
288*9880d681SAndroid Build Coastguard Workerbb2:
289*9880d681SAndroid Build Coastguard Worker  br label %bb3
290*9880d681SAndroid Build Coastguard Worker
291*9880d681SAndroid Build Coastguard Workerbb3:
292*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
293*9880d681SAndroid Build Coastguard Worker  call void @use_alloca(i8** %A)
294*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %y), !clang.imprecise_release !0
295*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %x)
296*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %x), !clang.imprecise_release !0
297*9880d681SAndroid Build Coastguard Worker  ret void
298*9880d681SAndroid Build Coastguard Worker}
299*9880d681SAndroid Build Coastguard Worker
300*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test2d(i8* %x)
301*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
302*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_retain(i8* %x)
303*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %y)
304*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release(i8* %x)
305*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
306*9880d681SAndroid Build Coastguard Worker; CHECK: }
307*9880d681SAndroid Build Coastguard Workerdefine void @test2d(i8* %x) {
308*9880d681SAndroid Build Coastguard Workerentry:
309*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
310*9880d681SAndroid Build Coastguard Worker  br label %bb1
311*9880d681SAndroid Build Coastguard Worker
312*9880d681SAndroid Build Coastguard Workerbb1:
313*9880d681SAndroid Build Coastguard Worker  %Abb1 = alloca i8*, i32 3
314*9880d681SAndroid Build Coastguard Worker  %gepbb11 = getelementptr i8*, i8** %Abb1, i32 2
315*9880d681SAndroid Build Coastguard Worker  store i8* %x, i8** %gepbb11, align 8
316*9880d681SAndroid Build Coastguard Worker  %gepbb12 = getelementptr i8*, i8** %Abb1, i32 2
317*9880d681SAndroid Build Coastguard Worker  %ybb1 = load i8*, i8** %gepbb12
318*9880d681SAndroid Build Coastguard Worker  br label %bb3
319*9880d681SAndroid Build Coastguard Worker
320*9880d681SAndroid Build Coastguard Workerbb2:
321*9880d681SAndroid Build Coastguard Worker  %Abb2 = alloca i8*, i32 4
322*9880d681SAndroid Build Coastguard Worker  %gepbb21 = getelementptr i8*, i8** %Abb2, i32 2
323*9880d681SAndroid Build Coastguard Worker  store i8* %x, i8** %gepbb21, align 8
324*9880d681SAndroid Build Coastguard Worker  %gepbb22 = getelementptr i8*, i8** %Abb2, i32 2
325*9880d681SAndroid Build Coastguard Worker  %ybb2 = load i8*, i8** %gepbb22
326*9880d681SAndroid Build Coastguard Worker  br label %bb3
327*9880d681SAndroid Build Coastguard Worker
328*9880d681SAndroid Build Coastguard Workerbb3:
329*9880d681SAndroid Build Coastguard Worker  %A = phi i8** [ %Abb1, %bb1 ], [ %Abb2, %bb2 ]
330*9880d681SAndroid Build Coastguard Worker  %y = phi i8* [ %ybb1, %bb1 ], [ %ybb2, %bb2 ]
331*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %x)
332*9880d681SAndroid Build Coastguard Worker  call void @use_alloca(i8** %A)
333*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %y), !clang.imprecise_release !0
334*9880d681SAndroid Build Coastguard Worker  call void @use_pointer(i8* %x)
335*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %x), !clang.imprecise_release !0
336*9880d681SAndroid Build Coastguard Worker  ret void
337*9880d681SAndroid Build Coastguard Worker}
338*9880d681SAndroid Build Coastguard Worker
339*9880d681SAndroid Build Coastguard Worker; Make sure in the presence of allocas, if we find a cfghazard we do not perform
340*9880d681SAndroid Build Coastguard Worker; code motion even if we are known safe. These two concepts are separate and
341*9880d681SAndroid Build Coastguard Worker; should be treated as such.
342*9880d681SAndroid Build Coastguard Worker;
343*9880d681SAndroid Build Coastguard Worker; rdar://13949644
344*9880d681SAndroid Build Coastguard Worker
345*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test3a() {
346*9880d681SAndroid Build Coastguard Worker; CHECK: entry:
347*9880d681SAndroid Build Coastguard Worker; CHECK:   @objc_retainAutoreleasedReturnValue
348*9880d681SAndroid Build Coastguard Worker; CHECK:   @objc_retain
349*9880d681SAndroid Build Coastguard Worker; CHECK:   @objc_retain
350*9880d681SAndroid Build Coastguard Worker; CHECK:   @objc_retain
351*9880d681SAndroid Build Coastguard Worker; CHECK:   @objc_retain
352*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.body:
353*9880d681SAndroid Build Coastguard Worker; CHECK:   @objc_release
354*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release
355*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.done:
356*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release
357*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.body1:
358*9880d681SAndroid Build Coastguard Worker; CHECK:   @objc_release
359*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release
360*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.done1:
361*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release
362*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
363*9880d681SAndroid Build Coastguard Worker; CHECK: }
364*9880d681SAndroid Build Coastguard Workerdefine void @test3a() {
365*9880d681SAndroid Build Coastguard Workerentry:
366*9880d681SAndroid Build Coastguard Worker  %keys = alloca [2 x i8*], align 16
367*9880d681SAndroid Build Coastguard Worker  %objs = alloca [2 x i8*], align 16
368*9880d681SAndroid Build Coastguard Worker
369*9880d681SAndroid Build Coastguard Worker  %call1 = call i8* @returner()
370*9880d681SAndroid Build Coastguard Worker  %tmp0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call1)
371*9880d681SAndroid Build Coastguard Worker
372*9880d681SAndroid Build Coastguard Worker  %objs.begin = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 0
373*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %call1)
374*9880d681SAndroid Build Coastguard Worker  store i8* %call1, i8** %objs.begin, align 8
375*9880d681SAndroid Build Coastguard Worker  %objs.elt = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 1
376*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %call1)
377*9880d681SAndroid Build Coastguard Worker  store i8* %call1, i8** %objs.elt
378*9880d681SAndroid Build Coastguard Worker
379*9880d681SAndroid Build Coastguard Worker  %call2 = call i8* @returner1()
380*9880d681SAndroid Build Coastguard Worker  %call3 = call i8* @returner2()
381*9880d681SAndroid Build Coastguard Worker  %keys.begin = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 0
382*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %call2)
383*9880d681SAndroid Build Coastguard Worker  store i8* %call2, i8** %keys.begin, align 8
384*9880d681SAndroid Build Coastguard Worker  %keys.elt = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 1
385*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %call3)
386*9880d681SAndroid Build Coastguard Worker  store i8* %call3, i8** %keys.elt
387*9880d681SAndroid Build Coastguard Worker
388*9880d681SAndroid Build Coastguard Worker  %gep = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 2
389*9880d681SAndroid Build Coastguard Worker  br label %arraydestroy.body
390*9880d681SAndroid Build Coastguard Worker
391*9880d681SAndroid Build Coastguard Workerarraydestroy.body:
392*9880d681SAndroid Build Coastguard Worker  %arraydestroy.elementPast = phi i8** [ %gep, %entry ], [ %arraydestroy.element, %arraydestroy.body ]
393*9880d681SAndroid Build Coastguard Worker  %arraydestroy.element = getelementptr inbounds i8*, i8** %arraydestroy.elementPast, i64 -1
394*9880d681SAndroid Build Coastguard Worker  %destroy_tmp = load i8*, i8** %arraydestroy.element, align 8
395*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %destroy_tmp), !clang.imprecise_release !0
396*9880d681SAndroid Build Coastguard Worker  %objs_ptr = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 0
397*9880d681SAndroid Build Coastguard Worker  %arraydestroy.cmp = icmp eq i8** %arraydestroy.element, %objs_ptr
398*9880d681SAndroid Build Coastguard Worker  br i1 %arraydestroy.cmp, label %arraydestroy.done, label %arraydestroy.body
399*9880d681SAndroid Build Coastguard Worker
400*9880d681SAndroid Build Coastguard Workerarraydestroy.done:
401*9880d681SAndroid Build Coastguard Worker  %gep1 = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 2
402*9880d681SAndroid Build Coastguard Worker  br label %arraydestroy.body1
403*9880d681SAndroid Build Coastguard Worker
404*9880d681SAndroid Build Coastguard Workerarraydestroy.body1:
405*9880d681SAndroid Build Coastguard Worker  %arraydestroy.elementPast1 = phi i8** [ %gep1, %arraydestroy.done ], [ %arraydestroy.element1, %arraydestroy.body1 ]
406*9880d681SAndroid Build Coastguard Worker  %arraydestroy.element1 = getelementptr inbounds i8*, i8** %arraydestroy.elementPast1, i64 -1
407*9880d681SAndroid Build Coastguard Worker  %destroy_tmp1 = load i8*, i8** %arraydestroy.element1, align 8
408*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %destroy_tmp1), !clang.imprecise_release !0
409*9880d681SAndroid Build Coastguard Worker  %keys_ptr = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 0
410*9880d681SAndroid Build Coastguard Worker  %arraydestroy.cmp1 = icmp eq i8** %arraydestroy.element1, %keys_ptr
411*9880d681SAndroid Build Coastguard Worker  br i1 %arraydestroy.cmp1, label %arraydestroy.done1, label %arraydestroy.body1
412*9880d681SAndroid Build Coastguard Worker
413*9880d681SAndroid Build Coastguard Workerarraydestroy.done1:
414*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %call1), !clang.imprecise_release !0
415*9880d681SAndroid Build Coastguard Worker  ret void
416*9880d681SAndroid Build Coastguard Worker}
417*9880d681SAndroid Build Coastguard Worker
418*9880d681SAndroid Build Coastguard Worker; Make sure that even though we stop said code motion we still allow for
419*9880d681SAndroid Build Coastguard Worker; pointers to be removed if we are known safe in both directions.
420*9880d681SAndroid Build Coastguard Worker;
421*9880d681SAndroid Build Coastguard Worker; rdar://13949644
422*9880d681SAndroid Build Coastguard Worker
423*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test3b() {
424*9880d681SAndroid Build Coastguard Worker; CHECK: entry:
425*9880d681SAndroid Build Coastguard Worker; CHECK:   @objc_retainAutoreleasedReturnValue
426*9880d681SAndroid Build Coastguard Worker; CHECK:   @objc_retain
427*9880d681SAndroid Build Coastguard Worker; CHECK:   @objc_retain
428*9880d681SAndroid Build Coastguard Worker; CHECK:   @objc_retain
429*9880d681SAndroid Build Coastguard Worker; CHECK:   @objc_retain
430*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.body:
431*9880d681SAndroid Build Coastguard Worker; CHECK:   @objc_release
432*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release
433*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.done:
434*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release
435*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.body1:
436*9880d681SAndroid Build Coastguard Worker; CHECK:   @objc_release
437*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: @objc_release
438*9880d681SAndroid Build Coastguard Worker; CHECK: arraydestroy.done1:
439*9880d681SAndroid Build Coastguard Worker; CHECK: @objc_release
440*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
441*9880d681SAndroid Build Coastguard Worker; CHECK: }
442*9880d681SAndroid Build Coastguard Workerdefine void @test3b() {
443*9880d681SAndroid Build Coastguard Workerentry:
444*9880d681SAndroid Build Coastguard Worker  %keys = alloca [2 x i8*], align 16
445*9880d681SAndroid Build Coastguard Worker  %objs = alloca [2 x i8*], align 16
446*9880d681SAndroid Build Coastguard Worker
447*9880d681SAndroid Build Coastguard Worker  %call1 = call i8* @returner()
448*9880d681SAndroid Build Coastguard Worker  %tmp0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call1)
449*9880d681SAndroid Build Coastguard Worker  %tmp1 = tail call i8* @objc_retain(i8* %call1)
450*9880d681SAndroid Build Coastguard Worker
451*9880d681SAndroid Build Coastguard Worker  %objs.begin = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 0
452*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %call1)
453*9880d681SAndroid Build Coastguard Worker  store i8* %call1, i8** %objs.begin, align 8
454*9880d681SAndroid Build Coastguard Worker  %objs.elt = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 1
455*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %call1)
456*9880d681SAndroid Build Coastguard Worker  store i8* %call1, i8** %objs.elt
457*9880d681SAndroid Build Coastguard Worker
458*9880d681SAndroid Build Coastguard Worker  %call2 = call i8* @returner1()
459*9880d681SAndroid Build Coastguard Worker  %call3 = call i8* @returner2()
460*9880d681SAndroid Build Coastguard Worker  %keys.begin = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 0
461*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %call2)
462*9880d681SAndroid Build Coastguard Worker  store i8* %call2, i8** %keys.begin, align 8
463*9880d681SAndroid Build Coastguard Worker  %keys.elt = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 1
464*9880d681SAndroid Build Coastguard Worker  tail call i8* @objc_retain(i8* %call3)
465*9880d681SAndroid Build Coastguard Worker  store i8* %call3, i8** %keys.elt
466*9880d681SAndroid Build Coastguard Worker
467*9880d681SAndroid Build Coastguard Worker  %gep = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 2
468*9880d681SAndroid Build Coastguard Worker  br label %arraydestroy.body
469*9880d681SAndroid Build Coastguard Worker
470*9880d681SAndroid Build Coastguard Workerarraydestroy.body:
471*9880d681SAndroid Build Coastguard Worker  %arraydestroy.elementPast = phi i8** [ %gep, %entry ], [ %arraydestroy.element, %arraydestroy.body ]
472*9880d681SAndroid Build Coastguard Worker  %arraydestroy.element = getelementptr inbounds i8*, i8** %arraydestroy.elementPast, i64 -1
473*9880d681SAndroid Build Coastguard Worker  %destroy_tmp = load i8*, i8** %arraydestroy.element, align 8
474*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %destroy_tmp), !clang.imprecise_release !0
475*9880d681SAndroid Build Coastguard Worker  %objs_ptr = getelementptr inbounds [2 x i8*], [2 x i8*]* %objs, i64 0, i64 0
476*9880d681SAndroid Build Coastguard Worker  %arraydestroy.cmp = icmp eq i8** %arraydestroy.element, %objs_ptr
477*9880d681SAndroid Build Coastguard Worker  br i1 %arraydestroy.cmp, label %arraydestroy.done, label %arraydestroy.body
478*9880d681SAndroid Build Coastguard Worker
479*9880d681SAndroid Build Coastguard Workerarraydestroy.done:
480*9880d681SAndroid Build Coastguard Worker  %gep1 = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 2
481*9880d681SAndroid Build Coastguard Worker  br label %arraydestroy.body1
482*9880d681SAndroid Build Coastguard Worker
483*9880d681SAndroid Build Coastguard Workerarraydestroy.body1:
484*9880d681SAndroid Build Coastguard Worker  %arraydestroy.elementPast1 = phi i8** [ %gep1, %arraydestroy.done ], [ %arraydestroy.element1, %arraydestroy.body1 ]
485*9880d681SAndroid Build Coastguard Worker  %arraydestroy.element1 = getelementptr inbounds i8*, i8** %arraydestroy.elementPast1, i64 -1
486*9880d681SAndroid Build Coastguard Worker  %destroy_tmp1 = load i8*, i8** %arraydestroy.element1, align 8
487*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %destroy_tmp1), !clang.imprecise_release !0
488*9880d681SAndroid Build Coastguard Worker  %keys_ptr = getelementptr inbounds [2 x i8*], [2 x i8*]* %keys, i64 0, i64 0
489*9880d681SAndroid Build Coastguard Worker  %arraydestroy.cmp1 = icmp eq i8** %arraydestroy.element1, %keys_ptr
490*9880d681SAndroid Build Coastguard Worker  br i1 %arraydestroy.cmp1, label %arraydestroy.done1, label %arraydestroy.body1
491*9880d681SAndroid Build Coastguard Worker
492*9880d681SAndroid Build Coastguard Workerarraydestroy.done1:
493*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %call1), !clang.imprecise_release !0
494*9880d681SAndroid Build Coastguard Worker  call void @objc_release(i8* %call1), !clang.imprecise_release !0
495*9880d681SAndroid Build Coastguard Worker  ret void
496*9880d681SAndroid Build Coastguard Worker}
497*9880d681SAndroid Build Coastguard Worker
498*9880d681SAndroid Build Coastguard Worker!0 = !{}
499*9880d681SAndroid Build Coastguard Worker
500*9880d681SAndroid Build Coastguard Workerdeclare i32 @__gxx_personality_v0(...)
501