1; RUN: opt -S -passes='require<scalar-evolution>,require<lazy-value-info>,loop-mssa(loop-predication)' -debug-pass-manager < %s 2>&1 | FileCheck %s 2 3; NOTE: LazyValueAnalysis is an arbitrary analysis that just isn't preserved by 4; this pass. If after your change this analysis is preserved by the pass, 5; please update this test some other analysis that isn't preserved. 6 7; CHECK: Running analysis: LazyValueAnalysis on drop_a_wc_and_leave_early 8; CHECK: Running pass: LoopPredicationPass on loop %loop in function drop_a_wc_and_leave_early 9; CHECK: Invalidating analysis: LazyValueAnalysis on drop_a_wc_and_leave_early 10; CHECK: Running analysis: LazyValueAnalysis on drop_a_wc_and_leave 11; CHECK: Running pass: LoopPredicationPass on loop %loop in function drop_a_wc_and_leave 12; CHECK: Invalidating analysis: LazyValueAnalysis on drop_a_wc_and_leave 13 14 15; This test makes the pass drop its attempts to optimize the exit condition in 16; `%loop` BB by using unanalyzable `%cond_0` as an exit condition. 17define i64 @drop_a_wc_and_leave_early(i64 %length, i64 %n, i1 %cond_0, i1 %cond_1) { 18; Make sure the pass has only replaced `%wc2` with `true` in the definition of `%wb_cond`. 19; CHECK-LABEL: define i64 @drop_a_wc_and_leave_early(i64 %length, i64 %n, i1 %cond_0, i1 %cond_1) { 20; CHECK-NEXT: entry: 21; CHECK-NEXT: %wc1 = call i1 @llvm.experimental.widenable.condition() 22; CHECK-NEXT: %wc2 = call i1 @llvm.experimental.widenable.condition() 23; CHECK-NEXT: %exiplicit_guard_cond = and i1 %cond_0, %wc1 24; CHECK-NEXT: br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 25; CHECK: deopt: 26; CHECK-NEXT: %deoptret = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ] 27; CHECK-NEXT: ret i64 %deoptret 28; CHECK: loop.preheader: 29; CHECK-NEXT: br label %loop 30; CHECK: loop: 31; CHECK-NEXT: %i = phi i64 [ %i.next, %guarded2 ], [ 0, %loop.preheader ] 32; CHECK-NEXT: br i1 %cond_0, label %guarded, label %deopt2, !prof !0 33; CHECK: deopt2: 34; CHECK-NEXT: %deoptret2 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ] 35; CHECK-NEXT: ret i64 %deoptret2 36; CHECK: guarded: 37; CHECK-NEXT: %wb_cond = and i1 %cond_1, true 38; CHECK-NEXT: br i1 %wb_cond, label %guarded2, label %deopt3, !prof !0 39; CHECK: deopt3: 40; CHECK-NEXT: %deoptret3 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ] 41; CHECK-NEXT: ret i64 %deoptret3 42; CHECK: guarded2: 43; CHECK-NEXT: %i.next = add nuw i64 %i, 1 44; CHECK-NEXT: %continue = icmp ult i64 %i.next, %n 45; CHECK-NEXT: br i1 %continue, label %loop, label %exit 46; CHECK: exit: 47; CHECK-NEXT: ret i64 0 48; CHECK-NEXT: } 49 50entry: 51 %wc1 = call i1 @llvm.experimental.widenable.condition() 52 %wc2 = call i1 @llvm.experimental.widenable.condition() 53 %exiplicit_guard_cond = and i1 %cond_0, %wc1 54 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 55 56deopt: 57 %deoptret = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ] 58 ret i64 %deoptret 59 60loop.preheader: 61 br label %loop 62 63loop: 64 %i = phi i64 [ %i.next, %guarded2 ], [ 0, %loop.preheader ] 65 br i1 %cond_0, label %guarded, label %deopt2, !prof !0 66 67deopt2: 68 %deoptret2 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ] 69 ret i64 %deoptret2 70 71guarded: 72 %wb_cond = and i1 %cond_1, %wc2 73 br i1 %wb_cond, label %guarded2, label %deopt3, !prof !0 74 75deopt3: 76 %deoptret3 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ] 77 ret i64 %deoptret3 78 79guarded2: 80 %i.next = add nuw i64 %i, 1 81 %continue = icmp ult i64 %i.next, %n 82 br i1 %continue, label %loop, label %exit 83 84exit: 85 ret i64 0 86} 87 88; This test makes the pass drop its attempts to optimize the exit condition in 89; `%loop` BB by using trivial `false` as an exit condition. 90define i64 @drop_a_wc_and_leave(i64 %n, i1 %cond_0, i1 %cond_1) { 91; Make sure the pass has only replaced `%wc2` with `true` in the definition of `%wb_cond`. 92; CHECK-LABEL: define i64 @drop_a_wc_and_leave(i64 %n, i1 %cond_0, i1 %cond_1) { 93; CHECK-NEXT: entry: 94; CHECK-NEXT: %wc1 = call i1 @llvm.experimental.widenable.condition() 95; CHECK-NEXT: %wc2 = call i1 @llvm.experimental.widenable.condition() 96; CHECK-NEXT: %exiplicit_guard_cond = and i1 %cond_0, %wc1 97; CHECK-NEXT: br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 98; CHECK: deopt: 99; CHECK-NEXT: %deoptret = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ] 100; CHECK-NEXT: ret i64 %deoptret 101; CHECK: loop.preheader: 102; CHECK-NEXT: br label %loop 103; CHECK: loop: 104; CHECK-NEXT: %i = phi i64 [ %i.next, %guarded2 ], [ 0, %loop.preheader ] 105; CHECK-NEXT: br i1 false, label %guarded, label %deopt2, !prof !0 106; CHECK: deopt2: 107; CHECK-NEXT: %deoptret2 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ] 108; CHECK-NEXT: ret i64 %deoptret2 109; CHECK: guarded: 110; CHECK-NEXT: %wb_cond = and i1 %cond_1, true 111; CHECK-NEXT: br i1 %wb_cond, label %guarded2, label %deopt3, !prof !0 112; CHECK: deopt3: 113; CHECK-NEXT: %deoptret3 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ] 114; CHECK-NEXT: ret i64 %deoptret3 115; CHECK: guarded2: 116; CHECK-NEXT: %i.next = add nuw i64 %i, 1 117; CHECK-NEXT: %continue = icmp ult i64 %i.next, %n 118; CHECK-NEXT: br i1 %continue, label %loop, label %exit 119; CHECK: exit: 120; CHECK-NEXT: ret i64 0 121; CHECK-NEXT: } 122 123entry: 124 %wc1 = call i1 @llvm.experimental.widenable.condition() 125 %wc2 = call i1 @llvm.experimental.widenable.condition() 126 %exiplicit_guard_cond = and i1 %cond_0, %wc1 127 br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 128 129deopt: 130 %deoptret = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ] 131 ret i64 %deoptret 132 133loop.preheader: 134 br label %loop 135 136loop: 137 %i = phi i64 [ %i.next, %guarded2 ], [ 0, %loop.preheader ] 138 br i1 false, label %guarded, label %deopt2, !prof !0 139 140deopt2: 141 %deoptret2 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ] 142 ret i64 %deoptret2 143 144guarded: 145 %wb_cond = and i1 %cond_1, %wc2 146 br i1 %wb_cond, label %guarded2, label %deopt3, !prof !0 147 148deopt3: 149 %deoptret3 = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ] 150 ret i64 %deoptret3 151 152guarded2: 153 %i.next = add nuw i64 %i, 1 154 %continue = icmp ult i64 %i.next, %n 155 br i1 %continue, label %loop, label %exit 156 157exit: 158 ret i64 0 159} 160 161 162declare i1 @llvm.experimental.widenable.condition() 163declare i64 @llvm.experimental.deoptimize.i64(...) 164 165!0 = !{!"branch_weights", i64 1048576, i64 1} 166