1*fe950cbaSDaniil Suchkov; RUN: opt -S -passes='require<scalar-evolution>,require<lazy-value-info>,loop-mssa(loop-predication)' -debug-pass-manager < %s 2>&1 | FileCheck %s
25f2b7879SDaniil Suchkov
3*fe950cbaSDaniil Suchkov; NOTE: LazyValueAnalysis is an arbitrary analysis that just isn't preserved by
4*fe950cbaSDaniil Suchkov;       this pass. If after your change this analysis is preserved by the pass,
5*fe950cbaSDaniil Suchkov;       please update this test some other analysis that isn't preserved.
65f2b7879SDaniil Suchkov
7*fe950cbaSDaniil Suchkov; CHECK: Running analysis: LazyValueAnalysis on drop_a_wc_and_leave_early
85f2b7879SDaniil Suchkov; CHECK: Running pass: LoopPredicationPass on Loop at depth 1 containing: %loop<header><exiting>,%guarded<exiting>,%guarded2<latch><exiting>
9*fe950cbaSDaniil Suchkov; CHECK: Invalidating analysis: LazyValueAnalysis on drop_a_wc_and_leave_early
10*fe950cbaSDaniil Suchkov; CHECK: Running analysis: LazyValueAnalysis on drop_a_wc_and_leave
115f2b7879SDaniil Suchkov; CHECK: Running pass: LoopPredicationPass on Loop at depth 1 containing: %loop<header><exiting>,%guarded<exiting>,%guarded2<latch><exiting>
12*fe950cbaSDaniil Suchkov; CHECK: Invalidating analysis: LazyValueAnalysis on drop_a_wc_and_leave
135f2b7879SDaniil Suchkov
145f2b7879SDaniil Suchkov
155f2b7879SDaniil Suchkov; This test makes the pass drop its attempts to optimize the exit condition in
165f2b7879SDaniil Suchkov; `%loop` BB by using unanalyzable `%cond_0` as an exit condition.
175f2b7879SDaniil Suchkovdefine i64 @drop_a_wc_and_leave_early(i64 %length, i64 %n, i1 %cond_0, i1 %cond_1) {
185f2b7879SDaniil Suchkov; Make sure the pass has only replaced `%wc2` with `true` in the definition of `%wb_cond`.
195f2b7879SDaniil Suchkov; CHECK-LABEL: define i64 @drop_a_wc_and_leave_early(i64 %length, i64 %n, i1 %cond_0, i1 %cond_1) {
205f2b7879SDaniil Suchkov; CHECK-NEXT: entry:
215f2b7879SDaniil Suchkov; CHECK-NEXT:   %wc1 = call i1 @llvm.experimental.widenable.condition()
225f2b7879SDaniil Suchkov; CHECK-NEXT:   %wc2 = call i1 @llvm.experimental.widenable.condition()
235f2b7879SDaniil Suchkov; CHECK-NEXT:   %exiplicit_guard_cond = and i1 %cond_0, %wc1
245f2b7879SDaniil Suchkov; CHECK-NEXT:   br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
255f2b7879SDaniil Suchkov; CHECK:      deopt:
265f2b7879SDaniil Suchkov; CHECK-NEXT:   %deoptret = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ]
275f2b7879SDaniil Suchkov; CHECK-NEXT:   ret i64 %deoptret
285f2b7879SDaniil Suchkov; CHECK:      loop.preheader:
295f2b7879SDaniil Suchkov; CHECK-NEXT:   br label %loop
305f2b7879SDaniil Suchkov; CHECK:      loop:
315f2b7879SDaniil Suchkov; CHECK-NEXT:   %i = phi i64 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
325f2b7879SDaniil Suchkov; CHECK-NEXT:   br i1 %cond_0, label %guarded, label %deopt2, !prof !0
335f2b7879SDaniil Suchkov; CHECK:      deopt2:
345f2b7879SDaniil Suchkov; CHECK-NEXT:   %deoptret2 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ]
355f2b7879SDaniil Suchkov; CHECK-NEXT:   ret i64 %deoptret2
365f2b7879SDaniil Suchkov; CHECK:      guarded:
375f2b7879SDaniil Suchkov; CHECK-NEXT:   %wb_cond = and i1 %cond_1, true
385f2b7879SDaniil Suchkov; CHECK-NEXT:   br i1 %wb_cond, label %guarded2, label %deopt3, !prof !0
395f2b7879SDaniil Suchkov; CHECK:      deopt3:
405f2b7879SDaniil Suchkov; CHECK-NEXT:   %deoptret3 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ]
415f2b7879SDaniil Suchkov; CHECK-NEXT:   ret i64 %deoptret3
425f2b7879SDaniil Suchkov; CHECK:      guarded2:
435f2b7879SDaniil Suchkov; CHECK-NEXT:   %i.next = add nuw i64 %i, 1
445f2b7879SDaniil Suchkov; CHECK-NEXT:   %continue = icmp ult i64 %i.next, %n
455f2b7879SDaniil Suchkov; CHECK-NEXT:   br i1 %continue, label %loop, label %exit
465f2b7879SDaniil Suchkov; CHECK:      exit:
475f2b7879SDaniil Suchkov; CHECK-NEXT:   ret i64 0
485f2b7879SDaniil Suchkov; CHECK-NEXT: }
495f2b7879SDaniil Suchkov
505f2b7879SDaniil Suchkoventry:
515f2b7879SDaniil Suchkov  %wc1 = call i1 @llvm.experimental.widenable.condition()
525f2b7879SDaniil Suchkov  %wc2 = call i1 @llvm.experimental.widenable.condition()
535f2b7879SDaniil Suchkov  %exiplicit_guard_cond = and i1 %cond_0, %wc1
545f2b7879SDaniil Suchkov  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
555f2b7879SDaniil Suchkov
565f2b7879SDaniil Suchkovdeopt:
575f2b7879SDaniil Suchkov  %deoptret = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ]
585f2b7879SDaniil Suchkov  ret i64 %deoptret
595f2b7879SDaniil Suchkov
605f2b7879SDaniil Suchkovloop.preheader:
615f2b7879SDaniil Suchkov  br label %loop
625f2b7879SDaniil Suchkov
635f2b7879SDaniil Suchkovloop:
645f2b7879SDaniil Suchkov  %i = phi i64 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
655f2b7879SDaniil Suchkov  br i1 %cond_0, label %guarded, label %deopt2, !prof !0
665f2b7879SDaniil Suchkov
675f2b7879SDaniil Suchkovdeopt2:
685f2b7879SDaniil Suchkov  %deoptret2 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ]
695f2b7879SDaniil Suchkov  ret i64 %deoptret2
705f2b7879SDaniil Suchkov
715f2b7879SDaniil Suchkovguarded:
725f2b7879SDaniil Suchkov  %wb_cond = and i1 %cond_1, %wc2
735f2b7879SDaniil Suchkov  br i1 %wb_cond, label %guarded2, label %deopt3, !prof !0
745f2b7879SDaniil Suchkov
755f2b7879SDaniil Suchkovdeopt3:
765f2b7879SDaniil Suchkov  %deoptret3 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ]
775f2b7879SDaniil Suchkov  ret i64 %deoptret3
785f2b7879SDaniil Suchkov
795f2b7879SDaniil Suchkovguarded2:
805f2b7879SDaniil Suchkov  %i.next = add nuw i64 %i, 1
815f2b7879SDaniil Suchkov  %continue = icmp ult i64 %i.next, %n
825f2b7879SDaniil Suchkov  br i1 %continue, label %loop, label %exit
835f2b7879SDaniil Suchkov
845f2b7879SDaniil Suchkovexit:
855f2b7879SDaniil Suchkov  ret i64 0
865f2b7879SDaniil Suchkov}
875f2b7879SDaniil Suchkov
885f2b7879SDaniil Suchkov; This test makes the pass drop its attempts to optimize the exit condition in
895f2b7879SDaniil Suchkov; `%loop` BB by using trivial `false` as an exit condition.
905f2b7879SDaniil Suchkovdefine i64 @drop_a_wc_and_leave(i64 %n, i1 %cond_0, i1 %cond_1) {
915f2b7879SDaniil Suchkov; Make sure the pass has only replaced `%wc2` with `true` in the definition of `%wb_cond`.
925f2b7879SDaniil Suchkov; CHECK-LABEL: define i64 @drop_a_wc_and_leave(i64 %n, i1 %cond_0, i1 %cond_1) {
935f2b7879SDaniil Suchkov; CHECK-NEXT: entry:
945f2b7879SDaniil Suchkov; CHECK-NEXT:   %wc1 = call i1 @llvm.experimental.widenable.condition()
955f2b7879SDaniil Suchkov; CHECK-NEXT:   %wc2 = call i1 @llvm.experimental.widenable.condition()
965f2b7879SDaniil Suchkov; CHECK-NEXT:   %exiplicit_guard_cond = and i1 %cond_0, %wc1
975f2b7879SDaniil Suchkov; CHECK-NEXT:   br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
985f2b7879SDaniil Suchkov; CHECK:      deopt:
995f2b7879SDaniil Suchkov; CHECK-NEXT:   %deoptret = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ]
1005f2b7879SDaniil Suchkov; CHECK-NEXT:   ret i64 %deoptret
1015f2b7879SDaniil Suchkov; CHECK:      loop.preheader:
1025f2b7879SDaniil Suchkov; CHECK-NEXT:   br label %loop
1035f2b7879SDaniil Suchkov; CHECK:      loop:
1045f2b7879SDaniil Suchkov; CHECK-NEXT:   %i = phi i64 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
1055f2b7879SDaniil Suchkov; CHECK-NEXT:   br i1 false, label %guarded, label %deopt2, !prof !0
1065f2b7879SDaniil Suchkov; CHECK:      deopt2:
1075f2b7879SDaniil Suchkov; CHECK-NEXT:   %deoptret2 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ]
1085f2b7879SDaniil Suchkov; CHECK-NEXT:   ret i64 %deoptret2
1095f2b7879SDaniil Suchkov; CHECK:      guarded:
1105f2b7879SDaniil Suchkov; CHECK-NEXT:   %wb_cond = and i1 %cond_1, true
1115f2b7879SDaniil Suchkov; CHECK-NEXT:   br i1 %wb_cond, label %guarded2, label %deopt3, !prof !0
1125f2b7879SDaniil Suchkov; CHECK:      deopt3:
1135f2b7879SDaniil Suchkov; CHECK-NEXT:   %deoptret3 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ]
1145f2b7879SDaniil Suchkov; CHECK-NEXT:   ret i64 %deoptret3
1155f2b7879SDaniil Suchkov; CHECK:      guarded2:
1165f2b7879SDaniil Suchkov; CHECK-NEXT:   %i.next = add nuw i64 %i, 1
1175f2b7879SDaniil Suchkov; CHECK-NEXT:   %continue = icmp ult i64 %i.next, %n
1185f2b7879SDaniil Suchkov; CHECK-NEXT:   br i1 %continue, label %loop, label %exit
1195f2b7879SDaniil Suchkov; CHECK:      exit:
1205f2b7879SDaniil Suchkov; CHECK-NEXT:   ret i64 0
1215f2b7879SDaniil Suchkov; CHECK-NEXT: }
1225f2b7879SDaniil Suchkov
1235f2b7879SDaniil Suchkoventry:
1245f2b7879SDaniil Suchkov  %wc1 = call i1 @llvm.experimental.widenable.condition()
1255f2b7879SDaniil Suchkov  %wc2 = call i1 @llvm.experimental.widenable.condition()
1265f2b7879SDaniil Suchkov  %exiplicit_guard_cond = and i1 %cond_0, %wc1
1275f2b7879SDaniil Suchkov  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
1285f2b7879SDaniil Suchkov
1295f2b7879SDaniil Suchkovdeopt:
1305f2b7879SDaniil Suchkov  %deoptret = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ]
1315f2b7879SDaniil Suchkov  ret i64 %deoptret
1325f2b7879SDaniil Suchkov
1335f2b7879SDaniil Suchkovloop.preheader:
1345f2b7879SDaniil Suchkov  br label %loop
1355f2b7879SDaniil Suchkov
1365f2b7879SDaniil Suchkovloop:
1375f2b7879SDaniil Suchkov  %i = phi i64 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
1385f2b7879SDaniil Suchkov  br i1 false, label %guarded, label %deopt2, !prof !0
1395f2b7879SDaniil Suchkov
1405f2b7879SDaniil Suchkovdeopt2:
1415f2b7879SDaniil Suchkov  %deoptret2 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ]
1425f2b7879SDaniil Suchkov  ret i64 %deoptret2
1435f2b7879SDaniil Suchkov
1445f2b7879SDaniil Suchkovguarded:
1455f2b7879SDaniil Suchkov  %wb_cond = and i1 %cond_1, %wc2
1465f2b7879SDaniil Suchkov  br i1 %wb_cond, label %guarded2, label %deopt3, !prof !0
1475f2b7879SDaniil Suchkov
1485f2b7879SDaniil Suchkovdeopt3:
1495f2b7879SDaniil Suchkov  %deoptret3 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ]
1505f2b7879SDaniil Suchkov  ret i64 %deoptret3
1515f2b7879SDaniil Suchkov
1525f2b7879SDaniil Suchkovguarded2:
1535f2b7879SDaniil Suchkov  %i.next = add nuw i64 %i, 1
1545f2b7879SDaniil Suchkov  %continue = icmp ult i64 %i.next, %n
1555f2b7879SDaniil Suchkov  br i1 %continue, label %loop, label %exit
1565f2b7879SDaniil Suchkov
1575f2b7879SDaniil Suchkovexit:
1585f2b7879SDaniil Suchkov  ret i64 0
1595f2b7879SDaniil Suchkov}
1605f2b7879SDaniil Suchkov
1615f2b7879SDaniil Suchkov
1625f2b7879SDaniil Suchkovdeclare i1 @llvm.experimental.widenable.condition()
1635f2b7879SDaniil Suchkovdeclare i64 @llvm.experimental.deoptimize.i64(...)
1645f2b7879SDaniil Suchkov
1655f2b7879SDaniil Suchkov!0 = !{!"branch_weights", i64 1048576, i64 1}
166