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