xref: /llvm-project/llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll (revision 8a6248b739d705577fa5414b4010605dca38aa79)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -sink-common-insts -S | FileCheck %s
3; RUN: opt --try-experimental-debuginfo-iterators < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -sink-common-insts -S | FileCheck %s
4; RUN: opt < %s -passes='simplifycfg<sink-common-insts>' -S | FileCheck %s
5; RUN: opt --try-experimental-debuginfo-iterators < %s -passes='simplifycfg<sink-common-insts>' -S | FileCheck %s
6
7target 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"
8target triple = "x86_64-pc-linux-gnu"
9
10define zeroext i1 @test1(i1 zeroext %flag, i32 %blksA, i32 %blksB, i32 %nblks) {
11; CHECK-LABEL: @test1(
12; CHECK-NEXT:  entry:
13; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[NBLKS:%.*]], [[BLKSB:%.*]]
14; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[ADD]], [[BLKSA:%.*]]
15; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[BLKSA]], [[NBLKS]]
16; CHECK-NEXT:    [[CMP2_SINK:%.*]] = select i1 [[FLAG:%.*]], i1 [[CMP]], i1 [[CMP2]]
17; CHECK-NEXT:    [[FROMBOOL3:%.*]] = zext i1 [[CMP2_SINK]] to i8
18; CHECK-NEXT:    [[TOBOOL4:%.*]] = icmp ne i8 [[FROMBOOL3]], 0
19; CHECK-NEXT:    ret i1 [[TOBOOL4]]
20;
21entry:
22  br i1 %flag, label %if.then, label %if.else
23
24if.then:
25  %cmp = icmp uge i32 %blksA, %nblks
26  %frombool1 = zext i1 %cmp to i8
27  br label %if.end
28
29if.else:
30  %add = add i32 %nblks, %blksB
31  %cmp2 = icmp ule i32 %add, %blksA
32  %frombool3 = zext i1 %cmp2 to i8
33  br label %if.end
34
35if.end:
36  %obeys.0 = phi i8 [ %frombool1, %if.then ], [ %frombool3, %if.else ]
37  %tobool4 = icmp ne i8 %obeys.0, 0
38  ret i1 %tobool4
39}
40
41define zeroext i1 @test2(i1 zeroext %flag, i32 %blksA, i32 %blksB, i32 %nblks) {
42; CHECK-LABEL: @test2(
43; CHECK-NEXT:  entry:
44; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[NBLKS:%.*]], [[BLKSB:%.*]]
45; CHECK-NEXT:    [[ADD_SINK:%.*]] = select i1 [[FLAG:%.*]], i32 [[NBLKS]], i32 [[ADD]]
46; CHECK-NEXT:    [[CMP2:%.*]] = icmp uge i32 [[BLKSA:%.*]], [[ADD_SINK]]
47; CHECK-NEXT:    [[FROMBOOL3:%.*]] = zext i1 [[CMP2]] to i8
48; CHECK-NEXT:    [[TOBOOL4:%.*]] = icmp ne i8 [[FROMBOOL3]], 0
49; CHECK-NEXT:    ret i1 [[TOBOOL4]]
50;
51entry:
52  br i1 %flag, label %if.then, label %if.else
53
54if.then:
55  %cmp = icmp uge i32 %blksA, %nblks
56  %frombool1 = zext i1 %cmp to i8
57  br label %if.end
58
59if.else:
60  %add = add i32 %nblks, %blksB
61  %cmp2 = icmp uge i32 %blksA, %add
62  %frombool3 = zext i1 %cmp2 to i8
63  br label %if.end
64
65if.end:
66  %obeys.0 = phi i8 [ %frombool1, %if.then ], [ %frombool3, %if.else ]
67  %tobool4 = icmp ne i8 %obeys.0, 0
68  ret i1 %tobool4
69}
70
71declare i32 @foo(i32, i32) nounwind readnone
72
73define i32 @test3(i1 zeroext %flag, i32 %x, i32 %y) {
74; CHECK-LABEL: @test3(
75; CHECK-NEXT:  entry:
76; CHECK-NEXT:    [[X_Y:%.*]] = select i1 [[FLAG:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]
77; CHECK-NEXT:    [[X1:%.*]] = call i32 @foo(i32 [[X_Y]], i32 0) #[[ATTR0:[0-9]+]]
78; CHECK-NEXT:    [[Y1:%.*]] = call i32 @foo(i32 [[X_Y]], i32 1) #[[ATTR0]]
79; CHECK-NEXT:    [[RET:%.*]] = add i32 [[X1]], [[Y1]]
80; CHECK-NEXT:    ret i32 [[RET]]
81;
82entry:
83  br i1 %flag, label %if.then, label %if.else
84
85if.then:
86  %x0 = call i32 @foo(i32 %x, i32 0) nounwind readnone
87  %y0 = call i32 @foo(i32 %x, i32 1) nounwind readnone
88  br label %if.end
89
90if.else:
91  %x1 = call i32 @foo(i32 %y, i32 0) nounwind readnone
92  %y1 = call i32 @foo(i32 %y, i32 1) nounwind readnone
93  br label %if.end
94
95if.end:
96  %xx = phi i32 [ %x0, %if.then ], [ %x1, %if.else ]
97  %yy = phi i32 [ %y0, %if.then ], [ %y1, %if.else ]
98  %ret = add i32 %xx, %yy
99  ret i32 %ret
100}
101
102
103define i32 @test4(i1 zeroext %flag, i32 %x, ptr %y) {
104; CHECK-LABEL: @test4(
105; CHECK-NEXT:  entry:
106; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[FLAG:%.*]], i32 5, i32 7
107; CHECK-NEXT:    [[B:%.*]] = add i32 [[X:%.*]], [[DOT]]
108; CHECK-NEXT:    store i32 [[B]], ptr [[Y:%.*]], align 4
109; CHECK-NEXT:    ret i32 1
110;
111entry:
112  br i1 %flag, label %if.then, label %if.else
113
114if.then:
115  %a = add i32 %x, 5
116  store i32 %a, ptr %y
117  br label %if.end
118
119if.else:
120  %b = add i32 %x, 7
121  store i32 %b, ptr %y
122  br label %if.end
123
124if.end:
125  ret i32 1
126}
127
128
129define i32 @test5(i1 zeroext %flag, i32 %x, ptr %y) {
130; CHECK-LABEL: @test5(
131; CHECK-NEXT:  entry:
132; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
133; CHECK:       if.then:
134; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], 5
135; CHECK-NEXT:    store volatile i32 [[A]], ptr [[Y:%.*]], align 4
136; CHECK-NEXT:    br label [[IF_END:%.*]]
137; CHECK:       if.else:
138; CHECK-NEXT:    [[B:%.*]] = add i32 [[X]], 7
139; CHECK-NEXT:    store i32 [[B]], ptr [[Y]], align 4
140; CHECK-NEXT:    br label [[IF_END]]
141; CHECK:       if.end:
142; CHECK-NEXT:    ret i32 1
143;
144entry:
145  br i1 %flag, label %if.then, label %if.else
146
147if.then:
148  %a = add i32 %x, 5
149  store volatile i32 %a, ptr %y
150  br label %if.end
151
152if.else:
153  %b = add i32 %x, 7
154  store i32 %b, ptr %y
155  br label %if.end
156
157if.end:
158  ret i32 1
159}
160
161
162define i32 @test6(i1 zeroext %flag, i32 %x, ptr %y) {
163; CHECK-LABEL: @test6(
164; CHECK-NEXT:  entry:
165; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[FLAG:%.*]], i32 5, i32 7
166; CHECK-NEXT:    [[B:%.*]] = add i32 [[X:%.*]], [[DOT]]
167; CHECK-NEXT:    store volatile i32 [[B]], ptr [[Y:%.*]], align 4
168; CHECK-NEXT:    ret i32 1
169;
170entry:
171  br i1 %flag, label %if.then, label %if.else
172
173if.then:
174  %a = add i32 %x, 5
175  store volatile i32 %a, ptr %y
176  br label %if.end
177
178if.else:
179  %b = add i32 %x, 7
180  store volatile i32 %b, ptr %y
181  br label %if.end
182
183if.end:
184  ret i32 1
185}
186
187
188define i32 @test7(i1 zeroext %flag, i32 %x, ptr %y) {
189; CHECK-LABEL: @test7(
190; CHECK-NEXT:  entry:
191; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[FLAG:%.*]], i32 5, i32 7
192; CHECK-NEXT:    [[W:%.*]] = load volatile i32, ptr [[Y:%.*]], align 4
193; CHECK-NEXT:    [[B:%.*]] = add i32 [[W]], [[DOT]]
194; CHECK-NEXT:    store volatile i32 [[B]], ptr [[Y]], align 4
195; CHECK-NEXT:    ret i32 1
196;
197entry:
198  br i1 %flag, label %if.then, label %if.else
199
200if.then:
201  %z = load volatile i32, ptr %y
202  %a = add i32 %z, 5
203  store volatile i32 %a, ptr %y
204  br label %if.end
205
206if.else:
207  %w = load volatile i32, ptr %y
208  %b = add i32 %w, 7
209  store volatile i32 %b, ptr %y
210  br label %if.end
211
212if.end:
213  ret i32 1
214}
215
216
217; %z and %w are in different blocks. We shouldn't sink the add because
218; there may be intervening memory instructions.
219define i32 @test8(i1 zeroext %flag, i32 %x, ptr %y) {
220; CHECK-LABEL: @test8(
221; CHECK-NEXT:  entry:
222; CHECK-NEXT:    [[Z:%.*]] = load volatile i32, ptr [[Y:%.*]], align 4
223; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
224; CHECK:       if.then:
225; CHECK-NEXT:    [[A:%.*]] = add i32 [[Z]], 5
226; CHECK-NEXT:    br label [[IF_END:%.*]]
227; CHECK:       if.else:
228; CHECK-NEXT:    [[W:%.*]] = load volatile i32, ptr [[Y]], align 4
229; CHECK-NEXT:    [[B:%.*]] = add i32 [[W]], 7
230; CHECK-NEXT:    br label [[IF_END]]
231; CHECK:       if.end:
232; CHECK-NEXT:    [[B_SINK:%.*]] = phi i32 [ [[B]], [[IF_ELSE]] ], [ [[A]], [[IF_THEN]] ]
233; CHECK-NEXT:    store volatile i32 [[B_SINK]], ptr [[Y]], align 4
234; CHECK-NEXT:    ret i32 1
235;
236entry:
237  %z = load volatile i32, ptr %y
238  br i1 %flag, label %if.then, label %if.else
239
240if.then:
241  %a = add i32 %z, 5
242  store volatile i32 %a, ptr %y
243  br label %if.end
244
245if.else:
246  %w = load volatile i32, ptr %y
247  %b = add i32 %w, 7
248  store volatile i32 %b, ptr %y
249  br label %if.end
250
251if.end:
252  ret i32 1
253}
254
255
256; The extra store in %if.then means %z and %w are not equivalent.
257define i32 @test9(i1 zeroext %flag, i32 %x, ptr %y, ptr %p) {
258; CHECK-LABEL: @test9(
259; CHECK-NEXT:  entry:
260; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
261; CHECK:       if.then:
262; CHECK-NEXT:    store i32 7, ptr [[P:%.*]], align 4
263; CHECK-NEXT:    [[Z:%.*]] = load volatile i32, ptr [[Y:%.*]], align 4
264; CHECK-NEXT:    store i32 6, ptr [[P]], align 4
265; CHECK-NEXT:    [[A:%.*]] = add i32 [[Z]], 5
266; CHECK-NEXT:    br label [[IF_END:%.*]]
267; CHECK:       if.else:
268; CHECK-NEXT:    [[W:%.*]] = load volatile i32, ptr [[Y]], align 4
269; CHECK-NEXT:    [[B:%.*]] = add i32 [[W]], 7
270; CHECK-NEXT:    br label [[IF_END]]
271; CHECK:       if.end:
272; CHECK-NEXT:    [[B_SINK:%.*]] = phi i32 [ [[B]], [[IF_ELSE]] ], [ [[A]], [[IF_THEN]] ]
273; CHECK-NEXT:    store volatile i32 [[B_SINK]], ptr [[Y]], align 4
274; CHECK-NEXT:    ret i32 1
275;
276entry:
277  br i1 %flag, label %if.then, label %if.else
278
279if.then:
280  store i32 7, ptr %p
281  %z = load volatile i32, ptr %y
282  store i32 6, ptr %p
283  %a = add i32 %z, 5
284  store volatile i32 %a, ptr %y
285  br label %if.end
286
287if.else:
288  %w = load volatile i32, ptr %y
289  %b = add i32 %w, 7
290  store volatile i32 %b, ptr %y
291  br label %if.end
292
293if.end:
294  ret i32 1
295}
296
297
298%struct.anon = type { i32, i32 }
299
300; The GEP indexes a struct type so cannot have a variable last index.
301define i32 @test10(i1 zeroext %flag, i32 %x, ptr %y, ptr %s) {
302; CHECK-LABEL: @test10(
303; CHECK-NEXT:  entry:
304; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
305; CHECK:       if.then:
306; CHECK-NEXT:    call void @bar(i32 5)
307; CHECK-NEXT:    store volatile i32 [[X:%.*]], ptr [[S:%.*]], align 4
308; CHECK-NEXT:    br label [[IF_END:%.*]]
309; CHECK:       if.else:
310; CHECK-NEXT:    call void @bar(i32 6)
311; CHECK-NEXT:    [[GEPB:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[S]], i32 0, i32 1
312; CHECK-NEXT:    store volatile i32 [[X]], ptr [[GEPB]], align 4
313; CHECK-NEXT:    br label [[IF_END]]
314; CHECK:       if.end:
315; CHECK-NEXT:    ret i32 1
316;
317entry:
318  br i1 %flag, label %if.then, label %if.else
319
320if.then:
321  call void @bar(i32 5)
322  store volatile i32 %x, ptr %s
323  br label %if.end
324
325if.else:
326  call void @bar(i32 6)
327  %gepb = getelementptr inbounds %struct.anon, ptr %s, i32 0, i32 1
328  store volatile i32 %x, ptr %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, ptr %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, ptr [[Y:%.*]], align 4
417; CHECK-NEXT:    [[B:%.*]] = add i32 [[W]], [[DOT]]
418; CHECK-NEXT:    store volatile i32 [[B]], ptr [[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, ptr %y
426  %a = add i32 %z, 5
427  store volatile i32 %a, ptr %y, !tbaa !3
428  br label %if.end
429
430if.else:
431  %w = load volatile i32, ptr %y
432  %b = add i32 %w, 7
433  store volatile i32 %b, ptr %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, ptr %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:%.*]], ptr [[S:%.*]], i32 0, i32 1
481; CHECK-NEXT:    [[SV2:%.*]] = load i32, ptr [[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, ptr %s, i32 0, i32 1
491  %sv1 = load i32, ptr %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, ptr %s, i32 0, i32 1
498  %sv2 = load i32, ptr %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 not be commoned, as it will get separated from the GEP
522; instruction producing the address.
523define i32 @test15(i1 zeroext %flag, i32 %w, i32 %x, i32 %y, ptr %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:    call void @bar(i32 1)
529; CHECK-NEXT:    [[SV1:%.*]] = load i32, ptr [[S:%.*]], align 4
530; CHECK-NEXT:    br label [[IF_END:%.*]]
531; CHECK:       if.else:
532; CHECK-NEXT:    call void @bar(i32 4)
533; CHECK-NEXT:    [[GEPB:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[S]], i32 0, i32 1
534; CHECK-NEXT:    [[SV2:%.*]] = load i32, ptr [[GEPB]], align 4
535; CHECK-NEXT:    br label [[IF_END]]
536; CHECK:       if.end:
537; CHECK-NEXT:    [[SV2_SINK:%.*]] = phi i32 [ [[SV2]], [[IF_ELSE]] ], [ [[SV1]], [[IF_THEN]] ]
538; CHECK-NEXT:    [[DOTSINK:%.*]] = phi i64 [ 57, [[IF_ELSE]] ], [ 56, [[IF_THEN]] ]
539; CHECK-NEXT:    [[EXT2:%.*]] = zext i32 [[SV2_SINK]] 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  call void @bar(i32 1)
548  %sv1 = load i32, ptr %s
549  %ext1 = zext i32 %sv1 to i64
550  %cmp1 = icmp eq i64 %ext1, 56
551  br label %if.end
552
553if.else:
554  call void @bar(i32 4)
555  %gepb = getelementptr inbounds %struct.anon, ptr %s, i32 0, i32 1
556  %sv2 = load i32, ptr %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, ptr %i4, ptr %m, ptr %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, ptr [[I4:%.*]], align 4
573; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[TMP1]], -1
574; CHECK-NEXT:    br label [[IF_END:%.*]]
575; CHECK:       if.else:
576; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[M:%.*]], align 4
577; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[N:%.*]], align 4
578; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[TMP3]], [[TMP4]]
579; CHECK-NEXT:    br label [[IF_END]]
580; CHECK:       if.end:
581; CHECK-NEXT:    [[TMP5_SINK:%.*]] = phi i32 [ [[TMP5]], [[IF_ELSE]] ], [ [[TMP2]], [[IF_THEN]] ]
582; CHECK-NEXT:    store i32 [[TMP5_SINK]], ptr [[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, ptr %i4
590  %tmp2 = add i32 %tmp1, -1
591  store i32 %tmp2, ptr %i4
592  br label %if.end
593
594if.else:
595  %tmp3 = load i32, ptr %m
596  %tmp4 = load i32, ptr %n
597  %tmp5 = add i32 %tmp3, %tmp4
598  store i32 %tmp5, ptr %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, ptr %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]], ptr [[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, ptr %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, ptr %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:    [[Y_Z:%.*]] = select i1 [[FLAG:%.*]], ptr [[Y]], ptr [[Z]]
807; CHECK-NEXT:    store i32 [[X:%.*]], ptr [[Y_Z]], align 4
808; CHECK-NEXT:    ret i32 1
809;
810entry:
811  %y = alloca i32
812  %z = alloca i32
813  br i1 %flag, label %if.then, label %if.else
814
815if.then:
816  store i32 %x, ptr %y
817  br label %if.end
818
819if.else:
820  store i32 %x, ptr %z
821  br label %if.end
822
823if.end:
824  ret i32 1
825}
826
827
828define i32 @test_pr30188a(i1 zeroext %flag, i32 %x) {
829; CHECK-LABEL: @test_pr30188a(
830; CHECK-NEXT:  entry:
831; CHECK-NEXT:    [[Y:%.*]] = alloca i32, align 4
832; CHECK-NEXT:    [[Z:%.*]] = alloca i32, align 4
833; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
834; CHECK:       if.then:
835; CHECK-NEXT:    call void @g()
836; CHECK-NEXT:    br label [[IF_END]]
837; CHECK:       if.end:
838; CHECK-NEXT:    [[Z_SINK:%.*]] = phi ptr [ [[Y]], [[IF_THEN]] ], [ [[Z]], [[ENTRY:%.*]] ]
839; CHECK-NEXT:    [[THREE:%.*]] = load i32, ptr [[Z_SINK]], align 4
840; CHECK-NEXT:    [[FOUR:%.*]] = add i32 [[THREE]], 2
841; CHECK-NEXT:    store i32 [[FOUR]], ptr [[Y]], align 4
842; CHECK-NEXT:    ret i32 1
843;
844entry:
845  %y = alloca i32
846  %z = alloca i32
847  br i1 %flag, label %if.then, label %if.else
848
849if.then:
850  call void @g()
851  %one = load i32, ptr %y
852  %two = add i32 %one, 2
853  store i32 %two, ptr %y
854  br label %if.end
855
856if.else:
857  %three = load i32, ptr %z
858  %four = add i32 %three, 2
859  store i32 %four, ptr %y
860  br label %if.end
861
862if.end:
863  ret i32 1
864}
865
866
867; The phi is confusing - both add instructions are used by it, but
868; not on their respective unconditional arcs. It should not be
869; optimized.
870define void @test_pr30292(i1 %cond, i1 %cond2, i32 %a, i32 %b) {
871; CHECK-LABEL: @test_pr30292(
872; CHECK-NEXT:  entry:
873; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A:%.*]], 1
874; CHECK-NEXT:    br label [[SUCC:%.*]]
875; CHECK:       two:
876; CHECK-NEXT:    call void @g()
877; CHECK-NEXT:    [[ADD2:%.*]] = add i32 [[A]], 1
878; CHECK-NEXT:    br label [[SUCC]]
879; CHECK:       succ:
880; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD1]], [[SUCC]] ], [ [[ADD2]], [[TWO:%.*]] ]
881; CHECK-NEXT:    br i1 [[COND:%.*]], label [[TWO]], label [[SUCC]]
882;
883entry:
884  %add1 = add i32 %a, 1
885  br label %succ
886
887one:
888  br i1 %cond, label %two, label %succ
889
890two:
891  call void @g()
892  %add2 = add i32 %a, 1
893  br label %succ
894
895succ:
896  %p = phi i32 [ 0, %entry ], [ %add1, %one ], [ %add2, %two ]
897  br label %one
898}
899declare void @g()
900
901
902define zeroext i1 @test_pr30244(i1 zeroext %flag, i1 zeroext %flag2, i32 %blksA, i32 %blksB, i32 %nblks) {
903; CHECK-LABEL: @test_pr30244(
904; CHECK-NEXT:  entry:
905; CHECK-NEXT:    [[P:%.*]] = alloca i8, align 1
906; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
907; CHECK:       if.then:
908; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[BLKSA:%.*]], [[NBLKS:%.*]]
909; CHECK-NEXT:    br label [[IF_END_SINK_SPLIT:%.*]]
910; CHECK:       if.else:
911; CHECK-NEXT:    br i1 [[FLAG2:%.*]], label [[IF_THEN2:%.*]], label [[IF_END:%.*]]
912; CHECK:       if.then2:
913; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[NBLKS]], [[BLKSB:%.*]]
914; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i32 [[ADD]], [[BLKSA]]
915; CHECK-NEXT:    br label [[IF_END_SINK_SPLIT]]
916; CHECK:       if.end.sink.split:
917; CHECK-NEXT:    [[CMP2_SINK:%.*]] = phi i1 [ [[CMP2]], [[IF_THEN2]] ], [ [[CMP]], [[IF_THEN]] ]
918; CHECK-NEXT:    [[FROMBOOL3:%.*]] = zext i1 [[CMP2_SINK]] to i8
919; CHECK-NEXT:    store i8 [[FROMBOOL3]], ptr [[P]], align 1
920; CHECK-NEXT:    br label [[IF_END]]
921; CHECK:       if.end:
922; CHECK-NEXT:    ret i1 true
923;
924entry:
925  %p = alloca i8
926  br i1 %flag, label %if.then, label %if.else
927
928if.then:
929  %cmp = icmp uge i32 %blksA, %nblks
930  %frombool1 = zext i1 %cmp to i8
931  store i8 %frombool1, ptr %p
932  br label %if.end
933
934if.else:
935  br i1 %flag2, label %if.then2, label %if.end
936
937if.then2:
938  %add = add i32 %nblks, %blksB
939  %cmp2 = icmp ule i32 %add, %blksA
940  %frombool3 = zext i1 %cmp2 to i8
941  store i8 %frombool3, ptr %p
942  br label %if.end
943
944if.end:
945  ret i1 true
946}
947
948
949define i32 @test_pr30373a(i1 zeroext %flag, i32 %x, i32 %y) {
950; CHECK-LABEL: @test_pr30373a(
951; CHECK-NEXT:  entry:
952; CHECK-NEXT:    [[X_Y:%.*]] = select i1 [[FLAG:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]
953; CHECK-NEXT:    [[X1:%.*]] = call i32 @foo(i32 [[X_Y]], i32 0) #[[ATTR0]]
954; CHECK-NEXT:    [[Y1:%.*]] = call i32 @foo(i32 [[X_Y]], i32 1) #[[ATTR0]]
955; CHECK-NEXT:    [[Z1:%.*]] = lshr i32 [[Y1]], 8
956; CHECK-NEXT:    [[RET:%.*]] = add i32 [[X1]], [[Z1]]
957; CHECK-NEXT:    ret i32 [[RET]]
958;
959entry:
960  br i1 %flag, label %if.then, label %if.else
961
962if.then:
963  %x0 = call i32 @foo(i32 %x, i32 0) nounwind readnone
964  %y0 = call i32 @foo(i32 %x, i32 1) nounwind readnone
965  %z0 = lshr i32 %y0, 8
966  br label %if.end
967
968if.else:
969  %x1 = call i32 @foo(i32 %y, i32 0) nounwind readnone
970  %y1 = call i32 @foo(i32 %y, i32 1) nounwind readnone
971  %z1 = lshr exact i32 %y1, 8
972  br label %if.end
973
974if.end:
975  %xx = phi i32 [ %x0, %if.then ], [ %x1, %if.else ]
976  %yy = phi i32 [ %z0, %if.then ], [ %z1, %if.else ]
977  %ret = add i32 %xx, %yy
978  ret i32 %ret
979}
980
981
982define i32 @test_pr30373b(i1 zeroext %flag, i32 %x, i32 %y) {
983; CHECK-LABEL: @test_pr30373b(
984; CHECK-NEXT:  entry:
985; CHECK-NEXT:    [[X_Y:%.*]] = select i1 [[FLAG:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]
986; CHECK-NEXT:    [[X1:%.*]] = call i32 @foo(i32 [[X_Y]], i32 0) #[[ATTR0]]
987; CHECK-NEXT:    [[Y1:%.*]] = call i32 @foo(i32 [[X_Y]], i32 1) #[[ATTR0]]
988; CHECK-NEXT:    [[Z1:%.*]] = lshr i32 [[Y1]], 8
989; CHECK-NEXT:    [[RET:%.*]] = add i32 [[X1]], [[Z1]]
990; CHECK-NEXT:    ret i32 [[RET]]
991;
992entry:
993  br i1 %flag, label %if.then, label %if.else
994
995if.then:
996  %x0 = call i32 @foo(i32 %x, i32 0) nounwind readnone
997  %y0 = call i32 @foo(i32 %x, i32 1) nounwind readnone
998  %z0 = lshr exact i32 %y0, 8
999  br label %if.end
1000
1001if.else:
1002  %x1 = call i32 @foo(i32 %y, i32 0) nounwind readnone
1003  %y1 = call i32 @foo(i32 %y, i32 1) nounwind readnone
1004  %z1 = lshr i32 %y1, 8
1005  br label %if.end
1006
1007if.end:
1008  %xx = phi i32 [ %x0, %if.then ], [ %x1, %if.else ]
1009  %yy = phi i32 [ %z0, %if.then ], [ %z1, %if.else ]
1010  %ret = add i32 %xx, %yy
1011  ret i32 %ret
1012}
1013
1014
1015
1016; FIXME:  Should turn into select
1017define float @allow_intrinsic_remove_constant(i1 zeroext %flag, float %w, float %x, float %y) {
1018; CHECK-LABEL: @allow_intrinsic_remove_constant(
1019; CHECK-NEXT:  entry:
1020; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1021; CHECK:       if.then:
1022; CHECK-NEXT:    [[DUMMY:%.*]] = fadd float [[W:%.*]], 4.000000e+00
1023; CHECK-NEXT:    [[SV1:%.*]] = call float @llvm.fma.f32(float [[DUMMY]], float 2.000000e+00, float 1.000000e+00)
1024; CHECK-NEXT:    br label [[IF_END:%.*]]
1025; CHECK:       if.else:
1026; CHECK-NEXT:    [[DUMMY1:%.*]] = fadd float [[W]], 8.000000e+00
1027; CHECK-NEXT:    [[SV2:%.*]] = call float @llvm.fma.f32(float 2.000000e+00, float [[DUMMY1]], float 1.000000e+00)
1028; CHECK-NEXT:    br label [[IF_END]]
1029; CHECK:       if.end:
1030; CHECK-NEXT:    [[P:%.*]] = phi float [ [[SV1]], [[IF_THEN]] ], [ [[SV2]], [[IF_ELSE]] ]
1031; CHECK-NEXT:    ret float [[P]]
1032;
1033entry:
1034  br i1 %flag, label %if.then, label %if.else
1035
1036if.then:
1037  %dummy = fadd float %w, 4.0
1038  %sv1 = call float @llvm.fma.f32(float %dummy, float 2.0, float 1.0)
1039  br label %if.end
1040
1041if.else:
1042  %dummy1 = fadd float %w, 8.0
1043  %sv2 = call float @llvm.fma.f32(float 2.0, float %dummy1, float 1.0)
1044  br label %if.end
1045
1046if.end:
1047  %p = phi float [ %sv1, %if.then ], [ %sv2, %if.else ]
1048  ret float %p
1049}
1050
1051declare float @llvm.fma.f32(float, float, float)
1052
1053define i32 @no_remove_constant_immarg(i1 zeroext %flag, i32 %w, i32 %x, i32 %y) {
1054; CHECK-LABEL: @no_remove_constant_immarg(
1055; CHECK-NEXT:  entry:
1056; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1057; CHECK:       if.then:
1058; CHECK-NEXT:    [[DUMMY:%.*]] = add i32 [[W:%.*]], 5
1059; CHECK-NEXT:    [[SV1:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X:%.*]], i1 true)
1060; CHECK-NEXT:    br label [[IF_END:%.*]]
1061; CHECK:       if.else:
1062; CHECK-NEXT:    [[DUMMY1:%.*]] = add i32 [[W]], 6
1063; CHECK-NEXT:    [[SV2:%.*]] = call i32 @llvm.ctlz.i32(i32 [[X]], i1 false)
1064; CHECK-NEXT:    br label [[IF_END]]
1065; CHECK:       if.end:
1066; CHECK-NEXT:    [[P:%.*]] = phi i32 [ [[SV1]], [[IF_THEN]] ], [ [[SV2]], [[IF_ELSE]] ]
1067; CHECK-NEXT:    ret i32 1
1068;
1069entry:
1070  br i1 %flag, label %if.then, label %if.else
1071
1072if.then:
1073  %dummy = add i32 %w, 5
1074  %sv1 = call i32 @llvm.ctlz.i32(i32 %x, i1 true)
1075  br label %if.end
1076
1077if.else:
1078  %dummy1 = add i32 %w, 6
1079  %sv2 = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
1080  br label %if.end
1081
1082if.end:
1083  %p = phi i32 [ %sv1, %if.then ], [ %sv2, %if.else ]
1084  ret i32 1
1085}
1086
1087declare void @llvm.memcpy.p1.p1.i64(ptr addrspace(1) nocapture, ptr addrspace(1) nocapture readonly, i64, i1)
1088
1089; Make sure a memcpy size isn't replaced with a variable
1090define void @no_replace_memcpy_size(i1 zeroext %flag, ptr addrspace(1) %dst, ptr addrspace(1) %src) {
1091; CHECK-LABEL: @no_replace_memcpy_size(
1092; CHECK-NEXT:  entry:
1093; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1094; CHECK:       if.then:
1095; CHECK-NEXT:    call void @llvm.memcpy.p1.p1.i64(ptr addrspace(1) [[DST:%.*]], ptr addrspace(1) [[SRC:%.*]], i64 1024, i1 false)
1096; CHECK-NEXT:    br label [[IF_END:%.*]]
1097; CHECK:       if.else:
1098; CHECK-NEXT:    call void @llvm.memcpy.p1.p1.i64(ptr addrspace(1) [[DST]], ptr addrspace(1) [[SRC]], i64 4096, i1 false)
1099; CHECK-NEXT:    br label [[IF_END]]
1100; CHECK:       if.end:
1101; CHECK-NEXT:    ret void
1102;
1103entry:
1104  br i1 %flag, label %if.then, label %if.else
1105
1106if.then:
1107  call void @llvm.memcpy.p1.p1.i64(ptr addrspace(1) %dst, ptr addrspace(1) %src, i64 1024, i1 false)
1108  br label %if.end
1109
1110if.else:
1111  call void @llvm.memcpy.p1.p1.i64(ptr addrspace(1) %dst, ptr addrspace(1) %src, i64 4096, i1 false)
1112  br label %if.end
1113
1114if.end:
1115  ret void
1116}
1117
1118declare void @llvm.memmove.p1.p1.i64(ptr addrspace(1) nocapture, ptr addrspace(1) nocapture readonly, i64, i1)
1119
1120; Make sure a memmove size isn't replaced with a variable
1121define void @no_replace_memmove_size(i1 zeroext %flag, ptr addrspace(1) %dst, ptr addrspace(1) %src) {
1122; CHECK-LABEL: @no_replace_memmove_size(
1123; CHECK-NEXT:  entry:
1124; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1125; CHECK:       if.then:
1126; CHECK-NEXT:    call void @llvm.memmove.p1.p1.i64(ptr addrspace(1) [[DST:%.*]], ptr addrspace(1) [[SRC:%.*]], i64 1024, i1 false)
1127; CHECK-NEXT:    br label [[IF_END:%.*]]
1128; CHECK:       if.else:
1129; CHECK-NEXT:    call void @llvm.memmove.p1.p1.i64(ptr addrspace(1) [[DST]], ptr addrspace(1) [[SRC]], i64 4096, i1 false)
1130; CHECK-NEXT:    br label [[IF_END]]
1131; CHECK:       if.end:
1132; CHECK-NEXT:    ret void
1133;
1134entry:
1135  br i1 %flag, label %if.then, label %if.else
1136
1137if.then:
1138  call void @llvm.memmove.p1.p1.i64(ptr addrspace(1) %dst, ptr addrspace(1) %src, i64 1024, i1 false)
1139  br label %if.end
1140
1141if.else:
1142  call void @llvm.memmove.p1.p1.i64(ptr addrspace(1) %dst, ptr addrspace(1) %src, i64 4096, i1 false)
1143  br label %if.end
1144
1145if.end:
1146  ret void
1147}
1148
1149declare void @llvm.memset.p1.i64(ptr addrspace(1) nocapture, i8, i64, i1)
1150
1151; Make sure a memset size isn't replaced with a variable
1152define void @no_replace_memset_size(i1 zeroext %flag, ptr addrspace(1) %dst) {
1153; CHECK-LABEL: @no_replace_memset_size(
1154; CHECK-NEXT:  entry:
1155; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1156; CHECK:       if.then:
1157; CHECK-NEXT:    call void @llvm.memset.p1.i64(ptr addrspace(1) [[DST:%.*]], i8 0, i64 1024, i1 false)
1158; CHECK-NEXT:    br label [[IF_END:%.*]]
1159; CHECK:       if.else:
1160; CHECK-NEXT:    call void @llvm.memset.p1.i64(ptr addrspace(1) [[DST]], i8 0, i64 4096, i1 false)
1161; CHECK-NEXT:    br label [[IF_END]]
1162; CHECK:       if.end:
1163; CHECK-NEXT:    ret void
1164;
1165entry:
1166  br i1 %flag, label %if.then, label %if.else
1167
1168if.then:
1169  call void @llvm.memset.p1.i64(ptr addrspace(1) %dst, i8 0, i64 1024, i1 false)
1170  br label %if.end
1171
1172if.else:
1173  call void @llvm.memset.p1.i64(ptr addrspace(1) %dst, i8 0, i64 4096, i1 false)
1174  br label %if.end
1175
1176if.end:
1177  ret void
1178}
1179
1180; Check that simplifycfg doesn't sink and merge inline-asm instructions.
1181
1182define i32 @test_inline_asm1(i32 %c, i32 %r6) {
1183; CHECK-LABEL: @test_inline_asm1(
1184; CHECK-NEXT:  entry:
1185; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[C:%.*]], 0
1186; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
1187; CHECK:       if.then:
1188; CHECK-NEXT:    [[TMP0:%.*]] = call i32 asm "rorl $2, $0", "=&r,0,n,~{dirflag},~{fpsr},~{flags}"(i32 [[R6:%.*]], i32 8)
1189; CHECK-NEXT:    br label [[IF_END:%.*]]
1190; CHECK:       if.else:
1191; CHECK-NEXT:    [[TMP1:%.*]] = call i32 asm "rorl $2, $0", "=&r,0,n,~{dirflag},~{fpsr},~{flags}"(i32 [[R6]], i32 6)
1192; CHECK-NEXT:    br label [[IF_END]]
1193; CHECK:       if.end:
1194; CHECK-NEXT:    [[R6_ADDR_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN]] ], [ [[TMP1]], [[IF_ELSE]] ]
1195; CHECK-NEXT:    ret i32 [[R6_ADDR_0]]
1196;
1197entry:
1198  %tobool = icmp eq i32 %c, 0
1199  br i1 %tobool, label %if.else, label %if.then
1200
1201if.then:
1202  %0 = call i32 asm "rorl $2, $0", "=&r,0,n,~{dirflag},~{fpsr},~{flags}"(i32 %r6, i32 8)
1203  br label %if.end
1204
1205if.else:
1206  %1 = call i32 asm "rorl $2, $0", "=&r,0,n,~{dirflag},~{fpsr},~{flags}"(i32 %r6, i32 6)
1207  br label %if.end
1208
1209if.end:
1210  %r6.addr.0 = phi i32 [ %0, %if.then ], [ %1, %if.else ]
1211  ret i32 %r6.addr.0
1212}
1213
1214
1215declare i32 @call_target()
1216
1217define void @test_operand_bundles(i1 %cond, ptr %ptr) {
1218; CHECK-LABEL: @test_operand_bundles(
1219; CHECK-NEXT:  entry:
1220; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
1221; CHECK:       left:
1222; CHECK-NEXT:    [[VAL0:%.*]] = call i32 @call_target() [ "deopt"(i32 10) ]
1223; CHECK-NEXT:    br label [[MERGE:%.*]]
1224; CHECK:       right:
1225; CHECK-NEXT:    [[VAL1:%.*]] = call i32 @call_target() [ "deopt"(i32 20) ]
1226; CHECK-NEXT:    br label [[MERGE]]
1227; CHECK:       merge:
1228; CHECK-NEXT:    [[VAL1_SINK:%.*]] = phi i32 [ [[VAL1]], [[RIGHT]] ], [ [[VAL0]], [[LEFT]] ]
1229; CHECK-NEXT:    store i32 [[VAL1_SINK]], ptr [[PTR:%.*]], align 4
1230; CHECK-NEXT:    ret void
1231;
1232entry:
1233  br i1 %cond, label %left, label %right
1234
1235left:
1236  %val0 = call i32 @call_target() [ "deopt"(i32 10) ]
1237  store i32 %val0, ptr %ptr
1238  br label %merge
1239
1240right:
1241  %val1 = call i32 @call_target() [ "deopt"(i32 20) ]
1242  store i32 %val1, ptr %ptr
1243  br label %merge
1244
1245merge:
1246  ret void
1247}
1248
1249
1250%TP = type {i32, i32}
1251
1252define i32 @test_insertvalue(i1 zeroext %flag, %TP %P) {
1253; CHECK-LABEL: @test_insertvalue(
1254; CHECK-NEXT:  entry:
1255; CHECK-NEXT:    [[DOT:%.*]] = select i1 [[FLAG:%.*]], i32 0, i32 1
1256; CHECK-NEXT:    [[I2:%.*]] = insertvalue [[TP:%.*]] [[P:%.*]], i32 [[DOT]], 0
1257; CHECK-NEXT:    ret i32 1
1258;
1259entry:
1260  br i1 %flag, label %if.then, label %if.else
1261
1262if.then:
1263  %i1 = insertvalue %TP %P, i32 0, 0
1264  br label %if.end
1265
1266if.else:
1267  %i2 = insertvalue %TP %P, i32 1, 0
1268  br label %if.end
1269
1270if.end:
1271  %i = phi %TP [%i1, %if.then], [%i2, %if.else]
1272  ret i32 1
1273}
1274
1275
1276
1277declare void @baz(i32)
1278
1279define void @test_sink_void_calls(i32 %x) {
1280; CHECK-LABEL: @test_sink_void_calls(
1281; CHECK-NEXT:  entry:
1282; CHECK-NEXT:    switch i32 [[X:%.*]], label [[DEFAULT:%.*]] [
1283; CHECK-NEXT:      i32 0, label [[RETURN:%.*]]
1284; CHECK-NEXT:      i32 1, label [[BB1:%.*]]
1285; CHECK-NEXT:      i32 2, label [[BB2:%.*]]
1286; CHECK-NEXT:      i32 3, label [[BB3:%.*]]
1287; CHECK-NEXT:      i32 4, label [[BB4:%.*]]
1288; CHECK-NEXT:    ]
1289; CHECK:       bb1:
1290; CHECK-NEXT:    br label [[RETURN]]
1291; CHECK:       bb2:
1292; CHECK-NEXT:    br label [[RETURN]]
1293; CHECK:       bb3:
1294; CHECK-NEXT:    br label [[RETURN]]
1295; CHECK:       bb4:
1296; CHECK-NEXT:    br label [[RETURN]]
1297; CHECK:       default:
1298; CHECK-NEXT:    unreachable
1299; CHECK:       return:
1300; CHECK-NEXT:    [[DOTSINK:%.*]] = phi i32 [ 90, [[BB4]] ], [ 78, [[BB3]] ], [ 56, [[BB2]] ], [ 34, [[BB1]] ], [ 12, [[ENTRY:%.*]] ]
1301; CHECK-NEXT:    call void @baz(i32 [[DOTSINK]])
1302; CHECK-NEXT:    ret void
1303;
1304entry:
1305  switch i32 %x, label %default [
1306  i32 0, label %bb0
1307  i32 1, label %bb1
1308  i32 2, label %bb2
1309  i32 3, label %bb3
1310  i32 4, label %bb4
1311  ]
1312bb0:
1313  call void @baz(i32 12)
1314  br label %return
1315bb1:
1316  call void @baz(i32 34)
1317  br label %return
1318bb2:
1319  call void @baz(i32 56)
1320  br label %return
1321bb3:
1322  call void @baz(i32 78)
1323  br label %return
1324bb4:
1325  call void @baz(i32 90)
1326  br label %return
1327default:
1328  unreachable
1329return:
1330  ret void
1331
1332; Check that the calls get sunk to the return block.
1333; We would previously not sink calls without uses, see PR41259.
1334}
1335
1336define i32 @test_not_sink_lifetime_marker(i1 zeroext %flag, i32 %x) {
1337; CHECK-LABEL: @test_not_sink_lifetime_marker(
1338; CHECK-NEXT:  entry:
1339; CHECK-NEXT:    [[Y:%.*]] = alloca i32, align 4
1340; CHECK-NEXT:    [[Z:%.*]] = alloca i32, align 4
1341; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1342; CHECK:       if.then:
1343; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[Y]])
1344; CHECK-NEXT:    br label [[IF_END:%.*]]
1345; CHECK:       if.else:
1346; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[Z]])
1347; CHECK-NEXT:    br label [[IF_END]]
1348; CHECK:       if.end:
1349; CHECK-NEXT:    ret i32 1
1350;
1351entry:
1352  %y = alloca i32
1353  %z = alloca i32
1354  br i1 %flag, label %if.then, label %if.else
1355
1356if.then:
1357  call void @llvm.lifetime.end.p0(i64 4, ptr %y)
1358  br label %if.end
1359
1360if.else:
1361  call void @llvm.lifetime.end.p0(i64 4, ptr %z)
1362  br label %if.end
1363
1364if.end:
1365  ret i32 1
1366}
1367
1368define void @direct_caller(i1 %c) {
1369; CHECK-LABEL: @direct_caller(
1370; CHECK-NEXT:    br i1 [[C:%.*]], label [[CALL_FOO:%.*]], label [[CALL_BAR:%.*]]
1371; CHECK:       call_foo:
1372; CHECK-NEXT:    call void @direct_callee()
1373; CHECK-NEXT:    br label [[END:%.*]]
1374; CHECK:       call_bar:
1375; CHECK-NEXT:    call void @direct_callee2()
1376; CHECK-NEXT:    br label [[END]]
1377; CHECK:       end:
1378; CHECK-NEXT:    ret void
1379;
1380  br i1 %c, label %call_foo, label %call_bar
1381
1382call_foo:
1383  call void @direct_callee()
1384  br label %end
1385
1386call_bar:
1387  call void @direct_callee2()
1388  br label %end
1389
1390end:
1391  ret void
1392}
1393
1394define void @indirect_caller(i1 %c, i32 %v, ptr %foo, ptr %bar) {
1395; CHECK-LABEL: @indirect_caller(
1396; CHECK-NEXT:  end:
1397; CHECK-NEXT:    [[FOO_BAR:%.*]] = select i1 [[C:%.*]], ptr [[FOO:%.*]], ptr [[BAR:%.*]]
1398; CHECK-NEXT:    tail call void [[FOO_BAR]](i32 [[V:%.*]])
1399; CHECK-NEXT:    ret void
1400;
1401  br i1 %c, label %call_foo, label %call_bar
1402
1403call_foo:
1404  tail call void %foo(i32 %v)
1405  br label %end
1406
1407call_bar:
1408  tail call void %bar(i32 %v)
1409  br label %end
1410
1411end:
1412  ret void
1413}
1414
1415define void @maybe_indirect_caller(ptr %fun) {
1416; CHECK-LABEL: @maybe_indirect_caller(
1417; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[FUN:%.*]], @direct_callee
1418; CHECK-NEXT:    br i1 [[C]], label [[IF_TRUE_DIRECT_TARG:%.*]], label [[IF_FALSE_ORIG_INDIRECT:%.*]]
1419; CHECK:       if.true.direct_targ:
1420; CHECK-NEXT:    tail call void @direct_callee()
1421; CHECK-NEXT:    br label [[IF_END_ICP:%.*]]
1422; CHECK:       if.false.orig_indirect:
1423; CHECK-NEXT:    tail call void [[FUN]]()
1424; CHECK-NEXT:    br label [[IF_END_ICP]]
1425; CHECK:       if.end.icp:
1426; CHECK-NEXT:    ret void
1427;
1428  %c = icmp eq ptr %fun, @direct_callee
1429  br i1 %c, label %if.true.direct_targ, label %if.false.orig_indirect
1430
1431if.true.direct_targ:
1432  tail call void @direct_callee()
1433  br label %if.end.icp
1434
1435if.false.orig_indirect:
1436  tail call void %fun()
1437  br label %if.end.icp
1438
1439if.end.icp:
1440  ret void
1441}
1442define void @maybe_indirect_caller2(ptr %fun) {
1443; CHECK-LABEL: @maybe_indirect_caller2(
1444; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[FUN:%.*]], @direct_callee
1445; CHECK-NEXT:    br i1 [[C]], label [[IF_TRUE_DIRECT_TARG:%.*]], label [[IF_FALSE_ORIG_INDIRECT:%.*]]
1446; CHECK:       if.false.orig_indirect:
1447; CHECK-NEXT:    tail call void [[FUN]]()
1448; CHECK-NEXT:    br label [[IF_END_ICP:%.*]]
1449; CHECK:       if.true.direct_targ:
1450; CHECK-NEXT:    tail call void @direct_callee()
1451; CHECK-NEXT:    br label [[IF_END_ICP]]
1452; CHECK:       if.end.icp:
1453; CHECK-NEXT:    ret void
1454;
1455  %c = icmp eq ptr %fun, @direct_callee
1456  br i1 %c, label %if.true.direct_targ, label %if.false.orig_indirect
1457
1458if.false.orig_indirect:
1459  tail call void %fun()
1460  br label %if.end.icp
1461
1462if.true.direct_targ:
1463  tail call void @direct_callee()
1464  br label %if.end.icp
1465
1466if.end.icp:
1467  ret void
1468}
1469declare void @direct_callee()
1470declare void @direct_callee2()
1471declare void @direct_callee3()
1472
1473declare void @llvm.lifetime.start.p0(i64, ptr nocapture)
1474declare void @llvm.lifetime.end.p0(i64, ptr nocapture)
1475
1476define void @creating_too_many_phis(i1 %cond, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) {
1477; CHECK-LABEL: @creating_too_many_phis(
1478; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]
1479; CHECK:       bb0:
1480; CHECK-NEXT:    [[V0:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
1481; CHECK-NEXT:    [[V1:%.*]] = add i32 [[V0]], [[C:%.*]]
1482; CHECK-NEXT:    [[V2:%.*]] = add i32 [[D:%.*]], [[E:%.*]]
1483; CHECK-NEXT:    [[R3:%.*]] = add i32 [[V1]], [[V2]]
1484; CHECK-NEXT:    br label [[END:%.*]]
1485; CHECK:       bb1:
1486; CHECK-NEXT:    [[V4:%.*]] = add i32 [[A]], [[B]]
1487; CHECK-NEXT:    [[V5:%.*]] = add i32 [[V4]], [[C]]
1488; CHECK-NEXT:    [[V6:%.*]] = add i32 [[G:%.*]], [[H:%.*]]
1489; CHECK-NEXT:    [[R7:%.*]] = add i32 [[V5]], [[V6]]
1490; CHECK-NEXT:    br label [[END]]
1491; CHECK:       end:
1492; CHECK-NEXT:    [[R7_SINK:%.*]] = phi i32 [ [[R7]], [[BB1]] ], [ [[R3]], [[BB0]] ]
1493; CHECK-NEXT:    call void @use32(i32 [[R7_SINK]])
1494; CHECK-NEXT:    ret void
1495;
1496  br i1 %cond, label %bb0, label %bb1
1497
1498bb0:
1499  %v0 = add i32 %a, %b
1500  %v1 = add i32 %v0, %c
1501  %v2 = add i32 %d, %e
1502  %r3 = add i32 %v1, %v2
1503  call void @use32(i32 %r3)
1504  br label %end
1505
1506bb1:
1507  %v4 = add i32 %a, %b
1508  %v5 = add i32 %v4, %c
1509  %v6 = add i32 %g, %h
1510  %r7 = add i32 %v5, %v6
1511  call void @use32(i32 %r7)
1512  br label %end
1513
1514end:
1515  ret void
1516}
1517declare void @use32(i32)
1518
1519define void @multiple_cond_preds(i1 %c0, i1 %c1, i1 %c2) {
1520; CHECK-LABEL: @multiple_cond_preds(
1521; CHECK-NEXT:  dispatch0:
1522; CHECK-NEXT:    br i1 [[C0:%.*]], label [[DISPATCH1:%.*]], label [[DISPATCH2:%.*]]
1523; CHECK:       dispatch1:
1524; CHECK-NEXT:    call void @direct_callee2()
1525; CHECK-NEXT:    br i1 [[C1:%.*]], label [[END_SINK_SPLIT:%.*]], label [[END:%.*]]
1526; CHECK:       dispatch2:
1527; CHECK-NEXT:    call void @direct_callee3()
1528; CHECK-NEXT:    br i1 [[C2:%.*]], label [[END_SINK_SPLIT]], label [[END]]
1529; CHECK:       end.sink.split:
1530; CHECK-NEXT:    call void @direct_callee()
1531; CHECK-NEXT:    br label [[END]]
1532; CHECK:       end:
1533; CHECK-NEXT:    ret void
1534;
1535dispatch0:
1536  br i1 %c0, label %dispatch1, label %dispatch2
1537
1538dispatch1:
1539  call void @direct_callee2()
1540  br i1 %c1, label %uncond_pred0, label %end
1541
1542dispatch2:
1543  call void @direct_callee3()
1544  br i1 %c2, label %uncond_pred1, label %end
1545
1546uncond_pred0:
1547  call void @direct_callee()
1548  br label %end
1549
1550uncond_pred1:
1551  call void @direct_callee()
1552  br label %end
1553
1554end:
1555  ret void
1556}
1557
1558define void @nontemporal(ptr %ptr, i1 %cond) {
1559; CHECK-LABEL: @nontemporal(
1560; CHECK-NEXT:  entry:
1561; CHECK-NEXT:    store i64 0, ptr [[PTR:%.*]], align 8, !nontemporal [[META7:![0-9]+]]
1562; CHECK-NEXT:    ret void
1563;
1564entry:
1565  br i1 %cond, label %if.then, label %if.else
1566
1567if.then:
1568  store i64 0, ptr %ptr, align 8, !nontemporal !12
1569  br label %if.end
1570
1571if.else:
1572  store i64 0, ptr %ptr, align 8, !nontemporal !12
1573  br label %if.end
1574
1575if.end:
1576  ret void
1577}
1578
1579define void @nontemporal_mismatch(ptr %ptr, i1 %cond) {
1580; CHECK-LABEL: @nontemporal_mismatch(
1581; CHECK-NEXT:  entry:
1582; CHECK-NEXT:    store i64 0, ptr [[PTR:%.*]], align 8
1583; CHECK-NEXT:    ret void
1584;
1585entry:
1586  br i1 %cond, label %if.then, label %if.else
1587
1588if.then:
1589  store i64 0, ptr %ptr, align 8, !nontemporal !12
1590  br label %if.end
1591
1592if.else:
1593  store i64 0, ptr %ptr, align 8
1594  br label %if.end
1595
1596if.end:
1597  ret void
1598}
1599
1600define void @loop_use_in_different_bb(i32 %n) {
1601; CHECK-LABEL: @loop_use_in_different_bb(
1602; CHECK-NEXT:  entry:
1603; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[N:%.*]], 1
1604; CHECK-NEXT:    br label [[FOR_COND:%.*]]
1605; CHECK:       for.cond:
1606; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
1607; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[IV]], [[ADD]]
1608; CHECK-NEXT:    br i1 [[EXITCOND]], label [[RETURN:%.*]], label [[FOR_BODY]]
1609; CHECK:       for.body:
1610; CHECK-NEXT:    [[INC]] = add i32 [[IV]], 1
1611; CHECK-NEXT:    br label [[FOR_COND]]
1612; CHECK:       return:
1613; CHECK-NEXT:    ret void
1614;
1615entry:
1616  %add = add i32 %n, 1
1617  br label %for.cond
1618
1619for.cond:
1620  %iv = phi i32 [ 0, %entry ], [ %inc, %for.body ]
1621  %exitcond = icmp eq i32 %iv, %add
1622  br i1 %exitcond, label %return, label %for.body
1623
1624for.body:
1625  %inc = add i32 %iv, 1
1626  br label %for.cond
1627
1628return:
1629  ret void
1630}
1631
1632define void @loop_use_in_different_bb_phi(i32 %n) {
1633; CHECK-LABEL: @loop_use_in_different_bb_phi(
1634; CHECK-NEXT:  entry:
1635; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[N:%.*]], 1
1636; CHECK-NEXT:    br label [[FOR_COND:%.*]]
1637; CHECK:       for.cond:
1638; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
1639; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[IV]], 42
1640; CHECK-NEXT:    br i1 [[EXITCOND]], label [[RETURN:%.*]], label [[FOR_BODY]]
1641; CHECK:       for.body:
1642; CHECK-NEXT:    [[DUMMY:%.*]] = phi i32 [ [[ADD]], [[FOR_COND]] ]
1643; CHECK-NEXT:    [[INC]] = add i32 [[IV]], 1
1644; CHECK-NEXT:    br label [[FOR_COND]]
1645; CHECK:       return:
1646; CHECK-NEXT:    ret void
1647;
1648entry:
1649  %add = add i32 %n, 1
1650  br label %for.cond
1651
1652for.cond:
1653  %iv = phi i32 [ 0, %entry ], [ %inc, %for.body ]
1654  %exitcond = icmp eq i32 %iv, 42
1655  br i1 %exitcond, label %return, label %for.body
1656
1657for.body:
1658  %dummy = phi i32 [ %add, %for.cond ]
1659  %inc = add i32 %iv, 1
1660  br label %for.cond
1661
1662return:
1663  ret void
1664}
1665
1666define void @loop_use_in_wrong_phi_operand(i32 %n) {
1667; CHECK-LABEL: @loop_use_in_wrong_phi_operand(
1668; CHECK-NEXT:  entry:
1669; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[N:%.*]], 1
1670; CHECK-NEXT:    br label [[FOR_COND:%.*]]
1671; CHECK:       for.cond:
1672; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD]], [[FOR_BODY:%.*]] ]
1673; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[IV]], 42
1674; CHECK-NEXT:    br i1 [[EXITCOND]], label [[RETURN:%.*]], label [[FOR_BODY]]
1675; CHECK:       for.body:
1676; CHECK-NEXT:    [[INC:%.*]] = add i32 [[IV]], 1
1677; CHECK-NEXT:    br label [[FOR_COND]]
1678; CHECK:       return:
1679; CHECK-NEXT:    ret void
1680;
1681entry:
1682  %add = add i32 %n, 1
1683  br label %for.cond
1684
1685for.cond:
1686  %iv = phi i32 [ 0, %entry ], [ %add, %for.body ]
1687  %exitcond = icmp eq i32 %iv, 42
1688  br i1 %exitcond, label %return, label %for.body
1689
1690for.body:
1691  %inc = add i32 %iv, 1
1692  br label %for.cond
1693
1694return:
1695  ret void
1696}
1697
1698define ptr @multi_use_in_phi(i1 %cond, ptr %p, i64 %a, i64 %b) {
1699; CHECK-LABEL: @multi_use_in_phi(
1700; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[JOIN:%.*]]
1701; CHECK:       if:
1702; CHECK-NEXT:    call void @dummy()
1703; CHECK-NEXT:    br label [[JOIN]]
1704; CHECK:       join:
1705; CHECK-NEXT:    [[GEP1_B:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[A:%.*]]
1706; CHECK-NEXT:    [[GEP2_B:%.*]] = getelementptr i8, ptr [[GEP1_B]], i64 [[B:%.*]]
1707; CHECK-NEXT:    call void @use.ptr(ptr [[GEP1_B]])
1708; CHECK-NEXT:    ret ptr [[GEP2_B]]
1709;
1710  br i1 %cond, label %if, label %else
1711
1712if:
1713  call void @dummy()
1714  %gep1.a = getelementptr i8, ptr %p, i64 %a
1715  %gep2.a = getelementptr i8, ptr %gep1.a, i64 %b
1716  br label %join
1717
1718else:
1719  %gep1.b = getelementptr i8, ptr %p, i64 %a
1720  %gep2.b = getelementptr i8, ptr %gep1.b, i64 %b
1721  br label %join
1722
1723join:
1724  %phi1 = phi ptr [ %gep1.a, %if ], [ %gep1.b, %else ]
1725  %phi2 = phi ptr [ %gep2.a, %if ], [ %gep2.b, %else ]
1726  call void @use.ptr(ptr %phi1)
1727  ret ptr %phi2
1728}
1729
1730define ptr @multi_use_in_phi_inconsistent(i1 %cond, ptr %p, i64 %a, i64 %b) {
1731; CHECK-LABEL: @multi_use_in_phi_inconsistent(
1732; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
1733; CHECK:       if:
1734; CHECK-NEXT:    call void @dummy()
1735; CHECK-NEXT:    [[GEP1_A:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[A:%.*]]
1736; CHECK-NEXT:    br label [[JOIN:%.*]]
1737; CHECK:       else:
1738; CHECK-NEXT:    [[GEP1_B:%.*]] = getelementptr i8, ptr [[P]], i64 [[A]]
1739; CHECK-NEXT:    br label [[JOIN]]
1740; CHECK:       join:
1741; CHECK-NEXT:    [[GEP1_B_SINK:%.*]] = phi ptr [ [[GEP1_B]], [[ELSE]] ], [ [[GEP1_A]], [[IF]] ]
1742; CHECK-NEXT:    [[PHI1:%.*]] = phi ptr [ [[GEP1_A]], [[IF]] ], [ [[P]], [[ELSE]] ]
1743; CHECK-NEXT:    [[GEP2_B:%.*]] = getelementptr i8, ptr [[GEP1_B_SINK]], i64 [[B:%.*]]
1744; CHECK-NEXT:    call void @use.ptr(ptr [[PHI1]])
1745; CHECK-NEXT:    ret ptr [[GEP2_B]]
1746;
1747  br i1 %cond, label %if, label %else
1748
1749if:
1750  call void @dummy()
1751  %gep1.a = getelementptr i8, ptr %p, i64 %a
1752  %gep2.a = getelementptr i8, ptr %gep1.a, i64 %b
1753  br label %join
1754
1755else:
1756  %gep1.b = getelementptr i8, ptr %p, i64 %a
1757  %gep2.b = getelementptr i8, ptr %gep1.b, i64 %b
1758  br label %join
1759
1760join:
1761  %phi1 = phi ptr [ %gep1.a, %if ], [ %p, %else ]
1762  %phi2 = phi ptr [ %gep2.a, %if ], [ %gep2.b, %else ]
1763  call void @use.ptr(ptr %phi1)
1764  ret ptr %phi2
1765}
1766
1767define i64 @multi_use_in_block(i1 %cond, ptr %p, i64 %a, i64 %b) {
1768; CHECK-LABEL: @multi_use_in_block(
1769; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[JOIN:%.*]]
1770; CHECK:       if:
1771; CHECK-NEXT:    call void @dummy()
1772; CHECK-NEXT:    br label [[JOIN]]
1773; CHECK:       join:
1774; CHECK-NEXT:    [[GEP1_B:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[A:%.*]]
1775; CHECK-NEXT:    [[V_B:%.*]] = load i64, ptr [[GEP1_B]], align 8
1776; CHECK-NEXT:    [[GEP2_B:%.*]] = getelementptr i8, ptr [[GEP1_B]], i64 [[V_B]]
1777; CHECK-NEXT:    call void @use.ptr(ptr [[GEP2_B]])
1778; CHECK-NEXT:    ret i64 [[V_B]]
1779;
1780  br i1 %cond, label %if, label %else
1781
1782if:
1783  call void @dummy()
1784  %gep1.a = getelementptr i8, ptr %p, i64 %a
1785  %v.a = load i64, ptr %gep1.a
1786  %gep2.a = getelementptr i8, ptr %gep1.a, i64 %v.a
1787  br label %join
1788
1789else:
1790  %gep1.b = getelementptr i8, ptr %p, i64 %a
1791  %v.b = load i64, ptr %gep1.b
1792  %gep2.b = getelementptr i8, ptr %gep1.b, i64 %v.b
1793  br label %join
1794
1795join:
1796  %phi1 = phi i64 [ %v.a, %if ], [ %v.b, %else ]
1797  %phi2 = phi ptr [ %gep2.a, %if ], [ %gep2.b, %else ]
1798  call void @use.ptr(ptr %phi2)
1799  ret i64 %phi1
1800}
1801
1802define i64 @multi_use_in_block_inconsistent(i1 %cond, ptr %p, i64 %a, i64 %b) {
1803; CHECK-LABEL: @multi_use_in_block_inconsistent(
1804; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
1805; CHECK:       if:
1806; CHECK-NEXT:    call void @dummy()
1807; CHECK-NEXT:    [[GEP1_A:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[A:%.*]]
1808; CHECK-NEXT:    [[V_A:%.*]] = load i64, ptr [[GEP1_A]], align 8
1809; CHECK-NEXT:    [[GEP2_A:%.*]] = getelementptr i8, ptr [[GEP1_A]], i64 [[V_A]]
1810; CHECK-NEXT:    br label [[JOIN:%.*]]
1811; CHECK:       else:
1812; CHECK-NEXT:    [[GEP1_B:%.*]] = getelementptr i8, ptr [[P]], i64 [[A]]
1813; CHECK-NEXT:    [[V_B:%.*]] = load i64, ptr [[P]], align 8
1814; CHECK-NEXT:    [[GEP2_B:%.*]] = getelementptr i8, ptr [[GEP1_B]], i64 [[V_B]]
1815; CHECK-NEXT:    br label [[JOIN]]
1816; CHECK:       join:
1817; CHECK-NEXT:    [[PHI1:%.*]] = phi i64 [ [[V_A]], [[IF]] ], [ [[V_B]], [[ELSE]] ]
1818; CHECK-NEXT:    [[PHI2:%.*]] = phi ptr [ [[GEP2_A]], [[IF]] ], [ [[GEP2_B]], [[ELSE]] ]
1819; CHECK-NEXT:    call void @use.ptr(ptr [[PHI2]])
1820; CHECK-NEXT:    ret i64 [[PHI1]]
1821;
1822  br i1 %cond, label %if, label %else
1823
1824if:
1825  call void @dummy()
1826  %gep1.a = getelementptr i8, ptr %p, i64 %a
1827  %v.a = load i64, ptr %gep1.a
1828  %gep2.a = getelementptr i8, ptr %gep1.a, i64 %v.a
1829  br label %join
1830
1831else:
1832  %gep1.b = getelementptr i8, ptr %p, i64 %a
1833  %v.b = load i64, ptr %p
1834  %gep2.b = getelementptr i8, ptr %gep1.b, i64 %v.b
1835  br label %join
1836
1837join:
1838  %phi1 = phi i64 [ %v.a, %if ], [ %v.b, %else ]
1839  %phi2 = phi ptr [ %gep2.a, %if ], [ %gep2.b, %else ]
1840  call void @use.ptr(ptr %phi2)
1841  ret i64 %phi1
1842}
1843
1844define i64 @load_with_sunk_gep(i1 %cond, ptr %p, i64 %a, i64 %b) {
1845; CHECK-LABEL: @load_with_sunk_gep(
1846; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[JOIN:%.*]]
1847; CHECK:       if:
1848; CHECK-NEXT:    call void @dummy()
1849; CHECK-NEXT:    br label [[JOIN]]
1850; CHECK:       join:
1851; CHECK-NEXT:    [[B_SINK:%.*]] = phi i64 [ [[A:%.*]], [[IF]] ], [ [[B:%.*]], [[TMP0:%.*]] ]
1852; CHECK-NEXT:    [[GEP_B:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[B_SINK]]
1853; CHECK-NEXT:    [[V_B:%.*]] = load i64, ptr [[GEP_B]], align 8
1854; CHECK-NEXT:    ret i64 [[V_B]]
1855;
1856  br i1 %cond, label %if, label %else
1857
1858if:
1859  call void @dummy()
1860  %gep.a = getelementptr i8, ptr %p, i64 %a
1861  %v.a = load i64, ptr %gep.a
1862  br label %join
1863
1864else:
1865  %gep.b = getelementptr i8, ptr %p, i64 %b
1866  %v.b = load i64, ptr %gep.b
1867  br label %join
1868
1869join:
1870  %v = phi i64 [ %v.a, %if ], [ %v.b, %else ]
1871  ret i64 %v
1872}
1873
1874define i64 @load_with_non_sunk_gep_both(i1 %cond, ptr %p.a, ptr %p.b, i64 %a, i64 %b) {
1875; CHECK-LABEL: @load_with_non_sunk_gep_both(
1876; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
1877; CHECK:       if:
1878; CHECK-NEXT:    call void @dummy()
1879; CHECK-NEXT:    [[GEP_A:%.*]] = getelementptr i8, ptr [[P_A:%.*]], i64 [[A:%.*]]
1880; CHECK-NEXT:    [[V_A:%.*]] = load i64, ptr [[GEP_A]], align 8
1881; CHECK-NEXT:    br label [[JOIN:%.*]]
1882; CHECK:       else:
1883; CHECK-NEXT:    [[GEP_B:%.*]] = getelementptr i8, ptr [[P_B:%.*]], i64 [[B:%.*]]
1884; CHECK-NEXT:    [[V_B:%.*]] = load i64, ptr [[GEP_B]], align 8
1885; CHECK-NEXT:    br label [[JOIN]]
1886; CHECK:       join:
1887; CHECK-NEXT:    [[V:%.*]] = phi i64 [ [[V_A]], [[IF]] ], [ [[V_B]], [[ELSE]] ]
1888; CHECK-NEXT:    ret i64 [[V]]
1889;
1890  br i1 %cond, label %if, label %else
1891
1892if:
1893  call void @dummy()
1894  %gep.a = getelementptr i8, ptr %p.a, i64 %a
1895  %v.a = load i64, ptr %gep.a
1896  br label %join
1897
1898else:
1899  %gep.b = getelementptr i8, ptr %p.b, i64 %b
1900  %v.b = load i64, ptr %gep.b
1901  br label %join
1902
1903join:
1904  %v = phi i64 [ %v.a, %if ], [ %v.b, %else ]
1905  ret i64 %v
1906}
1907
1908define i64 @load_with_non_sunk_gep_left(i1 %cond, ptr %p.a, ptr %p.b, i64 %b) {
1909; CHECK-LABEL: @load_with_non_sunk_gep_left(
1910; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
1911; CHECK:       if:
1912; CHECK-NEXT:    call void @dummy()
1913; CHECK-NEXT:    [[V_A:%.*]] = load i64, ptr [[P_A:%.*]], align 8
1914; CHECK-NEXT:    br label [[JOIN:%.*]]
1915; CHECK:       else:
1916; CHECK-NEXT:    [[GEP_B:%.*]] = getelementptr i8, ptr [[P_B:%.*]], i64 [[B:%.*]]
1917; CHECK-NEXT:    [[V_B:%.*]] = load i64, ptr [[GEP_B]], align 8
1918; CHECK-NEXT:    br label [[JOIN]]
1919; CHECK:       join:
1920; CHECK-NEXT:    [[V:%.*]] = phi i64 [ [[V_A]], [[IF]] ], [ [[V_B]], [[ELSE]] ]
1921; CHECK-NEXT:    ret i64 [[V]]
1922;
1923  br i1 %cond, label %if, label %else
1924
1925if:
1926  call void @dummy()
1927  %v.a = load i64, ptr %p.a
1928  br label %join
1929
1930else:
1931  %gep.b = getelementptr i8, ptr %p.b, i64 %b
1932  %v.b = load i64, ptr %gep.b
1933  br label %join
1934
1935join:
1936  %v = phi i64 [ %v.a, %if ], [ %v.b, %else ]
1937  ret i64 %v
1938}
1939
1940define i64 @load_with_non_sunk_gep_right(i1 %cond, ptr %p.a, ptr %p.b, i64 %a) {
1941; CHECK-LABEL: @load_with_non_sunk_gep_right(
1942; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
1943; CHECK:       if:
1944; CHECK-NEXT:    call void @dummy()
1945; CHECK-NEXT:    [[GEP_A:%.*]] = getelementptr i8, ptr [[P_A:%.*]], i64 [[A:%.*]]
1946; CHECK-NEXT:    [[V_A:%.*]] = load i64, ptr [[GEP_A]], align 8
1947; CHECK-NEXT:    br label [[JOIN:%.*]]
1948; CHECK:       else:
1949; CHECK-NEXT:    [[V_B:%.*]] = load i64, ptr [[P_B:%.*]], align 8
1950; CHECK-NEXT:    br label [[JOIN]]
1951; CHECK:       join:
1952; CHECK-NEXT:    [[V:%.*]] = phi i64 [ [[V_A]], [[IF]] ], [ [[V_B]], [[ELSE]] ]
1953; CHECK-NEXT:    ret i64 [[V]]
1954;
1955  br i1 %cond, label %if, label %else
1956
1957if:
1958  call void @dummy()
1959  %gep.a = getelementptr i8, ptr %p.a, i64 %a
1960  %v.a = load i64, ptr %gep.a
1961  br label %join
1962
1963else:
1964  %v.b = load i64, ptr %p.b
1965  br label %join
1966
1967join:
1968  %v = phi i64 [ %v.a, %if ], [ %v.b, %else ]
1969  ret i64 %v
1970}
1971
1972define void @store_with_non_sunk_gep(i1 %cond, ptr %p.a, ptr %p.b, i64 %a, i64 %b) {
1973; CHECK-LABEL: @store_with_non_sunk_gep(
1974; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
1975; CHECK:       if:
1976; CHECK-NEXT:    call void @dummy()
1977; CHECK-NEXT:    [[GEP_A:%.*]] = getelementptr i8, ptr [[P_A:%.*]], i64 [[A:%.*]]
1978; CHECK-NEXT:    store i64 0, ptr [[GEP_A]], align 8
1979; CHECK-NEXT:    br label [[JOIN:%.*]]
1980; CHECK:       else:
1981; CHECK-NEXT:    [[GEP_B:%.*]] = getelementptr i8, ptr [[P_B:%.*]], i64 [[B:%.*]]
1982; CHECK-NEXT:    store i64 0, ptr [[GEP_B]], align 8
1983; CHECK-NEXT:    br label [[JOIN]]
1984; CHECK:       join:
1985; CHECK-NEXT:    ret void
1986;
1987  br i1 %cond, label %if, label %else
1988
1989if:
1990  call void @dummy()
1991  %gep.a = getelementptr i8, ptr %p.a, i64 %a
1992  store i64 0, ptr %gep.a
1993  br label %join
1994
1995else:
1996  %gep.b = getelementptr i8, ptr %p.b, i64 %b
1997  store i64 0, ptr %gep.b
1998  br label %join
1999
2000join:
2001  ret void
2002}
2003
2004define void @store_with_non_sunk_gep_as_value(i1 %cond, ptr %p, ptr %p.a, ptr %p.b, i64 %a, i64 %b) {
2005; CHECK-LABEL: @store_with_non_sunk_gep_as_value(
2006; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
2007; CHECK:       if:
2008; CHECK-NEXT:    call void @dummy()
2009; CHECK-NEXT:    [[GEP_A:%.*]] = getelementptr i8, ptr [[P_A:%.*]], i64 [[A:%.*]]
2010; CHECK-NEXT:    br label [[JOIN:%.*]]
2011; CHECK:       else:
2012; CHECK-NEXT:    [[GEP_B:%.*]] = getelementptr i8, ptr [[P_B:%.*]], i64 [[B:%.*]]
2013; CHECK-NEXT:    br label [[JOIN]]
2014; CHECK:       join:
2015; CHECK-NEXT:    [[GEP_B_SINK:%.*]] = phi ptr [ [[GEP_B]], [[ELSE]] ], [ [[GEP_A]], [[IF]] ]
2016; CHECK-NEXT:    store ptr [[GEP_B_SINK]], ptr [[P:%.*]], align 8
2017; CHECK-NEXT:    ret void
2018;
2019  br i1 %cond, label %if, label %else
2020
2021if:
2022  call void @dummy()
2023  %gep.a = getelementptr i8, ptr %p.a, i64 %a
2024  store ptr %gep.a, ptr %p
2025  br label %join
2026
2027else:
2028  %gep.b = getelementptr i8, ptr %p.b, i64 %b
2029  store ptr %gep.b, ptr %p
2030  br label %join
2031
2032join:
2033  ret void
2034}
2035
2036define i32 @many_indirect_phis(i1 %cond, i32 %a, i32 %b) {
2037; CHECK-LABEL: @many_indirect_phis(
2038; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[JOIN:%.*]]
2039; CHECK:       if:
2040; CHECK-NEXT:    call void @dummy()
2041; CHECK-NEXT:    br label [[JOIN]]
2042; CHECK:       join:
2043; CHECK-NEXT:    [[B_SINK:%.*]] = phi i32 [ [[A:%.*]], [[IF]] ], [ [[B:%.*]], [[TMP0:%.*]] ]
2044; CHECK-NEXT:    [[DOTSINK3:%.*]] = phi i32 [ 10, [[IF]] ], [ 11, [[TMP0]] ]
2045; CHECK-NEXT:    [[DOTSINK2:%.*]] = phi i32 [ 20, [[IF]] ], [ 21, [[TMP0]] ]
2046; CHECK-NEXT:    [[DOTSINK1:%.*]] = phi i32 [ 30, [[IF]] ], [ 31, [[TMP0]] ]
2047; CHECK-NEXT:    [[DOTSINK:%.*]] = phi i32 [ 40, [[IF]] ], [ 41, [[TMP0]] ]
2048; CHECK-NEXT:    [[ADD_0_B:%.*]] = add i32 [[B_SINK]], 1
2049; CHECK-NEXT:    [[ADD_1_B:%.*]] = add i32 [[ADD_0_B]], [[DOTSINK3]]
2050; CHECK-NEXT:    [[ADD_2_B:%.*]] = add i32 [[ADD_1_B]], [[DOTSINK2]]
2051; CHECK-NEXT:    [[ADD_3_B:%.*]] = add i32 [[ADD_2_B]], [[DOTSINK1]]
2052; CHECK-NEXT:    [[ADD_4_B:%.*]] = add i32 [[ADD_3_B]], [[DOTSINK]]
2053; CHECK-NEXT:    ret i32 [[ADD_4_B]]
2054;
2055  br i1 %cond, label %if, label %else
2056
2057if:
2058  call void @dummy()
2059  %add.0.a = add i32 %a, 1
2060  %add.1.a = add i32 %add.0.a, 10
2061  %add.2.a = add i32 %add.1.a, 20
2062  %add.3.a = add i32 %add.2.a, 30
2063  %add.4.a = add i32 %add.3.a, 40
2064  br label %join
2065
2066else:
2067  %add.0.b = add i32 %b, 1
2068  %add.1.b = add i32 %add.0.b, 11
2069  %add.2.b = add i32 %add.1.b, 21
2070  %add.3.b = add i32 %add.2.b, 31
2071  %add.4.b = add i32 %add.3.b, 41
2072  br label %join
2073
2074join:
2075  %phi = phi i32 [ %add.4.a, %if ], [ %add.4.b, %else ]
2076  ret i32 %phi
2077}
2078
2079define i32 @store_and_unrelated_many_phi_add(i1 %cond, ptr %p, i32 %a, i32 %b) {
2080; CHECK-LABEL: @store_and_unrelated_many_phi_add(
2081; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
2082; CHECK:       if:
2083; CHECK-NEXT:    call void @dummy()
2084; CHECK-NEXT:    [[ADD_1:%.*]] = add i32 [[A:%.*]], 2
2085; CHECK-NEXT:    br label [[JOIN:%.*]]
2086; CHECK:       else:
2087; CHECK-NEXT:    [[ADD_2:%.*]] = add i32 [[B:%.*]], 3
2088; CHECK-NEXT:    br label [[JOIN]]
2089; CHECK:       join:
2090; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[ADD_1]], [[IF]] ], [ [[ADD_2]], [[ELSE]] ]
2091; CHECK-NEXT:    store i32 1, ptr [[P:%.*]], align 4
2092; CHECK-NEXT:    ret i32 [[PHI]]
2093;
2094  br i1 %cond, label %if, label %else
2095
2096if:
2097  call void @dummy()
2098  %add.1 = add i32 %a, 2
2099  store i32 1, ptr %p
2100  br label %join
2101
2102else:
2103  %add.2 = add i32 %b, 3
2104  store i32 1, ptr %p
2105  br label %join
2106
2107join:
2108  %phi = phi i32 [ %add.1, %if ], [ %add.2, %else ]
2109  ret i32 %phi
2110}
2111
2112define i32 @store_and_related_many_phi_add(i1 %cond, ptr %p, i32 %a, i32 %b) {
2113; CHECK-LABEL: @store_and_related_many_phi_add(
2114; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
2115; CHECK:       if:
2116; CHECK-NEXT:    call void @dummy()
2117; CHECK-NEXT:    [[ADD_1:%.*]] = add i32 [[A:%.*]], 2
2118; CHECK-NEXT:    br label [[JOIN:%.*]]
2119; CHECK:       else:
2120; CHECK-NEXT:    [[ADD_2:%.*]] = add i32 [[B:%.*]], 3
2121; CHECK-NEXT:    br label [[JOIN]]
2122; CHECK:       join:
2123; CHECK-NEXT:    [[ADD_2_SINK:%.*]] = phi i32 [ [[ADD_2]], [[ELSE]] ], [ [[ADD_1]], [[IF]] ]
2124; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[ADD_1]], [[IF]] ], [ [[ADD_2]], [[ELSE]] ]
2125; CHECK-NEXT:    store i32 [[ADD_2_SINK]], ptr [[P:%.*]], align 4
2126; CHECK-NEXT:    ret i32 [[PHI]]
2127;
2128  br i1 %cond, label %if, label %else
2129
2130if:
2131  call void @dummy()
2132  %add.1 = add i32 %a, 2
2133  store i32 %add.1, ptr %p
2134  br label %join
2135
2136else:
2137  %add.2 = add i32 %b, 3
2138  store i32 %add.2, ptr %p
2139  br label %join
2140
2141join:
2142  %phi = phi i32 [ %add.1, %if ], [ %add.2, %else ]
2143  ret i32 %phi
2144}
2145
2146define i32 @store_and_unrelated_many_phi_add2(i1 %cond, ptr %p, i32 %a, i32 %b) {
2147; CHECK-LABEL: @store_and_unrelated_many_phi_add2(
2148; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
2149; CHECK:       if:
2150; CHECK-NEXT:    call void @dummy()
2151; CHECK-NEXT:    [[ADD_1:%.*]] = add i32 [[A:%.*]], 2
2152; CHECK-NEXT:    br label [[JOIN:%.*]]
2153; CHECK:       else:
2154; CHECK-NEXT:    [[ADD_2:%.*]] = add i32 [[B:%.*]], 3
2155; CHECK-NEXT:    br label [[JOIN]]
2156; CHECK:       join:
2157; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[ADD_1]], [[IF]] ], [ [[ADD_2]], [[ELSE]] ]
2158; CHECK-NEXT:    [[ADD_A_2:%.*]] = add i32 [[A]], 1
2159; CHECK-NEXT:    store i32 [[ADD_A_2]], ptr [[P:%.*]], align 4
2160; CHECK-NEXT:    ret i32 [[PHI]]
2161;
2162  br i1 %cond, label %if, label %else
2163
2164if:
2165  call void @dummy()
2166  %add.1 = add i32 %a, 2
2167  %add.a.1 = add i32 %a, 1
2168  store i32 %add.a.1, ptr %p
2169  br label %join
2170
2171else:
2172  %add.2 = add i32 %b, 3
2173  %add.a.2 = add i32 %a, 1
2174  store i32 %add.a.2, ptr %p
2175  br label %join
2176
2177join:
2178  %phi = phi i32 [ %add.1, %if ], [ %add.2, %else ]
2179  ret i32 %phi
2180}
2181
2182declare void @dummy()
2183declare void @use.ptr(ptr)
2184
2185!12 = !{i32 1}
2186