1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -guard-widening-widen-frequent-branches=true -guard-widening-frequent-branch-threshold=1000 -S -guard-widening < %s | FileCheck %s
3 ; RUN: opt -guard-widening-widen-frequent-branches=true -guard-widening-frequent-branch-threshold=1000 -S -passes='require<branch-prob>,guard-widening' < %s | FileCheck %s
5 declare void @llvm.experimental.guard(i1,...)
9 ; Check that we don't widen without branch probability.
10 define void @test_01(i1 %cond_0, i1 %cond_1) {
11 ; CHECK-LABEL: @test_01(
13 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0:%.*]]) [ "deopt"() ]
14 ; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
16 ; CHECK-NEXT: call void @foo()
17 ; CHECK-NEXT: br label [[MERGE:%.*]]
19 ; CHECK-NEXT: call void @bar()
20 ; CHECK-NEXT: br label [[MERGE]]
22 ; CHECK-NEXT: ret void
25 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
26 br i1 %cond_1, label %if.true, label %if.false
40 ; Check that we don't widen with branch probability below threshold.
41 define void @test_02(i1 %cond_0, i1 %cond_1) {
42 ; CHECK-LABEL: @test_02(
44 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0:%.*]]) [ "deopt"() ]
45 ; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !0
47 ; CHECK-NEXT: call void @foo()
48 ; CHECK-NEXT: br label [[MERGE:%.*]]
50 ; CHECK-NEXT: call void @bar()
51 ; CHECK-NEXT: br label [[MERGE]]
53 ; CHECK-NEXT: ret void
56 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
57 br i1 %cond_1, label %if.true, label %if.false, !prof !0
71 ; Check that we widen conditions of explicit branches into dominating guards
72 ; when the probability is high enough.
73 define void @test_03(i1 %cond_0, i1 %cond_1) {
74 ; CHECK-LABEL: @test_03(
76 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
77 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
78 ; CHECK-NEXT: br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !1
80 ; CHECK-NEXT: call void @foo()
81 ; CHECK-NEXT: br label [[MERGE:%.*]]
83 ; CHECK-NEXT: call void @bar()
84 ; CHECK-NEXT: br label [[MERGE]]
86 ; CHECK-NEXT: ret void
89 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
90 br i1 %cond_1, label %if.true, label %if.false, !prof !1
104 ; Similar to test_03, but the likely taken branch is the false branch.
105 define void @test_03_not_taken(i1 %cond_0, i1 %cond_1) {
106 ; CHECK-LABEL: @test_03_not_taken(
108 ; CHECK-NEXT: [[INVERTED:%.*]] = xor i1 [[COND_1:%.*]], true
109 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[INVERTED]]
110 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
111 ; CHECK-NEXT: br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !2
113 ; CHECK-NEXT: call void @foo()
114 ; CHECK-NEXT: br label [[MERGE:%.*]]
116 ; CHECK-NEXT: call void @bar()
117 ; CHECK-NEXT: br label [[MERGE]]
119 ; CHECK-NEXT: ret void
122 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
123 br i1 %cond_1, label %if.true, label %if.false, !prof !3
137 ; Widen loop-invariant condition into the guard in preheader.
138 define void @test_04(i1 %cond_0, i1 %cond_1, i32 %n) {
139 ; CHECK-LABEL: @test_04(
141 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
142 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
143 ; CHECK-NEXT: br label [[LOOP:%.*]]
145 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[MERGE:%.*]] ]
146 ; CHECK-NEXT: br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !1
148 ; CHECK-NEXT: call void @foo()
149 ; CHECK-NEXT: br label [[MERGE]]
151 ; CHECK-NEXT: call void @bar()
152 ; CHECK-NEXT: br label [[MERGE]]
154 ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
155 ; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[N:%.*]]
156 ; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
158 ; CHECK-NEXT: ret void
161 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
165 %iv = phi i32 [ 0, %entry ], [ %iv.next, %merge ]
166 br i1 %cond_1, label %if.true, label %if.false, !prof !1
177 %iv.next = add i32 %iv, 1
178 %cond = icmp slt i32 %iv.next, %n
179 br i1 %cond, label %loop, label %exit
185 ; Similar to test_04, but the likely taken branch is the false branch.
186 define void @test_04_not_taken(i1 %cond_0, i1 %cond_1, i32 %n) {
187 ; CHECK-LABEL: @test_04_not_taken(
189 ; CHECK-NEXT: [[INVERTED:%.*]] = xor i1 [[COND_1:%.*]], true
190 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[INVERTED]]
191 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
192 ; CHECK-NEXT: br label [[LOOP:%.*]]
194 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[MERGE:%.*]] ]
195 ; CHECK-NEXT: br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !2
197 ; CHECK-NEXT: call void @foo()
198 ; CHECK-NEXT: br label [[MERGE]]
200 ; CHECK-NEXT: call void @bar()
201 ; CHECK-NEXT: br label [[MERGE]]
203 ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
204 ; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[N:%.*]]
205 ; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
207 ; CHECK-NEXT: ret void
210 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
214 %iv = phi i32 [ 0, %entry ], [ %iv.next, %merge ]
215 br i1 %cond_1, label %if.true, label %if.false, !prof !3
226 %iv.next = add i32 %iv, 1
227 %cond = icmp slt i32 %iv.next, %n
228 br i1 %cond, label %loop, label %exit
234 ; Widen loop-invariant condition into the guard in the same loop.
235 define void @test_05(i1 %cond_0, i1 %cond_1, i32 %n) {
236 ; CHECK-LABEL: @test_05(
238 ; CHECK-NEXT: br label [[LOOP:%.*]]
240 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[MERGE:%.*]] ]
241 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
242 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
243 ; CHECK-NEXT: br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !1
245 ; CHECK-NEXT: call void @foo()
246 ; CHECK-NEXT: br label [[MERGE]]
248 ; CHECK-NEXT: call void @bar()
249 ; CHECK-NEXT: br label [[MERGE]]
251 ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
252 ; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[N:%.*]]
253 ; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
255 ; CHECK-NEXT: ret void
261 %iv = phi i32 [ 0, %entry ], [ %iv.next, %merge ]
262 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
263 br i1 %cond_1, label %if.true, label %if.false, !prof !1
274 %iv.next = add i32 %iv, 1
275 %cond = icmp slt i32 %iv.next, %n
276 br i1 %cond, label %loop, label %exit
282 ; Similar to test_05, but the likely taken branch is the false branch.
283 define void @test_05_not_taken(i1 %cond_0, i1 %cond_1, i32 %n) {
284 ; CHECK-LABEL: @test_05_not_taken(
286 ; CHECK-NEXT: br label [[LOOP:%.*]]
288 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[MERGE:%.*]] ]
289 ; CHECK-NEXT: [[INVERTED:%.*]] = xor i1 [[COND_1:%.*]], true
290 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[INVERTED]]
291 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
292 ; CHECK-NEXT: br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !2
294 ; CHECK-NEXT: call void @foo()
295 ; CHECK-NEXT: br label [[MERGE]]
297 ; CHECK-NEXT: call void @bar()
298 ; CHECK-NEXT: br label [[MERGE]]
300 ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
301 ; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[N:%.*]]
302 ; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
304 ; CHECK-NEXT: ret void
310 %iv = phi i32 [ 0, %entry ], [ %iv.next, %merge ]
311 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
312 br i1 %cond_1, label %if.true, label %if.false, !prof !3
323 %iv.next = add i32 %iv, 1
324 %cond = icmp slt i32 %iv.next, %n
325 br i1 %cond, label %loop, label %exit
331 ; Some of checks are frequently taken and some are not, make sure that we only
332 ; widen frequent ones.
333 define void @test_06(i1 %cond_0, i1 %cond_1, i1 %cond_2, i1 %cond_3, i1 %cond_4, i32 %n) {
334 ; CHECK-LABEL: @test_06(
336 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_2:%.*]]
337 ; CHECK-NEXT: [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_4:%.*]]
338 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"() ]
339 ; CHECK-NEXT: br label [[LOOP:%.*]]
341 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
342 ; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_FALSE_1:%.*]], !prof !3
344 ; CHECK-NEXT: call void @foo()
345 ; CHECK-NEXT: br label [[MERGE_1:%.*]]
347 ; CHECK-NEXT: call void @bar()
348 ; CHECK-NEXT: br label [[MERGE_1]]
350 ; CHECK-NEXT: br i1 true, label [[IF_TRUE_2:%.*]], label [[IF_FALSE_2:%.*]], !prof !1
352 ; CHECK-NEXT: call void @foo()
353 ; CHECK-NEXT: br label [[MERGE_2:%.*]]
355 ; CHECK-NEXT: call void @bar()
356 ; CHECK-NEXT: br label [[MERGE_2]]
358 ; CHECK-NEXT: br i1 [[COND_3:%.*]], label [[IF_TRUE_3:%.*]], label [[IF_FALSE_3:%.*]], !prof !3
360 ; CHECK-NEXT: call void @foo()
361 ; CHECK-NEXT: br label [[MERGE_3:%.*]]
363 ; CHECK-NEXT: call void @bar()
364 ; CHECK-NEXT: br label [[MERGE_3]]
366 ; CHECK-NEXT: br i1 true, label [[IF_TRUE_4:%.*]], label [[IF_FALSE_4:%.*]], !prof !1
368 ; CHECK-NEXT: call void @foo()
369 ; CHECK-NEXT: br label [[BACKEDGE]]
371 ; CHECK-NEXT: call void @bar()
372 ; CHECK-NEXT: br label [[BACKEDGE]]
374 ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
375 ; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[N:%.*]]
376 ; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
378 ; CHECK-NEXT: ret void
381 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
385 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
386 br i1 %cond_1, label %if.true_1, label %if.false_1, !prof !2
397 br i1 %cond_2, label %if.true_2, label %if.false_2, !prof !1
408 br i1 %cond_3, label %if.true_3, label %if.false_3, !prof !2
419 br i1 %cond_4, label %if.true_4, label %if.false_4, !prof !1
430 %iv.next = add i32 %iv, 1
431 %cond = icmp slt i32 %iv.next, %n
432 br i1 %cond, label %loop, label %exit
438 ; Similar to test_06, but the likely taken branch is the false branch.
439 define void @test_06_not_taken(i1 %cond_0, i1 %cond_1, i1 %cond_2, i1 %cond_3, i1 %cond_4, i32 %n) {
440 ; CHECK-LABEL: @test_06_not_taken(
442 ; CHECK-NEXT: [[INVERTED:%.*]] = xor i1 [[COND_2:%.*]], true
443 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[INVERTED]]
444 ; CHECK-NEXT: [[INVERTED1:%.*]] = xor i1 [[COND_4:%.*]], true
445 ; CHECK-NEXT: [[WIDE_CHK2:%.*]] = and i1 [[WIDE_CHK]], [[INVERTED1]]
446 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK2]]) [ "deopt"() ]
447 ; CHECK-NEXT: br label [[LOOP:%.*]]
449 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
450 ; CHECK-NEXT: br i1 [[COND_1:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_FALSE_1:%.*]], !prof !3
452 ; CHECK-NEXT: call void @foo()
453 ; CHECK-NEXT: br label [[MERGE_1:%.*]]
455 ; CHECK-NEXT: call void @bar()
456 ; CHECK-NEXT: br label [[MERGE_1]]
458 ; CHECK-NEXT: br i1 false, label [[IF_TRUE_2:%.*]], label [[IF_FALSE_2:%.*]], !prof !2
460 ; CHECK-NEXT: call void @foo()
461 ; CHECK-NEXT: br label [[MERGE_2:%.*]]
463 ; CHECK-NEXT: call void @bar()
464 ; CHECK-NEXT: br label [[MERGE_2]]
466 ; CHECK-NEXT: br i1 [[COND_3:%.*]], label [[IF_TRUE_3:%.*]], label [[IF_FALSE_3:%.*]], !prof !3
468 ; CHECK-NEXT: call void @foo()
469 ; CHECK-NEXT: br label [[MERGE_3:%.*]]
471 ; CHECK-NEXT: call void @bar()
472 ; CHECK-NEXT: br label [[MERGE_3]]
474 ; CHECK-NEXT: br i1 false, label [[IF_TRUE_4:%.*]], label [[IF_FALSE_4:%.*]], !prof !2
476 ; CHECK-NEXT: call void @foo()
477 ; CHECK-NEXT: br label [[BACKEDGE]]
479 ; CHECK-NEXT: call void @bar()
480 ; CHECK-NEXT: br label [[BACKEDGE]]
482 ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
483 ; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 [[IV_NEXT]], [[N:%.*]]
484 ; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
486 ; CHECK-NEXT: ret void
489 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
493 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
494 br i1 %cond_1, label %if.true_1, label %if.false_1, !prof !2
505 br i1 %cond_2, label %if.true_2, label %if.false_2, !prof !3
516 br i1 %cond_3, label %if.true_3, label %if.false_3, !prof !2
527 br i1 %cond_4, label %if.true_4, label %if.false_4, !prof !3
538 %iv.next = add i32 %iv, 1
539 %cond = icmp slt i32 %iv.next, %n
540 br i1 %cond, label %loop, label %exit
546 ; Check triangle CFG pattern.
547 define void @test_07(i1 %cond_0, i1 %cond_1) {
548 ; CHECK-LABEL: @test_07(
550 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
551 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
552 ; CHECK-NEXT: br i1 true, label [[IF_TRUE:%.*]], label [[MERGE:%.*]], !prof !1
554 ; CHECK-NEXT: call void @foo()
555 ; CHECK-NEXT: br label [[MERGE]]
557 ; CHECK-NEXT: ret void
560 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
561 br i1 %cond_1, label %if.true, label %merge, !prof !1
571 ; Similar to test_07, but the likely taken branch is the false branch.
572 define void @test_07_not_taken(i1 %cond_0, i1 %cond_1) {
573 ; CHECK-LABEL: @test_07_not_taken(
575 ; CHECK-NEXT: [[INVERTED:%.*]] = xor i1 [[COND_1:%.*]], true
576 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[INVERTED]]
577 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
578 ; CHECK-NEXT: br i1 false, label [[IF_TRUE:%.*]], label [[MERGE:%.*]], !prof !2
580 ; CHECK-NEXT: call void @foo()
581 ; CHECK-NEXT: br label [[MERGE]]
583 ; CHECK-NEXT: ret void
586 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
587 br i1 %cond_1, label %if.true, label %merge, !prof !3
597 define void @test_08(i1 %cond_0, i1 %cond_1) {
598 ; CHECK-LABEL: @test_08(
600 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
601 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
602 ; CHECK-NEXT: br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !1
604 ; CHECK-NEXT: call void @foo()
605 ; CHECK-NEXT: br label [[MERGE:%.*]]
607 ; CHECK-NEXT: ret void
609 ; CHECK-NEXT: ret void
612 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
613 br i1 %cond_1, label %if.true, label %if.false, !prof !1
626 define void @test_08_not_taken(i1 %cond_0, i1 %cond_1) {
627 ; CHECK-LABEL: @test_08_not_taken(
629 ; CHECK-NEXT: [[INVERTED:%.*]] = xor i1 [[COND_1:%.*]], true
630 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[INVERTED]]
631 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
632 ; CHECK-NEXT: br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !2
634 ; CHECK-NEXT: call void @foo()
635 ; CHECK-NEXT: br label [[MERGE:%.*]]
637 ; CHECK-NEXT: ret void
639 ; CHECK-NEXT: ret void
642 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
643 br i1 %cond_1, label %if.true, label %if.false, !prof !3
656 ; Check that L >u C0 && L >u C1 -> L >u max(C0, C1).
657 define void @test_09(i32 %L) {
658 ; CHECK-LABEL: @test_09(
660 ; CHECK-NEXT: [[COND_0:%.*]] = icmp ugt i32 [[L:%.*]], 123
661 ; CHECK-NEXT: [[COND_1:%.*]] = icmp ugt i32 [[L]], 456
662 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = icmp uge i32 [[L]], 457
663 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
664 ; CHECK-NEXT: br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !1
666 ; CHECK-NEXT: call void @foo()
667 ; CHECK-NEXT: br label [[MERGE:%.*]]
669 ; CHECK-NEXT: ret void
671 ; CHECK-NEXT: ret void
674 %cond_0 = icmp ugt i32 %L, 123
675 %cond_1 = icmp ugt i32 %L, 456
676 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
677 br i1 %cond_1, label %if.true, label %if.false, !prof !1
690 ; Check that L >u C0 && !(L <=u C1) -> L >u max(C0, C1).
691 define void @test_09_not_taken(i32 %L) {
692 ; CHECK-LABEL: @test_09_not_taken(
694 ; CHECK-NEXT: [[COND_0:%.*]] = icmp ugt i32 [[L:%.*]], 123
695 ; CHECK-NEXT: [[COND_1:%.*]] = icmp ule i32 [[L]], 456
696 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = icmp uge i32 [[L]], 457
697 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
698 ; CHECK-NEXT: br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !2
700 ; CHECK-NEXT: call void @foo()
701 ; CHECK-NEXT: br label [[MERGE:%.*]]
703 ; CHECK-NEXT: ret void
705 ; CHECK-NEXT: ret void
708 %cond_0 = icmp ugt i32 %L, 123
709 %cond_1 = icmp ule i32 %L, 456
710 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
711 br i1 %cond_1, label %if.true, label %if.false, !prof !3
724 ; Check that a profitable transform is preferred over non-profitable.
725 define void @test_10(i32 %L, i1 %irrelevant_cond, i1 %infinite_loop_cond) {
726 ; CHECK-LABEL: @test_10(
728 ; CHECK-NEXT: [[COND_0:%.*]] = icmp ugt i32 [[L:%.*]], 123
729 ; CHECK-NEXT: [[COND_1:%.*]] = icmp ugt i32 [[L]], 456
730 ; CHECK-NEXT: br label [[LOOP:%.*]]
732 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[IRRELEVANT_COND:%.*]]) [ "deopt"() ]
733 ; CHECK-NEXT: br i1 [[INFINITE_LOOP_COND:%.*]], label [[LOOP]], label [[AFTER_LOOP:%.*]]
735 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = icmp uge i32 [[L]], 457
736 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
737 ; CHECK-NEXT: br i1 true, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !1
739 ; CHECK-NEXT: call void @foo()
740 ; CHECK-NEXT: br label [[MERGE:%.*]]
742 ; CHECK-NEXT: br label [[MERGE]]
744 ; CHECK-NEXT: ret void
747 %cond_0 = icmp ugt i32 %L, 123
748 %cond_1 = icmp ugt i32 %L, 456
752 call void(i1, ...) @llvm.experimental.guard(i1 %irrelevant_cond) [ "deopt"() ]
753 br i1 %infinite_loop_cond, label %loop, label %after_loop
756 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
757 br i1 %cond_1, label %if.true, label %if.false, !prof !1
770 ; Check that a profitable transform is preferred over non-profitable.
772 define void @test_10_not_taken(i32 %L, i1 %irrelevant_cond, i1 %infinite_loop_cond) {
773 ; CHECK-LABEL: @test_10_not_taken(
775 ; CHECK-NEXT: [[COND_0:%.*]] = icmp ugt i32 [[L:%.*]], 123
776 ; CHECK-NEXT: [[COND_1:%.*]] = icmp ule i32 [[L]], 456
777 ; CHECK-NEXT: br label [[LOOP:%.*]]
779 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[IRRELEVANT_COND:%.*]]) [ "deopt"() ]
780 ; CHECK-NEXT: br i1 [[INFINITE_LOOP_COND:%.*]], label [[LOOP]], label [[AFTER_LOOP:%.*]]
782 ; CHECK-NEXT: [[WIDE_CHK:%.*]] = icmp uge i32 [[L]], 457
783 ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
784 ; CHECK-NEXT: br i1 false, label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]], !prof !2
786 ; CHECK-NEXT: call void @foo()
787 ; CHECK-NEXT: br label [[MERGE:%.*]]
789 ; CHECK-NEXT: br label [[MERGE]]
791 ; CHECK-NEXT: ret void
794 %cond_0 = icmp ugt i32 %L, 123
795 %cond_1 = icmp ule i32 %L, 456
799 call void(i1, ...) @llvm.experimental.guard(i1 %irrelevant_cond) [ "deopt"() ]
800 br i1 %infinite_loop_cond, label %loop, label %after_loop
803 call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
804 br i1 %cond_1, label %if.true, label %if.false, !prof !3
817 !0 = !{!"branch_weights", i32 998, i32 1}
818 !1 = !{!"branch_weights", i32 999, i32 1}
819 !2 = !{!"branch_weights", i32 500, i32 500}
820 !3 = !{!"branch_weights", i32 1, i32 999}