1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -sink-common-insts -S | FileCheck %s
3; RUN: opt < %s -passes='simplifycfg<sink-common-insts>' -S | FileCheck %s
4
5target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
6target triple = "x86_64-pc-linux-gnu"
7
8define zeroext i1 @test1(i1 zeroext %flag, i32 %blksA, i32 %blksB, i32 %nblks) {
9; CHECK-LABEL: @test1(
10; CHECK-NEXT:  entry:
11; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[NBLKS:%.*]], [[BLKSB:%.*]]
12; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[ADD]], [[BLKSA:%.*]]
13; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[BLKSA]], [[NBLKS]]
14; CHECK-NEXT:    [[CMP2_SINK:%.*]] = select i1 [[FLAG:%.*]], i1 [[CMP]], i1 [[CMP2]]
15; CHECK-NEXT:    [[FROMBOOL3:%.*]] = zext i1 [[CMP2_SINK]] to i8
16; CHECK-NEXT:    [[TOBOOL4:%.*]] = icmp ne i8 [[FROMBOOL3]], 0
17; CHECK-NEXT:    ret i1 [[TOBOOL4]]
18;
19entry:
20  br i1 %flag, label %if.then, label %if.else
21
22if.then:
23  %cmp = icmp uge i32 %blksA, %nblks
24  %frombool1 = zext i1 %cmp to i8
25  br label %if.end
26
27if.else:
28  %add = add i32 %nblks, %blksB
29  %cmp2 = icmp ule i32 %add, %blksA
30  %frombool3 = zext i1 %cmp2 to i8
31  br label %if.end
32
33if.end:
34  %obeys.0 = phi i8 [ %frombool1, %if.then ], [ %frombool3, %if.else ]
35  %tobool4 = icmp ne i8 %obeys.0, 0
36  ret i1 %tobool4
37}
38
39define zeroext i1 @test2(i1 zeroext %flag, i32 %blksA, i32 %blksB, i32 %nblks) {
40; CHECK-LABEL: @test2(
41; CHECK-NEXT:  entry:
42; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[NBLKS:%.*]], [[BLKSB:%.*]]
43; CHECK-NEXT:    [[ADD_SINK:%.*]] = select i1 [[FLAG:%.*]], i32 [[NBLKS]], i32 [[ADD]]
44; CHECK-NEXT:    [[CMP2:%.*]] = icmp uge i32 [[BLKSA:%.*]], [[ADD_SINK]]
45; CHECK-NEXT:    [[FROMBOOL3:%.*]] = zext i1 [[CMP2]] to i8
46; CHECK-NEXT:    [[TOBOOL4:%.*]] = icmp ne i8 [[FROMBOOL3]], 0
47; CHECK-NEXT:    ret i1 [[TOBOOL4]]
48;
49entry:
50  br i1 %flag, label %if.then, label %if.else
51
52if.then:
53  %cmp = icmp uge i32 %blksA, %nblks
54  %frombool1 = zext i1 %cmp to i8
55  br label %if.end
56
57if.else:
58  %add = add i32 %nblks, %blksB
59  %cmp2 = icmp uge i32 %blksA, %add
60  %frombool3 = zext i1 %cmp2 to i8
61  br label %if.end
62
63if.end:
64  %obeys.0 = phi i8 [ %frombool1, %if.then ], [ %frombool3, %if.else ]
65  %tobool4 = icmp ne i8 %obeys.0, 0
66  ret i1 %tobool4
67}
68
69declare i32 @foo(i32, i32) nounwind readnone
70
71define i32 @test3(i1 zeroext %flag, i32 %x, i32 %y) {
72; CHECK-LABEL: @test3(
73; CHECK-NEXT:  entry:
74; CHECK-NEXT:    [[X_Y:%.*]] = select i1 [[FLAG:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]
75; CHECK-NEXT:    [[X1:%.*]] = call i32 @foo(i32 [[X_Y]], i32 0) #[[ATTR0:[0-9]+]]
76; CHECK-NEXT:    [[Y1:%.*]] = call i32 @foo(i32 [[X_Y]], i32 1) #[[ATTR0]]
77; CHECK-NEXT:    [[RET:%.*]] = add i32 [[X1]], [[Y1]]
78; CHECK-NEXT:    ret i32 [[RET]]
79;
80entry:
81  br i1 %flag, label %if.then, label %if.else
82
83if.then:
84  %x0 = call i32 @foo(i32 %x, i32 0) nounwind readnone
85  %y0 = call i32 @foo(i32 %x, i32 1) nounwind readnone
86  br label %if.end
87
88if.else:
89  %x1 = call i32 @foo(i32 %y, i32 0) nounwind readnone
90  %y1 = call i32 @foo(i32 %y, i32 1) nounwind readnone
91  br label %if.end
92
93if.end:
94  %xx = phi i32 [ %x0, %if.then ], [ %x1, %if.else ]
95  %yy = phi i32 [ %y0, %if.then ], [ %y1, %if.else ]
96  %ret = add i32 %xx, %yy
97  ret i32 %ret
98}
99
100
101define i32 @test4(i1 zeroext %flag, i32 %x, i32* %y) {
102; CHECK-LABEL: @test4(
103; CHECK-NEXT:  entry:
104; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[FLAG:%.*]], i32 5, i32 7
105; CHECK-NEXT:    [[B:%.*]] = add i32 [[X:%.*]], [[DOT]]
106; CHECK-NEXT:    store i32 [[B]], i32* [[Y:%.*]], align 4
107; CHECK-NEXT:    ret i32 1
108;
109entry:
110  br i1 %flag, label %if.then, label %if.else
111
112if.then:
113  %a = add i32 %x, 5
114  store i32 %a, i32* %y
115  br label %if.end
116
117if.else:
118  %b = add i32 %x, 7
119  store i32 %b, i32* %y
120  br label %if.end
121
122if.end:
123  ret i32 1
124}
125
126
127define i32 @test5(i1 zeroext %flag, i32 %x, i32* %y) {
128; CHECK-LABEL: @test5(
129; CHECK-NEXT:  entry:
130; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
131; CHECK:       if.then:
132; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], 5
133; CHECK-NEXT:    store volatile i32 [[A]], i32* [[Y:%.*]], align 4
134; CHECK-NEXT:    br label [[IF_END:%.*]]
135; CHECK:       if.else:
136; CHECK-NEXT:    [[B:%.*]] = add i32 [[X]], 7
137; CHECK-NEXT:    store i32 [[B]], i32* [[Y]], align 4
138; CHECK-NEXT:    br label [[IF_END]]
139; CHECK:       if.end:
140; CHECK-NEXT:    ret i32 1
141;
142entry:
143  br i1 %flag, label %if.then, label %if.else
144
145if.then:
146  %a = add i32 %x, 5
147  store volatile i32 %a, i32* %y
148  br label %if.end
149
150if.else:
151  %b = add i32 %x, 7
152  store i32 %b, i32* %y
153  br label %if.end
154
155if.end:
156  ret i32 1
157}
158
159
160define i32 @test6(i1 zeroext %flag, i32 %x, i32* %y) {
161; CHECK-LABEL: @test6(
162; CHECK-NEXT:  entry:
163; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[FLAG:%.*]], i32 5, i32 7
164; CHECK-NEXT:    [[B:%.*]] = add i32 [[X:%.*]], [[DOT]]
165; CHECK-NEXT:    store volatile i32 [[B]], i32* [[Y:%.*]], align 4
166; CHECK-NEXT:    ret i32 1
167;
168entry:
169  br i1 %flag, label %if.then, label %if.else
170
171if.then:
172  %a = add i32 %x, 5
173  store volatile i32 %a, i32* %y
174  br label %if.end
175
176if.else:
177  %b = add i32 %x, 7
178  store volatile i32 %b, i32* %y
179  br label %if.end
180
181if.end:
182  ret i32 1
183}
184
185
186define i32 @test7(i1 zeroext %flag, i32 %x, i32* %y) {
187; CHECK-LABEL: @test7(
188; CHECK-NEXT:  entry:
189; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[FLAG:%.*]], i32 5, i32 7
190; CHECK-NEXT:    [[W:%.*]] = load volatile i32, i32* [[Y:%.*]], align 4
191; CHECK-NEXT:    [[B:%.*]] = add i32 [[W]], [[DOT]]
192; CHECK-NEXT:    store volatile i32 [[B]], i32* [[Y]], align 4
193; CHECK-NEXT:    ret i32 1
194;
195entry:
196  br i1 %flag, label %if.then, label %if.else
197
198if.then:
199  %z = load volatile i32, i32* %y
200  %a = add i32 %z, 5
201  store volatile i32 %a, i32* %y
202  br label %if.end
203
204if.else:
205  %w = load volatile i32, i32* %y
206  %b = add i32 %w, 7
207  store volatile i32 %b, i32* %y
208  br label %if.end
209
210if.end:
211  ret i32 1
212}
213
214
215; %z and %w are in different blocks. We shouldn't sink the add because
216; there may be intervening memory instructions.
217define i32 @test8(i1 zeroext %flag, i32 %x, i32* %y) {
218; CHECK-LABEL: @test8(
219; CHECK-NEXT:  entry:
220; CHECK-NEXT:    [[Z:%.*]] = load volatile i32, i32* [[Y:%.*]], align 4
221; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
222; CHECK:       if.then:
223; CHECK-NEXT:    [[A:%.*]] = add i32 [[Z]], 5
224; CHECK-NEXT:    br label [[IF_END:%.*]]
225; CHECK:       if.else:
226; CHECK-NEXT:    [[W:%.*]] = load volatile i32, i32* [[Y]], align 4
227; CHECK-NEXT:    [[B:%.*]] = add i32 [[W]], 7
228; CHECK-NEXT:    br label [[IF_END]]
229; CHECK:       if.end:
230; CHECK-NEXT:    [[B_SINK:%.*]] = phi i32 [ [[B]], [[IF_ELSE]] ], [ [[A]], [[IF_THEN]] ]
231; CHECK-NEXT:    store volatile i32 [[B_SINK]], i32* [[Y]], align 4
232; CHECK-NEXT:    ret i32 1
233;
234entry:
235  %z = load volatile i32, i32* %y
236  br i1 %flag, label %if.then, label %if.else
237
238if.then:
239  %a = add i32 %z, 5
240  store volatile i32 %a, i32* %y
241  br label %if.end
242
243if.else:
244  %w = load volatile i32, i32* %y
245  %b = add i32 %w, 7
246  store volatile i32 %b, i32* %y
247  br label %if.end
248
249if.end:
250  ret i32 1
251}
252
253
254; The extra store in %if.then means %z and %w are not equivalent.
255define i32 @test9(i1 zeroext %flag, i32 %x, i32* %y, i32* %p) {
256; CHECK-LABEL: @test9(
257; CHECK-NEXT:  entry:
258; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
259; CHECK:       if.then:
260; CHECK-NEXT:    store i32 7, i32* [[P:%.*]], align 4
261; CHECK-NEXT:    [[Z:%.*]] = load volatile i32, i32* [[Y:%.*]], align 4
262; CHECK-NEXT:    store i32 6, i32* [[P]], align 4
263; CHECK-NEXT:    [[A:%.*]] = add i32 [[Z]], 5
264; CHECK-NEXT:    br label [[IF_END:%.*]]
265; CHECK:       if.else:
266; CHECK-NEXT:    [[W:%.*]] = load volatile i32, i32* [[Y]], align 4
267; CHECK-NEXT:    [[B:%.*]] = add i32 [[W]], 7
268; CHECK-NEXT:    br label [[IF_END]]
269; CHECK:       if.end:
270; CHECK-NEXT:    [[B_SINK:%.*]] = phi i32 [ [[B]], [[IF_ELSE]] ], [ [[A]], [[IF_THEN]] ]
271; CHECK-NEXT:    store volatile i32 [[B_SINK]], i32* [[Y]], align 4
272; CHECK-NEXT:    ret i32 1
273;
274entry:
275  br i1 %flag, label %if.then, label %if.else
276
277if.then:
278  store i32 7, i32* %p
279  %z = load volatile i32, i32* %y
280  store i32 6, i32* %p
281  %a = add i32 %z, 5
282  store volatile i32 %a, i32* %y
283  br label %if.end
284
285if.else:
286  %w = load volatile i32, i32* %y
287  %b = add i32 %w, 7
288  store volatile i32 %b, i32* %y
289  br label %if.end
290
291if.end:
292  ret i32 1
293}
294
295
296%struct.anon = type { i32, i32 }
297
298; The GEP indexes a struct type so cannot have a variable last index.
299define i32 @test10(i1 zeroext %flag, i32 %x, i32* %y, %struct.anon* %s) {
300; CHECK-LABEL: @test10(
301; CHECK-NEXT:  entry:
302; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
303; CHECK:       if.then:
304; CHECK-NEXT:    [[DUMMY:%.*]] = add i32 [[X:%.*]], 5
305; CHECK-NEXT:    [[GEPA:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[S:%.*]], i32 0, i32 0
306; CHECK-NEXT:    br label [[IF_END:%.*]]
307; CHECK:       if.else:
308; CHECK-NEXT:    [[DUMMY1:%.*]] = add i32 [[X]], 6
309; CHECK-NEXT:    [[GEPB:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[S]], i32 0, i32 1
310; CHECK-NEXT:    br label [[IF_END]]
311; CHECK:       if.end:
312; CHECK-NEXT:    [[GEPB_SINK:%.*]] = phi i32* [ [[GEPB]], [[IF_ELSE]] ], [ [[GEPA]], [[IF_THEN]] ]
313; CHECK-NEXT:    store volatile i32 [[X]], i32* [[GEPB_SINK]], align 4
314; CHECK-NEXT:    ret i32 1
315;
316entry:
317  br i1 %flag, label %if.then, label %if.else
318
319if.then:
320  %dummy = add i32 %x, 5
321  %gepa = getelementptr inbounds %struct.anon, %struct.anon* %s, i32 0, i32 0
322  store volatile i32 %x, i32* %gepa
323  br label %if.end
324
325if.else:
326  %dummy1 = add i32 %x, 6
327  %gepb = getelementptr inbounds %struct.anon, %struct.anon* %s, i32 0, i32 1
328  store volatile i32 %x, i32* %gepb
329  br label %if.end
330
331if.end:
332  ret i32 1
333}
334
335
336; The shufflevector's mask operand cannot be merged in a PHI.
337define i32 @test11(i1 zeroext %flag, i32 %w, <2 x i32> %x, <2 x i32> %y) {
338; CHECK-LABEL: @test11(
339; CHECK-NEXT:  entry:
340; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
341; CHECK:       if.then:
342; CHECK-NEXT:    [[DUMMY:%.*]] = add i32 [[W:%.*]], 5
343; CHECK-NEXT:    [[SV1:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 0, i32 1>
344; CHECK-NEXT:    br label [[IF_END:%.*]]
345; CHECK:       if.else:
346; CHECK-NEXT:    [[DUMMY1:%.*]] = add i32 [[W]], 6
347; CHECK-NEXT:    [[SV2:%.*]] = shufflevector <2 x i32> [[X]], <2 x i32> [[Y]], <2 x i32> <i32 1, i32 0>
348; CHECK-NEXT:    br label [[IF_END]]
349; CHECK:       if.end:
350; CHECK-NEXT:    [[P:%.*]] = phi <2 x i32> [ [[SV1]], [[IF_THEN]] ], [ [[SV2]], [[IF_ELSE]] ]
351; CHECK-NEXT:    ret i32 1
352;
353entry:
354  br i1 %flag, label %if.then, label %if.else
355
356if.then:
357  %dummy = add i32 %w, 5
358  %sv1 = shufflevector <2 x i32> %x, <2 x i32> %y, <2 x i32> <i32 0, i32 1>
359  br label %if.end
360
361if.else:
362  %dummy1 = add i32 %w, 6
363  %sv2 = shufflevector <2 x i32> %x, <2 x i32> %y, <2 x i32> <i32 1, i32 0>
364  br label %if.end
365
366if.end:
367  %p = phi <2 x i32> [ %sv1, %if.then ], [ %sv2, %if.else ]
368  ret i32 1
369}
370
371
372; We can't common an intrinsic!
373define i32 @test12(i1 zeroext %flag, i32 %w, i32 %x, i32 %y) {
374; CHECK-LABEL: @test12(
375; CHECK-NEXT:  entry:
376; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
377; CHECK:       if.then:
378; CHECK-NEXT:    [[DUMMY:%.*]] = add i32 [[W:%.*]], 5
379; CHECK-NEXT:    [[SV1:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 false)
380; CHECK-NEXT:    br label [[IF_END:%.*]]
381; CHECK:       if.else:
382; CHECK-NEXT:    [[DUMMY1:%.*]] = add i32 [[W]], 6
383; CHECK-NEXT:    [[SV2:%.*]] = call i32 @llvm.cttz.i32(i32 [[X]], i1 false)
384; CHECK-NEXT:    br label [[IF_END]]
385; CHECK:       if.end:
386; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[SV1]], [[IF_THEN]] ], [ [[SV2]], [[IF_ELSE]] ]
387; CHECK-NEXT:    ret i32 1
388;
389entry:
390  br i1 %flag, label %if.then, label %if.else
391
392if.then:
393  %dummy = add i32 %w, 5
394  %sv1 = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
395  br label %if.end
396
397if.else:
398  %dummy1 = add i32 %w, 6
399  %sv2 = call i32 @llvm.cttz.i32(i32 %x, i1 false)
400  br label %if.end
401
402if.end:
403  %p = phi i32 [ %sv1, %if.then ], [ %sv2, %if.else ]
404  ret i32 1
405}
406
407declare i32 @llvm.ctlz.i32(i32 %x, i1 immarg) readnone
408declare i32 @llvm.cttz.i32(i32 %x, i1 immarg) readnone
409
410
411; The TBAA metadata should be properly combined.
412define i32 @test13(i1 zeroext %flag, i32 %x, i32* %y) {
413; CHECK-LABEL: @test13(
414; CHECK-NEXT:  entry:
415; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[FLAG:%.*]], i32 5, i32 7
416; CHECK-NEXT:    [[W:%.*]] = load volatile i32, i32* [[Y:%.*]], align 4
417; CHECK-NEXT:    [[B:%.*]] = add i32 [[W]], [[DOT]]
418; CHECK-NEXT:    store volatile i32 [[B]], i32* [[Y]], align 4, !tbaa [[TBAA4:![0-9]+]]
419; CHECK-NEXT:    ret i32 1
420;
421entry:
422  br i1 %flag, label %if.then, label %if.else
423
424if.then:
425  %z = load volatile i32, i32* %y
426  %a = add i32 %z, 5
427  store volatile i32 %a, i32* %y, !tbaa !3
428  br label %if.end
429
430if.else:
431  %w = load volatile i32, i32* %y
432  %b = add i32 %w, 7
433  store volatile i32 %b, i32* %y, !tbaa !4
434  br label %if.end
435
436if.end:
437  ret i32 1
438}
439
440!0 = !{ !"an example type tree" }
441!1 = !{ !"int", !0 }
442!2 = !{ !"float", !0 }
443!3 = !{ !"const float", !2, i64 0 }
444!4 = !{ !"special float", !2, i64 1 }
445
446
447; The call should be commoned.
448define i32 @test13a(i1 zeroext %flag, i32 %w, i32 %x, i32 %y) {
449; CHECK-LABEL: @test13a(
450; CHECK-NEXT:  entry:
451; CHECK-NEXT:    [[X_Y:%.*]] = select i1 [[FLAG:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]
452; CHECK-NEXT:    [[SV2:%.*]] = call i32 @bar(i32 [[X_Y]])
453; CHECK-NEXT:    ret i32 1
454;
455entry:
456  br i1 %flag, label %if.then, label %if.else
457
458if.then:
459  %sv1 = call i32 @bar(i32 %x)
460  br label %if.end
461
462if.else:
463  %sv2 = call i32 @bar(i32 %y)
464  br label %if.end
465
466if.end:
467  %p = phi i32 [ %sv1, %if.then ], [ %sv2, %if.else ]
468  ret i32 1
469}
470declare i32 @bar(i32)
471
472
473; The load should be commoned.
474define i32 @test14(i1 zeroext %flag, i32 %w, i32 %x, i32 %y, %struct.anon* %s) {
475; CHECK-LABEL: @test14(
476; CHECK-NEXT:  entry:
477; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[FLAG:%.*]], i32 1, i32 4
478; CHECK-NEXT:    [[DOT2:%.*]] = select i1 [[FLAG]], i32 56, i32 57
479; CHECK-NEXT:    [[DUMMY2:%.*]] = add i32 [[X:%.*]], [[DOT]]
480; CHECK-NEXT:    [[GEPB:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[S:%.*]], i32 0, i32 1
481; CHECK-NEXT:    [[SV2:%.*]] = load i32, i32* [[GEPB]], align 4
482; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[SV2]], [[DOT2]]
483; CHECK-NEXT:    ret i32 1
484;
485entry:
486  br i1 %flag, label %if.then, label %if.else
487
488if.then:
489  %dummy = add i32 %x, 1
490  %gepa = getelementptr inbounds %struct.anon, %struct.anon* %s, i32 0, i32 1
491  %sv1 = load i32, i32* %gepa
492  %cmp1 = icmp eq i32 %sv1, 56
493  br label %if.end
494
495if.else:
496  %dummy2 = add i32 %x, 4
497  %gepb = getelementptr inbounds %struct.anon, %struct.anon* %s, i32 0, i32 1
498  %sv2 = load i32, i32* %gepb
499  %cmp2 = icmp eq i32 %sv2, 57
500  call void @llvm.dbg.value(metadata i32 0, metadata !9, metadata !DIExpression()), !dbg !11
501  br label %if.end
502
503if.end:
504  %p = phi i1 [ %cmp1, %if.then ], [ %cmp2, %if.else ]
505  ret i32 1
506}
507
508declare void @llvm.dbg.value(metadata, metadata, metadata)
509!llvm.module.flags = !{!5, !6}
510!llvm.dbg.cu = !{!7}
511
512!5 = !{i32 2, !"Dwarf Version", i32 4}
513!6 = !{i32 2, !"Debug Info Version", i32 3}
514!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !10)
515!8 = distinct !DISubprogram(name: "foo", unit: !7)
516!9 = !DILocalVariable(name: "b", line: 1, arg: 2, scope: !8)
517!10 = !DIFile(filename: "a.c", directory: "a/b")
518!11 = !DILocation(line: 1, column: 14, scope: !8)
519
520
521; The load should be commoned.
522define i32 @test15(i1 zeroext %flag, i32 %w, i32 %x, i32 %y, %struct.anon* %s) {
523; CHECK-LABEL: @test15(
524; CHECK-NEXT:  entry:
525; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
526; CHECK:       if.then:
527; CHECK-NEXT:    [[DUMMY:%.*]] = add i32 [[X:%.*]], 1
528; CHECK-NEXT:    [[GEPA:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[S:%.*]], i32 0, i32 0
529; CHECK-NEXT:    br label [[IF_END:%.*]]
530; CHECK:       if.else:
531; CHECK-NEXT:    [[DUMMY2:%.*]] = add i32 [[X]], 4
532; CHECK-NEXT:    [[GEPB:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[S]], i32 0, i32 1
533; CHECK-NEXT:    br label [[IF_END]]
534; CHECK:       if.end:
535; CHECK-NEXT:    [[GEPB_SINK:%.*]] = phi i32* [ [[GEPB]], [[IF_ELSE]] ], [ [[GEPA]], [[IF_THEN]] ]
536; CHECK-NEXT:    [[DOTSINK:%.*]] = phi i64 [ 57, [[IF_ELSE]] ], [ 56, [[IF_THEN]] ]
537; CHECK-NEXT:    [[SV2:%.*]] = load i32, i32* [[GEPB_SINK]], align 4
538; CHECK-NEXT:    [[EXT2:%.*]] = zext i32 [[SV2]] to i64
539; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i64 [[EXT2]], [[DOTSINK]]
540; CHECK-NEXT:    ret i32 1
541;
542entry:
543  br i1 %flag, label %if.then, label %if.else
544
545if.then:
546  %dummy = add i32 %x, 1
547  %gepa = getelementptr inbounds %struct.anon, %struct.anon* %s, i32 0, i32 0
548  %sv1 = load i32, i32* %gepa
549  %ext1 = zext i32 %sv1 to i64
550  %cmp1 = icmp eq i64 %ext1, 56
551  br label %if.end
552
553if.else:
554  %dummy2 = add i32 %x, 4
555  %gepb = getelementptr inbounds %struct.anon, %struct.anon* %s, i32 0, i32 1
556  %sv2 = load i32, i32* %gepb
557  %ext2 = zext i32 %sv2 to i64
558  %cmp2 = icmp eq i64 %ext2, 57
559  br label %if.end
560
561if.end:
562  %p = phi i1 [ %cmp1, %if.then ], [ %cmp2, %if.else ]
563  ret i32 1
564}
565
566
567define zeroext i1 @test_crash(i1 zeroext %flag, i32* %i4, i32* %m, i32* %n) {
568; CHECK-LABEL: @test_crash(
569; CHECK-NEXT:  entry:
570; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
571; CHECK:       if.then:
572; CHECK-NEXT:    [[TMP1:%.*]] = load i32, i32* [[I4:%.*]], align 4
573; CHECK-NEXT:    br label [[IF_END:%.*]]
574; CHECK:       if.else:
575; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[M:%.*]], align 4
576; CHECK-NEXT:    [[TMP4:%.*]] = load i32, i32* [[N:%.*]], align 4
577; CHECK-NEXT:    br label [[IF_END]]
578; CHECK:       if.end:
579; CHECK-NEXT:    [[TMP4_SINK:%.*]] = phi i32 [ [[TMP4]], [[IF_ELSE]] ], [ -1, [[IF_THEN]] ]
580; CHECK-NEXT:    [[TMP3_SINK:%.*]] = phi i32 [ [[TMP3]], [[IF_ELSE]] ], [ [[TMP1]], [[IF_THEN]] ]
581; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[TMP3_SINK]], [[TMP4_SINK]]
582; CHECK-NEXT:    store i32 [[TMP5]], i32* [[I4]], align 4
583; CHECK-NEXT:    ret i1 true
584;
585entry:
586  br i1 %flag, label %if.then, label %if.else
587
588if.then:
589  %tmp1 = load i32, i32* %i4
590  %tmp2 = add i32 %tmp1, -1
591  store i32 %tmp2, i32* %i4
592  br label %if.end
593
594if.else:
595  %tmp3 = load i32, i32* %m
596  %tmp4 = load i32, i32* %n
597  %tmp5 = add i32 %tmp3, %tmp4
598  store i32 %tmp5, i32* %i4
599  br label %if.end
600
601if.end:
602  ret i1 true
603}
604
605; No checks for test_crash - just ensure it doesn't crash!
606
607define zeroext i1 @test16(i1 zeroext %flag, i1 zeroext %flag2, i32 %blksA, i32 %blksB, i32 %nblks) {
608; CHECK-LABEL: @test16(
609; CHECK-NEXT:  entry:
610; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
611; CHECK:       if.then:
612; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[BLKSA:%.*]], [[NBLKS:%.*]]
613; CHECK-NEXT:    [[FROMBOOL1:%.*]] = zext i1 [[CMP]] to i8
614; CHECK-NEXT:    br label [[IF_END:%.*]]
615; CHECK:       if.else:
616; CHECK-NEXT:    br i1 [[FLAG2:%.*]], label [[IF_THEN2:%.*]], label [[IF_END]]
617; CHECK:       if.then2:
618; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[NBLKS]], [[BLKSB:%.*]]
619; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[ADD]], [[BLKSA]]
620; CHECK-NEXT:    [[FROMBOOL3:%.*]] = zext i1 [[CMP2]] to i8
621; CHECK-NEXT:    br label [[IF_END]]
622; CHECK:       if.end:
623; CHECK-NEXT:    [[OBEYS_0:%.*]] = phi i8 [ [[FROMBOOL1]], [[IF_THEN]] ], [ [[FROMBOOL3]], [[IF_THEN2]] ], [ 0, [[IF_ELSE]] ]
624; CHECK-NEXT:    [[TOBOOL4:%.*]] = icmp ne i8 [[OBEYS_0]], 0
625; CHECK-NEXT:    ret i1 [[TOBOOL4]]
626;
627entry:
628  br i1 %flag, label %if.then, label %if.else
629
630if.then:
631  %cmp = icmp uge i32 %blksA, %nblks
632  %frombool1 = zext i1 %cmp to i8
633  br label %if.end
634
635if.else:
636  br i1 %flag2, label %if.then2, label %if.end
637
638if.then2:
639  %add = add i32 %nblks, %blksB
640  %cmp2 = icmp ule i32 %add, %blksA
641  %frombool3 = zext i1 %cmp2 to i8
642  br label %if.end
643
644if.end:
645  %obeys.0 = phi i8 [ %frombool1, %if.then ], [ %frombool3, %if.then2 ], [ 0, %if.else ]
646  %tobool4 = icmp ne i8 %obeys.0, 0
647  ret i1 %tobool4
648}
649
650
651define zeroext i1 @test16a(i1 zeroext %flag, i1 zeroext %flag2, i32 %blksA, i32 %blksB, i32 %nblks, i8* %p) {
652; CHECK-LABEL: @test16a(
653; CHECK-NEXT:  entry:
654; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
655; CHECK:       if.then:
656; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[BLKSA:%.*]], [[NBLKS:%.*]]
657; CHECK-NEXT:    br label [[IF_END_SINK_SPLIT:%.*]]
658; CHECK:       if.else:
659; CHECK-NEXT:    br i1 [[FLAG2:%.*]], label [[IF_THEN2:%.*]], label [[IF_END:%.*]]
660; CHECK:       if.then2:
661; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[NBLKS]], [[BLKSB:%.*]]
662; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[ADD]], [[BLKSA]]
663; CHECK-NEXT:    br label [[IF_END_SINK_SPLIT]]
664; CHECK:       if.end.sink.split:
665; CHECK-NEXT:    [[CMP2_SINK:%.*]] = phi i1 [ [[CMP2]], [[IF_THEN2]] ], [ [[CMP]], [[IF_THEN]] ]
666; CHECK-NEXT:    [[FROMBOOL3:%.*]] = zext i1 [[CMP2_SINK]] to i8
667; CHECK-NEXT:    store i8 [[FROMBOOL3]], i8* [[P:%.*]], align 1
668; CHECK-NEXT:    br label [[IF_END]]
669; CHECK:       if.end:
670; CHECK-NEXT:    ret i1 true
671;
672entry:
673  br i1 %flag, label %if.then, label %if.else
674
675if.then:
676  %cmp = icmp uge i32 %blksA, %nblks
677  %frombool1 = zext i1 %cmp to i8
678  store i8 %frombool1, i8* %p
679  br label %if.end
680
681if.else:
682  br i1 %flag2, label %if.then2, label %if.end
683
684if.then2:
685  %add = add i32 %nblks, %blksB
686  %cmp2 = icmp ule i32 %add, %blksA
687  %frombool3 = zext i1 %cmp2 to i8
688  store i8 %frombool3, i8* %p
689  br label %if.end
690
691if.end:
692  ret i1 true
693}
694
695
696define zeroext i1 @test17(i32 %flag, i32 %blksA, i32 %blksB, i32 %nblks) {
697; CHECK-LABEL: @test17(
698; CHECK-NEXT:  entry:
699; CHECK-NEXT:    switch i32 [[FLAG:%.*]], label [[IF_END:%.*]] [
700; CHECK-NEXT:    i32 0, label [[IF_THEN:%.*]]
701; CHECK-NEXT:    i32 1, label [[IF_THEN2:%.*]]
702; CHECK-NEXT:    ]
703; CHECK:       if.then:
704; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[BLKSA:%.*]], [[NBLKS:%.*]]
705; CHECK-NEXT:    br label [[IF_END_SINK_SPLIT:%.*]]
706; CHECK:       if.then2:
707; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[NBLKS]], [[BLKSB:%.*]]
708; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[ADD]], [[BLKSA]]
709; CHECK-NEXT:    br label [[IF_END_SINK_SPLIT]]
710; CHECK:       if.end.sink.split:
711; CHECK-NEXT:    [[CMP2_SINK:%.*]] = phi i1 [ [[CMP2]], [[IF_THEN2]] ], [ [[CMP]], [[IF_THEN]] ]
712; CHECK-NEXT:    [[FROMBOOL3:%.*]] = call i8 @i1toi8(i1 [[CMP2_SINK]])
713; CHECK-NEXT:    br label [[IF_END]]
714; CHECK:       if.end:
715; CHECK-NEXT:    [[OBEYS_0:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[FROMBOOL3]], [[IF_END_SINK_SPLIT]] ]
716; CHECK-NEXT:    [[TOBOOL4:%.*]] = icmp ne i8 [[OBEYS_0]], 0
717; CHECK-NEXT:    ret i1 [[TOBOOL4]]
718;
719entry:
720  switch i32 %flag, label %if.end [
721  i32 0, label %if.then
722  i32 1, label %if.then2
723  ]
724
725if.then:
726  %cmp = icmp uge i32 %blksA, %nblks
727  %frombool1 = call i8 @i1toi8(i1 %cmp)
728  br label %if.end
729
730if.then2:
731  %add = add i32 %nblks, %blksB
732  %cmp2 = icmp ule i32 %add, %blksA
733  %frombool3 = call i8 @i1toi8(i1 %cmp2)
734  br label %if.end
735
736if.end:
737  %obeys.0 = phi i8 [ %frombool1, %if.then ], [ %frombool3, %if.then2 ], [ 0, %entry ]
738  %tobool4 = icmp ne i8 %obeys.0, 0
739  ret i1 %tobool4
740}
741declare i8 @i1toi8(i1)
742
743
744
745
746
747define zeroext i1 @test18(i32 %flag, i32 %blksA, i32 %blksB, i32 %nblks) {
748; CHECK-LABEL: @test18(
749; CHECK-NEXT:  entry:
750; CHECK-NEXT:    switch i32 [[FLAG:%.*]], label [[IF_THEN3:%.*]] [
751; CHECK-NEXT:    i32 0, label [[IF_THEN:%.*]]
752; CHECK-NEXT:    i32 1, label [[IF_THEN2:%.*]]
753; CHECK-NEXT:    ]
754; CHECK:       if.then:
755; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[BLKSA:%.*]], [[NBLKS:%.*]]
756; CHECK-NEXT:    br label [[IF_END:%.*]]
757; CHECK:       if.then2:
758; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[NBLKS]], [[BLKSB:%.*]]
759; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[ADD]], [[BLKSA]]
760; CHECK-NEXT:    br label [[IF_END]]
761; CHECK:       if.then3:
762; CHECK-NEXT:    [[ADD2:%.*]] = add i32 [[NBLKS]], [[BLKSA]]
763; CHECK-NEXT:    [[CMP3:%.*]] = icmp ule i32 [[ADD2]], [[BLKSA]]
764; CHECK-NEXT:    br label [[IF_END]]
765; CHECK:       if.end:
766; CHECK-NEXT:    [[CMP3_SINK:%.*]] = phi i1 [ [[CMP3]], [[IF_THEN3]] ], [ [[CMP2]], [[IF_THEN2]] ], [ [[CMP]], [[IF_THEN]] ]
767; CHECK-NEXT:    [[FROMBOOL4:%.*]] = zext i1 [[CMP3_SINK]] to i8
768; CHECK-NEXT:    [[TOBOOL4:%.*]] = icmp ne i8 [[FROMBOOL4]], 0
769; CHECK-NEXT:    ret i1 [[TOBOOL4]]
770;
771entry:
772  switch i32 %flag, label %if.then3 [
773  i32 0, label %if.then
774  i32 1, label %if.then2
775  ]
776
777if.then:
778  %cmp = icmp uge i32 %blksA, %nblks
779  %frombool1 = zext i1 %cmp to i8
780  br label %if.end
781
782if.then2:
783  %add = add i32 %nblks, %blksB
784  %cmp2 = icmp ule i32 %add, %blksA
785  %frombool3 = zext i1 %cmp2 to i8
786  br label %if.end
787
788if.then3:
789  %add2 = add i32 %nblks, %blksA
790  %cmp3 = icmp ule i32 %add2, %blksA
791  %frombool4 = zext i1 %cmp3 to i8
792  br label %if.end
793
794if.end:
795  %obeys.0 = phi i8 [ %frombool1, %if.then ], [ %frombool3, %if.then2 ], [ %frombool4, %if.then3 ]
796  %tobool4 = icmp ne i8 %obeys.0, 0
797  ret i1 %tobool4
798}
799
800
801define i32 @test_pr30188(i1 zeroext %flag, i32 %x) {
802; CHECK-LABEL: @test_pr30188(
803; CHECK-NEXT:  entry:
804; CHECK-NEXT:    [[Y:%.*]] = alloca i32, align 4
805; CHECK-NEXT:    [[Z:%.*]] = alloca i32, align 4
806; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
807; CHECK:       if.then:
808; CHECK-NEXT:    store i32 [[X:%.*]], i32* [[Y]], align 4
809; CHECK-NEXT:    br label [[IF_END:%.*]]
810; CHECK:       if.else:
811; CHECK-NEXT:    store i32 [[X]], i32* [[Z]], align 4
812; CHECK-NEXT:    br label [[IF_END]]
813; CHECK:       if.end:
814; CHECK-NEXT:    ret i32 1
815;
816entry:
817  %y = alloca i32
818  %z = alloca i32
819  br i1 %flag, label %if.then, label %if.else
820
821if.then:
822  store i32 %x, i32* %y
823  br label %if.end
824
825if.else:
826  store i32 %x, i32* %z
827  br label %if.end
828
829if.end:
830  ret i32 1
831}
832
833
834define i32 @test_pr30188a(i1 zeroext %flag, i32 %x) {
835; CHECK-LABEL: @test_pr30188a(
836; CHECK-NEXT:  entry:
837; CHECK-NEXT:    [[Y:%.*]] = alloca i32, align 4
838; CHECK-NEXT:    [[Z:%.*]] = alloca i32, align 4
839; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
840; CHECK:       if.then:
841; CHECK-NEXT:    call void @g()
842; CHECK-NEXT:    [[ONE:%.*]] = load i32, i32* [[Y]], align 4
843; CHECK-NEXT:    [[TWO:%.*]] = add i32 [[ONE]], 2
844; CHECK-NEXT:    store i32 [[TWO]], i32* [[Y]], align 4
845; CHECK-NEXT:    br label [[IF_END:%.*]]
846; CHECK:       if.else:
847; CHECK-NEXT:    [[THREE:%.*]] = load i32, i32* [[Z]], align 4
848; CHECK-NEXT:    [[FOUR:%.*]] = add i32 [[THREE]], 2
849; CHECK-NEXT:    store i32 [[FOUR]], i32* [[Y]], align 4
850; CHECK-NEXT:    br label [[IF_END]]
851; CHECK:       if.end:
852; CHECK-NEXT:    ret i32 1
853;
854entry:
855  %y = alloca i32
856  %z = alloca i32
857  br i1 %flag, label %if.then, label %if.else
858
859if.then:
860  call void @g()
861  %one = load i32, i32* %y
862  %two = add i32 %one, 2
863  store i32 %two, i32* %y
864  br label %if.end
865
866if.else:
867  %three = load i32, i32* %z
868  %four = add i32 %three, 2
869  store i32 %four, i32* %y
870  br label %if.end
871
872if.end:
873  ret i32 1
874}
875
876
877; The phi is confusing - both add instructions are used by it, but
878; not on their respective unconditional arcs. It should not be
879; optimized.
880define void @test_pr30292(i1 %cond, i1 %cond2, i32 %a, i32 %b) {
881; CHECK-LABEL: @test_pr30292(
882; CHECK-NEXT:  entry:
883; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A:%.*]], 1
884; CHECK-NEXT:    br label [[SUCC:%.*]]
885; CHECK:       two:
886; CHECK-NEXT:    call void @g()
887; CHECK-NEXT:    [[ADD2:%.*]] = add i32 [[A]], 1
888; CHECK-NEXT:    br label [[SUCC]]
889; CHECK:       succ:
890; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD1]], [[SUCC]] ], [ [[ADD2]], [[TWO:%.*]] ]
891; CHECK-NEXT:    br i1 [[COND:%.*]], label [[TWO]], label [[SUCC]]
892;
893entry:
894  %add1 = add i32 %a, 1
895  br label %succ
896
897one:
898  br i1 %cond, label %two, label %succ
899
900two:
901  call void @g()
902  %add2 = add i32 %a, 1
903  br label %succ
904
905succ:
906  %p = phi i32 [ 0, %entry ], [ %add1, %one ], [ %add2, %two ]
907  br label %one
908}
909declare void @g()
910
911
912define zeroext i1 @test_pr30244(i1 zeroext %flag, i1 zeroext %flag2, i32 %blksA, i32 %blksB, i32 %nblks) {
913; CHECK-LABEL: @test_pr30244(
914; CHECK-NEXT:  entry:
915; CHECK-NEXT:    [[P:%.*]] = alloca i8, align 1
916; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
917; CHECK:       if.then:
918; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[BLKSA:%.*]], [[NBLKS:%.*]]
919; CHECK-NEXT:    [[FROMBOOL1:%.*]] = zext i1 [[CMP]] to i8
920; CHECK-NEXT:    store i8 [[FROMBOOL1]], i8* [[P]], align 1
921; CHECK-NEXT:    br label [[IF_END:%.*]]
922; CHECK:       if.else:
923; CHECK-NEXT:    br i1 [[FLAG2:%.*]], label [[IF_THEN2:%.*]], label [[IF_END]]
924; CHECK:       if.then2:
925; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[NBLKS]], [[BLKSB:%.*]]
926; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[ADD]], [[BLKSA]]
927; CHECK-NEXT:    [[FROMBOOL3:%.*]] = zext i1 [[CMP2]] to i8
928; CHECK-NEXT:    store i8 [[FROMBOOL3]], i8* [[P]], align 1
929; CHECK-NEXT:    br label [[IF_END]]
930; CHECK:       if.end:
931; CHECK-NEXT:    ret i1 true
932;
933entry:
934  %p = alloca i8
935  br i1 %flag, label %if.then, label %if.else
936
937if.then:
938  %cmp = icmp uge i32 %blksA, %nblks
939  %frombool1 = zext i1 %cmp to i8
940  store i8 %frombool1, i8* %p
941  br label %if.end
942
943if.else:
944  br i1 %flag2, label %if.then2, label %if.end
945
946if.then2:
947  %add = add i32 %nblks, %blksB
948  %cmp2 = icmp ule i32 %add, %blksA
949  %frombool3 = zext i1 %cmp2 to i8
950  store i8 %frombool3, i8* %p
951  br label %if.end
952
953if.end:
954  ret i1 true
955}
956
957
958define i32 @test_pr30373a(i1 zeroext %flag, i32 %x, i32 %y) {
959; CHECK-LABEL: @test_pr30373a(
960; CHECK-NEXT:  entry:
961; CHECK-NEXT:    [[X_Y:%.*]] = select i1 [[FLAG:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]
962; CHECK-NEXT:    [[X1:%.*]] = call i32 @foo(i32 [[X_Y]], i32 0) #[[ATTR0]]
963; CHECK-NEXT:    [[Y1:%.*]] = call i32 @foo(i32 [[X_Y]], i32 1) #[[ATTR0]]
964; CHECK-NEXT:    [[Z1:%.*]] = lshr i32 [[Y1]], 8
965; CHECK-NEXT:    [[RET:%.*]] = add i32 [[X1]], [[Z1]]
966; CHECK-NEXT:    ret i32 [[RET]]
967;
968entry:
969  br i1 %flag, label %if.then, label %if.else
970
971if.then:
972  %x0 = call i32 @foo(i32 %x, i32 0) nounwind readnone
973  %y0 = call i32 @foo(i32 %x, i32 1) nounwind readnone
974  %z0 = lshr i32 %y0, 8
975  br label %if.end
976
977if.else:
978  %x1 = call i32 @foo(i32 %y, i32 0) nounwind readnone
979  %y1 = call i32 @foo(i32 %y, i32 1) nounwind readnone
980  %z1 = lshr exact i32 %y1, 8
981  br label %if.end
982
983if.end:
984  %xx = phi i32 [ %x0, %if.then ], [ %x1, %if.else ]
985  %yy = phi i32 [ %z0, %if.then ], [ %z1, %if.else ]
986  %ret = add i32 %xx, %yy
987  ret i32 %ret
988}
989
990
991define i32 @test_pr30373b(i1 zeroext %flag, i32 %x, i32 %y) {
992; CHECK-LABEL: @test_pr30373b(
993; CHECK-NEXT:  entry:
994; CHECK-NEXT:    [[X_Y:%.*]] = select i1 [[FLAG:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]
995; CHECK-NEXT:    [[X1:%.*]] = call i32 @foo(i32 [[X_Y]], i32 0) #[[ATTR0]]
996; CHECK-NEXT:    [[Y1:%.*]] = call i32 @foo(i32 [[X_Y]], i32 1) #[[ATTR0]]
997; CHECK-NEXT:    [[Z1:%.*]] = lshr i32 [[Y1]], 8
998; CHECK-NEXT:    [[RET:%.*]] = add i32 [[X1]], [[Z1]]
999; CHECK-NEXT:    ret i32 [[RET]]
1000;
1001entry:
1002  br i1 %flag, label %if.then, label %if.else
1003
1004if.then:
1005  %x0 = call i32 @foo(i32 %x, i32 0) nounwind readnone
1006  %y0 = call i32 @foo(i32 %x, i32 1) nounwind readnone
1007  %z0 = lshr exact i32 %y0, 8
1008  br label %if.end
1009
1010if.else:
1011  %x1 = call i32 @foo(i32 %y, i32 0) nounwind readnone
1012  %y1 = call i32 @foo(i32 %y, i32 1) nounwind readnone
1013  %z1 = lshr i32 %y1, 8
1014  br label %if.end
1015
1016if.end:
1017  %xx = phi i32 [ %x0, %if.then ], [ %x1, %if.else ]
1018  %yy = phi i32 [ %z0, %if.then ], [ %z1, %if.else ]
1019  %ret = add i32 %xx, %yy
1020  ret i32 %ret
1021}
1022
1023
1024
1025; FIXME:  Should turn into select
1026define float @allow_intrinsic_remove_constant(i1 zeroext %flag, float %w, float %x, float %y) {
1027; CHECK-LABEL: @allow_intrinsic_remove_constant(
1028; CHECK-NEXT:  entry:
1029; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1030; CHECK:       if.then:
1031; CHECK-NEXT:    [[DUMMY:%.*]] = fadd float [[W:%.*]], 4.000000e+00
1032; CHECK-NEXT:    [[SV1:%.*]] = call float @llvm.fma.f32(float [[DUMMY]], float 2.000000e+00, float 1.000000e+00)
1033; CHECK-NEXT:    br label [[IF_END:%.*]]
1034; CHECK:       if.else:
1035; CHECK-NEXT:    [[DUMMY1:%.*]] = fadd float [[W]], 8.000000e+00
1036; CHECK-NEXT:    [[SV2:%.*]] = call float @llvm.fma.f32(float 2.000000e+00, float [[DUMMY1]], float 1.000000e+00)
1037; CHECK-NEXT:    br label [[IF_END]]
1038; CHECK:       if.end:
1039; CHECK-NEXT:    [[P:%.*]] = phi float [ [[SV1]], [[IF_THEN]] ], [ [[SV2]], [[IF_ELSE]] ]
1040; CHECK-NEXT:    ret float [[P]]
1041;
1042entry:
1043  br i1 %flag, label %if.then, label %if.else
1044
1045if.then:
1046  %dummy = fadd float %w, 4.0
1047  %sv1 = call float @llvm.fma.f32(float %dummy, float 2.0, float 1.0)
1048  br label %if.end
1049
1050if.else:
1051  %dummy1 = fadd float %w, 8.0
1052  %sv2 = call float @llvm.fma.f32(float 2.0, float %dummy1, float 1.0)
1053  br label %if.end
1054
1055if.end:
1056  %p = phi float [ %sv1, %if.then ], [ %sv2, %if.else ]
1057  ret float %p
1058}
1059
1060declare float @llvm.fma.f32(float, float, float)
1061
1062define i32 @no_remove_constant_immarg(i1 zeroext %flag, i32 %w, i32 %x, i32 %y) {
1063; CHECK-LABEL: @no_remove_constant_immarg(
1064; CHECK-NEXT:  entry:
1065; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1066; CHECK:       if.then:
1067; CHECK-NEXT:    [[DUMMY:%.*]] = add i32 [[W:%.*]], 5
1068; CHECK-NEXT:    [[SV1:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true)
1069; CHECK-NEXT:    br label [[IF_END:%.*]]
1070; CHECK:       if.else:
1071; CHECK-NEXT:    [[DUMMY1:%.*]] = add i32 [[W]], 6
1072; CHECK-NEXT:    [[SV2:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X]], i1 false)
1073; CHECK-NEXT:    br label [[IF_END]]
1074; CHECK:       if.end:
1075; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[SV1]], [[IF_THEN]] ], [ [[SV2]], [[IF_ELSE]] ]
1076; CHECK-NEXT:    ret i32 1
1077;
1078entry:
1079  br i1 %flag, label %if.then, label %if.else
1080
1081if.then:
1082  %dummy = add i32 %w, 5
1083  %sv1 = call i32 @llvm.ctlz.i32(i32 %x, i1 true)
1084  br label %if.end
1085
1086if.else:
1087  %dummy1 = add i32 %w, 6
1088  %sv2 = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
1089  br label %if.end
1090
1091if.end:
1092  %p = phi i32 [ %sv1, %if.then ], [ %sv2, %if.else ]
1093  ret i32 1
1094}
1095
1096declare void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* nocapture, i8 addrspace(1)* nocapture readonly, i64, i1)
1097
1098; Make sure a memcpy size isn't replaced with a variable
1099define void @no_replace_memcpy_size(i1 zeroext %flag, i8 addrspace(1)* %dst, i8 addrspace(1)* %src) {
1100; CHECK-LABEL: @no_replace_memcpy_size(
1101; CHECK-NEXT:  entry:
1102; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1103; CHECK:       if.then:
1104; CHECK-NEXT:    call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* [[DST:%.*]], i8 addrspace(1)* [[SRC:%.*]], i64 1024, i1 false)
1105; CHECK-NEXT:    br label [[IF_END:%.*]]
1106; CHECK:       if.else:
1107; CHECK-NEXT:    call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* [[DST]], i8 addrspace(1)* [[SRC]], i64 4096, i1 false)
1108; CHECK-NEXT:    br label [[IF_END]]
1109; CHECK:       if.end:
1110; CHECK-NEXT:    ret void
1111;
1112entry:
1113  br i1 %flag, label %if.then, label %if.else
1114
1115if.then:
1116  call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* %dst, i8 addrspace(1)* %src, i64 1024, i1 false)
1117  br label %if.end
1118
1119if.else:
1120  call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* %dst, i8 addrspace(1)* %src, i64 4096, i1 false)
1121  br label %if.end
1122
1123if.end:
1124  ret void
1125}
1126
1127declare void @llvm.memmove.p1i8.p1i8.i64(i8 addrspace(1)* nocapture, i8 addrspace(1)* nocapture readonly, i64, i1)
1128
1129; Make sure a memmove size isn't replaced with a variable
1130define void @no_replace_memmove_size(i1 zeroext %flag, i8 addrspace(1)* %dst, i8 addrspace(1)* %src) {
1131; CHECK-LABEL: @no_replace_memmove_size(
1132; CHECK-NEXT:  entry:
1133; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1134; CHECK:       if.then:
1135; CHECK-NEXT:    call void @llvm.memmove.p1i8.p1i8.i64(i8 addrspace(1)* [[DST:%.*]], i8 addrspace(1)* [[SRC:%.*]], i64 1024, i1 false)
1136; CHECK-NEXT:    br label [[IF_END:%.*]]
1137; CHECK:       if.else:
1138; CHECK-NEXT:    call void @llvm.memmove.p1i8.p1i8.i64(i8 addrspace(1)* [[DST]], i8 addrspace(1)* [[SRC]], i64 4096, i1 false)
1139; CHECK-NEXT:    br label [[IF_END]]
1140; CHECK:       if.end:
1141; CHECK-NEXT:    ret void
1142;
1143entry:
1144  br i1 %flag, label %if.then, label %if.else
1145
1146if.then:
1147  call void @llvm.memmove.p1i8.p1i8.i64(i8 addrspace(1)* %dst, i8 addrspace(1)* %src, i64 1024, i1 false)
1148  br label %if.end
1149
1150if.else:
1151  call void @llvm.memmove.p1i8.p1i8.i64(i8 addrspace(1)* %dst, i8 addrspace(1)* %src, i64 4096, i1 false)
1152  br label %if.end
1153
1154if.end:
1155  ret void
1156}
1157
1158declare void @llvm.memset.p1i8.i64(i8 addrspace(1)* nocapture, i8, i64, i1)
1159
1160; Make sure a memset size isn't replaced with a variable
1161define void @no_replace_memset_size(i1 zeroext %flag, i8 addrspace(1)* %dst) {
1162; CHECK-LABEL: @no_replace_memset_size(
1163; CHECK-NEXT:  entry:
1164; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1165; CHECK:       if.then:
1166; CHECK-NEXT:    call void @llvm.memset.p1i8.i64(i8 addrspace(1)* [[DST:%.*]], i8 0, i64 1024, i1 false)
1167; CHECK-NEXT:    br label [[IF_END:%.*]]
1168; CHECK:       if.else:
1169; CHECK-NEXT:    call void @llvm.memset.p1i8.i64(i8 addrspace(1)* [[DST]], i8 0, i64 4096, i1 false)
1170; CHECK-NEXT:    br label [[IF_END]]
1171; CHECK:       if.end:
1172; CHECK-NEXT:    ret void
1173;
1174entry:
1175  br i1 %flag, label %if.then, label %if.else
1176
1177if.then:
1178  call void @llvm.memset.p1i8.i64(i8 addrspace(1)* %dst, i8 0, i64 1024, i1 false)
1179  br label %if.end
1180
1181if.else:
1182  call void @llvm.memset.p1i8.i64(i8 addrspace(1)* %dst, i8 0, i64 4096, i1 false)
1183  br label %if.end
1184
1185if.end:
1186  ret void
1187}
1188
1189; Check that simplifycfg doesn't sink and merge inline-asm instructions.
1190
1191define i32 @test_inline_asm1(i32 %c, i32 %r6) {
1192; CHECK-LABEL: @test_inline_asm1(
1193; CHECK-NEXT:  entry:
1194; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C:%.*]], 0
1195; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
1196; CHECK:       if.then:
1197; CHECK-NEXT:    [[TMP0:%.*]] = call i32 asm "rorl $2, $0", "=&r,0,n,~{dirflag},~{fpsr},~{flags}"(i32 [[R6:%.*]], i32 8)
1198; CHECK-NEXT:    br label [[IF_END:%.*]]
1199; CHECK:       if.else:
1200; CHECK-NEXT:    [[TMP1:%.*]] = call i32 asm "rorl $2, $0", "=&r,0,n,~{dirflag},~{fpsr},~{flags}"(i32 [[R6]], i32 6)
1201; CHECK-NEXT:    br label [[IF_END]]
1202; CHECK:       if.end:
1203; CHECK-NEXT:    [[R6_ADDR_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN]] ], [ [[TMP1]], [[IF_ELSE]] ]
1204; CHECK-NEXT:    ret i32 [[R6_ADDR_0]]
1205;
1206entry:
1207  %tobool = icmp eq i32 %c, 0
1208  br i1 %tobool, label %if.else, label %if.then
1209
1210if.then:
1211  %0 = call i32 asm "rorl $2, $0", "=&r,0,n,~{dirflag},~{fpsr},~{flags}"(i32 %r6, i32 8)
1212  br label %if.end
1213
1214if.else:
1215  %1 = call i32 asm "rorl $2, $0", "=&r,0,n,~{dirflag},~{fpsr},~{flags}"(i32 %r6, i32 6)
1216  br label %if.end
1217
1218if.end:
1219  %r6.addr.0 = phi i32 [ %0, %if.then ], [ %1, %if.else ]
1220  ret i32 %r6.addr.0
1221}
1222
1223
1224declare i32 @call_target()
1225
1226define void @test_operand_bundles(i1 %cond, i32* %ptr) {
1227; CHECK-LABEL: @test_operand_bundles(
1228; CHECK-NEXT:  entry:
1229; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
1230; CHECK:       left:
1231; CHECK-NEXT:    [[VAL0:%.*]] = call i32 @call_target() [ "deopt"(i32 10) ]
1232; CHECK-NEXT:    br label [[MERGE:%.*]]
1233; CHECK:       right:
1234; CHECK-NEXT:    [[VAL1:%.*]] = call i32 @call_target() [ "deopt"(i32 20) ]
1235; CHECK-NEXT:    br label [[MERGE]]
1236; CHECK:       merge:
1237; CHECK-NEXT:    [[VAL1_SINK:%.*]] = phi i32 [ [[VAL1]], [[RIGHT]] ], [ [[VAL0]], [[LEFT]] ]
1238; CHECK-NEXT:    store i32 [[VAL1_SINK]], i32* [[PTR:%.*]], align 4
1239; CHECK-NEXT:    ret void
1240;
1241entry:
1242  br i1 %cond, label %left, label %right
1243
1244left:
1245  %val0 = call i32 @call_target() [ "deopt"(i32 10) ]
1246  store i32 %val0, i32* %ptr
1247  br label %merge
1248
1249right:
1250  %val1 = call i32 @call_target() [ "deopt"(i32 20) ]
1251  store i32 %val1, i32* %ptr
1252  br label %merge
1253
1254merge:
1255  ret void
1256}
1257
1258
1259%TP = type {i32, i32}
1260
1261define i32 @test_insertvalue(i1 zeroext %flag, %TP %P) {
1262; CHECK-LABEL: @test_insertvalue(
1263; CHECK-NEXT:  entry:
1264; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[FLAG:%.*]], i32 0, i32 1
1265; CHECK-NEXT:    [[I2:%.*]] = insertvalue [[TP:%.*]] [[P:%.*]], i32 [[DOT]], 0
1266; CHECK-NEXT:    ret i32 1
1267;
1268entry:
1269  br i1 %flag, label %if.then, label %if.else
1270
1271if.then:
1272  %i1 = insertvalue %TP %P, i32 0, 0
1273  br label %if.end
1274
1275if.else:
1276  %i2 = insertvalue %TP %P, i32 1, 0
1277  br label %if.end
1278
1279if.end:
1280  %i = phi %TP [%i1, %if.then], [%i2, %if.else]
1281  ret i32 1
1282}
1283
1284
1285
1286declare void @baz(i32)
1287
1288define void @test_sink_void_calls(i32 %x) {
1289; CHECK-LABEL: @test_sink_void_calls(
1290; CHECK-NEXT:  entry:
1291; CHECK-NEXT:    switch i32 [[X:%.*]], label [[DEFAULT:%.*]] [
1292; CHECK-NEXT:    i32 0, label [[RETURN:%.*]]
1293; CHECK-NEXT:    i32 1, label [[BB1:%.*]]
1294; CHECK-NEXT:    i32 2, label [[BB2:%.*]]
1295; CHECK-NEXT:    i32 3, label [[BB3:%.*]]
1296; CHECK-NEXT:    i32 4, label [[BB4:%.*]]
1297; CHECK-NEXT:    ]
1298; CHECK:       bb1:
1299; CHECK-NEXT:    br label [[RETURN]]
1300; CHECK:       bb2:
1301; CHECK-NEXT:    br label [[RETURN]]
1302; CHECK:       bb3:
1303; CHECK-NEXT:    br label [[RETURN]]
1304; CHECK:       bb4:
1305; CHECK-NEXT:    br label [[RETURN]]
1306; CHECK:       default:
1307; CHECK-NEXT:    unreachable
1308; CHECK:       return:
1309; CHECK-NEXT:    [[DOTSINK:%.*]] = phi i32 [ 90, [[BB4]] ], [ 78, [[BB3]] ], [ 56, [[BB2]] ], [ 34, [[BB1]] ], [ 12, [[ENTRY:%.*]] ]
1310; CHECK-NEXT:    call void @baz(i32 [[DOTSINK]])
1311; CHECK-NEXT:    ret void
1312;
1313entry:
1314  switch i32 %x, label %default [
1315  i32 0, label %bb0
1316  i32 1, label %bb1
1317  i32 2, label %bb2
1318  i32 3, label %bb3
1319  i32 4, label %bb4
1320  ]
1321bb0:
1322  call void @baz(i32 12)
1323  br label %return
1324bb1:
1325  call void @baz(i32 34)
1326  br label %return
1327bb2:
1328  call void @baz(i32 56)
1329  br label %return
1330bb3:
1331  call void @baz(i32 78)
1332  br label %return
1333bb4:
1334  call void @baz(i32 90)
1335  br label %return
1336default:
1337  unreachable
1338return:
1339  ret void
1340
1341; Check that the calls get sunk to the return block.
1342; We would previously not sink calls without uses, see PR41259.
1343}
1344
1345define i32 @test_not_sink_lifetime_marker(i1 zeroext %flag, i32 %x) {
1346; CHECK-LABEL: @test_not_sink_lifetime_marker(
1347; CHECK-NEXT:  entry:
1348; CHECK-NEXT:    [[Y:%.*]] = alloca i32, align 4
1349; CHECK-NEXT:    [[Z:%.*]] = alloca i32, align 4
1350; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1351; CHECK:       if.then:
1352; CHECK-NEXT:    [[Y_CAST:%.*]] = bitcast i32* [[Y]] to i8*
1353; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[Y_CAST]])
1354; CHECK-NEXT:    br label [[IF_END:%.*]]
1355; CHECK:       if.else:
1356; CHECK-NEXT:    [[Z_CAST:%.*]] = bitcast i32* [[Z]] to i8*
1357; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 4, i8* [[Z_CAST]])
1358; CHECK-NEXT:    br label [[IF_END]]
1359; CHECK:       if.end:
1360; CHECK-NEXT:    ret i32 1
1361;
1362entry:
1363  %y = alloca i32
1364  %z = alloca i32
1365  br i1 %flag, label %if.then, label %if.else
1366
1367if.then:
1368  %y.cast = bitcast i32* %y to i8*
1369  call void @llvm.lifetime.end.p0i8(i64 4, i8* %y.cast)
1370  br label %if.end
1371
1372if.else:
1373  %z.cast = bitcast i32* %z to i8*
1374  call void @llvm.lifetime.end.p0i8(i64 4, i8* %z.cast)
1375  br label %if.end
1376
1377if.end:
1378  ret i32 1
1379}
1380
1381define void @direct_caller(i1 %c) {
1382; CHECK-LABEL: @direct_caller(
1383; CHECK-NEXT:    br i1 [[C:%.*]], label [[CALL_FOO:%.*]], label [[CALL_BAR:%.*]]
1384; CHECK:       call_foo:
1385; CHECK-NEXT:    call void @direct_callee()
1386; CHECK-NEXT:    br label [[END:%.*]]
1387; CHECK:       call_bar:
1388; CHECK-NEXT:    call void @direct_callee2()
1389; CHECK-NEXT:    br label [[END]]
1390; CHECK:       end:
1391; CHECK-NEXT:    ret void
1392;
1393  br i1 %c, label %call_foo, label %call_bar
1394
1395call_foo:
1396  call void @direct_callee()
1397  br label %end
1398
1399call_bar:
1400  call void @direct_callee2()
1401  br label %end
1402
1403end:
1404  ret void
1405}
1406
1407define void @indirect_caller(i1 %c, i32 %v, void (i32)* %foo, void (i32)* %bar) {
1408; CHECK-LABEL: @indirect_caller(
1409; CHECK-NEXT:  end:
1410; CHECK-NEXT:    [[FOO_BAR:%.*]] = select i1 [[C:%.*]], void (i32)* [[FOO:%.*]], void (i32)* [[BAR:%.*]]
1411; CHECK-NEXT:    tail call void [[FOO_BAR]](i32 [[V:%.*]])
1412; CHECK-NEXT:    ret void
1413;
1414  br i1 %c, label %call_foo, label %call_bar
1415
1416call_foo:
1417  tail call void %foo(i32 %v)
1418  br label %end
1419
1420call_bar:
1421  tail call void %bar(i32 %v)
1422  br label %end
1423
1424end:
1425  ret void
1426}
1427
1428define void @maybe_indirect_caller(void ()* %fun) {
1429; CHECK-LABEL: @maybe_indirect_caller(
1430; CHECK-NEXT:    [[C:%.*]] = icmp eq void ()* [[FUN:%.*]], @direct_callee
1431; CHECK-NEXT:    br i1 [[C]], label [[IF_TRUE_DIRECT_TARG:%.*]], label [[IF_FALSE_ORIG_INDIRECT:%.*]]
1432; CHECK:       if.true.direct_targ:
1433; CHECK-NEXT:    tail call void @direct_callee()
1434; CHECK-NEXT:    br label [[IF_END_ICP:%.*]]
1435; CHECK:       if.false.orig_indirect:
1436; CHECK-NEXT:    tail call void [[FUN]]()
1437; CHECK-NEXT:    br label [[IF_END_ICP]]
1438; CHECK:       if.end.icp:
1439; CHECK-NEXT:    ret void
1440;
1441  %c = icmp eq void ()* %fun, @direct_callee
1442  br i1 %c, label %if.true.direct_targ, label %if.false.orig_indirect
1443
1444if.true.direct_targ:
1445  tail call void @direct_callee()
1446  br label %if.end.icp
1447
1448if.false.orig_indirect:
1449  tail call void %fun()
1450  br label %if.end.icp
1451
1452if.end.icp:
1453  ret void
1454}
1455define void @maybe_indirect_caller2(void ()* %fun) {
1456; CHECK-LABEL: @maybe_indirect_caller2(
1457; CHECK-NEXT:    [[C:%.*]] = icmp eq void ()* [[FUN:%.*]], @direct_callee
1458; CHECK-NEXT:    br i1 [[C]], label [[IF_TRUE_DIRECT_TARG:%.*]], label [[IF_FALSE_ORIG_INDIRECT:%.*]]
1459; CHECK:       if.false.orig_indirect:
1460; CHECK-NEXT:    tail call void [[FUN]]()
1461; CHECK-NEXT:    br label [[IF_END_ICP:%.*]]
1462; CHECK:       if.true.direct_targ:
1463; CHECK-NEXT:    tail call void @direct_callee()
1464; CHECK-NEXT:    br label [[IF_END_ICP]]
1465; CHECK:       if.end.icp:
1466; CHECK-NEXT:    ret void
1467;
1468  %c = icmp eq void ()* %fun, @direct_callee
1469  br i1 %c, label %if.true.direct_targ, label %if.false.orig_indirect
1470
1471if.false.orig_indirect:
1472  tail call void %fun()
1473  br label %if.end.icp
1474
1475if.true.direct_targ:
1476  tail call void @direct_callee()
1477  br label %if.end.icp
1478
1479if.end.icp:
1480  ret void
1481}
1482declare void @direct_callee()
1483declare void @direct_callee2()
1484declare void @direct_callee3()
1485
1486declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
1487declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
1488
1489define void @creating_too_many_phis(i1 %cond, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) {
1490; CHECK-LABEL: @creating_too_many_phis(
1491; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]
1492; CHECK:       bb0:
1493; CHECK-NEXT:    [[V0:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
1494; CHECK-NEXT:    [[V1:%.*]] = add i32 [[V0]], [[C:%.*]]
1495; CHECK-NEXT:    [[V2:%.*]] = add i32 [[D:%.*]], [[E:%.*]]
1496; CHECK-NEXT:    [[R3:%.*]] = add i32 [[V1]], [[V2]]
1497; CHECK-NEXT:    br label [[END:%.*]]
1498; CHECK:       bb1:
1499; CHECK-NEXT:    [[V4:%.*]] = add i32 [[A]], [[B]]
1500; CHECK-NEXT:    [[V5:%.*]] = add i32 [[V4]], [[C]]
1501; CHECK-NEXT:    [[V6:%.*]] = add i32 [[G:%.*]], [[H:%.*]]
1502; CHECK-NEXT:    [[R7:%.*]] = add i32 [[V5]], [[V6]]
1503; CHECK-NEXT:    br label [[END]]
1504; CHECK:       end:
1505; CHECK-NEXT:    [[R7_SINK:%.*]] = phi i32 [ [[R7]], [[BB1]] ], [ [[R3]], [[BB0]] ]
1506; CHECK-NEXT:    call void @use32(i32 [[R7_SINK]])
1507; CHECK-NEXT:    ret void
1508;
1509  br i1 %cond, label %bb0, label %bb1
1510
1511bb0:
1512  %v0 = add i32 %a, %b
1513  %v1 = add i32 %v0, %c
1514  %v2 = add i32 %d, %e
1515  %r3 = add i32 %v1, %v2
1516  call void @use32(i32 %r3)
1517  br label %end
1518
1519bb1:
1520  %v4 = add i32 %a, %b
1521  %v5 = add i32 %v4, %c
1522  %v6 = add i32 %g, %h
1523  %r7 = add i32 %v5, %v6
1524  call void @use32(i32 %r7)
1525  br label %end
1526
1527end:
1528  ret void
1529}
1530declare void @use32(i32)
1531
1532define void @multiple_cond_preds(i1 %c0, i1 %c1, i1 %c2) {
1533; CHECK-LABEL: @multiple_cond_preds(
1534; CHECK-NEXT:  dispatch0:
1535; CHECK-NEXT:    br i1 [[C0:%.*]], label [[DISPATCH1:%.*]], label [[DISPATCH2:%.*]]
1536; CHECK:       dispatch1:
1537; CHECK-NEXT:    call void @direct_callee2()
1538; CHECK-NEXT:    br i1 [[C1:%.*]], label [[END_SINK_SPLIT:%.*]], label [[END:%.*]]
1539; CHECK:       dispatch2:
1540; CHECK-NEXT:    call void @direct_callee3()
1541; CHECK-NEXT:    br i1 [[C2:%.*]], label [[END_SINK_SPLIT]], label [[END]]
1542; CHECK:       end.sink.split:
1543; CHECK-NEXT:    call void @direct_callee()
1544; CHECK-NEXT:    br label [[END]]
1545; CHECK:       end:
1546; CHECK-NEXT:    ret void
1547;
1548dispatch0:
1549  br i1 %c0, label %dispatch1, label %dispatch2
1550
1551dispatch1:
1552  call void @direct_callee2()
1553  br i1 %c1, label %uncond_pred0, label %end
1554
1555dispatch2:
1556  call void @direct_callee3()
1557  br i1 %c2, label %uncond_pred1, label %end
1558
1559uncond_pred0:
1560  call void @direct_callee()
1561  br label %end
1562
1563uncond_pred1:
1564  call void @direct_callee()
1565  br label %end
1566
1567end:
1568  ret void
1569}
1570