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