1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
3
4target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
5
6declare void @use(i32 *)
7
8; Tests where the pointer/object is accessible after the function returns.
9
10define void @accessible_after_return_1(i32* noalias %P, i1 %c1) {
11; CHECK-LABEL: @accessible_after_return_1(
12; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
13; CHECK:       bb1:
14; CHECK-NEXT:    store i32 0, i32* [[P:%.*]], align 4
15; CHECK-NEXT:    br label [[BB5:%.*]]
16; CHECK:       bb2:
17; CHECK-NEXT:    store i32 3, i32* [[P]], align 4
18; CHECK-NEXT:    br label [[BB5]]
19; CHECK:       bb5:
20; CHECK-NEXT:    call void @use(i32* [[P]])
21; CHECK-NEXT:    ret void
22;
23  store i32 1, i32* %P
24  br i1 %c1, label %bb1, label %bb2
25
26bb1:
27  store i32 0, i32* %P
28  br label %bb5
29bb2:
30  store i32 3, i32* %P
31  br label %bb5
32
33bb5:
34  call void @use(i32* %P)
35  ret void
36}
37
38define void @accessible_after_return_2(i32* noalias %P, i1 %c.1, i1 %c.2) {
39; CHECK-LABEL: @accessible_after_return_2(
40; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
41; CHECK:       bb1:
42; CHECK-NEXT:    store i32 0, i32* [[P:%.*]], align 4
43; CHECK-NEXT:    br label [[BB5:%.*]]
44; CHECK:       bb2:
45; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
46; CHECK:       bb3:
47; CHECK-NEXT:    store i32 3, i32* [[P]], align 4
48; CHECK-NEXT:    br label [[BB5]]
49; CHECK:       bb4:
50; CHECK-NEXT:    store i32 5, i32* [[P]], align 4
51; CHECK-NEXT:    br label [[BB5]]
52; CHECK:       bb5:
53; CHECK-NEXT:    call void @use(i32* [[P]])
54; CHECK-NEXT:    ret void
55;
56  store i32 1, i32* %P
57  br i1 %c.1, label %bb1, label %bb2
58bb1:
59  store i32 0, i32* %P
60  br label %bb5
61
62bb2:
63  br i1 %c.2, label %bb3, label %bb4
64
65bb3:
66  store i32 3, i32* %P
67  br label %bb5
68
69bb4:
70  store i32 5, i32* %P
71  br label %bb5
72
73bb5:
74  call void @use(i32* %P)
75  ret void
76}
77
78; Cannot remove store in entry block because it is not overwritten on path
79; entry->bb2->bb5.
80define void @accessible_after_return_3(i32* noalias %P, i1 %c1) {
81; CHECK-LABEL: @accessible_after_return_3(
82; CHECK-NEXT:    store i32 1, i32* [[P:%.*]], align 4
83; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
84; CHECK:       bb1:
85; CHECK-NEXT:    store i32 0, i32* [[P]], align 4
86; CHECK-NEXT:    br label [[BB5:%.*]]
87; CHECK:       bb2:
88; CHECK-NEXT:    br label [[BB5]]
89; CHECK:       bb5:
90; CHECK-NEXT:    call void @use(i32* [[P]])
91; CHECK-NEXT:    ret void
92;
93  store i32 1, i32* %P
94  br i1 %c1, label %bb1, label %bb2
95
96bb1:
97  store i32 0, i32* %P
98  br label %bb5
99
100bb2:
101  br label %bb5
102
103bb5:
104  call void @use(i32* %P)
105  ret void
106}
107
108; Cannot remove store in entry block because it is not overwritten on path
109; entry->bb2->bb5.
110define void @accessible_after_return_4(i32* noalias %P, i1 %c1) {
111; CHECK-LABEL: @accessible_after_return_4(
112; CHECK-NEXT:    store i32 1, i32* [[P:%.*]], align 4
113; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
114; CHECK:       bb1:
115; CHECK-NEXT:    store i32 0, i32* [[P]], align 4
116; CHECK-NEXT:    call void @use(i32* [[P]])
117; CHECK-NEXT:    br label [[BB5:%.*]]
118; CHECK:       bb2:
119; CHECK-NEXT:    br label [[BB5]]
120; CHECK:       bb5:
121; CHECK-NEXT:    ret void
122;
123  store i32 1, i32* %P
124  br i1 %c1, label %bb1, label %bb2
125
126bb1:
127  store i32 0, i32* %P
128  call void @use(i32* %P)
129  br label %bb5
130
131bb2:
132  br label %bb5
133
134bb5:
135  ret void
136}
137
138; Cannot remove the store in entry, as it is not overwritten on all paths to an
139; exit (patch including bb4).
140define void @accessible_after_return5(i32* %P, i1 %c.1, i1 %c.2) {
141; CHECK-LABEL: @accessible_after_return5(
142; CHECK-NEXT:  entry:
143; CHECK-NEXT:    store i32 0, i32* [[P:%.*]], align 4
144; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
145; CHECK:       bb1:
146; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
147; CHECK:       bb2:
148; CHECK-NEXT:    store i32 1, i32* [[P]], align 4
149; CHECK-NEXT:    br label [[BB5:%.*]]
150; CHECK:       bb3:
151; CHECK-NEXT:    store i32 2, i32* [[P]], align 4
152; CHECK-NEXT:    br label [[BB5]]
153; CHECK:       bb4:
154; CHECK-NEXT:    br label [[BB5]]
155; CHECK:       bb5:
156; CHECK-NEXT:    ret void
157;
158entry:
159  store i32 0, i32* %P
160  br i1 %c.1, label %bb1, label %bb2
161
162bb1:
163  br i1 %c.2, label %bb3, label %bb4
164
165bb2:
166  store i32 1, i32* %P
167  br label %bb5
168
169bb3:
170  store i32 2, i32* %P
171  br label %bb5
172
173bb4:
174  br label %bb5
175
176bb5:
177  ret void
178}
179
180; Can remove store in entry block, because it is overwritten before each return.
181define void @accessible_after_return6(i32* %P, i1 %c.1, i1 %c.2) {
182; CHECK-LABEL: @accessible_after_return6(
183; CHECK-NEXT:  entry:
184; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
185; CHECK:       bb1:
186; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
187; CHECK:       bb2:
188; CHECK-NEXT:    store i32 1, i32* [[P:%.*]], align 4
189; CHECK-NEXT:    ret void
190; CHECK:       bb3:
191; CHECK-NEXT:    store i32 2, i32* [[P]], align 4
192; CHECK-NEXT:    ret void
193; CHECK:       bb4:
194; CHECK-NEXT:    store i32 3, i32* [[P]], align 4
195; CHECK-NEXT:    ret void
196;
197entry:
198  store i32 0, i32* %P
199  br i1 %c.1, label %bb1, label %bb2
200
201bb1:
202  br i1 %c.2, label %bb3, label %bb4
203
204bb2:
205  store i32 1, i32* %P
206  ret void
207
208bb3:
209  store i32 2, i32* %P
210  ret void
211
212bb4:
213  store i32 3, i32* %P
214  ret void
215}
216
217; Can remove store in bb1, because it is overwritten along each path
218; from bb1 to the exit.
219define void @accessible_after_return7(i32* %P, i1 %c.1, i1 %c.2) {
220; CHECK-LABEL: @accessible_after_return7(
221; CHECK-NEXT:  entry:
222; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
223; CHECK:       bb1:
224; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
225; CHECK:       bb3:
226; CHECK-NEXT:    store i32 2, i32* [[P:%.*]], align 4
227; CHECK-NEXT:    br label [[BB5:%.*]]
228; CHECK:       bb4:
229; CHECK-NEXT:    store i32 1, i32* [[P]], align 4
230; CHECK-NEXT:    br label [[BB5]]
231; CHECK:       bb2:
232; CHECK-NEXT:    br label [[BB5]]
233; CHECK:       bb5:
234; CHECK-NEXT:    ret void
235;
236entry:
237  br i1 %c.1, label %bb1, label %bb2
238
239bb1:
240  store i32 0, i32* %P
241  br i1 %c.2, label %bb3, label %bb4
242
243bb3:
244  store i32 2, i32* %P
245  br label %bb5
246
247bb4:
248  store i32 1, i32* %P
249  br label %bb5
250
251bb2:
252  br label %bb5
253
254bb5:
255  ret void
256}
257
258
259; Cannot remove store in entry block, because it is overwritten along each path to
260; the exit (entry->bb1->bb4->bb5).
261define void @accessible_after_return8(i32* %P, i1 %c.1, i1 %c.2) {
262; CHECK-LABEL: @accessible_after_return8(
263; CHECK-NEXT:  entry:
264; CHECK-NEXT:    store i32 0, i32* [[P:%.*]], align 4
265; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
266; CHECK:       bb1:
267; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
268; CHECK:       bb2:
269; CHECK-NEXT:    store i32 1, i32* [[P]], align 4
270; CHECK-NEXT:    br label [[BB5:%.*]]
271; CHECK:       bb3:
272; CHECK-NEXT:    store i32 2, i32* [[P]], align 4
273; CHECK-NEXT:    br label [[BB5]]
274; CHECK:       bb4:
275; CHECK-NEXT:    br label [[BB5]]
276; CHECK:       bb5:
277; CHECK-NEXT:    ret void
278;
279entry:
280  store i32 0, i32* %P
281  br i1 %c.1, label %bb1, label %bb2
282
283bb1:
284  br i1 %c.2, label %bb3, label %bb4
285
286bb2:
287  store i32 1, i32* %P
288  br label %bb5
289
290bb3:
291  store i32 2, i32* %P
292  br label %bb5
293
294bb4:
295  br label %bb5
296
297bb5:
298  ret void
299}
300
301; Make sure no stores are removed here. In particular, the store in if.then
302; should not be removed.
303define void @accessible_after_return9(i8* noalias %ptr) {
304; CHECK-LABEL: @accessible_after_return9(
305; CHECK-NEXT:  entry:
306; CHECK-NEXT:    [[C_0:%.*]] = call i1 @cond()
307; CHECK-NEXT:    br i1 [[C_0]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
308; CHECK:       for.body:
309; CHECK-NEXT:    store i8 99, i8* [[PTR:%.*]], align 8
310; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
311; CHECK-NEXT:    br i1 [[C_1]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
312; CHECK:       if.then:
313; CHECK-NEXT:    store i8 20, i8* [[PTR]], align 8
314; CHECK-NEXT:    br label [[IF_END]]
315; CHECK:       if.end:
316; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
317; CHECK-NEXT:    br i1 [[C_2]], label [[IF_THEN10:%.*]], label [[FOR_INC:%.*]]
318; CHECK:       if.then10:
319; CHECK-NEXT:    store i8 0, i8* [[PTR]], align 8
320; CHECK-NEXT:    br label [[FOR_INC]]
321; CHECK:       for.inc:
322; CHECK-NEXT:    [[C_3:%.*]] = call i1 @cond()
323; CHECK-NEXT:    br i1 [[C_3]], label [[FOR_BODY]], label [[FOR_END]]
324; CHECK:       for.end:
325; CHECK-NEXT:    ret void
326;
327entry:
328  %c.0 = call i1 @cond()
329  br i1 %c.0, label %for.body, label %for.end
330
331for.body:
332  store i8 99, i8* %ptr, align 8
333  %c.1 = call i1 @cond()
334  br i1 %c.1, label %if.end, label %if.then
335
336if.then:
337  store i8 20, i8* %ptr, align 8
338  br label %if.end
339
340if.end:
341  %c.2 = call i1 @cond()
342  br i1 %c.2, label %if.then10, label %for.inc
343
344if.then10:
345  store i8 0, i8* %ptr, align 8
346  br label %for.inc
347
348for.inc:
349  %c.3 = call i1 @cond()
350  br i1 %c.3, label %for.body, label %for.end
351
352for.end:
353  ret void
354}
355
356; Cannot remove store in entry block because it is not overwritten on path
357; entry->bb2->bb4. Also make sure we deal with dead exit blocks without
358; crashing.
359define void @accessible_after_return10_dead_block(i32* %P, i1 %c.1, i1 %c.2) {
360; CHECK-LABEL: @accessible_after_return10_dead_block(
361; CHECK-NEXT:  entry:
362; CHECK-NEXT:    store i32 0, i32* [[P:%.*]], align 4
363; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
364; CHECK:       bb1:
365; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
366; CHECK:       bb2:
367; CHECK-NEXT:    store i32 1, i32* [[P]], align 4
368; CHECK-NEXT:    ret void
369; CHECK:       bb3:
370; CHECK-NEXT:    store i32 2, i32* [[P]], align 4
371; CHECK-NEXT:    ret void
372; CHECK:       bb4:
373; CHECK-NEXT:    ret void
374; CHECK:       bb5:
375; CHECK-NEXT:    ret void
376;
377entry:
378  store i32 0, i32* %P
379  br i1 %c.1, label %bb1, label %bb2
380
381bb1:
382  br i1 %c.2, label %bb3, label %bb4
383
384bb2:
385  store i32 1, i32* %P
386  ret void
387
388bb3:
389  store i32 2, i32* %P
390  ret void
391
392bb4:
393  ret void
394
395bb5:
396  ret void
397}
398
399@linenum = external local_unnamed_addr global i32, align 4
400
401define void @accessible_after_return11_loop() {
402; CHECK-LABEL: @accessible_after_return11_loop(
403; CHECK-NEXT:  entry:
404; CHECK-NEXT:    br label [[FOR_BODY_I:%.*]]
405; CHECK:       for.body.i:
406; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
407; CHECK-NEXT:    br i1 [[C_1]], label [[FOR_BODY_I]], label [[INIT_PARSE_EXIT:%.*]]
408; CHECK:       init_parse.exit:
409; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull undef)
410; CHECK-NEXT:    store i32 0, i32* @linenum, align 4
411; CHECK-NEXT:    br label [[FOR_BODY_I20:%.*]]
412; CHECK:       for.body.i20:
413; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
414; CHECK-NEXT:    br i1 [[C_2]], label [[FOR_BODY_I20]], label [[EXIT:%.*]]
415; CHECK:       exit:
416; CHECK-NEXT:    ret void
417;
418entry:
419  br label %for.body.i
420
421for.body.i:                                       ; preds = %for.body.i, %entry
422  %c.1 = call i1 @cond()
423  br i1 %c.1, label %for.body.i, label %init_parse.exit
424
425init_parse.exit:                                  ; preds = %for.body.i
426  store i32 0, i32* @linenum, align 4
427  call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull undef) #2
428  store i32 0, i32* @linenum, align 4
429  br label %for.body.i20
430
431for.body.i20:                                     ; preds = %for.body.i20, %init_parse.exit
432  %c.2 = call i1 @cond()
433  br i1 %c.2, label %for.body.i20, label %exit
434
435exit:
436  ret void
437}
438declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
439declare i1 @cond() readnone nounwind
440
441; Tests where the pointer/object is *NOT* accessible after the function returns.
442
443; The store in the entry block can be eliminated, because it is overwritten
444; on all paths to the exit.
445define void @alloca_1(i1 %c1) {
446; CHECK-LABEL: @alloca_1(
447; CHECK-NEXT:    [[P:%.*]] = alloca i32, align 4
448; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
449; CHECK:       bb1:
450; CHECK-NEXT:    store i32 0, i32* [[P]], align 4
451; CHECK-NEXT:    br label [[BB5:%.*]]
452; CHECK:       bb2:
453; CHECK-NEXT:    store i32 3, i32* [[P]], align 4
454; CHECK-NEXT:    br label [[BB5]]
455; CHECK:       bb5:
456; CHECK-NEXT:    call void @use(i32* [[P]])
457; CHECK-NEXT:    ret void
458;
459  %P = alloca i32
460  store i32 1, i32* %P
461  br i1 %c1, label %bb1, label %bb2
462
463bb1:
464  store i32 0, i32* %P
465  br label %bb5
466bb2:
467  store i32 3, i32* %P
468  br label %bb5
469
470bb5:
471  call void @use(i32* %P)
472  ret void
473}
474
475; The store in the entry block can be eliminated, because it is overwritten
476; on all paths to the exit.
477define void @alloca_2(i1 %c.1, i1 %c.2) {
478; CHECK-LABEL: @alloca_2(
479; CHECK-NEXT:    [[P:%.*]] = alloca i32, align 4
480; CHECK-NEXT:    br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
481; CHECK:       bb1:
482; CHECK-NEXT:    store i32 0, i32* [[P]], align 4
483; CHECK-NEXT:    br label [[BB5:%.*]]
484; CHECK:       bb2:
485; CHECK-NEXT:    br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
486; CHECK:       bb3:
487; CHECK-NEXT:    store i32 3, i32* [[P]], align 4
488; CHECK-NEXT:    br label [[BB5]]
489; CHECK:       bb4:
490; CHECK-NEXT:    store i32 5, i32* [[P]], align 4
491; CHECK-NEXT:    br label [[BB5]]
492; CHECK:       bb5:
493; CHECK-NEXT:    call void @use(i32* [[P]])
494; CHECK-NEXT:    ret void
495;
496  %P = alloca i32
497  store i32 1, i32* %P
498  br i1 %c.1, label %bb1, label %bb2
499
500bb1:
501  store i32 0, i32* %P
502  br label %bb5
503
504bb2:
505  br i1 %c.2, label %bb3, label %bb4
506
507bb3:
508  store i32 3, i32* %P
509  br label %bb5
510
511bb4:
512  store i32 5, i32* %P
513  br label %bb5
514
515bb5:
516  call void @use(i32* %P)
517  ret void
518}
519
520; The store in the entry block cannot be eliminated. There's a path from the
521; first store to the read in bb5, where the location is not overwritten.
522define void @alloca_3(i1 %c1) {
523; CHECK-LABEL: @alloca_3(
524; CHECK-NEXT:    [[P:%.*]] = alloca i32, align 4
525; CHECK-NEXT:    store i32 1, i32* [[P]], align 4
526; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
527; CHECK:       bb1:
528; CHECK-NEXT:    store i32 0, i32* [[P]], align 4
529; CHECK-NEXT:    br label [[BB5:%.*]]
530; CHECK:       bb2:
531; CHECK-NEXT:    br label [[BB5]]
532; CHECK:       bb5:
533; CHECK-NEXT:    call void @use(i32* [[P]])
534; CHECK-NEXT:    ret void
535;
536  %P = alloca i32
537  store i32 1, i32* %P
538  br i1 %c1, label %bb1, label %bb2
539
540bb1:
541  store i32 0, i32* %P
542  br label %bb5
543bb2:
544  br label %bb5
545
546bb5:
547  call void @use(i32* %P)
548  ret void
549}
550
551; The store in the entry block can be eliminated, because it is overwritten
552; before the use in bb1 and not read on other paths to the function exit. The
553; object cannot be accessed by the caller.
554define void @alloca_4(i1 %c1) {
555; CHECK-LABEL: @alloca_4(
556; CHECK-NEXT:    [[P:%.*]] = alloca i32, align 4
557; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
558; CHECK:       bb1:
559; CHECK-NEXT:    store i32 0, i32* [[P]], align 4
560; CHECK-NEXT:    call void @use(i32* [[P]])
561; CHECK-NEXT:    br label [[BB5:%.*]]
562; CHECK:       bb2:
563; CHECK-NEXT:    br label [[BB5]]
564; CHECK:       bb5:
565; CHECK-NEXT:    ret void
566;
567  %P = alloca i32
568  store i32 1, i32* %P
569  br i1 %c1, label %bb1, label %bb2
570
571bb1:
572  store i32 0, i32* %P
573  call void @use(i32* %P)
574  br label %bb5
575
576bb2:
577  br label %bb5
578
579bb5:
580  ret void
581}
582
583%struct.blam.4 = type { %struct.bar.5, [4 x i8] }
584%struct.bar.5 = type <{ i64, i64*, i32, i64 }>
585
586; Make sure we do not eliminate the store in %bb.
587define void @alloca_5(i1 %c) {
588; CHECK-LABEL: @alloca_5(
589; CHECK-NEXT:  bb:
590; CHECK-NEXT:    [[TMP:%.*]] = alloca [[STRUCT_BLAM_4:%.*]], align 8
591; CHECK-NEXT:    [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_BLAM_4]], %struct.blam.4* [[TMP]], i64 0, i32 0, i32 3
592; CHECK-NEXT:    [[TMP39:%.*]] = bitcast i64* [[TMP38]] to i64*
593; CHECK-NEXT:    store i64 0, i64* [[TMP39]], align 4
594; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB46:%.*]], label [[BB47:%.*]]
595; CHECK:       bb46:
596; CHECK-NEXT:    ret void
597; CHECK:       bb47:
598; CHECK-NEXT:    [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_BLAM_4]], %struct.blam.4* [[TMP]], i64 0, i32 0, i32 2
599; CHECK-NEXT:    store i32 20, i32* [[TMP48]], align 8
600; CHECK-NEXT:    br label [[BB52:%.*]]
601; CHECK:       bb52:
602; CHECK-NEXT:    br i1 [[C]], label [[BB68:%.*]], label [[BB59:%.*]]
603; CHECK:       bb59:
604; CHECK-NEXT:    call void @use.2(%struct.blam.4* [[TMP]])
605; CHECK-NEXT:    ret void
606; CHECK:       bb68:
607; CHECK-NEXT:    ret void
608;
609bb:
610  %tmp = alloca %struct.blam.4, align 8
611  %tmp36 = getelementptr inbounds %struct.blam.4, %struct.blam.4* %tmp, i64 0, i32 0, i32 1
612  %tmp37 = bitcast i64** %tmp36 to i8*
613  %tmp38 = getelementptr inbounds %struct.blam.4, %struct.blam.4* %tmp, i64 0, i32 0, i32 3
614  %tmp39 = bitcast i64* %tmp38 to i64*
615  store i64 0, i64* %tmp39, align 4
616  br i1 %c, label %bb46, label %bb47
617
618bb46:                                             ; preds = %bb12
619  call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(20) %tmp37, i8 0, i64 26, i1 false)
620  ret void
621
622bb47:                                             ; preds = %bb12
623  %tmp48 = getelementptr inbounds %struct.blam.4, %struct.blam.4* %tmp, i64 0, i32 0, i32 2
624  store i32 20, i32* %tmp48, align 8
625  br label %bb52
626
627bb52:                                             ; preds = %bb47
628  br i1 %c, label %bb68, label %bb59
629
630bb59:                                             ; preds = %bb52
631  call void @use.2(%struct.blam.4* %tmp)
632  ret void
633
634bb68:                                             ; preds = %bb52
635  ret void
636}
637
638declare void @use.2(%struct.blam.4*)
639
640declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg)
641