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
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)
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]]
35 ; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
36 ; CHECK-NEXT: ret i32 0
38 %a = alloca i32, align 4
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)
47 call void @escape_and_clobber(ptr %a)
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:%.*]]
55 ; CHECK-NEXT: call void @escape_and_clobber(ptr [[A:%.*]])
56 ; CHECK-NEXT: ret i32 0
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]]
68 call void @escape_and_clobber(ptr %a)
72 %a = alloca i32, align 4
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)
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
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
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
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
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
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
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
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
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
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
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
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)
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
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)
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:%.*]]
230 ; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
231 ; CHECK-NEXT: br label [[EXIT:%.*]]
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]]
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
244 br i1 %c.1, label %then, label %else
247 call void @escape_writeonly(ptr %a)
251 %in.lv.1 = load ptr , ptr %in.ptr, align 2
252 %in.lv.2 = load i32 , ptr %in.lv.1, align 2
256 %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
257 store i32 99, ptr %a, align 4
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:%.*]]
267 ; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
268 ; CHECK-NEXT: ret i32 0
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:%.*]]
274 ; CHECK-NEXT: call void @clobber()
275 ; CHECK-NEXT: ret i32 [[IN_LV_2]]
277 %a = alloca i32, align 4
279 br i1 %c.1, label %then, label %else
282 call void @escape_writeonly(ptr %a)
286 %in.lv.1 = load ptr , ptr %in.ptr, align 2
287 %in.lv.2 = load i32 , ptr %in.lv.1, align 2
291 store i32 99, ptr %a, align 4
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:%.*]]
302 ; CHECK-NEXT: br label [[EXIT:%.*]]
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]]
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
316 br i1 %c.1, label %then, label %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
328 %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
329 store i32 99, ptr %a, align 4
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(
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:%.*]]
344 ; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
345 ; CHECK-NEXT: br label [[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]]
353 %a = alloca i32, align 4
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
361 call void @escape_writeonly(ptr %a)
365 %p = phi i32 [ 0, %then ], [ %in.lv.2, %entry ]
366 store i32 99, ptr %a, align 4
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(
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:%.*]]
378 ; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
379 ; CHECK-NEXT: br label [[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]]
388 %a = alloca i32, align 4
390 br i1 %c.1, label %then, label %exit
393 call void @escape_writeonly(ptr %a)
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
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(
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:%.*]]
411 ; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
412 ; CHECK-NEXT: br label [[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]]
422 %a = alloca i32, align 4
424 br i1 %c.1, label %then, label %exit
427 call void @escape_writeonly(ptr %a)
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)
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:%.*]]
447 ; CHECK-NEXT: br label [[EXIT:%.*]]
449 ; CHECK-NEXT: br label [[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
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
468 call void @escape_and_clobber(ptr %a)
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:%.*]]
480 ; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
481 ; CHECK-NEXT: br label [[EXIT:%.*]]
483 ; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
484 ; CHECK-NEXT: br label [[EXIT]]
486 ; CHECK-NEXT: ret i32 [[IN_LV_2]]
488 %a = alloca i32, align 4
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
496 call void @escape_and_clobber(ptr %a)
500 call void @escape_and_clobber(ptr %a)
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:%.*]]
515 ; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
516 ; CHECK-NEXT: br label [[EXIT:%.*]]
518 ; CHECK-NEXT: br label [[EXIT]]
520 ; CHECK-NEXT: ret i32 [[IN_LV_2]]
522 %a = alloca i32, align 4
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
530 call void @escape_and_clobber(ptr %a)
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:%.*]]
545 ; CHECK-NEXT: br label [[EXIT:%.*]]
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]]
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
559 br i1 %c.1, label %then, label %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)
571 %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
572 store i32 99, ptr %a, align 4
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(
580 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
581 ; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
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]]
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]]
594 %a = alloca i32, align 4
596 br i1 %c.1, label %then, label %exit
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)
605 %p = phi i32 [ %in.lv.2, %then ], [ 0, %entry ]
606 store i32 99, ptr %a, align 4
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(
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:%.*]]
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]]
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]]
630 %a = alloca i32, align 4
632 br i1 %c.1, label %then, label %exit
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)
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)
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(
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:%.*]]
657 ; CHECK-NEXT: call void @escape_writeonly(ptr [[A]])
658 ; CHECK-NEXT: br label [[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]]
666 %a = alloca i32, align 4
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
674 call void @escape_writeonly(ptr %a)
678 %p = phi i32 [ 0, %then ], [ %in.lv.2, %entry ]
679 store i32 99, ptr %a, align 4
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
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
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
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
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:%.*]]
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:%.*]]
742 ; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
743 ; CHECK-NEXT: ret i32 [[IN_LV_2]]
745 %a = alloca i32, align 4
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
756 call void @escape_and_clobber(ptr %a)
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:%.*]]
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:%.*]]
772 ; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
773 ; CHECK-NEXT: ret i32 [[IN_LV_2]]
775 %a = alloca i32, align 4
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
787 call void @escape_and_clobber(ptr %a)
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)
821 define void @test_test_not_captured_before_load(i1 %c.1) {
822 ; CHECK-LABEL: @test_test_not_captured_before_load(
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:%.*]]
833 ; CHECK-NEXT: call void @escape_and_clobber(ptr [[A]])
834 ; CHECK-NEXT: br label [[EXIT:%.*]]
836 ; CHECK-NEXT: br label [[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
854 call void @escape_and_clobber(ptr %a)
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)
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(
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:%.*]]
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]]
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]]
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
900 %lv.2 = load i64, ptr %lv.1
901 call void @use.i64(i64 %lv.2)
905 call void @llvm.lifetime.start.p0(i64 8, ptr %a)
908 call void @llvm.memset.p0.i64(ptr %a, i8 0, i64 8, i1 false)
909 %l = load i64, ptr %a
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:%.*]]
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:%.*]]
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]]
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
935 br i1 %c.1, label %then, label %else
938 store i32 99, ptr %a, align 4
939 call void @escape_writeonly(ptr %a)
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)
950 %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
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:%.*]]
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:%.*]]
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]]
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
977 br i1 %c.1, label %then, label %else
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)
987 store i32 99, ptr %a, align 4
988 call void @escape_writeonly(ptr %a)
992 %p = phi i32 [ %in.lv.2, %then ], [ 0, %else ]
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:%.*]]
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:%.*]]
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]]
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
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
1029 call void @escape_writeonly(ptr %a)
1030 store i32 99, ptr %a, align 4
1034 %p = phi i32 [ %in.lv.2, %then ], [ 0, %else ]
1035 call void @clobber()
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)
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)
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:%.*]]
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]]
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]]
1096 store i32 0, ptr %p.1, align 8
1097 br i1 %c, label %then, label %else
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
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)
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]]
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)
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)