Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / DeadStoreElimination / captures-before-load.ll
blob7d827fa2f6996cb5021e07866a02874155547497
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(ptr)
5 declare void @escape_writeonly(ptr) writeonly
6 declare void @clobber()
8 define i32 @test_not_captured_before_load_same_bb(ptr %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 ptr, ptr [[IN_PTR:%.*]], align 2
12 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
13 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
14 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
15 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
17   %a = alloca i32, align 4
18   store i32 55, ptr %a
19   %in.lv.1 = load ptr , ptr %in.ptr, align 2
20   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
21   store i32 99, ptr %a, align 4
22   call void @escape_and_clobber(ptr %a)
23   ret i32 %in.lv.2
26 define i32 @test_not_captured_before_load_same_bb_escape_unreachable_block(ptr %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 ptr, ptr [[IN_PTR:%.*]], align 2
30 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
31 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
32 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
33 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
34 ; CHECK:       unreach:
35 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
36 ; CHECK-NEXT:    ret i32 0
38   %a = alloca i32, align 4
39   store i32 55, ptr %a
40   %in.lv.1 = load ptr , ptr %in.ptr, align 2
41   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
42   store i32 99, ptr %a, align 4
43   call void @escape_and_clobber(ptr %a)
44   ret i32 %in.lv.2
46 unreach:
47   call void @escape_and_clobber(ptr %a)
48   ret i32 0
51 define i32 @test_not_captured_before_load_same_bb_escape_unreachable_block2(ptr %in.ptr) {
52 ; CHECK-LABEL: @test_not_captured_before_load_same_bb_escape_unreachable_block2(
53 ; CHECK-NEXT:    br label [[BB:%.*]]
54 ; CHECK:       unreach:
55 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A:%.*]])
56 ; CHECK-NEXT:    ret i32 0
57 ; CHECK:       bb:
58 ; CHECK-NEXT:    [[A]] = alloca i32, align 4
59 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
60 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
61 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
62 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
63 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
65   br label %bb
67 unreach:
68   call void @escape_and_clobber(ptr %a)
69   ret i32 0
71 bb:
72   %a = alloca i32, align 4
73   store i32 55, ptr %a
74   %in.lv.1 = load ptr , ptr %in.ptr, align 2
75   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
76   store i32 99, ptr %a, align 4
77   call void @escape_and_clobber(ptr %a)
78   ret i32 %in.lv.2
81 define i32 @test_captured_and_clobbered_after_load_same_bb_2(ptr %in.ptr) {
82 ; CHECK-LABEL: @test_captured_and_clobbered_after_load_same_bb_2(
83 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
84 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
85 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
86 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
87 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
88 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
89 ; CHECK-NEXT:    call void @clobber()
90 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
92   %a = alloca i32, align 4
93   store i32 55, ptr %a
94   %in.lv.1 = load ptr , ptr %in.ptr, align 2
95   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
96   call void @escape_and_clobber(ptr %a)
97   store i32 99, ptr %a, align 4
98   call void @clobber()
99   ret i32 %in.lv.2
102 define i32 @test_captured_after_load_same_bb_2_clobbered_later(ptr %in.ptr) {
103 ; CHECK-LABEL: @test_captured_after_load_same_bb_2_clobbered_later(
104 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
105 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
106 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
107 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
108 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
109 ; CHECK-NEXT:    call void @clobber()
110 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
112   %a = alloca i32, align 4
113   store i32 55, ptr %a
114   %in.lv.1 = load ptr , ptr %in.ptr, align 2
115   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
116   call void @escape_writeonly(ptr %a)
117   store i32 99, ptr %a, align 4
118   call void @clobber()
119   ret i32 %in.lv.2
122 define i32 @test_captured_and_clobbered_before_load_same_bb_1(ptr %in.ptr) {
123 ; CHECK-LABEL: @test_captured_and_clobbered_before_load_same_bb_1(
124 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
125 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
126 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
127 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
128 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
129 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
130 ; CHECK-NEXT:    call void @clobber()
131 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
133   %a = alloca i32, align 4
134   store i32 55, ptr %a
135   %in.lv.1 = load ptr , ptr %in.ptr, align 2
136   call void @escape_and_clobber(ptr %a)
137   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
138   store i32 99, ptr %a, align 4
139   call void @clobber()
140   ret i32 %in.lv.2
143 define i32 @test_captured_before_load_same_bb_1_clobbered_later(ptr %in.ptr) {
144 ; CHECK-LABEL: @test_captured_before_load_same_bb_1_clobbered_later(
145 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
146 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
147 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
148 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
149 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
150 ; CHECK-NEXT:    call void @clobber()
151 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
153   %a = alloca i32, align 4
154   store i32 55, ptr %a
155   %in.lv.1 = load ptr , ptr %in.ptr, align 2
156   call void @escape_writeonly(ptr %a)
157   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
158   store i32 99, ptr %a, align 4
159   call void @clobber()
160   ret i32 %in.lv.2
163 define i32 @test_captured_before_load_same_bb_2(ptr %in.ptr) {
164 ; CHECK-LABEL: @test_captured_before_load_same_bb_2(
165 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
166 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
167 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
168 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
169 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
170 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
171 ; CHECK-NEXT:    call void @clobber()
172 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
174   %a = alloca i32, align 4
175   store i32 55, ptr %a
176   call void @escape_writeonly(ptr %a)
177   %in.lv.1 = load ptr , ptr %in.ptr, align 2
178   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
179   store i32 99, ptr %a, align 4
180   call void @clobber()
181   ret i32 %in.lv.2
184 define i32 @test_not_captured_before_load_same_bb_clobber(ptr %in.ptr) {
185 ; CHECK-LABEL: @test_not_captured_before_load_same_bb_clobber(
186 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
187 ; CHECK-NEXT:    call void @clobber()
188 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
189 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
190 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
191 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
192 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
194   %a = alloca i32, align 4
195   store i32 55, ptr %a
196   call void @clobber()
197   %in.lv.1 = load ptr , ptr %in.ptr, align 2
198   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
199   store i32 99, ptr %a, align 4
200   call void @escape_and_clobber(ptr %a)
201   ret i32 %in.lv.2
204 define i32 @test_captured_before_load_same_bb(ptr %in.ptr) {
205 ; CHECK-LABEL: @test_captured_before_load_same_bb(
206 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
207 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
208 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
209 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
210 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
211 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
212 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
213 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
215   %a = alloca i32, align 4
216   store i32 55, ptr %a
217   call void @escape_and_clobber(ptr %a)
218   %in.lv.1 = load ptr , ptr %in.ptr, align 2
219   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
220   store i32 99, ptr %a, align 4
221   call void @escape_and_clobber(ptr %a)
222   ret i32 %in.lv.2
225 define i32 @test_captured_sibling_path_to_load_other_blocks_1(ptr %in.ptr, i1 %c.1) {
226 ; CHECK-LABEL: @test_captured_sibling_path_to_load_other_blocks_1(
227 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
228 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
229 ; CHECK:       then:
230 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
231 ; CHECK-NEXT:    br label [[EXIT:%.*]]
232 ; CHECK:       else:
233 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
234 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
235 ; CHECK-NEXT:    br label [[EXIT]]
236 ; CHECK:       exit:
237 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ELSE]] ]
238 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
239 ; CHECK-NEXT:    call void @clobber()
240 ; CHECK-NEXT:    ret i32 [[P]]
242   %a = alloca i32, align 4
243   store i32 55, ptr %a
244   br i1 %c.1, label %then, label %else
246 then:
247   call void @escape_writeonly(ptr %a)
248   br label %exit
250 else:
251   %in.lv.1 = load ptr , ptr %in.ptr, align 2
252   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
253   br label %exit
255 exit:
256   %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
257   store i32 99, ptr %a, align 4
258   call void @clobber()
259   ret i32 %p
262 define i32 @test_only_captured_sibling_path_with_ret_to_load_other_blocks(ptr %in.ptr, i1 %c.1) {
263 ; CHECK-LABEL: @test_only_captured_sibling_path_with_ret_to_load_other_blocks(
264 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
265 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
266 ; CHECK:       then:
267 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
268 ; CHECK-NEXT:    ret i32 0
269 ; CHECK:       else:
270 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
271 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
272 ; CHECK-NEXT:    br label [[EXIT:%.*]]
273 ; CHECK:       exit:
274 ; CHECK-NEXT:    call void @clobber()
275 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
277   %a = alloca i32, align 4
278   store i32 55, ptr %a
279   br i1 %c.1, label %then, label %else
281 then:
282   call void @escape_writeonly(ptr %a)
283   ret i32 0
285 else:
286   %in.lv.1 = load ptr , ptr %in.ptr, align 2
287   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
288   br label %exit
290 exit:
291   store i32 99, ptr %a, align 4
292   call void @clobber()
293   ret i32 %in.lv.2
296 define i32 @test_captured_before_load_other_blocks_2(ptr %in.ptr, i1 %c.1) {
297 ; CHECK-LABEL: @test_captured_before_load_other_blocks_2(
298 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
299 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
300 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
301 ; CHECK:       then:
302 ; CHECK-NEXT:    br label [[EXIT:%.*]]
303 ; CHECK:       else:
304 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
305 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
306 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
307 ; CHECK-NEXT:    br label [[EXIT]]
308 ; CHECK:       exit:
309 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ELSE]] ]
310 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
311 ; CHECK-NEXT:    call void @clobber()
312 ; CHECK-NEXT:    ret i32 [[P]]
314   %a = alloca i32, align 4
315   store i32 55, ptr %a
316   br i1 %c.1, label %then, label %else
318 then:
319   br label %exit
321 else:
322   call void @escape_and_clobber(ptr %a)
323   %in.lv.1 = load ptr , ptr %in.ptr, align 2
324   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
325   br label %exit
327 exit:
328   %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
329   store i32 99, ptr %a, align 4
330   call void @clobber()
331   ret i32 %p
334 define i32 @test_captured_before_load_other_blocks_4(ptr %in.ptr, i1 %c.1) {
335 ; CHECK-LABEL: @test_captured_before_load_other_blocks_4(
336 ; CHECK-NEXT:  entry:
337 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
338 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
339 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
340 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
341 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
342 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
343 ; CHECK:       then:
344 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
345 ; CHECK-NEXT:    br label [[EXIT]]
346 ; CHECK:       exit:
347 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ENTRY:%.*]] ]
348 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
349 ; CHECK-NEXT:    call void @clobber()
350 ; CHECK-NEXT:    ret i32 [[P]]
352 entry:
353   %a = alloca i32, align 4
354   store i32 55, ptr %a
355   call void @escape_writeonly(ptr %a)
356   %in.lv.1 = load ptr , ptr %in.ptr, align 2
357   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
358   br i1 %c.1, label %then, label %exit
360 then:
361   call void @escape_writeonly(ptr %a)
362   br label %exit
364 exit:
365   %p = phi i32 [ 0, %then ], [ %in.lv.2, %entry ]
366   store i32 99, ptr %a, align 4
367   call void @clobber()
368   ret i32 %p
371 define i32 @test_captured_before_load_other_blocks_5(ptr %in.ptr, i1 %c.1) {
372 ; CHECK-LABEL: @test_captured_before_load_other_blocks_5(
373 ; CHECK-NEXT:  entry:
374 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
375 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
376 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
377 ; CHECK:       then:
378 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
379 ; CHECK-NEXT:    br label [[EXIT]]
380 ; CHECK:       exit:
381 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
382 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
383 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
384 ; CHECK-NEXT:    call void @clobber()
385 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
387 entry:
388   %a = alloca i32, align 4
389   store i32 55, ptr %a
390   br i1 %c.1, label %then, label %exit
392 then:
393   call void @escape_writeonly(ptr %a)
394   br label %exit
396 exit:
397   %in.lv.1 = load ptr , ptr %in.ptr, align 2
398   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
399   store i32 99, ptr %a, align 4
400   call void @clobber()
401   ret i32 %in.lv.2
404 define i32 @test_captured_before_load_other_blocks_6(ptr %in.ptr, i1 %c.1) {
405 ; CHECK-LABEL: @test_captured_before_load_other_blocks_6(
406 ; CHECK-NEXT:  entry:
407 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
408 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
409 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
410 ; CHECK:       then:
411 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
412 ; CHECK-NEXT:    br label [[EXIT]]
413 ; CHECK:       exit:
414 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
415 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
416 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
417 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
418 ; CHECK-NEXT:    call void @clobber()
419 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
421 entry:
422   %a = alloca i32, align 4
423   store i32 55, ptr %a
424   br i1 %c.1, label %then, label %exit
426 then:
427   call void @escape_writeonly(ptr %a)
428   br label %exit
430 exit:
431   %in.lv.1 = load ptr , ptr %in.ptr, align 2
432   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
433   store i32 99, ptr %a, align 4
434   call void @escape_writeonly(ptr %a)
435   call void @clobber()
436   ret i32 %in.lv.2
439 define i32 @test_not_captured_before_load_other_blocks_1(ptr %in.ptr, i1 %c.1) {
440 ; CHECK-LABEL: @test_not_captured_before_load_other_blocks_1(
441 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
442 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
443 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
444 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
445 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
446 ; CHECK:       then:
447 ; CHECK-NEXT:    br label [[EXIT:%.*]]
448 ; CHECK:       else:
449 ; CHECK-NEXT:    br label [[EXIT]]
450 ; CHECK:       exit:
451 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
452 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
454   %a = alloca i32, align 4
455   store i32 55, ptr %a
456   %in.lv.1 = load ptr , ptr %in.ptr, align 2
457   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
458   store i32 99, ptr %a, align 4
459   br i1 %c.1, label %then, label %else
461 then:
462   br label %exit
464 else:
465   br label %exit
467 exit:
468   call void @escape_and_clobber(ptr %a)
469   ret i32 %in.lv.2
472 define i32 @test_not_captured_before_load_other_blocks_2(ptr %in.ptr, i1 %c.1) {
473 ; CHECK-LABEL: @test_not_captured_before_load_other_blocks_2(
474 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
475 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
476 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
477 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
478 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
479 ; CHECK:       then:
480 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
481 ; CHECK-NEXT:    br label [[EXIT:%.*]]
482 ; CHECK:       else:
483 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
484 ; CHECK-NEXT:    br label [[EXIT]]
485 ; CHECK:       exit:
486 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
488   %a = alloca i32, align 4
489   store i32 55, ptr %a
490   %in.lv.1 = load ptr , ptr %in.ptr, align 2
491   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
492   store i32 99, ptr %a, align 4
493   br i1 %c.1, label %then, label %else
495 then:
496   call void @escape_and_clobber(ptr %a)
497   br label %exit
499 else:
500   call void @escape_and_clobber(ptr %a)
501   br label %exit
503 exit:
504   ret i32 %in.lv.2
507 define i32 @test_not_captured_before_load_other_blocks_3(ptr %in.ptr, i1 %c.1) {
508 ; CHECK-LABEL: @test_not_captured_before_load_other_blocks_3(
509 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
510 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
511 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
512 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
513 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
514 ; CHECK:       then:
515 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
516 ; CHECK-NEXT:    br label [[EXIT:%.*]]
517 ; CHECK:       else:
518 ; CHECK-NEXT:    br label [[EXIT]]
519 ; CHECK:       exit:
520 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
522   %a = alloca i32, align 4
523   store i32 55, ptr %a
524   %in.lv.1 = load ptr , ptr %in.ptr, align 2
525   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
526   store i32 99, ptr %a, align 4
527   br i1 %c.1, label %then, label %else
529 then:
530   call void @escape_and_clobber(ptr %a)
531   br label %exit
533 else:
534   br label %exit
536 exit:
537   ret i32 %in.lv.2
540 define i32 @test_not_captured_before_load_other_blocks_4(ptr %in.ptr, i1 %c.1) {
541 ; CHECK-LABEL: @test_not_captured_before_load_other_blocks_4(
542 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
543 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
544 ; CHECK:       then:
545 ; CHECK-NEXT:    br label [[EXIT:%.*]]
546 ; CHECK:       else:
547 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
548 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
549 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
550 ; CHECK-NEXT:    br label [[EXIT]]
551 ; CHECK:       exit:
552 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ELSE]] ]
553 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
554 ; CHECK-NEXT:    call void @clobber()
555 ; CHECK-NEXT:    ret i32 [[P]]
557   %a = alloca i32, align 4
558   store i32 55, ptr %a
559   br i1 %c.1, label %then, label %else
561 then:
562   br label %exit
564 else:
565   %in.lv.1 = load ptr , ptr %in.ptr, align 2
566   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
567   call void @escape_writeonly(ptr %a)
568   br label %exit
570 exit:
571   %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
572   store i32 99, ptr %a, align 4
573   call void @clobber()
574   ret i32 %p
577 define i32 @test_not_captured_before_load_other_blocks_5(ptr %in.ptr, i1 %c.1) {
578 ; CHECK-LABEL: @test_not_captured_before_load_other_blocks_5(
579 ; CHECK-NEXT:  entry:
580 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
581 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
582 ; CHECK:       then:
583 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
584 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
585 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
586 ; CHECK-NEXT:    br label [[EXIT]]
587 ; CHECK:       exit:
588 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[IN_LV_2]], [[THEN]] ], [ 0, [[ENTRY:%.*]] ]
589 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
590 ; CHECK-NEXT:    call void @clobber()
591 ; CHECK-NEXT:    ret i32 [[P]]
593 entry:
594   %a = alloca i32, align 4
595   store i32 55, ptr %a
596   br i1 %c.1, label %then, label %exit
598 then:
599   %in.lv.1 = load ptr , ptr %in.ptr, align 2
600   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
601   call void @escape_writeonly(ptr %a)
602   br label %exit
604 exit:
605   %p = phi i32 [ %in.lv.2, %then ], [ 0, %entry ]
606   store i32 99, ptr %a, align 4
607   call void @clobber()
608   ret i32 %p
611 define i32 @test_not_captured_before_load_other_blocks_6(ptr %in.ptr, i1 %c.1) {
612 ; CHECK-LABEL: @test_not_captured_before_load_other_blocks_6(
613 ; CHECK-NEXT:  entry:
614 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
615 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
616 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
617 ; CHECK:       then:
618 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
619 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
620 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
621 ; CHECK-NEXT:    br label [[EXIT]]
622 ; CHECK:       exit:
623 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[IN_LV_2]], [[THEN]] ], [ 0, [[ENTRY:%.*]] ]
624 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
625 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
626 ; CHECK-NEXT:    call void @clobber()
627 ; CHECK-NEXT:    ret i32 [[P]]
629 entry:
630   %a = alloca i32, align 4
631   store i32 55, ptr %a
632   br i1 %c.1, label %then, label %exit
634 then:
635   %in.lv.1 = load ptr , ptr %in.ptr, align 2
636   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
637   call void @escape_writeonly(ptr %a)
638   br label %exit
640 exit:
641   %p = phi i32 [ %in.lv.2, %then ], [ 0, %entry ]
642   store i32 99, ptr %a, align 4
643   call void @escape_writeonly(ptr %a)
644   call void @clobber()
645   ret i32 %p
648 define i32 @test_not_captured_before_load_other_blocks_7(ptr %in.ptr, i1 %c.1) {
649 ; CHECK-LABEL: @test_not_captured_before_load_other_blocks_7(
650 ; CHECK-NEXT:  entry:
651 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
652 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
653 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
654 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
655 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
656 ; CHECK:       then:
657 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
658 ; CHECK-NEXT:    br label [[EXIT]]
659 ; CHECK:       exit:
660 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ENTRY:%.*]] ]
661 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
662 ; CHECK-NEXT:    call void @clobber()
663 ; CHECK-NEXT:    ret i32 [[P]]
665 entry:
666   %a = alloca i32, align 4
667   store i32 55, ptr %a
668   %in.lv.1 = load ptr , ptr %in.ptr, align 2
669   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
670   call void @escape_writeonly(ptr %a)
671   br i1 %c.1, label %then, label %exit
673 then:
674   call void @escape_writeonly(ptr %a)
675   br label %exit
677 exit:
678   %p = phi i32 [ 0, %then ], [ %in.lv.2, %entry ]
679   store i32 99, ptr %a, align 4
680   call void @clobber()
681   ret i32 %p
684 define i32 @test_not_captured_before_load_same_bb_but_read(ptr %in.ptr) {
685 ; CHECK-LABEL: @test_not_captured_before_load_same_bb_but_read(
686 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
687 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
688 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
689 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
690 ; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[A]], align 4
691 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
692 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
693 ; CHECK-NEXT:    [[RES:%.*]] = add i32 [[IN_LV_2]], [[LV]]
694 ; CHECK-NEXT:    ret i32 [[RES]]
696   %a = alloca i32, align 4
697   store i32 55, ptr %a
698   %in.lv.1 = load ptr , ptr %in.ptr, align 2
699   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
700   %lv = load i32, ptr %a
701   store i32 99, ptr %a, align 4
702   call void @escape_and_clobber(ptr %a)
703   %res = add i32 %in.lv.2, %lv
704   ret i32 %res
707 define i32 @test_not_captured_before_load_may_alias_same_bb_but_read(ptr %in.ptr, ptr %b, i1 %c) {
708 ; CHECK-LABEL: @test_not_captured_before_load_may_alias_same_bb_but_read(
709 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
710 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
711 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
712 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
713 ; CHECK-NEXT:    [[PTR:%.*]] = select i1 [[C:%.*]], ptr [[A]], ptr [[B:%.*]]
714 ; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[PTR]], align 4
715 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
716 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
717 ; CHECK-NEXT:    [[RES:%.*]] = add i32 [[IN_LV_2]], [[LV]]
718 ; CHECK-NEXT:    ret i32 [[RES]]
720   %a = alloca i32, align 4
721   store i32 55, ptr %a
722   %in.lv.1 = load ptr , ptr %in.ptr, align 2
723   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
724   %ptr = select i1 %c, ptr %a, ptr %b
725   %lv = load i32, ptr %ptr
726   store i32 99, ptr %a, align 4
727   call void @escape_and_clobber(ptr %a)
728   %res = add i32 %in.lv.2, %lv
729   ret i32 %res
732 define i32 @test_captured_after_loop(ptr %in.ptr, i1 %c.1) {
733 ; CHECK-LABEL: @test_captured_after_loop(
734 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
735 ; CHECK-NEXT:    br label [[LOOP:%.*]]
736 ; CHECK:       loop:
737 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
738 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
739 ; CHECK-NEXT:    store i32 99, ptr [[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(ptr [[A]])
743 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
745   %a = alloca i32, align 4
746   store i32 55, ptr %a
747   br label %loop
749 loop:
750   %in.lv.1 = load ptr , ptr %in.ptr, align 2
751   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
752   store i32 99, ptr %a, align 4
753   br i1 %c.1, label %loop, label %exit
755 exit:
756   call void @escape_and_clobber(ptr %a)
757   ret i32 %in.lv.2
760 define i32 @test_captured_in_loop(ptr %in.ptr, i1 %c.1) {
761 ; CHECK-LABEL: @test_captured_in_loop(
762 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
763 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
764 ; CHECK-NEXT:    br label [[LOOP:%.*]]
765 ; CHECK:       loop:
766 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
767 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
768 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
769 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
770 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
771 ; CHECK:       exit:
772 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
773 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
775   %a = alloca i32, align 4
776   store i32 55, ptr %a
777   br label %loop
779 loop:
780   %in.lv.1 = load ptr , ptr %in.ptr, align 2
781   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
782   call void @escape_writeonly(ptr %a)
783   store i32 99, ptr %a, align 4
784   br i1 %c.1, label %loop, label %exit
786 exit:
787   call void @escape_and_clobber(ptr %a)
788   ret i32 %in.lv.2
791 declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg)
793 @global = external global ptr
795 define void @test_memset_not_captured_before_load() {
796 ; CHECK-LABEL: @test_memset_not_captured_before_load(
797 ; CHECK-NEXT:    [[A:%.*]] = alloca [2 x i32], align 4
798 ; CHECK-NEXT:    [[LV_1:%.*]] = load ptr, ptr @global, align 8
799 ; CHECK-NEXT:    store i32 1, ptr [[A]], align 4
800 ; CHECK-NEXT:    [[GEP_LV:%.*]] = getelementptr inbounds [10 x i16], ptr [[LV_1]], i64 0, i32 1
801 ; CHECK-NEXT:    [[LV_2:%.*]] = load i16, ptr [[GEP_LV]], align 2
802 ; CHECK-NEXT:    [[EXT_LV_2:%.*]] = zext i16 [[LV_2]] to i32
803 ; CHECK-NEXT:    [[GEP_A_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i32 0, i32 1
804 ; CHECK-NEXT:    store i32 [[EXT_LV_2]], ptr [[GEP_A_1]], align 4
805 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
806 ; CHECK-NEXT:    ret void
808   %a = alloca [2 x i32], align 4
809   call void @llvm.memset.p0.i32(ptr %a, i8 0, i32 8, i1 false)
810   %lv.1 = load ptr, ptr @global, align 8
811   store i32 1, ptr %a, align 4
812   %gep.lv = getelementptr inbounds [10 x i16], ptr %lv.1, i64 0, i32 1
813   %lv.2 = load i16, ptr %gep.lv, align 2
814   %ext.lv.2 = zext i16 %lv.2 to i32
815   %gep.a.1 = getelementptr inbounds [2 x i32], ptr %a, i32 0, i32 1
816   store i32 %ext.lv.2, ptr %gep.a.1, align 4
817   call void @escape_and_clobber(ptr %a)
818   ret void
821 define void @test_test_not_captured_before_load(i1 %c.1) {
822 ; CHECK-LABEL: @test_test_not_captured_before_load(
823 ; CHECK-NEXT:  bb:
824 ; CHECK-NEXT:    [[A:%.*]] = alloca [2 x i32], align 4
825 ; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[A]], i32 4
826 ; CHECK-NEXT:    call void @llvm.memset.p0.i32(ptr align 1 [[TMP0]], i8 0, i32 4, i1 false)
827 ; CHECK-NEXT:    [[LV_1:%.*]] = load ptr, ptr @global, align 8
828 ; CHECK-NEXT:    [[GEP_LV:%.*]] = getelementptr inbounds [10 x i16], ptr [[LV_1]], i64 0, i32 1
829 ; CHECK-NEXT:    [[LV_2:%.*]] = load i16, ptr [[GEP_LV]], align 2
830 ; CHECK-NEXT:    store i32 1, ptr [[A]], align 4
831 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
832 ; CHECK:       then:
833 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
834 ; CHECK-NEXT:    br label [[EXIT:%.*]]
835 ; CHECK:       else:
836 ; CHECK-NEXT:    br label [[EXIT]]
837 ; CHECK:       exit:
838 ; CHECK-NEXT:    [[EXT_LV_2:%.*]] = zext i16 [[LV_2]] to i32
839 ; CHECK-NEXT:    [[GEP_A_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[A]], i32 0, i32 1
840 ; CHECK-NEXT:    store i32 [[EXT_LV_2]], ptr [[GEP_A_1]], align 4
841 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
842 ; CHECK-NEXT:    ret void
845   %a = alloca [2 x i32], align 4
846   call void @llvm.memset.p0.i32(ptr %a, i8 0, i32 8, i1 false)
847   %lv.1 = load ptr, ptr @global, align 8
848   %gep.lv = getelementptr inbounds [10 x i16], ptr %lv.1, i64 0, i32 1
849   %lv.2 = load i16, ptr %gep.lv, align 2
850   store i32 1, ptr %a, align 4
851   br i1 %c.1, label %then, label %else
853 then:
854   call void @escape_and_clobber(ptr %a)
855   br label %exit
857 else:
858   br label %exit
860 exit:
861   %ext.lv.2 = zext i16 %lv.2 to i32
862   %gep.a.1 = getelementptr inbounds [2 x i32], ptr %a, i32 0, i32 1
863   store i32 %ext.lv.2, ptr %gep.a.1, align 4
864   call void @escape_and_clobber(ptr %a)
865   ret void
868 declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #0
869 declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #1
871 declare void @use.i64(i64)
873 define i64 @test_a_not_captured_at_all(ptr %ptr, ptr %ptr.2, i1 %c) {
874 ; CHECK-LABEL: @test_a_not_captured_at_all(
875 ; CHECK-NEXT:  entry:
876 ; CHECK-NEXT:    [[A:%.*]] = alloca i64, align 8
877 ; CHECK-NEXT:    [[B:%.*]] = alloca i64, align 8
878 ; CHECK-NEXT:    store ptr [[B]], ptr [[PTR:%.*]], align 8
879 ; CHECK-NEXT:    [[LV_1:%.*]] = load ptr, ptr [[PTR_2:%.*]], align 8
880 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[EXIT:%.*]], label [[THEN:%.*]]
881 ; CHECK:       then:
882 ; CHECK-NEXT:    [[LV_2:%.*]] = load i64, ptr [[LV_1]], align 4
883 ; CHECK-NEXT:    call void @use.i64(i64 [[LV_2]])
884 ; CHECK-NEXT:    br label [[EXIT]]
885 ; CHECK:       exit:
886 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 8, ptr [[A]])
887 ; CHECK-NEXT:    call void @clobber()
888 ; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[A]], i8 0, i64 8, i1 false)
889 ; CHECK-NEXT:    [[L:%.*]] = load i64, ptr [[A]], align 4
890 ; CHECK-NEXT:    ret i64 [[L]]
892 entry:
893   %a = alloca i64, align 8
894   %b = alloca i64, align 8
895   store ptr %b, ptr %ptr, align 8
896   %lv.1 = load ptr, ptr %ptr.2, align 8
897   br i1 %c, label %exit, label %then
899 then:
900   %lv.2 = load i64, ptr %lv.1
901   call void @use.i64(i64 %lv.2)
902   br label %exit
904 exit:
905   call void @llvm.lifetime.start.p0(i64 8, ptr %a)
906   store i64 99, ptr %a
907   call void @clobber()
908   call void @llvm.memset.p0.i64(ptr %a, i8 0, i64 8, i1 false)
909   %l = load i64, ptr %a
910   ret i64 %l
913 define i32 @test_not_captured_both_paths_1(ptr %in.ptr, i1 %c.1) {
914 ; CHECK-LABEL: @test_not_captured_both_paths_1(
915 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
916 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
917 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
918 ; CHECK:       then:
919 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
920 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
921 ; CHECK-NEXT:    br label [[EXIT:%.*]]
922 ; CHECK:       else:
923 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
924 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
925 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
926 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
927 ; CHECK-NEXT:    br label [[EXIT]]
928 ; CHECK:       exit:
929 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[IN_LV_2]], [[ELSE]] ]
930 ; CHECK-NEXT:    call void @clobber()
931 ; CHECK-NEXT:    ret i32 [[P]]
933   %a = alloca i32, align 4
934   store i32 55, ptr %a
935   br i1 %c.1, label %then, label %else
937 then:
938   store i32 99, ptr %a, align 4
939   call void @escape_writeonly(ptr %a)
940   br label %exit
942 else:
943   %in.lv.1 = load ptr , ptr %in.ptr, align 2
944   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
945   store i32 99, ptr %a, align 4
946   call void @escape_writeonly(ptr %a)
947   br label %exit
949 exit:
950   %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
951   call void @clobber()
952   ret i32 %p
955 define i32 @test_not_captured_both_paths_2(ptr %in.ptr, i1 %c.1) {
956 ; CHECK-LABEL: @test_not_captured_both_paths_2(
957 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
958 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
959 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
960 ; CHECK:       then:
961 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
962 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
963 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
964 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
965 ; CHECK-NEXT:    br label [[EXIT:%.*]]
966 ; CHECK:       else:
967 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
968 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
969 ; CHECK-NEXT:    br label [[EXIT]]
970 ; CHECK:       exit:
971 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[IN_LV_2]], [[THEN]] ], [ 0, [[ELSE]] ]
972 ; CHECK-NEXT:    call void @clobber()
973 ; CHECK-NEXT:    ret i32 [[P]]
975   %a = alloca i32, align 4
976   store i32 55, ptr %a
977   br i1 %c.1, label %then, label %else
979 then:
980   %in.lv.1 = load ptr , ptr %in.ptr, align 2
981   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
982   store i32 99, ptr %a, align 4
983   call void @escape_writeonly(ptr %a)
984   br label %exit
986 else:
987   store i32 99, ptr %a, align 4
988   call void @escape_writeonly(ptr %a)
989   br label %exit
991 exit:
992   %p = phi i32 [ %in.lv.2, %then ], [ 0, %else ]
993   call void @clobber()
994   ret i32 %p
997 define i32 @test_captured_before_store_both_paths_2(ptr %in.ptr, i1 %c.1) {
998 ; CHECK-LABEL: @test_captured_before_store_both_paths_2(
999 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
1000 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
1001 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
1002 ; CHECK:       then:
1003 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
1004 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
1005 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
1006 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
1007 ; CHECK-NEXT:    br label [[EXIT:%.*]]
1008 ; CHECK:       else:
1009 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
1010 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
1011 ; CHECK-NEXT:    br label [[EXIT]]
1012 ; CHECK:       exit:
1013 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[IN_LV_2]], [[THEN]] ], [ 0, [[ELSE]] ]
1014 ; CHECK-NEXT:    call void @clobber()
1015 ; CHECK-NEXT:    ret i32 [[P]]
1017   %a = alloca i32, align 4
1018   store i32 55, ptr %a
1019   br i1 %c.1, label %then, label %else
1021 then:
1022   call void @escape_writeonly(ptr %a)
1023   %in.lv.1 = load ptr , ptr %in.ptr, align 2
1024   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
1025   store i32 99, ptr %a, align 4
1026   br label %exit
1028 else:
1029   call void @escape_writeonly(ptr %a)
1030   store i32 99, ptr %a, align 4
1031   br label %exit
1033 exit:
1034   %p = phi i32 [ %in.lv.2, %then ], [ 0, %else ]
1035   call void @clobber()
1036   ret i32 %p
1040 declare noalias ptr @alloc() nounwind
1042 define i32 @test_not_captured_before_load_same_bb_noalias_call(ptr %in.ptr) {
1043 ; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_call(
1044 ; CHECK-NEXT:    [[A:%.*]] = call ptr @alloc()
1045 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
1046 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
1047 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
1048 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
1049 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
1051   %a = call ptr @alloc()
1052   store i32 55, ptr %a
1053   %in.lv.1 = load ptr , ptr %in.ptr, align 2
1054   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
1055   store i32 99, ptr %a, align 4
1056   call void @escape_and_clobber(ptr %a)
1057   ret i32 %in.lv.2
1060 define i32 @test_not_captured_before_load_same_bb_noalias_arg(ptr %in.ptr, ptr noalias %a) {
1061 ; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_arg(
1062 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
1063 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
1064 ; CHECK-NEXT:    store i32 99, ptr [[A:%.*]], align 4
1065 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
1066 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
1068   store i32 55, ptr %a
1069   %in.lv.1 = load ptr , ptr %in.ptr, align 2
1070   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
1071   store i32 99, ptr %a, align 4
1072   call void @escape_and_clobber(ptr %a)
1073   ret i32 %in.lv.2
1076 define i32 @instruction_captures_multiple_objects(ptr %p.1, ptr %p.2, ptr %p.3, i1 %c) {
1077 ; CHECK-LABEL: @instruction_captures_multiple_objects(
1078 ; CHECK-NEXT:  entry:
1079 ; CHECK-NEXT:    [[A_1:%.*]] = alloca i32, align 4
1080 ; CHECK-NEXT:    [[A_2:%.*]] = alloca i32, align 4
1081 ; CHECK-NEXT:    store i32 0, ptr [[P_1:%.*]], align 8
1082 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
1083 ; CHECK:       then:
1084 ; CHECK-NEXT:    [[LV_2:%.*]] = load ptr, ptr [[P_2:%.*]], align 8
1085 ; CHECK-NEXT:    [[LV_2_2:%.*]] = load i32, ptr [[LV_2]], align 4
1086 ; CHECK-NEXT:    ret i32 [[LV_2_2]]
1087 ; CHECK:       else:
1088 ; CHECK-NEXT:    [[LV_3:%.*]] = load ptr, ptr [[P_3:%.*]], align 8
1089 ; CHECK-NEXT:    [[LV_3_2:%.*]] = load i32, ptr [[LV_3]], align 4
1090 ; CHECK-NEXT:    call void @capture_and_clobber_multiple(ptr [[A_1]], ptr [[A_2]])
1091 ; CHECK-NEXT:    ret i32 [[LV_3_2]]
1093 entry:
1094   %a.1 = alloca i32
1095   %a.2 = alloca i32
1096   store i32 0, ptr %p.1, align 8
1097   br i1 %c, label %then, label %else
1099 then:
1100   store i32 99, ptr %a.2, align 4
1101   %lv.2 = load ptr, ptr %p.2
1102   %lv.2.2 = load i32, ptr %lv.2
1103   store i32 0, ptr %a.1, align 8
1104   ret i32 %lv.2.2
1106 else:
1107   %lv.3 = load ptr, ptr %p.3
1108   %lv.3.2 = load i32, ptr %lv.3
1109   call void @capture_and_clobber_multiple(ptr %a.1, ptr %a.2)
1110   ret i32 %lv.3.2
1113 declare void @capture_and_clobber_multiple(ptr, ptr)
1115 declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
1117 define i64 @earliest_escape_ptrtoint(ptr %p.1) {
1118 ; CHECK-LABEL: @earliest_escape_ptrtoint(
1119 ; CHECK-NEXT:  entry:
1120 ; CHECK-NEXT:    [[A_1:%.*]] = alloca i64, align 8
1121 ; CHECK-NEXT:    [[A_2:%.*]] = alloca i64, align 8
1122 ; CHECK-NEXT:    [[LV_1:%.*]] = load ptr, ptr [[P_1:%.*]], align 8
1123 ; CHECK-NEXT:    [[LV_2:%.*]] = load i64, ptr [[LV_1]], align 4
1124 ; CHECK-NEXT:    store ptr [[A_1]], ptr [[P_1]], align 8
1125 ; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 8, ptr [[A_2]])
1126 ; CHECK-NEXT:    ret i64 [[LV_2]]
1128 entry:
1129   %a.1 = alloca i64
1130   %a.2 = alloca i64
1131   store i64 99, ptr %a.1
1132   %lv.1 = load ptr, ptr %p.1
1133   %lv.2 = load i64, ptr %lv.1
1134   store ptr %a.1, ptr %p.1, align 8
1135   %int = ptrtoint ptr %a.2 to i64
1136   store i64 %int , ptr %a.2, align 8
1137   call void @llvm.lifetime.end.p0(i64 8, ptr %a.2)
1138   ret i64 %lv.2
1141 define i32 @test_not_captured_before_load_of_ptrtoint(i64 %in) {
1142 ; CHECK-LABEL: @test_not_captured_before_load_of_ptrtoint(
1143 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
1144 ; CHECK-NEXT:    [[IN_PTR:%.*]] = inttoptr i64 [[IN:%.*]] to ptr
1145 ; CHECK-NEXT:    [[IN_PTR_LOAD:%.*]] = load i32, ptr [[IN_PTR]], align 4
1146 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
1147 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
1148 ; CHECK-NEXT:    ret i32 [[IN_PTR_LOAD]]
1150   %a = alloca i32, align 4
1151   store i32 55, ptr %a
1152   %in.ptr = inttoptr i64 %in to ptr
1153   %in.ptr.load = load i32, ptr %in.ptr
1154   store i32 99, ptr %a
1155   call void @escape_and_clobber(ptr %a)
1156   ret i32 %in.ptr.load
1159 declare ptr @getptr()
1161 define i32 @test_not_captured_before_load_of_call() {
1162 ; CHECK-LABEL: @test_not_captured_before_load_of_call(
1163 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
1164 ; CHECK-NEXT:    [[IN_PTR:%.*]] = call ptr @getptr() #[[ATTR4:[0-9]+]]
1165 ; CHECK-NEXT:    [[IN_PTR_LOAD:%.*]] = load i32, ptr [[IN_PTR]], align 4
1166 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
1167 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
1168 ; CHECK-NEXT:    ret i32 [[IN_PTR_LOAD]]
1170   %a = alloca i32, align 4
1171   store i32 55, ptr %a
1172   %in.ptr = call ptr @getptr() readnone
1173   %in.ptr.load = load i32, ptr %in.ptr
1174   store i32 99, ptr %a
1175   call void @escape_and_clobber(ptr %a)
1176   ret i32 %in.ptr.load
1179 define i32 @test_not_captured_multiple_objects(i1 %c, ptr %in.ptr) {
1180 ; CHECK-LABEL: @test_not_captured_multiple_objects(
1181 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
1182 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
1183 ; CHECK-NEXT:    [[O:%.*]] = select i1 [[C:%.*]], ptr [[A]], ptr [[B]]
1184 ; CHECK-NEXT:    [[IN_LV_1:%.*]] = load ptr, ptr [[IN_PTR:%.*]], align 2
1185 ; CHECK-NEXT:    [[IN_LV_2:%.*]] = load i32, ptr [[IN_LV_1]], align 2
1186 ; CHECK-NEXT:    store i32 99, ptr [[O]], align 4
1187 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[O]])
1188 ; CHECK-NEXT:    ret i32 [[IN_LV_2]]
1190   %a = alloca i32, align 4
1191   %b = alloca i32, align 4
1192   %o = select i1 %c, ptr %a, ptr %b
1193   store i32 55, ptr %o
1194   %in.lv.1 = load ptr , ptr %in.ptr, align 2
1195   %in.lv.2 = load i32 , ptr %in.lv.1, align 2
1196   store i32 99, ptr %o
1197   call void @escape_and_clobber(ptr %o)
1198   ret i32 %in.lv.2