1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes='dse' -S %s | FileCheck %s
3
4target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
5
6; Test case from PR50220.
7define 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, i32* [[V1]], align 4
13; CHECK-NEXT:    call void @escape(i32* nonnull [[V1]])
14; CHECK-NEXT:    [[CALL:%.*]] = call i32 @getval()
15; CHECK-NEXT:    store i32 [[CALL]], i32* [[V2]], align 4
16; CHECK-NEXT:    call void @escape(i32* nonnull [[V2]])
17; CHECK-NEXT:    [[LOAD_V2:%.*]] = load i32, i32* [[V2]], align 4
18; CHECK-NEXT:    [[LOAD_V1:%.*]] = load i32, i32* [[V1]], align 4
19; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[LOAD_V2]], [[LOAD_V1]]
20; CHECK-NEXT:    ret i32 [[ADD]]
21;
22entry:
23  %v1 = alloca i32, align 4
24  %v2 = alloca i32, align 4
25  store i32 0, i32* %v1, align 4
26  call void @escape(i32* nonnull %v1)
27  store i32 55555, i32* %v2, align 4
28  %call = call i32 @getval()
29  store i32 %call, i32* %v2, align 4
30  call void @escape(i32* nonnull %v2)
31  %load.v2 = load i32, i32* %v2, align 4
32  %load.v1 = load i32, i32* %v1, align 4
33  %add = add nsw i32 %load.v2, %load.v1
34  ret i32 %add
35}
36
37declare void @escape(i32*)
38
39declare i32 @getval()
40
41declare void @escape_and_clobber(i32*)
42declare void @escape_writeonly(i32*) writeonly
43declare void @clobber()
44
45define 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, i32* [[A]], align 4
50; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
51; CHECK-NEXT:    ret i32 [[R]]
52;
53  %a = alloca i32, align 4
54  store i32 55, i32* %a
55  %r = call i32 @getval()
56  store i32 99, i32* %a, align 4
57  call void @escape_and_clobber(i32* %a)
58  ret i32 %r
59}
60
61define 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, i32* [[A]], align 4
66; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
67; CHECK-NEXT:    ret i32 [[R]]
68; CHECK:       unreach:
69; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
70; CHECK-NEXT:    ret i32 0
71;
72  %a = alloca i32, align 4
73  store i32 55, i32* %a
74  %r = call i32 @getval()
75  store i32 99, i32* %a, align 4
76  call void @escape_and_clobber(i32* %a)
77  ret i32 %r
78
79unreach:
80  call void @escape_and_clobber(i32* %a)
81  ret i32 0
82}
83
84define 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, i32* [[A]], align 4
88; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
89; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
90; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
91; CHECK-NEXT:    call void @clobber()
92; CHECK-NEXT:    ret i32 [[R]]
93;
94  %a = alloca i32, align 4
95  store i32 55, i32* %a
96  %r = call i32 @getval()
97  call void @escape_and_clobber(i32* %a)
98  store i32 99, i32* %a, align 4
99  call void @clobber()
100  ret i32 %r
101}
102
103define 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(i32* [[A]])
108; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
109; CHECK-NEXT:    call void @clobber()
110; CHECK-NEXT:    ret i32 [[R]]
111;
112  %a = alloca i32, align 4
113  store i32 55, i32* %a
114  %r = call i32 @getval()
115  call void @escape_writeonly(i32* %a)
116  store i32 99, i32* %a, align 4
117  call void @clobber()
118  ret i32 %r
119}
120
121define 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(i32* [[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, i32* [[A]], align 4
134; CHECK-NEXT:    call void @clobber()
135; CHECK-NEXT:    ret i32 [[P]]
136;
137  %a = alloca i32, align 4
138  store i32 55, i32* %a
139  br i1 %c.1, label %then, label %else
140
141then:
142  call void @escape_writeonly(i32* %a)
143  br label %exit
144
145else:
146  %r = call i32 @getval()
147  br label %exit
148
149exit:
150  %p = phi i32 [ 0, %then ], [ %r, %else ]
151  store i32 99, i32* %a, align 4
152  call void @clobber()
153  ret i32 %p
154}
155
156define 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, i32* [[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(i32* [[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, i32* [[A]], align 4
170; CHECK-NEXT:    call void @clobber()
171; CHECK-NEXT:    ret i32 [[P]]
172;
173  %a = alloca i32, align 4
174  store i32 55, i32* %a
175  br i1 %c.1, label %then, label %else
176
177then:
178  br label %exit
179
180else:
181  call void @escape_and_clobber(i32* %a)
182  %r = call i32 @getval()
183  br label %exit
184
185exit:
186  %p = phi i32 [ 0, %then ], [ %r, %else ]
187  store i32 99, i32* %a, align 4
188  call void @clobber()
189  ret i32 %p
190}
191
192define 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, i32* [[A]], align 4
197; CHECK-NEXT:    call void @escape_writeonly(i32* [[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(i32* [[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, i32* [[A]], align 4
206; CHECK-NEXT:    call void @clobber()
207; CHECK-NEXT:    ret i32 [[P]]
208;
209entry:
210  %a = alloca i32, align 4
211  store i32 55, i32* %a
212  call void @escape_writeonly(i32* %a)
213  %r = call i32 @getval()
214  br i1 %c.1, label %then, label %exit
215
216then:
217  call void @escape_writeonly(i32* %a)
218  br label %exit
219
220exit:
221  %p = phi i32 [ 0, %then ], [ %r, %entry ]
222  store i32 99, i32* %a, align 4
223  call void @clobber()
224  ret i32 %p
225}
226
227define 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, i32* [[A]], align 4
232; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
233; CHECK:       then:
234; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
235; CHECK-NEXT:    br label [[EXIT]]
236; CHECK:       exit:
237; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
238; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
239; CHECK-NEXT:    call void @clobber()
240; CHECK-NEXT:    ret i32 [[R]]
241;
242entry:
243  %a = alloca i32, align 4
244  store i32 55, i32* %a
245  br i1 %c.1, label %then, label %exit
246
247then:
248  call void @escape_writeonly(i32* %a)
249  br label %exit
250
251exit:
252  %r = call i32 @getval()
253  store i32 99, i32* %a, align 4
254  call void @clobber()
255  ret i32 %r
256}
257
258define 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, i32* [[A]], align 4
263; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
264; CHECK:       then:
265; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
266; CHECK-NEXT:    br label [[EXIT]]
267; CHECK:       exit:
268; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
269; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
270; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
271; CHECK-NEXT:    call void @clobber()
272; CHECK-NEXT:    ret i32 [[R]]
273;
274entry:
275  %a = alloca i32, align 4
276  store i32 55, i32* %a
277  br i1 %c.1, label %then, label %exit
278
279then:
280  call void @escape_writeonly(i32* %a)
281  br label %exit
282
283exit:
284  %r = call i32 @getval()
285  store i32 99, i32* %a, align 4
286  call void @escape_writeonly(i32* %a)
287  call void @clobber()
288  ret i32 %r
289}
290
291define 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, i32* [[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(i32* [[A]])
303; CHECK-NEXT:    ret i32 [[R]]
304;
305  %a = alloca i32, align 4
306  store i32 55, i32* %a
307  %r = call i32 @getval()
308  store i32 99, i32* %a, align 4
309  br i1 %c.1, label %then, label %else
310
311then:
312  br label %exit
313
314else:
315  br label %exit
316
317exit:
318  call void @escape_and_clobber(i32* %a)
319  ret i32 %r
320}
321
322define 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, i32* [[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(i32* [[A]])
330; CHECK-NEXT:    br label [[EXIT:%.*]]
331; CHECK:       else:
332; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
333; CHECK-NEXT:    br label [[EXIT]]
334; CHECK:       exit:
335; CHECK-NEXT:    ret i32 [[R]]
336;
337  %a = alloca i32, align 4
338  store i32 55, i32* %a
339  %r = call i32 @getval()
340  store i32 99, i32* %a, align 4
341  br i1 %c.1, label %then, label %else
342
343then:
344  call void @escape_and_clobber(i32* %a)
345  br label %exit
346
347else:
348  call void @escape_and_clobber(i32* %a)
349  br label %exit
350
351exit:
352  ret i32 %r
353}
354
355define 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, i32* [[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(i32* [[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]]
368;
369  %a = alloca i32, align 4
370  store i32 55, i32* %a
371  %r = call i32 @getval()
372  store i32 99, i32* %a, align 4
373  br i1 %c.1, label %then, label %else
374
375then:
376  call void @escape_and_clobber(i32* %a)
377  br label %exit
378
379else:
380  br label %exit
381
382exit:
383  ret i32 %r
384}
385
386define 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(i32* [[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, i32* [[A]], align 4
399; CHECK-NEXT:    call void @clobber()
400; CHECK-NEXT:    ret i32 [[P]]
401;
402  %a = alloca i32, align 4
403  store i32 55, i32* %a
404  br i1 %c.1, label %then, label %else
405
406then:
407  br label %exit
408
409else:
410  %r = call i32 @getval()
411  call void @escape_writeonly(i32* %a)
412  br label %exit
413
414exit:
415  %p = phi i32 [ 0, %then ], [ %r, %else ]
416  store i32 99, i32* %a, align 4
417  call void @clobber()
418  ret i32 %p
419}
420
421define 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(i32* [[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, i32* [[A]], align 4
433; CHECK-NEXT:    call void @clobber()
434; CHECK-NEXT:    ret i32 [[P]]
435;
436entry:
437  %a = alloca i32, align 4
438  store i32 55, i32* %a
439  br i1 %c.1, label %then, label %exit
440
441then:
442  %r = call i32 @getval()
443  call void @escape_writeonly(i32* %a)
444  br label %exit
445
446exit:
447  %p = phi i32 [ %r, %then ], [ 0, %entry ]
448  store i32 99, i32* %a, align 4
449  call void @clobber()
450  ret i32 %p
451}
452
453define 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, i32* [[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(i32* [[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, i32* [[A]], align 4
466; CHECK-NEXT:    call void @escape_writeonly(i32* [[A]])
467; CHECK-NEXT:    call void @clobber()
468; CHECK-NEXT:    ret i32 [[P]]
469;
470entry:
471  %a = alloca i32, align 4
472  store i32 55, i32* %a
473  br i1 %c.1, label %then, label %exit
474
475then:
476  %r = call i32 @getval()
477  call void @escape_writeonly(i32* %a)
478  br label %exit
479
480exit:
481  %p = phi i32 [ %r, %then ], [ 0, %entry ]
482  store i32 99, i32* %a, align 4
483  call void @escape_writeonly(i32* %a)
484  call void @clobber()
485  ret i32 %p
486}
487
488define 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(i32* [[A]])
494; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]]
495; CHECK:       then:
496; CHECK-NEXT:    call void @escape_writeonly(i32* [[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, i32* [[A]], align 4
501; CHECK-NEXT:    call void @clobber()
502; CHECK-NEXT:    ret i32 [[P]]
503;
504entry:
505  %a = alloca i32, align 4
506  store i32 55, i32* %a
507  %r = call i32 @getval()
508  call void @escape_writeonly(i32* %a)
509  br i1 %c.1, label %then, label %exit
510
511then:
512  call void @escape_writeonly(i32* %a)
513  br label %exit
514
515exit:
516  %p = phi i32 [ 0, %then ], [ %r, %entry ]
517  store i32 99, i32* %a, align 4
518  call void @clobber()
519  ret i32 %p
520}
521
522define 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, i32* [[A]], align 4
526; CHECK-NEXT:    [[R:%.*]] = call i32 @getval()
527; CHECK-NEXT:    [[LV:%.*]] = load i32, i32* [[A]], align 4
528; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
529; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
530; CHECK-NEXT:    [[RES:%.*]] = add i32 [[R]], [[LV]]
531; CHECK-NEXT:    ret i32 [[RES]]
532;
533  %a = alloca i32, align 4
534  store i32 55, i32* %a
535  %r = call i32 @getval()
536  %lv = load i32, i32* %a
537  store i32 99, i32* %a, align 4
538  call void @escape_and_clobber(i32* %a)
539  %res = add i32 %r, %lv
540  ret i32 %res
541}
542
543define 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, i32* [[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(i32* [[A]])
553; CHECK-NEXT:    ret i32 [[R]]
554;
555  %a = alloca i32, align 4
556  store i32 55, i32* %a
557  br label %loop
558
559loop:
560  %r = call i32 @getval()
561  store i32 99, i32* %a, align 4
562  br i1 %c.1, label %loop, label %exit
563
564exit:
565  call void @escape_and_clobber(i32* %a)
566  ret i32 %r
567}
568
569define 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, i32* [[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(i32* [[A]])
577; CHECK-NEXT:    store i32 99, i32* [[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(i32* [[A]])
581; CHECK-NEXT:    ret i32 [[R]]
582;
583  %a = alloca i32, align 4
584  store i32 55, i32* %a
585  br label %loop
586
587loop:
588  %r = call i32 @getval()
589  call void @escape_writeonly(i32* %a)
590  store i32 99, i32* %a, align 4
591  br i1 %c.1, label %loop, label %exit
592
593exit:
594  call void @escape_and_clobber(i32* %a)
595  ret i32 %r
596}
597
598declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1)
599define void @test_escaping_store_removed(i8* %src, i64** %escape) {
600; CHECK-LABEL: @test_escaping_store_removed(
601; CHECK-NEXT:  bb:
602; CHECK-NEXT:    [[A:%.*]] = alloca i64, align 8
603; CHECK-NEXT:    [[EXT_A:%.*]] = bitcast i64* [[A]] to i8*
604; CHECK-NEXT:    call void @clobber()
605; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[EXT_A]], i8* [[SRC:%.*]], i64 8, i1 false)
606; CHECK-NEXT:    store i64* [[A]], i64** [[ESCAPE:%.*]], align 8
607; CHECK-NEXT:    call void @clobber()
608; CHECK-NEXT:    store i64 99, i64* [[A]], align 8
609; CHECK-NEXT:    call void @clobber()
610; CHECK-NEXT:    ret void
611;
612bb:
613  %a = alloca i64, align 8
614  %ext.a = bitcast i64* %a to i8*
615  store i64 0, i64* %a
616  call void @clobber()
617  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %ext.a, i8* %src, i64 8, i1 false)
618  store i64* %a, i64** %escape, align 8
619  store i64* %a, i64** %escape, align 8
620  call void @clobber()
621  store i64 99, i64* %a
622  call void @clobber()
623  ret void
624}
625
626
627define void @test_invoke_captures() personality i8* undef {
628; CHECK-LABEL: @test_invoke_captures(
629; CHECK-NEXT:  bb:
630; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
631; CHECK-NEXT:    invoke void @clobber()
632; CHECK-NEXT:    to label [[BB2:%.*]] unwind label [[BB5:%.*]]
633; CHECK:       bb2:
634; CHECK-NEXT:    store i32 0, i32* [[A]], align 8
635; CHECK-NEXT:    invoke void @escape(i32* [[A]])
636; CHECK-NEXT:    to label [[BB9:%.*]] unwind label [[BB10:%.*]]
637; CHECK:       bb4:
638; CHECK-NEXT:    ret void
639; CHECK:       bb5:
640; CHECK-NEXT:    [[LP_1:%.*]] = landingpad { i8*, i32 }
641; CHECK-NEXT:    cleanup
642; CHECK-NEXT:    ret void
643; CHECK:       bb9:
644; CHECK-NEXT:    ret void
645; CHECK:       bb10:
646; CHECK-NEXT:    [[LP_2:%.*]] = landingpad { i8*, i32 }
647; CHECK-NEXT:    cleanup
648; CHECK-NEXT:    unreachable
649;
650bb:
651  %a = alloca i32
652  store i32 99, i32* %a
653  invoke void @clobber()
654  to label %bb2 unwind label %bb5
655
656bb2:
657  store i32 0, i32* %a, align 8
658  invoke void @escape(i32* %a)
659  to label %bb9 unwind label %bb10
660
661bb4:
662  ret void
663
664bb5:
665  %lp.1 = landingpad { i8*, i32 }
666  cleanup
667  ret void
668
669bb9:
670  ret void
671
672bb10:
673  %lp.2 = landingpad { i8*, i32 }
674  cleanup
675  unreachable
676}
677
678declare noalias i32* @alloc() nounwind
679declare i32 @getval_nounwind() nounwind
680
681define i32 @test_not_captured_before_load_same_bb_noalias_call() {
682; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_call(
683; CHECK-NEXT:    [[A:%.*]] = call i32* @alloc()
684; CHECK-NEXT:    [[R:%.*]] = call i32 @getval_nounwind()
685; CHECK-NEXT:    store i32 99, i32* [[A]], align 4
686; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
687; CHECK-NEXT:    ret i32 [[R]]
688;
689  %a = call i32* @alloc()
690  store i32 55, i32* %a
691  %r = call i32 @getval_nounwind()
692  store i32 99, i32* %a, align 4
693  call void @escape_and_clobber(i32* %a)
694  ret i32 %r
695}
696
697define i32 @test_not_captured_before_load_same_bb_noalias_arg(i32* noalias %a) {
698; CHECK-LABEL: @test_not_captured_before_load_same_bb_noalias_arg(
699; CHECK-NEXT:    [[R:%.*]] = call i32 @getval_nounwind()
700; CHECK-NEXT:    store i32 99, i32* [[A:%.*]], align 4
701; CHECK-NEXT:    call void @escape_and_clobber(i32* [[A]])
702; CHECK-NEXT:    ret i32 [[R]]
703;
704  store i32 55, i32* %a
705  %r = call i32 @getval_nounwind()
706  store i32 99, i32* %a, align 4
707  call void @escape_and_clobber(i32* %a)
708  ret i32 %r
709}
710