Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / DeadStoreElimination / captures-before-call.ll
blob9a23c738ef6899cc4c73a12e1c62c91093e921ae
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes='dse' -S %s | FileCheck %s
4 target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
6 ; Test case from PR50220.
7 define i32 @other_value_escapes_before_call() {
8 ; CHECK-LABEL: @other_value_escapes_before_call(
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    [[V1:%.*]] = alloca i32, align 4
11 ; CHECK-NEXT:    [[V2:%.*]] = alloca i32, align 4
12 ; CHECK-NEXT:    store i32 0, ptr [[V1]], align 4
13 ; CHECK-NEXT:    call void @escape(ptr nonnull [[V1]])
14 ; CHECK-NEXT:    [[CALL:%.*]] = call i32 @getval()
15 ; CHECK-NEXT:    store i32 [[CALL]], ptr [[V2]], align 4
16 ; CHECK-NEXT:    call void @escape(ptr nonnull [[V2]])
17 ; CHECK-NEXT:    [[LOAD_V2:%.*]] = load i32, ptr [[V2]], align 4
18 ; CHECK-NEXT:    [[LOAD_V1:%.*]] = load i32, ptr [[V1]], align 4
19 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[LOAD_V2]], [[LOAD_V1]]
20 ; CHECK-NEXT:    ret i32 [[ADD]]
22 entry:
23   %v1 = alloca i32, align 4
24   %v2 = alloca i32, align 4
25   store i32 0, ptr %v1, align 4
26   call void @escape(ptr nonnull %v1)
27   store i32 55555, ptr %v2, align 4
28   %call = call i32 @getval()
29   store i32 %call, ptr %v2, align 4
30   call void @escape(ptr nonnull %v2)
31   %load.v2 = load i32, ptr %v2, align 4
32   %load.v1 = load i32, ptr %v1, align 4
33   %add = add nsw i32 %load.v2, %load.v1
34   ret i32 %add
37 declare void @escape(ptr)
39 declare i32 @getval()
41 declare void @escape_and_clobber(ptr)
42 declare void @escape_writeonly(ptr) writeonly
43 declare void @clobber()
45 define i32 @test_not_captured_before_call_same_bb() {
46 ; CHECK-LABEL: @test_not_captured_before_call_same_bb(
47 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
48 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
49 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
50 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
51 ; CHECK-NEXT:    ret i32 [[R]]
53   %a = alloca i32, align 4
54   store i32 55, ptr %a
55   %r = call i32 @getval()
56   store i32 99, ptr %a, align 4
57   call void @escape_and_clobber(ptr %a)
58   ret i32 %r
61 define i32 @test_not_captured_before_call_same_bb_escape_unreachable_block() {
62 ; CHECK-LABEL: @test_not_captured_before_call_same_bb_escape_unreachable_block(
63 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
64 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
65 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
66 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
67 ; CHECK-NEXT:    ret i32 [[R]]
68 ; CHECK:       unreach:
69 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
70 ; CHECK-NEXT:    ret i32 0
72   %a = alloca i32, align 4
73   store i32 55, ptr %a
74   %r = call i32 @getval()
75   store i32 99, ptr %a, align 4
76   call void @escape_and_clobber(ptr %a)
77   ret i32 %r
79 unreach:
80   call void @escape_and_clobber(ptr %a)
81   ret i32 0
84 define i32 @test_captured_and_clobbered_after_load_same_bb_2() {
85 ; CHECK-LABEL: @test_captured_and_clobbered_after_load_same_bb_2(
86 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
87 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
88 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
89 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
90 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
91 ; CHECK-NEXT:    call void @clobber()
92 ; CHECK-NEXT:    ret i32 [[R]]
94   %a = alloca i32, align 4
95   store i32 55, ptr %a
96   %r = call i32 @getval()
97   call void @escape_and_clobber(ptr %a)
98   store i32 99, ptr %a, align 4
99   call void @clobber()
100   ret i32 %r
103 define i32 @test_captured_after_call_same_bb_2_clobbered_later() {
104 ; CHECK-LABEL: @test_captured_after_call_same_bb_2_clobbered_later(
105 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
106 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
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 [[R]]
112   %a = alloca i32, align 4
113   store i32 55, ptr %a
114   %r = call i32 @getval()
115   call void @escape_writeonly(ptr %a)
116   store i32 99, ptr %a, align 4
117   call void @clobber()
118   ret i32 %r
121 define i32 @test_captured_sibling_path_to_call_other_blocks_1(i1 %c.1) {
122 ; CHECK-LABEL: @test_captured_sibling_path_to_call_other_blocks_1(
123 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
124 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
125 ; CHECK:       then:
126 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
127 ; CHECK-NEXT:    br label [[EXIT:%.*]]
128 ; CHECK:       else:
129 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
130 ; CHECK-NEXT:    br label [[EXIT]]
131 ; CHECK:       exit:
132 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ELSE]] ]
133 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
134 ; CHECK-NEXT:    call void @clobber()
135 ; CHECK-NEXT:    ret i32 [[P]]
137   %a = alloca i32, align 4
138   store i32 55, ptr %a
139   br i1 %c.1, label %then, label %else
141 then:
142   call void @escape_writeonly(ptr %a)
143   br label %exit
145 else:
146   %r = call i32 @getval()
147   br label %exit
149 exit:
150   %p = phi i32 [ 0, %then ], [ %r, %else ]
151   store i32 99, ptr %a, align 4
152   call void @clobber()
153   ret i32 %p
156 define i32 @test_captured_before_call_other_blocks_2(i1 %c.1) {
157 ; CHECK-LABEL: @test_captured_before_call_other_blocks_2(
158 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
159 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
160 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
161 ; CHECK:       then:
162 ; CHECK-NEXT:    br label [[EXIT:%.*]]
163 ; CHECK:       else:
164 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
165 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
166 ; CHECK-NEXT:    br label [[EXIT]]
167 ; CHECK:       exit:
168 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ELSE]] ]
169 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
170 ; CHECK-NEXT:    call void @clobber()
171 ; CHECK-NEXT:    ret i32 [[P]]
173   %a = alloca i32, align 4
174   store i32 55, ptr %a
175   br i1 %c.1, label %then, label %else
177 then:
178   br label %exit
180 else:
181   call void @escape_and_clobber(ptr %a)
182   %r = call i32 @getval()
183   br label %exit
185 exit:
186   %p = phi i32 [ 0, %then ], [ %r, %else ]
187   store i32 99, ptr %a, align 4
188   call void @clobber()
189   ret i32 %p
192 define i32 @test_captured_before_call_other_blocks_4(i1 %c.1) {
193 ; CHECK-LABEL: @test_captured_before_call_other_blocks_4(
194 ; CHECK-NEXT:  entry:
195 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
196 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
197 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
198 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
199 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
200 ; CHECK:       then:
201 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
202 ; CHECK-NEXT:    br label [[EXIT]]
203 ; CHECK:       exit:
204 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ENTRY:%.*]] ]
205 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
206 ; CHECK-NEXT:    call void @clobber()
207 ; CHECK-NEXT:    ret i32 [[P]]
209 entry:
210   %a = alloca i32, align 4
211   store i32 55, ptr %a
212   call void @escape_writeonly(ptr %a)
213   %r = call i32 @getval()
214   br i1 %c.1, label %then, label %exit
216 then:
217   call void @escape_writeonly(ptr %a)
218   br label %exit
220 exit:
221   %p = phi i32 [ 0, %then ], [ %r, %entry ]
222   store i32 99, ptr %a, align 4
223   call void @clobber()
224   ret i32 %p
227 define i32 @test_captured_before_call_other_blocks_5(i1 %c.1) {
228 ; CHECK-LABEL: @test_captured_before_call_other_blocks_5(
229 ; CHECK-NEXT:  entry:
230 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
231 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
232 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
233 ; CHECK:       then:
234 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
235 ; CHECK-NEXT:    br label [[EXIT]]
236 ; CHECK:       exit:
237 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
238 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
239 ; CHECK-NEXT:    call void @clobber()
240 ; CHECK-NEXT:    ret i32 [[R]]
242 entry:
243   %a = alloca i32, align 4
244   store i32 55, ptr %a
245   br i1 %c.1, label %then, label %exit
247 then:
248   call void @escape_writeonly(ptr %a)
249   br label %exit
251 exit:
252   %r = call i32 @getval()
253   store i32 99, ptr %a, align 4
254   call void @clobber()
255   ret i32 %r
258 define i32 @test_captured_before_call_other_blocks_6(i1 %c.1) {
259 ; CHECK-LABEL: @test_captured_before_call_other_blocks_6(
260 ; CHECK-NEXT:  entry:
261 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
262 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
263 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
264 ; CHECK:       then:
265 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
266 ; CHECK-NEXT:    br label [[EXIT]]
267 ; CHECK:       exit:
268 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
269 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
270 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
271 ; CHECK-NEXT:    call void @clobber()
272 ; CHECK-NEXT:    ret i32 [[R]]
274 entry:
275   %a = alloca i32, align 4
276   store i32 55, ptr %a
277   br i1 %c.1, label %then, label %exit
279 then:
280   call void @escape_writeonly(ptr %a)
281   br label %exit
283 exit:
284   %r = call i32 @getval()
285   store i32 99, ptr %a, align 4
286   call void @escape_writeonly(ptr %a)
287   call void @clobber()
288   ret i32 %r
291 define i32 @test_not_captured_before_call_other_blocks_1(i1 %c.1) {
292 ; CHECK-LABEL: @test_not_captured_before_call_other_blocks_1(
293 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
294 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
295 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
296 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
297 ; CHECK:       then:
298 ; CHECK-NEXT:    br label [[EXIT:%.*]]
299 ; CHECK:       else:
300 ; CHECK-NEXT:    br label [[EXIT]]
301 ; CHECK:       exit:
302 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
303 ; CHECK-NEXT:    ret i32 [[R]]
305   %a = alloca i32, align 4
306   store i32 55, ptr %a
307   %r = call i32 @getval()
308   store i32 99, ptr %a, align 4
309   br i1 %c.1, label %then, label %else
311 then:
312   br label %exit
314 else:
315   br label %exit
317 exit:
318   call void @escape_and_clobber(ptr %a)
319   ret i32 %r
322 define i32 @test_not_captured_before_call_other_blocks_2(i1 %c.1) {
323 ; CHECK-LABEL: @test_not_captured_before_call_other_blocks_2(
324 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
325 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
326 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
327 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
328 ; CHECK:       then:
329 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
330 ; CHECK-NEXT:    br label [[EXIT:%.*]]
331 ; CHECK:       else:
332 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
333 ; CHECK-NEXT:    br label [[EXIT]]
334 ; CHECK:       exit:
335 ; CHECK-NEXT:    ret i32 [[R]]
337   %a = alloca i32, align 4
338   store i32 55, ptr %a
339   %r = call i32 @getval()
340   store i32 99, ptr %a, align 4
341   br i1 %c.1, label %then, label %else
343 then:
344   call void @escape_and_clobber(ptr %a)
345   br label %exit
347 else:
348   call void @escape_and_clobber(ptr %a)
349   br label %exit
351 exit:
352   ret i32 %r
355 define i32 @test_not_captured_before_call_other_blocks_3(i1 %c.1) {
356 ; CHECK-LABEL: @test_not_captured_before_call_other_blocks_3(
357 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
358 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
359 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
360 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
361 ; CHECK:       then:
362 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
363 ; CHECK-NEXT:    br label [[EXIT:%.*]]
364 ; CHECK:       else:
365 ; CHECK-NEXT:    br label [[EXIT]]
366 ; CHECK:       exit:
367 ; CHECK-NEXT:    ret i32 [[R]]
369   %a = alloca i32, align 4
370   store i32 55, ptr %a
371   %r = call i32 @getval()
372   store i32 99, ptr %a, align 4
373   br i1 %c.1, label %then, label %else
375 then:
376   call void @escape_and_clobber(ptr %a)
377   br label %exit
379 else:
380   br label %exit
382 exit:
383   ret i32 %r
386 define i32 @test_not_captured_before_call_other_blocks_4(i1 %c.1) {
387 ; CHECK-LABEL: @test_not_captured_before_call_other_blocks_4(
388 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
389 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
390 ; CHECK:       then:
391 ; CHECK-NEXT:    br label [[EXIT:%.*]]
392 ; CHECK:       else:
393 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
394 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
395 ; CHECK-NEXT:    br label [[EXIT]]
396 ; CHECK:       exit:
397 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ELSE]] ]
398 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
399 ; CHECK-NEXT:    call void @clobber()
400 ; CHECK-NEXT:    ret i32 [[P]]
402   %a = alloca i32, align 4
403   store i32 55, ptr %a
404   br i1 %c.1, label %then, label %else
406 then:
407   br label %exit
409 else:
410   %r = call i32 @getval()
411   call void @escape_writeonly(ptr %a)
412   br label %exit
414 exit:
415   %p = phi i32 [ 0, %then ], [ %r, %else ]
416   store i32 99, ptr %a, align 4
417   call void @clobber()
418   ret i32 %p
421 define i32 @test_not_captured_before_call_other_blocks_5(i1 %c.1) {
422 ; CHECK-LABEL: @test_not_captured_before_call_other_blocks_5(
423 ; CHECK-NEXT:  entry:
424 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
425 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
426 ; CHECK:       then:
427 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
428 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
429 ; CHECK-NEXT:    br label [[EXIT]]
430 ; CHECK:       exit:
431 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[R]], [[THEN]] ], [ 0, [[ENTRY:%.*]] ]
432 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
433 ; CHECK-NEXT:    call void @clobber()
434 ; CHECK-NEXT:    ret i32 [[P]]
436 entry:
437   %a = alloca i32, align 4
438   store i32 55, ptr %a
439   br i1 %c.1, label %then, label %exit
441 then:
442   %r = call i32 @getval()
443   call void @escape_writeonly(ptr %a)
444   br label %exit
446 exit:
447   %p = phi i32 [ %r, %then ], [ 0, %entry ]
448   store i32 99, ptr %a, align 4
449   call void @clobber()
450   ret i32 %p
453 define i32 @test_not_captured_before_call_other_blocks_6(i1 %c.1) {
454 ; CHECK-LABEL: @test_not_captured_before_call_other_blocks_6(
455 ; CHECK-NEXT:  entry:
456 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
457 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
458 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
459 ; CHECK:       then:
460 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
461 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
462 ; CHECK-NEXT:    br label [[EXIT]]
463 ; CHECK:       exit:
464 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[R]], [[THEN]] ], [ 0, [[ENTRY:%.*]] ]
465 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
466 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
467 ; CHECK-NEXT:    call void @clobber()
468 ; CHECK-NEXT:    ret i32 [[P]]
470 entry:
471   %a = alloca i32, align 4
472   store i32 55, ptr %a
473   br i1 %c.1, label %then, label %exit
475 then:
476   %r = call i32 @getval()
477   call void @escape_writeonly(ptr %a)
478   br label %exit
480 exit:
481   %p = phi i32 [ %r, %then ], [ 0, %entry ]
482   store i32 99, ptr %a, align 4
483   call void @escape_writeonly(ptr %a)
484   call void @clobber()
485   ret i32 %p
488 define i32 @test_not_captured_before_call_other_blocks_7(i1 %c.1) {
489 ; CHECK-LABEL: @test_not_captured_before_call_other_blocks_7(
490 ; CHECK-NEXT:  entry:
491 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
492 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
493 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
494 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
495 ; CHECK:       then:
496 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
497 ; CHECK-NEXT:    br label [[EXIT]]
498 ; CHECK:       exit:
499 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[R]], [[ENTRY:%.*]] ]
500 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
501 ; CHECK-NEXT:    call void @clobber()
502 ; CHECK-NEXT:    ret i32 [[P]]
504 entry:
505   %a = alloca i32, align 4
506   store i32 55, ptr %a
507   %r = call i32 @getval()
508   call void @escape_writeonly(ptr %a)
509   br i1 %c.1, label %then, label %exit
511 then:
512   call void @escape_writeonly(ptr %a)
513   br label %exit
515 exit:
516   %p = phi i32 [ 0, %then ], [ %r, %entry ]
517   store i32 99, ptr %a, align 4
518   call void @clobber()
519   ret i32 %p
522 define i32 @test_not_captured_before_call_same_bb_but_read() {
523 ; CHECK-LABEL: @test_not_captured_before_call_same_bb_but_read(
524 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
525 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
526 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
527 ; CHECK-NEXT:    [[LV:%.*]] = load i32, ptr [[A]], align 4
528 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
529 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
530 ; CHECK-NEXT:    [[RES:%.*]] = add i32 [[R]], [[LV]]
531 ; CHECK-NEXT:    ret i32 [[RES]]
533   %a = alloca i32, align 4
534   store i32 55, ptr %a
535   %r = call i32 @getval()
536   %lv = load i32, ptr %a
537   store i32 99, ptr %a, align 4
538   call void @escape_and_clobber(ptr %a)
539   %res = add i32 %r, %lv
540   ret i32 %res
543 define i32 @test_captured_after_loop(i1 %c.1) {
544 ; CHECK-LABEL: @test_captured_after_loop(
545 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
546 ; CHECK-NEXT:    br label [[LOOP:%.*]]
547 ; CHECK:       loop:
548 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
549 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
550 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
551 ; CHECK:       exit:
552 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
553 ; CHECK-NEXT:    ret i32 [[R]]
555   %a = alloca i32, align 4
556   store i32 55, ptr %a
557   br label %loop
559 loop:
560   %r = call i32 @getval()
561   store i32 99, ptr %a, align 4
562   br i1 %c.1, label %loop, label %exit
564 exit:
565   call void @escape_and_clobber(ptr %a)
566   ret i32 %r
569 define i32 @test_captured_in_loop(i1 %c.1) {
570 ; CHECK-LABEL: @test_captured_in_loop(
571 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
572 ; CHECK-NEXT:    store i32 55, ptr [[A]], align 4
573 ; CHECK-NEXT:    br label [[LOOP:%.*]]
574 ; CHECK:       loop:
575 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
576 ; CHECK-NEXT:    call void @escape_writeonly(ptr [[A]])
577 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
578 ; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[LOOP]], label [[EXIT:%.*]]
579 ; CHECK:       exit:
580 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
581 ; CHECK-NEXT:    ret i32 [[R]]
583   %a = alloca i32, align 4
584   store i32 55, ptr %a
585   br label %loop
587 loop:
588   %r = call i32 @getval()
589   call void @escape_writeonly(ptr %a)
590   store i32 99, ptr %a, align 4
591   br i1 %c.1, label %loop, label %exit
593 exit:
594   call void @escape_and_clobber(ptr %a)
595   ret i32 %r
598 declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1)
599 define void @test_escaping_store_removed(ptr %src, ptr %escape) {
600 ; CHECK-LABEL: @test_escaping_store_removed(
601 ; CHECK-NEXT:  bb:
602 ; CHECK-NEXT:    [[A:%.*]] = alloca i64, align 8
603 ; CHECK-NEXT:    call void @clobber()
604 ; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[A]], ptr [[SRC:%.*]], i64 8, i1 false)
605 ; CHECK-NEXT:    store ptr [[A]], ptr [[ESCAPE:%.*]], align 8
606 ; CHECK-NEXT:    call void @clobber()
607 ; CHECK-NEXT:    store i64 99, ptr [[A]], align 8
608 ; CHECK-NEXT:    call void @clobber()
609 ; CHECK-NEXT:    ret void
612   %a = alloca i64, align 8
613   store i64 0, ptr %a
614   call void @clobber()
615   call void @llvm.memcpy.p0.p0.i64(ptr %a, ptr %src, i64 8, i1 false)
616   store ptr %a, ptr %escape, align 8
617   store ptr %a, ptr %escape, align 8
618   call void @clobber()
619   store i64 99, ptr %a
620   call void @clobber()
621   ret void
625 define void @test_invoke_captures() personality ptr undef {
626 ; CHECK-LABEL: @test_invoke_captures(
627 ; CHECK-NEXT:  bb:
628 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
629 ; CHECK-NEXT:    invoke void @clobber()
630 ; CHECK-NEXT:    to label [[BB2:%.*]] unwind label [[BB5:%.*]]
631 ; CHECK:       bb2:
632 ; CHECK-NEXT:    store i32 0, ptr [[A]], align 8
633 ; CHECK-NEXT:    invoke void @escape(ptr [[A]])
634 ; CHECK-NEXT:    to label [[BB9:%.*]] unwind label [[BB10:%.*]]
635 ; CHECK:       bb4:
636 ; CHECK-NEXT:    ret void
637 ; CHECK:       bb5:
638 ; CHECK-NEXT:    [[LP_1:%.*]] = landingpad { ptr, i32 }
639 ; CHECK-NEXT:    cleanup
640 ; CHECK-NEXT:    ret void
641 ; CHECK:       bb9:
642 ; CHECK-NEXT:    ret void
643 ; CHECK:       bb10:
644 ; CHECK-NEXT:    [[LP_2:%.*]] = landingpad { ptr, i32 }
645 ; CHECK-NEXT:    cleanup
646 ; CHECK-NEXT:    unreachable
649   %a = alloca i32
650   store i32 99, ptr %a
651   invoke void @clobber()
652   to label %bb2 unwind label %bb5
654 bb2:
655   store i32 0, ptr %a, align 8
656   invoke void @escape(ptr %a)
657   to label %bb9 unwind label %bb10
659 bb4:
660   ret void
662 bb5:
663   %lp.1 = landingpad { ptr, i32 }
664   cleanup
665   ret void
667 bb9:
668   ret void
670 bb10:
671   %lp.2 = landingpad { ptr, i32 }
672   cleanup
673   unreachable
676 declare noalias ptr @alloc() nounwind
677 declare i32 @getval_nounwind() nounwind
679 define i32 @test_not_captured_before_load_same_bb_noalias_call() {
680 ; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_call(
681 ; CHECK-NEXT:    [[A:%.*]] = call ptr @alloc()
682 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval_nounwind()
683 ; CHECK-NEXT:    store i32 99, ptr [[A]], align 4
684 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
685 ; CHECK-NEXT:    ret i32 [[R]]
687   %a = call ptr @alloc()
688   store i32 55, ptr %a
689   %r = call i32 @getval_nounwind()
690   store i32 99, ptr %a, align 4
691   call void @escape_and_clobber(ptr %a)
692   ret i32 %r
695 define i32 @test_not_captured_before_load_same_bb_noalias_arg(ptr noalias %a) {
696 ; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_arg(
697 ; CHECK-NEXT:    [[R:%.*]] = call i32 @getval_nounwind()
698 ; CHECK-NEXT:    store i32 99, ptr [[A:%.*]], align 4
699 ; CHECK-NEXT:    call void @escape_and_clobber(ptr [[A]])
700 ; CHECK-NEXT:    ret i32 [[R]]
702   store i32 55, ptr %a
703   %r = call i32 @getval_nounwind()
704   store i32 99, ptr %a, align 4
705   call void @escape_and_clobber(ptr %a)
706   ret i32 %r