[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / DeadStoreElimination / captures-before-load.ll
blobf50d1775e576bdefdba5b4924f56a0b374aa8eb8
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes='dse' -S %s | FileCheck %s
4 declare void @escape_and_clobber(i32*)
5 declare void @escape_writeonly(i32*) writeonly
6 declare void @clobber()
8 define i32 @test_not_captured_before_load_same_bb(i32** %in.ptr) {
9 ; CHECK-LABEL: @test_not_captured_before_load_same_bb(
10 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
11 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
12 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
13 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
14 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
15 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
17   %a = alloca i32, align 4
18   store i32 55, i32* %a
19   %in.lv.1 = load i32* , i32** %in.ptr, align 2
20   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
21   store i32 99, i32* %a, align 4
22   call void @escape_and_clobber(i32* %a)
23   ret i32 %in.lv.2
26 define i32 @test_not_captured_before_load_same_bb_escape_unreachable_block(i32** %in.ptr) {
27 ; CHECK-LABEL: @test_not_captured_before_load_same_bb_escape_unreachable_block(
28 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
29 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
30 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
31 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
32 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
33 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
34 ; CHECK:       unreach:
35 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
36 ; CHECK-NEXT:    ret i32 0
38   %a = alloca i32, align 4
39   store i32 55, i32* %a
40   %in.lv.1 = load i32* , i32** %in.ptr, align 2
41   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
42   store i32 99, i32* %a, align 4
43   call void @escape_and_clobber(i32* %a)
44   ret i32 %in.lv.2
46 unreach:
47   call void @escape_and_clobber(i32* %a)
48   ret i32 0
51 define i32 @test_captured_and_clobbered_after_load_same_bb_2(i32** %in.ptr) {
52 ; CHECK-LABEL: @test_captured_and_clobbered_after_load_same_bb_2(
53 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
54 ; CHECK-NEXT:    store i32 55, i32* [[A]], align 4
55 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
56 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
57 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
58 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
59 ; CHECK-NEXT:    call void @clobber()
60 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
62   %a = alloca i32, align 4
63   store i32 55, i32* %a
64   %in.lv.1 = load i32* , i32** %in.ptr, align 2
65   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
66   call void @escape_and_clobber(i32* %a)
67   store i32 99, i32* %a, align 4
68   call void @clobber()
69   ret i32 %in.lv.2
72 define i32 @test_captured_after_load_same_bb_2_clobbered_later(i32** %in.ptr) {
73 ; CHECK-LABEL: @test_captured_after_load_same_bb_2_clobbered_later(
74 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
75 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
76 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
77 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
78 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
79 ; CHECK-NEXT:    call void @clobber()
80 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
82   %a = alloca i32, align 4
83   store i32 55, i32* %a
84   %in.lv.1 = load i32* , i32** %in.ptr, align 2
85   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
86   call void @escape_writeonly(i32* %a)
87   store i32 99, i32* %a, align 4
88   call void @clobber()
89   ret i32 %in.lv.2
92 define i32 @test_captured_and_clobbered_before_load_same_bb_1(i32** %in.ptr) {
93 ; CHECK-LABEL: @test_captured_and_clobbered_before_load_same_bb_1(
94 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
95 ; CHECK-NEXT:    store i32 55, i32* [[A]], align 4
96 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
97 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
98 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
99 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
100 ; CHECK-NEXT:    call void @clobber()
101 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
103   %a = alloca i32, align 4
104   store i32 55, i32* %a
105   %in.lv.1 = load i32* , i32** %in.ptr, align 2
106   call void @escape_and_clobber(i32* %a)
107   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
108   store i32 99, i32* %a, align 4
109   call void @clobber()
110   ret i32 %in.lv.2
113 define i32 @test_captured_before_load_same_bb_1_clobbered_later(i32** %in.ptr) {
114 ; CHECK-LABEL: @test_captured_before_load_same_bb_1_clobbered_later(
115 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
116 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
117 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
118 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
119 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
120 ; CHECK-NEXT:    call void @clobber()
121 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
123   %a = alloca i32, align 4
124   store i32 55, i32* %a
125   %in.lv.1 = load i32* , i32** %in.ptr, align 2
126   call void @escape_writeonly(i32* %a)
127   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
128   store i32 99, i32* %a, align 4
129   call void @clobber()
130   ret i32 %in.lv.2
133 define i32 @test_captured_before_load_same_bb_2(i32** %in.ptr) {
134 ; CHECK-LABEL: @test_captured_before_load_same_bb_2(
135 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
136 ; CHECK-NEXT:    store i32 55, i32* [[A]], align 4
137 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
138 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
139 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
140 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
141 ; CHECK-NEXT:    call void @clobber()
142 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
144   %a = alloca i32, align 4
145   store i32 55, i32* %a
146   call void @escape_writeonly(i32* %a)
147   %in.lv.1 = load i32* , i32** %in.ptr, align 2
148   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
149   store i32 99, i32* %a, align 4
150   call void @clobber()
151   ret i32 %in.lv.2
154 define i32 @test_not_captured_before_load_same_bb_clobber(i32** %in.ptr) {
155 ; CHECK-LABEL: @test_not_captured_before_load_same_bb_clobber(
156 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
157 ; CHECK-NEXT:    call void @clobber()
158 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
159 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
160 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
161 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
162 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
164   %a = alloca i32, align 4
165   store i32 55, i32* %a
166   call void @clobber()
167   %in.lv.1 = load i32* , i32** %in.ptr, align 2
168   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
169   store i32 99, i32* %a, align 4
170   call void @escape_and_clobber(i32* %a)
171   ret i32 %in.lv.2
174 define i32 @test_captured_before_load_same_bb(i32** %in.ptr) {
175 ; CHECK-LABEL: @test_captured_before_load_same_bb(
176 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
177 ; CHECK-NEXT:    store i32 55, i32* [[A]], align 4
178 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
179 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
180 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
181 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
182 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
183 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
185   %a = alloca i32, align 4
186   store i32 55, i32* %a
187   call void @escape_and_clobber(i32* %a)
188   %in.lv.1 = load i32* , i32** %in.ptr, align 2
189   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
190   store i32 99, i32* %a, align 4
191   call void @escape_and_clobber(i32* %a)
192   ret i32 %in.lv.2
195 define i32 @test_captured_sibling_path_to_load_other_blocks_1(i32** %in.ptr, i1 %c.1) {
196 ; CHECK-LABEL: @test_captured_sibling_path_to_load_other_blocks_1(
197 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
198 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
199 ; CHECK:       then:
200 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
201 ; CHECK-NEXT:    br label [[EXIT:%.*]]
202 ; CHECK:       else:
203 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
204 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
205 ; CHECK-NEXT:    br label [[EXIT]]
206 ; CHECK:       exit:
207 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ELSE]] ]
208 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
209 ; CHECK-NEXT:    call void @clobber()
210 ; CHECK-NEXT:    ret i32 [[P]]
212   %a = alloca i32, align 4
213   store i32 55, i32* %a
214   br i1 %c.1, label %then, label %else
216 then:
217   call void @escape_writeonly(i32* %a)
218   br label %exit
220 else:
221   %in.lv.1 = load i32* , i32** %in.ptr, align 2
222   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
223   br label %exit
225 exit:
226   %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
227   store i32 99, i32* %a, align 4
228   call void @clobber()
229   ret i32 %p
232 define i32 @test_only_captured_sibling_path_with_ret_to_load_other_blocks(i32** %in.ptr, i1 %c.1) {
233 ; CHECK-LABEL: @test_only_captured_sibling_path_with_ret_to_load_other_blocks(
234 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
235 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
236 ; CHECK:       then:
237 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
238 ; CHECK-NEXT:    ret i32 0
239 ; CHECK:       else:
240 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
241 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
242 ; CHECK-NEXT:    br label [[EXIT:%.*]]
243 ; CHECK:       exit:
244 ; CHECK-NEXT:    call void @clobber()
245 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
247   %a = alloca i32, align 4
248   store i32 55, i32* %a
249   br i1 %c.1, label %then, label %else
251 then:
252   call void @escape_writeonly(i32* %a)
253   ret i32 0
255 else:
256   %in.lv.1 = load i32* , i32** %in.ptr, align 2
257   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
258   br label %exit
260 exit:
261   store i32 99, i32* %a, align 4
262   call void @clobber()
263   ret i32 %in.lv.2
266 define i32 @test_captured_before_load_other_blocks_2(i32** %in.ptr, i1 %c.1) {
267 ; CHECK-LABEL: @test_captured_before_load_other_blocks_2(
268 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
269 ; CHECK-NEXT:    store i32 55, i32* [[A]], align 4
270 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
271 ; CHECK:       then:
272 ; CHECK-NEXT:    br label [[EXIT:%.*]]
273 ; CHECK:       else:
274 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
275 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
276 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
277 ; CHECK-NEXT:    br label [[EXIT]]
278 ; CHECK:       exit:
279 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ELSE]] ]
280 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
281 ; CHECK-NEXT:    call void @clobber()
282 ; CHECK-NEXT:    ret i32 [[P]]
284   %a = alloca i32, align 4
285   store i32 55, i32* %a
286   br i1 %c.1, label %then, label %else
288 then:
289   br label %exit
291 else:
292   call void @escape_and_clobber(i32* %a)
293   %in.lv.1 = load i32* , i32** %in.ptr, align 2
294   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
295   br label %exit
297 exit:
298   %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
299   store i32 99, i32* %a, align 4
300   call void @clobber()
301   ret i32 %p
304 define i32 @test_captured_before_load_other_blocks_4(i32** %in.ptr, i1 %c.1) {
305 ; CHECK-LABEL: @test_captured_before_load_other_blocks_4(
306 ; CHECK-NEXT:  entry:
307 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
308 ; CHECK-NEXT:    store i32 55, i32* [[A]], align 4
309 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
310 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
311 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
312 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
313 ; CHECK:       then:
314 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
315 ; CHECK-NEXT:    br label [[EXIT]]
316 ; CHECK:       exit:
317 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ENTRY:%.*]] ]
318 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
319 ; CHECK-NEXT:    call void @clobber()
320 ; CHECK-NEXT:    ret i32 [[P]]
322 entry:
323   %a = alloca i32, align 4
324   store i32 55, i32* %a
325   call void @escape_writeonly(i32* %a)
326   %in.lv.1 = load i32* , i32** %in.ptr, align 2
327   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
328   br i1 %c.1, label %then, label %exit
330 then:
331   call void @escape_writeonly(i32* %a)
332   br label %exit
334 exit:
335   %p = phi i32 [ 0, %then ], [ %in.lv.2, %entry ]
336   store i32 99, i32* %a, align 4
337   call void @clobber()
338   ret i32 %p
341 define i32 @test_captured_before_load_other_blocks_5(i32** %in.ptr, i1 %c.1) {
342 ; CHECK-LABEL: @test_captured_before_load_other_blocks_5(
343 ; CHECK-NEXT:  entry:
344 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
345 ; CHECK-NEXT:    store i32 55, i32* [[A]], align 4
346 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
347 ; CHECK:       then:
348 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
349 ; CHECK-NEXT:    br label [[EXIT]]
350 ; CHECK:       exit:
351 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
352 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
353 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
354 ; CHECK-NEXT:    call void @clobber()
355 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
357 entry:
358   %a = alloca i32, align 4
359   store i32 55, i32* %a
360   br i1 %c.1, label %then, label %exit
362 then:
363   call void @escape_writeonly(i32* %a)
364   br label %exit
366 exit:
367   %in.lv.1 = load i32* , i32** %in.ptr, align 2
368   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
369   store i32 99, i32* %a, align 4
370   call void @clobber()
371   ret i32 %in.lv.2
374 define i32 @test_captured_before_load_other_blocks_6(i32** %in.ptr, i1 %c.1) {
375 ; CHECK-LABEL: @test_captured_before_load_other_blocks_6(
376 ; CHECK-NEXT:  entry:
377 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
378 ; CHECK-NEXT:    store i32 55, i32* [[A]], align 4
379 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
380 ; CHECK:       then:
381 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
382 ; CHECK-NEXT:    br label [[EXIT]]
383 ; CHECK:       exit:
384 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
385 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
386 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
387 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
388 ; CHECK-NEXT:    call void @clobber()
389 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
391 entry:
392   %a = alloca i32, align 4
393   store i32 55, i32* %a
394   br i1 %c.1, label %then, label %exit
396 then:
397   call void @escape_writeonly(i32* %a)
398   br label %exit
400 exit:
401   %in.lv.1 = load i32* , i32** %in.ptr, align 2
402   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
403   store i32 99, i32* %a, align 4
404   call void @escape_writeonly(i32* %a)
405   call void @clobber()
406   ret i32 %in.lv.2
409 define i32 @test_not_captured_before_load_other_blocks_1(i32** %in.ptr, i1 %c.1) {
410 ; CHECK-LABEL: @test_not_captured_before_load_other_blocks_1(
411 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
412 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
413 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
414 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
415 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
416 ; CHECK:       then:
417 ; CHECK-NEXT:    br label [[EXIT:%.*]]
418 ; CHECK:       else:
419 ; CHECK-NEXT:    br label [[EXIT]]
420 ; CHECK:       exit:
421 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
422 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
424   %a = alloca i32, align 4
425   store i32 55, i32* %a
426   %in.lv.1 = load i32* , i32** %in.ptr, align 2
427   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
428   store i32 99, i32* %a, align 4
429   br i1 %c.1, label %then, label %else
431 then:
432   br label %exit
434 else:
435   br label %exit
437 exit:
438   call void @escape_and_clobber(i32* %a)
439   ret i32 %in.lv.2
442 define i32 @test_not_captured_before_load_other_blocks_2(i32** %in.ptr, i1 %c.1) {
443 ; CHECK-LABEL: @test_not_captured_before_load_other_blocks_2(
444 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
445 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
446 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
447 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
448 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
449 ; CHECK:       then:
450 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
451 ; CHECK-NEXT:    br label [[EXIT:%.*]]
452 ; CHECK:       else:
453 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
454 ; CHECK-NEXT:    br label [[EXIT]]
455 ; CHECK:       exit:
456 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
458   %a = alloca i32, align 4
459   store i32 55, i32* %a
460   %in.lv.1 = load i32* , i32** %in.ptr, align 2
461   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
462   store i32 99, i32* %a, align 4
463   br i1 %c.1, label %then, label %else
465 then:
466   call void @escape_and_clobber(i32* %a)
467   br label %exit
469 else:
470   call void @escape_and_clobber(i32* %a)
471   br label %exit
473 exit:
474   ret i32 %in.lv.2
477 define i32 @test_not_captured_before_load_other_blocks_3(i32** %in.ptr, i1 %c.1) {
478 ; CHECK-LABEL: @test_not_captured_before_load_other_blocks_3(
479 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
480 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
481 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
482 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
483 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
484 ; CHECK:       then:
485 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
486 ; CHECK-NEXT:    br label [[EXIT:%.*]]
487 ; CHECK:       else:
488 ; CHECK-NEXT:    br label [[EXIT]]
489 ; CHECK:       exit:
490 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
492   %a = alloca i32, align 4
493   store i32 55, i32* %a
494   %in.lv.1 = load i32* , i32** %in.ptr, align 2
495   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
496   store i32 99, i32* %a, align 4
497   br i1 %c.1, label %then, label %else
499 then:
500   call void @escape_and_clobber(i32* %a)
501   br label %exit
503 else:
504   br label %exit
506 exit:
507   ret i32 %in.lv.2
510 define i32 @test_not_captured_before_load_other_blocks_4(i32** %in.ptr, i1 %c.1) {
511 ; CHECK-LABEL: @test_not_captured_before_load_other_blocks_4(
512 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
513 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
514 ; CHECK:       then:
515 ; CHECK-NEXT:    br label [[EXIT:%.*]]
516 ; CHECK:       else:
517 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
518 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
519 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
520 ; CHECK-NEXT:    br label [[EXIT]]
521 ; CHECK:       exit:
522 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ELSE]] ]
523 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
524 ; CHECK-NEXT:    call void @clobber()
525 ; CHECK-NEXT:    ret i32 [[P]]
527   %a = alloca i32, align 4
528   store i32 55, i32* %a
529   br i1 %c.1, label %then, label %else
531 then:
532   br label %exit
534 else:
535   %in.lv.1 = load i32* , i32** %in.ptr, align 2
536   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
537   call void @escape_writeonly(i32* %a)
538   br label %exit
540 exit:
541   %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
542   store i32 99, i32* %a, align 4
543   call void @clobber()
544   ret i32 %p
547 define i32 @test_not_captured_before_load_other_blocks_5(i32** %in.ptr, i1 %c.1) {
548 ; CHECK-LABEL: @test_not_captured_before_load_other_blocks_5(
549 ; CHECK-NEXT:  entry:
550 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
551 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
552 ; CHECK:       then:
553 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
554 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
555 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
556 ; CHECK-NEXT:    br label [[EXIT]]
557 ; CHECK:       exit:
558 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[IN_LV_2]], [[THEN]] ], [ 0, [[ENTRY:%.*]] ]
559 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
560 ; CHECK-NEXT:    call void @clobber()
561 ; CHECK-NEXT:    ret i32 [[P]]
563 entry:
564   %a = alloca i32, align 4
565   store i32 55, i32* %a
566   br i1 %c.1, label %then, label %exit
568 then:
569   %in.lv.1 = load i32* , i32** %in.ptr, align 2
570   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
571   call void @escape_writeonly(i32* %a)
572   br label %exit
574 exit:
575   %p = phi i32 [ %in.lv.2, %then ], [ 0, %entry ]
576   store i32 99, i32* %a, align 4
577   call void @clobber()
578   ret i32 %p
581 define i32 @test_not_captured_before_load_other_blocks_6(i32** %in.ptr, i1 %c.1) {
582 ; CHECK-LABEL: @test_not_captured_before_load_other_blocks_6(
583 ; CHECK-NEXT:  entry:
584 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
585 ; CHECK-NEXT:    store i32 55, i32* [[A]], align 4
586 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
587 ; CHECK:       then:
588 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
589 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
590 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
591 ; CHECK-NEXT:    br label [[EXIT]]
592 ; CHECK:       exit:
593 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[IN_LV_2]], [[THEN]] ], [ 0, [[ENTRY:%.*]] ]
594 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
595 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
596 ; CHECK-NEXT:    call void @clobber()
597 ; CHECK-NEXT:    ret i32 [[P]]
599 entry:
600   %a = alloca i32, align 4
601   store i32 55, i32* %a
602   br i1 %c.1, label %then, label %exit
604 then:
605   %in.lv.1 = load i32* , i32** %in.ptr, align 2
606   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
607   call void @escape_writeonly(i32* %a)
608   br label %exit
610 exit:
611   %p = phi i32 [ %in.lv.2, %then ], [ 0, %entry ]
612   store i32 99, i32* %a, align 4
613   call void @escape_writeonly(i32* %a)
614   call void @clobber()
615   ret i32 %p
618 define i32 @test_not_captured_before_load_other_blocks_7(i32** %in.ptr, i1 %c.1) {
619 ; CHECK-LABEL: @test_not_captured_before_load_other_blocks_7(
620 ; CHECK-NEXT:  entry:
621 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
622 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
623 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
624 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
625 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
626 ; CHECK:       then:
627 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
628 ; CHECK-NEXT:    br label [[EXIT]]
629 ; CHECK:       exit:
630 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ENTRY:%.*]] ]
631 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
632 ; CHECK-NEXT:    call void @clobber()
633 ; CHECK-NEXT:    ret i32 [[P]]
635 entry:
636   %a = alloca i32, align 4
637   store i32 55, i32* %a
638   %in.lv.1 = load i32* , i32** %in.ptr, align 2
639   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
640   call void @escape_writeonly(i32* %a)
641   br i1 %c.1, label %then, label %exit
643 then:
644   call void @escape_writeonly(i32* %a)
645   br label %exit
647 exit:
648   %p = phi i32 [ 0, %then ], [ %in.lv.2, %entry ]
649   store i32 99, i32* %a, align 4
650   call void @clobber()
651   ret i32 %p
654 define i32 @test_not_captured_before_load_same_bb_but_read(i32** %in.ptr) {
655 ; CHECK-LABEL: @test_not_captured_before_load_same_bb_but_read(
656 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
657 ; CHECK-NEXT:    store i32 55, i32* [[A]], align 4
658 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
659 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
660 ; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[A]], align 4
661 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
662 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
663 ; CHECK-NEXT:    [[RES:%.*]] = add i32 [[IN_LV_2]], [[LV]]
664 ; CHECK-NEXT:    ret i32 [[RES]]
666   %a = alloca i32, align 4
667   store i32 55, i32* %a
668   %in.lv.1 = load i32* , i32** %in.ptr, align 2
669   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
670   %lv = load i32, i32* %a
671   store i32 99, i32* %a, align 4
672   call void @escape_and_clobber(i32* %a)
673   %res = add i32 %in.lv.2, %lv
674   ret i32 %res
677 define i32 @test_not_captured_before_load_may_alias_same_bb_but_read(i32** %in.ptr, i32* %b, i1 %c) {
678 ; CHECK-LABEL: @test_not_captured_before_load_may_alias_same_bb_but_read(
679 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
680 ; CHECK-NEXT:    store i32 55, i32* [[A]], align 4
681 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
682 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
683 ; CHECK-NEXT:    [[PTR:%.*]] = select i1 [[C:%.*]], i32* [[A]], i32* [[B:%.*]]
684 ; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[PTR]], align 4
685 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
686 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
687 ; CHECK-NEXT:    [[RES:%.*]] = add i32 [[IN_LV_2]], [[LV]]
688 ; CHECK-NEXT:    ret i32 [[RES]]
690   %a = alloca i32, align 4
691   store i32 55, i32* %a
692   %in.lv.1 = load i32* , i32** %in.ptr, align 2
693   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
694   %ptr = select i1 %c, i32* %a, i32* %b
695   %lv = load i32, i32* %ptr
696   store i32 99, i32* %a, align 4
697   call void @escape_and_clobber(i32* %a)
698   %res = add i32 %in.lv.2, %lv
699   ret i32 %res
702 define i32 @test_captured_after_loop(i32** %in.ptr, i1 %c.1) {
703 ; CHECK-LABEL: @test_captured_after_loop(
704 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
705 ; CHECK-NEXT:    br label [[LOOP:%.*]]
706 ; CHECK:       loop:
707 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
708 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
709 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
710 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
711 ; CHECK:       exit:
712 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
713 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
715   %a = alloca i32, align 4
716   store i32 55, i32* %a
717   br label %loop
719 loop:
720   %in.lv.1 = load i32* , i32** %in.ptr, align 2
721   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
722   store i32 99, i32* %a, align 4
723   br i1 %c.1, label %loop, label %exit
725 exit:
726   call void @escape_and_clobber(i32* %a)
727   ret i32 %in.lv.2
730 define i32 @test_captured_in_loop(i32** %in.ptr, i1 %c.1) {
731 ; CHECK-LABEL: @test_captured_in_loop(
732 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
733 ; CHECK-NEXT:    store i32 55, i32* [[A]], align 4
734 ; CHECK-NEXT:    br label [[LOOP:%.*]]
735 ; CHECK:       loop:
736 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
737 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
738 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
739 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
740 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
741 ; CHECK:       exit:
742 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
743 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
745   %a = alloca i32, align 4
746   store i32 55, i32* %a
747   br label %loop
749 loop:
750   %in.lv.1 = load i32* , i32** %in.ptr, align 2
751   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
752   call void @escape_writeonly(i32* %a)
753   store i32 99, i32* %a, align 4
754   br i1 %c.1, label %loop, label %exit
756 exit:
757   call void @escape_and_clobber(i32* %a)
758   ret i32 %in.lv.2
761 declare void @llvm.memset.p0i8.i32(i8* nocapture writeonly, i8, i32, i1 immarg)
763 @global = external global [10 x i16]*
765 define void @test_memset_not_captured_before_load() {
766 ; CHECK-LABEL: @test_memset_not_captured_before_load(
767 ; CHECK-NEXT:    [[A:%.*]] = alloca [2 x i32], align 4
768 ; CHECK-NEXT:    [[LV_1:%.*]] = load [10 x i16]*, [10 x i16]** @global, align 8
769 ; CHECK-NEXT:    [[GEP_A_0:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[A]], i32 0, i32 0
770 ; CHECK-NEXT:    store i32 1, i32* [[GEP_A_0]], align 4
771 ; CHECK-NEXT:    [[GEP_LV:%.*]] = getelementptr inbounds [10 x i16], [10 x i16]* [[LV_1]], i64 0, i32 1
772 ; CHECK-NEXT:    [[LV_2:%.*]] = load i16, i16* [[GEP_LV]], align 2
773 ; CHECK-NEXT:    [[EXT_LV_2:%.*]] = zext i16 [[LV_2]] to i32
774 ; CHECK-NEXT:    [[GEP_A_1:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[A]], i32 0, i32 1
775 ; CHECK-NEXT:    store i32 [[EXT_LV_2]], i32* [[GEP_A_1]], align 4
776 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[GEP_A_0]])
777 ; CHECK-NEXT:    ret void
779   %a = alloca [2 x i32], align 4
780   %cast.a = bitcast [2 x i32]* %a to i8*
781   call void @llvm.memset.p0i8.i32(i8* %cast.a, i8 0, i32 8, i1 false)
782   %lv.1 = load [10 x i16]*, [10 x i16]** @global, align 8
783   %gep.a.0 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i32 0, i32 0
784   store i32 1, i32* %gep.a.0, align 4
785   %gep.lv = getelementptr inbounds [10 x i16], [10 x i16]* %lv.1, i64 0, i32 1
786   %lv.2 = load i16, i16* %gep.lv, align 2
787   %ext.lv.2 = zext i16 %lv.2 to i32
788   %gep.a.1 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i32 0, i32 1
789   store i32 %ext.lv.2, i32* %gep.a.1, align 4
790   call void @escape_and_clobber(i32* %gep.a.0)
791   ret void
794 define void @test_test_not_captured_before_load(i1 %c.1) {
795 ; CHECK-LABEL: @test_test_not_captured_before_load(
796 ; CHECK-NEXT:  bb:
797 ; CHECK-NEXT:    [[A:%.*]] = alloca [2 x i32], align 4
798 ; CHECK-NEXT:    [[CAST_A:%.*]] = bitcast [2 x i32]* [[A]] to i8*
799 ; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, i8* [[CAST_A]], i32 4
800 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i32(i8* align 1 [[TMP0]], i8 0, i32 4, i1 false)
801 ; CHECK-NEXT:    [[LV_1:%.*]] = load [10 x i16]*, [10 x i16]** @global, align 8
802 ; CHECK-NEXT:    [[GEP_LV:%.*]] = getelementptr inbounds [10 x i16], [10 x i16]* [[LV_1]], i64 0, i32 1
803 ; CHECK-NEXT:    [[LV_2:%.*]] = load i16, i16* [[GEP_LV]], align 2
804 ; CHECK-NEXT:    [[GEP_A_0:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[A]], i32 0, i32 0
805 ; CHECK-NEXT:    store i32 1, i32* [[GEP_A_0]], align 4
806 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
807 ; CHECK:       then:
808 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[GEP_A_0]])
809 ; CHECK-NEXT:    br label [[EXIT:%.*]]
810 ; CHECK:       else:
811 ; CHECK-NEXT:    br label [[EXIT]]
812 ; CHECK:       exit:
813 ; CHECK-NEXT:    [[EXT_LV_2:%.*]] = zext i16 [[LV_2]] to i32
814 ; CHECK-NEXT:    [[GEP_A_1:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[A]], i32 0, i32 1
815 ; CHECK-NEXT:    store i32 [[EXT_LV_2]], i32* [[GEP_A_1]], align 4
816 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[GEP_A_0]])
817 ; CHECK-NEXT:    ret void
820   %a = alloca [2 x i32], align 4
821   %cast.a = bitcast [2 x i32]* %a to i8*
822   call void @llvm.memset.p0i8.i32(i8* %cast.a, i8 0, i32 8, i1 false)
823   %lv.1 = load [10 x i16]*, [10 x i16]** @global, align 8
824   %gep.lv = getelementptr inbounds [10 x i16], [10 x i16]* %lv.1, i64 0, i32 1
825   %lv.2 = load i16, i16* %gep.lv, align 2
826   %gep.a.0 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i32 0, i32 0
827   store i32 1, i32* %gep.a.0, align 4
828   br i1 %c.1, label %then, label %else
830 then:
831   call void @escape_and_clobber(i32* %gep.a.0)
832   br label %exit
834 else:
835   br label %exit
837 exit:
838   %ext.lv.2 = zext i16 %lv.2 to i32
839   %gep.a.1 = getelementptr inbounds [2 x i32], [2 x i32]* %a, i32 0, i32 1
840   store i32 %ext.lv.2, i32* %gep.a.1, align 4
841   call void @escape_and_clobber(i32* %gep.a.0)
842   ret void
845 declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #0
846 declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #1
848 declare void @use.i64(i64)
850 define i64 @test_a_not_captured_at_all(i64** %ptr, i64** %ptr.2, i1 %c) {
851 ; CHECK-LABEL: @test_a_not_captured_at_all(
852 ; CHECK-NEXT:  entry:
853 ; CHECK-NEXT:    [[A:%.*]] = alloca i64, align 8
854 ; CHECK-NEXT:    [[B:%.*]] = alloca i64, align 8
855 ; CHECK-NEXT:    store i64* [[B]], i64** [[PTR:%.*]], align 8
856 ; CHECK-NEXT:    [[LV_1:%.*]] = load i64*, i64** [[PTR_2:%.*]], align 8
857 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EXIT:%.*]], label [[THEN:%.*]]
858 ; CHECK:       then:
859 ; CHECK-NEXT:    [[LV_2:%.*]] = load i64, i64* [[LV_1]], align 4
860 ; CHECK-NEXT:    call void @use.i64(i64 [[LV_2]])
861 ; CHECK-NEXT:    br label [[EXIT]]
862 ; CHECK:       exit:
863 ; CHECK-NEXT:    [[A_CAST:%.*]] = bitcast i64* [[A]] to i8*
864 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 8, i8* [[A_CAST]])
865 ; CHECK-NEXT:    call void @clobber()
866 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* [[A_CAST]], i8 0, i64 8, i1 false)
867 ; CHECK-NEXT:    [[L:%.*]] = load i64, i64* [[A]], align 4
868 ; CHECK-NEXT:    ret i64 [[L]]
870 entry:
871   %a = alloca i64, align 8
872   %b = alloca i64, align 8
873   store i64* %b, i64** %ptr, align 8
874   %lv.1 = load i64*, i64** %ptr.2, align 8
875   br i1 %c, label %exit, label %then
877 then:
878   %lv.2 = load i64, i64* %lv.1
879   call void @use.i64(i64 %lv.2)
880   br label %exit
882 exit:
883   %a.cast = bitcast i64* %a to i8*
884   call void @llvm.lifetime.start.p0i8(i64 8, i8* %a.cast)
885   store i64 99, i64* %a
886   call void @clobber()
887   call void @llvm.memset.p0i8.i64(i8* %a.cast, i8 0, i64 8, i1 false)
888   %l = load i64, i64* %a
889   ret i64 %l
892 define i32 @test_not_captured_both_paths_1(i32** %in.ptr, i1 %c.1) {
893 ; CHECK-LABEL: @test_not_captured_both_paths_1(
894 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
895 ; CHECK-NEXT:    store i32 55, i32* [[A]], align 4
896 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
897 ; CHECK:       then:
898 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
899 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
900 ; CHECK-NEXT:    br label [[EXIT:%.*]]
901 ; CHECK:       else:
902 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
903 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
904 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
905 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
906 ; CHECK-NEXT:    br label [[EXIT]]
907 ; CHECK:       exit:
908 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ELSE]] ]
909 ; CHECK-NEXT:    call void @clobber()
910 ; CHECK-NEXT:    ret i32 [[P]]
912   %a = alloca i32, align 4
913   store i32 55, i32* %a
914   br i1 %c.1, label %then, label %else
916 then:
917   store i32 99, i32* %a, align 4
918   call void @escape_writeonly(i32* %a)
919   br label %exit
921 else:
922   %in.lv.1 = load i32* , i32** %in.ptr, align 2
923   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
924   store i32 99, i32* %a, align 4
925   call void @escape_writeonly(i32* %a)
926   br label %exit
928 exit:
929   %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
930   call void @clobber()
931   ret i32 %p
934 define i32 @test_not_captured_both_paths_2(i32** %in.ptr, i1 %c.1) {
935 ; CHECK-LABEL: @test_not_captured_both_paths_2(
936 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
937 ; CHECK-NEXT:    store i32 55, i32* [[A]], align 4
938 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
939 ; CHECK:       then:
940 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
941 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
942 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
943 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
944 ; CHECK-NEXT:    br label [[EXIT:%.*]]
945 ; CHECK:       else:
946 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
947 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
948 ; CHECK-NEXT:    br label [[EXIT]]
949 ; CHECK:       exit:
950 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[IN_LV_2]], [[THEN]] ], [ 0, [[ELSE]] ]
951 ; CHECK-NEXT:    call void @clobber()
952 ; CHECK-NEXT:    ret i32 [[P]]
954   %a = alloca i32, align 4
955   store i32 55, i32* %a
956   br i1 %c.1, label %then, label %else
958 then:
959   %in.lv.1 = load i32* , i32** %in.ptr, align 2
960   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
961   store i32 99, i32* %a, align 4
962   call void @escape_writeonly(i32* %a)
963   br label %exit
965 else:
966   store i32 99, i32* %a, align 4
967   call void @escape_writeonly(i32* %a)
968   br label %exit
970 exit:
971   %p = phi i32 [ %in.lv.2, %then ], [ 0, %else ]
972   call void @clobber()
973   ret i32 %p
976 define i32 @test_captured_before_store_both_paths_2(i32** %in.ptr, i1 %c.1) {
977 ; CHECK-LABEL: @test_captured_before_store_both_paths_2(
978 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
979 ; CHECK-NEXT:    store i32 55, i32* [[A]], align 4
980 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
981 ; CHECK:       then:
982 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
983 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
984 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
985 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
986 ; CHECK-NEXT:    br label [[EXIT:%.*]]
987 ; CHECK:       else:
988 ; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
989 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
990 ; CHECK-NEXT:    br label [[EXIT]]
991 ; CHECK:       exit:
992 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[IN_LV_2]], [[THEN]] ], [ 0, [[ELSE]] ]
993 ; CHECK-NEXT:    call void @clobber()
994 ; CHECK-NEXT:    ret i32 [[P]]
996   %a = alloca i32, align 4
997   store i32 55, i32* %a
998   br i1 %c.1, label %then, label %else
1000 then:
1001   call void @escape_writeonly(i32* %a)
1002   %in.lv.1 = load i32* , i32** %in.ptr, align 2
1003   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
1004   store i32 99, i32* %a, align 4
1005   br label %exit
1007 else:
1008   call void @escape_writeonly(i32* %a)
1009   store i32 99, i32* %a, align 4
1010   br label %exit
1012 exit:
1013   %p = phi i32 [ %in.lv.2, %then ], [ 0, %else ]
1014   call void @clobber()
1015   ret i32 %p
1019 declare noalias i32* @alloc() nounwind
1021 define i32 @test_not_captured_before_load_same_bb_noalias_call(i32** %in.ptr) {
1022 ; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_call(
1023 ; CHECK-NEXT:    [[A:%.*]] = call i32* @alloc()
1024 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
1025 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
1026 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
1027 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
1028 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
1030   %a = call i32* @alloc()
1031   store i32 55, i32* %a
1032   %in.lv.1 = load i32* , i32** %in.ptr, align 2
1033   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
1034   store i32 99, i32* %a, align 4
1035   call void @escape_and_clobber(i32* %a)
1036   ret i32 %in.lv.2
1039 define i32 @test_not_captured_before_load_same_bb_noalias_arg(i32** %in.ptr, i32* noalias %a) {
1040 ; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_arg(
1041 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
1042 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
1043 ; CHECK-NEXT:    store i32 99, i32* [[A:%.*]], align 4
1044 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
1045 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
1047   store i32 55, i32* %a
1048   %in.lv.1 = load i32* , i32** %in.ptr, align 2
1049   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
1050   store i32 99, i32* %a, align 4
1051   call void @escape_and_clobber(i32* %a)
1052   ret i32 %in.lv.2
1055 define i32 @instruction_captures_multiple_objects(i32* %p.1, i32** %p.2, i32** %p.3, i1 %c) {
1056 ; CHECK-LABEL: @instruction_captures_multiple_objects(
1057 ; CHECK-NEXT:  entry:
1058 ; CHECK-NEXT:    [[A_1:%.*]] = alloca i32, align 4
1059 ; CHECK-NEXT:    [[A_2:%.*]] = alloca i32, align 4
1060 ; CHECK-NEXT:    store i32 0, i32* [[P_1:%.*]], align 8
1061 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
1062 ; CHECK:       then:
1063 ; CHECK-NEXT:    [[LV_2:%.*]] = load i32*, i32** [[P_2:%.*]], align 8
1064 ; CHECK-NEXT:    [[LV_2_2:%.*]] = load i32, i32* [[LV_2]], align 4
1065 ; CHECK-NEXT:    ret i32 [[LV_2_2]]
1066 ; CHECK:       else:
1067 ; CHECK-NEXT:    [[LV_3:%.*]] = load i32*, i32** [[P_3:%.*]], align 8
1068 ; CHECK-NEXT:    [[LV_3_2:%.*]] = load i32, i32* [[LV_3]], align 4
1069 ; CHECK-NEXT:    call void @capture_and_clobber_multiple(i32* [[A_1]], i32* [[A_2]])
1070 ; CHECK-NEXT:    ret i32 [[LV_3_2]]
1072 entry:
1073   %a.1 = alloca i32
1074   %a.2 = alloca i32
1075   store i32 0, i32* %p.1, align 8
1076   br i1 %c, label %then, label %else
1078 then:
1079   store i32 99, i32* %a.2, align 4
1080   %lv.2 = load i32*, i32** %p.2
1081   %lv.2.2 = load i32, i32* %lv.2
1082   store i32 0, i32* %a.1, align 8
1083   ret i32 %lv.2.2
1085 else:
1086   %lv.3 = load i32*, i32** %p.3
1087   %lv.3.2 = load i32, i32* %lv.3
1088   call void @capture_and_clobber_multiple(i32* %a.1, i32* %a.2)
1089   ret i32 %lv.3.2
1092 declare void @capture_and_clobber_multiple(i32*, i32*)
1094 declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
1096 define i64 @earliest_escape_ptrtoint(i64** %p.1) {
1097 ; CHECK-LABEL: @earliest_escape_ptrtoint(
1098 ; CHECK-NEXT:  entry:
1099 ; CHECK-NEXT:    [[A_1:%.*]] = alloca i64, align 8
1100 ; CHECK-NEXT:    [[A_2:%.*]] = alloca i64, align 8
1101 ; CHECK-NEXT:    [[LV_1:%.*]] = load i64*, i64** [[P_1:%.*]], align 8
1102 ; CHECK-NEXT:    [[LV_2:%.*]] = load i64, i64* [[LV_1]], align 4
1103 ; CHECK-NEXT:    store i64* [[A_1]], i64** [[P_1]], align 8
1104 ; CHECK-NEXT:    [[A_2_CAST:%.*]] = bitcast i64* [[A_2]] to i8*
1105 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 8, i8* [[A_2_CAST]])
1106 ; CHECK-NEXT:    ret i64 [[LV_2]]
1108 entry:
1109   %a.1 = alloca i64
1110   %a.2 = alloca i64
1111   store i64 99, i64* %a.1
1112   %lv.1 = load i64*, i64** %p.1
1113   %lv.2 = load i64, i64* %lv.1
1114   store i64* %a.1, i64** %p.1, align 8
1115   %int = ptrtoint i64* %a.2 to i64
1116   store i64 %int , i64* %a.2, align 8
1117   %a.2.cast = bitcast i64* %a.2 to i8*
1118   call void @llvm.lifetime.end.p0i8(i64 8, i8* %a.2.cast)
1119   ret i64 %lv.2
1122 define i32 @test_not_captured_before_load_of_ptrtoint(i64 %in) {
1123 ; CHECK-LABEL: @test_not_captured_before_load_of_ptrtoint(
1124 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
1125 ; CHECK-NEXT:    [[IN_PTR:%.*]] = inttoptr i64 [[IN:%.*]] to i32*
1126 ; CHECK-NEXT:    [[IN_PTR_LOAD:%.*]] = load i32, i32* [[IN_PTR]], align 4
1127 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
1128 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
1129 ; CHECK-NEXT:    ret i32 [[IN_PTR_LOAD]]
1131   %a = alloca i32, align 4
1132   store i32 55, i32* %a
1133   %in.ptr = inttoptr i64 %in to i32*
1134   %in.ptr.load = load i32, i32* %in.ptr
1135   store i32 99, i32* %a
1136   call void @escape_and_clobber(i32* %a)
1137   ret i32 %in.ptr.load
1140 declare i32* @getptr()
1142 define i32 @test_not_captured_before_load_of_call() {
1143 ; CHECK-LABEL: @test_not_captured_before_load_of_call(
1144 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
1145 ; CHECK-NEXT:    [[IN_PTR:%.*]] = call i32* @getptr() #[[ATTR4:[0-9]+]]
1146 ; CHECK-NEXT:    [[IN_PTR_LOAD:%.*]] = load i32, i32* [[IN_PTR]], align 4
1147 ; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
1148 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
1149 ; CHECK-NEXT:    ret i32 [[IN_PTR_LOAD]]
1151   %a = alloca i32, align 4
1152   store i32 55, i32* %a
1153   %in.ptr = call i32* @getptr() readnone
1154   %in.ptr.load = load i32, i32* %in.ptr
1155   store i32 99, i32* %a
1156   call void @escape_and_clobber(i32* %a)
1157   ret i32 %in.ptr.load
1160 define i32 @test_not_captured_multiple_objects(i1 %c, i32** %in.ptr) {
1161 ; CHECK-LABEL: @test_not_captured_multiple_objects(
1162 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
1163 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
1164 ; CHECK-NEXT:    [[O:%.*]] = select i1 [[C:%.*]], i32* [[A]], i32* [[B]]
1165 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load i32*, i32** [[IN_PTR:%.*]], align 2
1166 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, i32* [[IN_LV_1]], align 2
1167 ; CHECK-NEXT:    store i32 99, i32* [[O]], align 4
1168 ; CHECK-NEXT:    call void @escape_and_clobber(i32* [[O]])
1169 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
1171   %a = alloca i32, align 4
1172   %b = alloca i32, align 4
1173   %o = select i1 %c, i32* %a, i32* %b
1174   store i32 55, i32* %o
1175   %in.lv.1 = load i32* , i32** %in.ptr, align 2
1176   %in.lv.2 = load i32 , i32* %in.lv.1, align 2
1177   store i32 99, i32* %o
1178   call void @escape_and_clobber(i32* %o)
1179   ret i32 %in.lv.2