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
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)
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]]
35 ; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
36 ; CHECK-NEXT: ret i32 0
38 %a = alloca i32, align 4
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)
47 call void @escape_and_clobber(i32* %a)
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
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
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
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
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
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
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
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
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)
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)
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:%.*]]
200 ; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
201 ; CHECK-NEXT: br label [[EXIT:%.*]]
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]]
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
217 call void @escape_writeonly(i32* %a)
221 %in.lv.1 = load i32* , i32** %in.ptr, align 2
222 %in.lv.2 = load i32 , i32* %in.lv.1, align 2
226 %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
227 store i32 99, i32* %a, align 4
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:%.*]]
237 ; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
238 ; CHECK-NEXT: ret i32 0
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:%.*]]
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
252 call void @escape_writeonly(i32* %a)
256 %in.lv.1 = load i32* , i32** %in.ptr, align 2
257 %in.lv.2 = load i32 , i32* %in.lv.1, align 2
261 store i32 99, i32* %a, align 4
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:%.*]]
272 ; CHECK-NEXT: br label [[EXIT:%.*]]
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]]
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
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
298 %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
299 store i32 99, i32* %a, align 4
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(
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:%.*]]
314 ; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
315 ; CHECK-NEXT: br label [[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]]
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
331 call void @escape_writeonly(i32* %a)
335 %p = phi i32 [ 0, %then ], [ %in.lv.2, %entry ]
336 store i32 99, i32* %a, align 4
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(
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:%.*]]
348 ; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
349 ; CHECK-NEXT: br label [[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]]
358 %a = alloca i32, align 4
359 store i32 55, i32* %a
360 br i1 %c.1, label %then, label %exit
363 call void @escape_writeonly(i32* %a)
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
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(
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:%.*]]
381 ; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
382 ; CHECK-NEXT: br label [[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]]
392 %a = alloca i32, align 4
393 store i32 55, i32* %a
394 br i1 %c.1, label %then, label %exit
397 call void @escape_writeonly(i32* %a)
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)
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:%.*]]
417 ; CHECK-NEXT: br label [[EXIT:%.*]]
419 ; CHECK-NEXT: br label [[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
438 call void @escape_and_clobber(i32* %a)
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:%.*]]
450 ; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
451 ; CHECK-NEXT: br label [[EXIT:%.*]]
453 ; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
454 ; CHECK-NEXT: br label [[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
466 call void @escape_and_clobber(i32* %a)
470 call void @escape_and_clobber(i32* %a)
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:%.*]]
485 ; CHECK-NEXT: call void @escape_and_clobber(i32* [[A]])
486 ; CHECK-NEXT: br label [[EXIT:%.*]]
488 ; CHECK-NEXT: br label [[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
500 call void @escape_and_clobber(i32* %a)
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:%.*]]
515 ; CHECK-NEXT: br label [[EXIT:%.*]]
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]]
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
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)
541 %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
542 store i32 99, i32* %a, align 4
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(
550 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
551 ; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
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]]
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]]
564 %a = alloca i32, align 4
565 store i32 55, i32* %a
566 br i1 %c.1, label %then, label %exit
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)
575 %p = phi i32 [ %in.lv.2, %then ], [ 0, %entry ]
576 store i32 99, i32* %a, align 4
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(
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:%.*]]
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]]
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]]
600 %a = alloca i32, align 4
601 store i32 55, i32* %a
602 br i1 %c.1, label %then, label %exit
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)
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)
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(
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:%.*]]
627 ; CHECK-NEXT: call void @escape_writeonly(i32* [[A]])
628 ; CHECK-NEXT: br label [[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]]
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
644 call void @escape_writeonly(i32* %a)
648 %p = phi i32 [ 0, %then ], [ %in.lv.2, %entry ]
649 store i32 99, i32* %a, align 4
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
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
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:%.*]]
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:%.*]]
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
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
726 call void @escape_and_clobber(i32* %a)
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:%.*]]
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:%.*]]
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
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
757 call void @escape_and_clobber(i32* %a)
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)
794 define void @test_test_not_captured_before_load(i1 %c.1) {
795 ; CHECK-LABEL: @test_test_not_captured_before_load(
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:%.*]]
808 ; CHECK-NEXT: call void @escape_and_clobber(i32* [[GEP_A_0]])
809 ; CHECK-NEXT: br label [[EXIT:%.*]]
811 ; CHECK-NEXT: br label [[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
831 call void @escape_and_clobber(i32* %gep.a.0)
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)
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(
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:%.*]]
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]]
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]]
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
878 %lv.2 = load i64, i64* %lv.1
879 call void @use.i64(i64 %lv.2)
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
887 call void @llvm.memset.p0i8.i64(i8* %a.cast, i8 0, i64 8, i1 false)
888 %l = load i64, i64* %a
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:%.*]]
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:%.*]]
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]]
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
917 store i32 99, i32* %a, align 4
918 call void @escape_writeonly(i32* %a)
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)
929 %p = phi i32 [ 0, %then ], [ %in.lv.2, %else ]
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:%.*]]
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:%.*]]
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]]
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
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)
966 store i32 99, i32* %a, align 4
967 call void @escape_writeonly(i32* %a)
971 %p = phi i32 [ %in.lv.2, %then ], [ 0, %else ]
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:%.*]]
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:%.*]]
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]]
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
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
1008 call void @escape_writeonly(i32* %a)
1009 store i32 99, i32* %a, align 4
1013 %p = phi i32 [ %in.lv.2, %then ], [ 0, %else ]
1014 call void @clobber()
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)
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)
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:%.*]]
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]]
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]]
1075 store i32 0, i32* %p.1, align 8
1076 br i1 %c, label %then, label %else
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
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)
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]]
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)
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)