1*ad5a84c8SPhilip Reames; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2*ad5a84c8SPhilip Reames; RUN: opt < %s -loop-predication -S | FileCheck %s 3*ad5a84c8SPhilip Reames 4*ad5a84c8SPhilip Reamesdeclare void @prevent_merging() 5*ad5a84c8SPhilip Reames 6*ad5a84c8SPhilip Reames; Base case - with side effects in loop 7*ad5a84c8SPhilip Reamesdefine i32 @test1(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 8*ad5a84c8SPhilip Reames; CHECK-LABEL: @test1( 9*ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 10*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 11*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], 1 12*ad5a84c8SPhilip Reames; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1 13*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[UMAX]], -1 14*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[LENGTH:%.*]], [[TMP1]] 15*ad5a84c8SPhilip Reames; CHECK-NEXT: [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]] 16*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 17*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]] 18*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[COND_0:%.*]] 19*ad5a84c8SPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND]] 20*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 21*ad5a84c8SPhilip Reames; CHECK: deopt: 22*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 23*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 24*ad5a84c8SPhilip Reames; CHECK: loop.preheader: 25*ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 26*ad5a84c8SPhilip Reames; CHECK: loop: 27*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 28*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 29*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 30*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 31*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 32*ad5a84c8SPhilip Reames; CHECK: deopt2: 33*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 34*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 35*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 36*ad5a84c8SPhilip Reames; CHECK: guarded: 37*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 38*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 39*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 40*ad5a84c8SPhilip Reames; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]] 41*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 42*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 43*ad5a84c8SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 44*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 45*ad5a84c8SPhilip Reames; CHECK: exit: 46*ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 47*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 48*ad5a84c8SPhilip Reames; 49*ad5a84c8SPhilip Reamesentry: 50*ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 51*ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 52*ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 53*ad5a84c8SPhilip Reames 54*ad5a84c8SPhilip Reamesdeopt: 55*ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 56*ad5a84c8SPhilip Reames ret i32 %deoptret 57*ad5a84c8SPhilip Reames 58*ad5a84c8SPhilip Reamesloop.preheader: 59*ad5a84c8SPhilip Reames br label %loop 60*ad5a84c8SPhilip Reames 61*ad5a84c8SPhilip Reamesloop: 62*ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 63*ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 64*ad5a84c8SPhilip Reames call void @unknown() 65*ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, %length 66*ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 67*ad5a84c8SPhilip Reames 68*ad5a84c8SPhilip Reamesdeopt2: 69*ad5a84c8SPhilip Reames call void @unknown() 70*ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 71*ad5a84c8SPhilip Reames ret i32 %deoptret2 72*ad5a84c8SPhilip Reames 73*ad5a84c8SPhilip Reamesguarded: 74*ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 75*ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 76*ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 77*ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 78*ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 79*ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 80*ad5a84c8SPhilip Reames %continue = icmp ult i32 %i.next, %n 81*ad5a84c8SPhilip Reames br i1 %continue, label %loop, label %exit 82*ad5a84c8SPhilip Reames 83*ad5a84c8SPhilip Reamesexit: 84*ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded ] 85*ad5a84c8SPhilip Reames ret i32 %result 86*ad5a84c8SPhilip Reames} 87*ad5a84c8SPhilip Reames 88*ad5a84c8SPhilip Reames 89*ad5a84c8SPhilip Reames 90*ad5a84c8SPhilip Reamesdefine i32 @test_non_canonical(i32* %array, i32 %length, i1 %cond_0) { 91*ad5a84c8SPhilip Reames; CHECK-LABEL: @test_non_canonical( 92*ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 93*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 94*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[LENGTH:%.*]], 1 95*ad5a84c8SPhilip Reames; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[LENGTH]], i32 1 96*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[UMAX]], -1 97*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[LENGTH]], [[TMP1]] 98*ad5a84c8SPhilip Reames; CHECK-NEXT: [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]] 99*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 100*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]] 101*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[COND_0:%.*]] 102*ad5a84c8SPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND]] 103*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 104*ad5a84c8SPhilip Reames; CHECK: deopt: 105*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 106*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 107*ad5a84c8SPhilip Reames; CHECK: loop.preheader: 108*ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 109*ad5a84c8SPhilip Reames; CHECK: loop: 110*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 111*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 112*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 113*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 114*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 115*ad5a84c8SPhilip Reames; CHECK: deopt2: 116*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 117*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 118*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 119*ad5a84c8SPhilip Reames; CHECK: guarded: 120*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 121*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 122*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 123*ad5a84c8SPhilip Reames; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]] 124*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 125*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 126*ad5a84c8SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]] 127*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 128*ad5a84c8SPhilip Reames; CHECK: exit: 129*ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 130*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 131*ad5a84c8SPhilip Reames; 132*ad5a84c8SPhilip Reamesentry: 133*ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 134*ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 135*ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 136*ad5a84c8SPhilip Reames 137*ad5a84c8SPhilip Reamesdeopt: 138*ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 139*ad5a84c8SPhilip Reames ret i32 %deoptret 140*ad5a84c8SPhilip Reames 141*ad5a84c8SPhilip Reamesloop.preheader: 142*ad5a84c8SPhilip Reames br label %loop 143*ad5a84c8SPhilip Reames 144*ad5a84c8SPhilip Reamesloop: 145*ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 146*ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 147*ad5a84c8SPhilip Reames call void @unknown() 148*ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, %length 149*ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 150*ad5a84c8SPhilip Reames 151*ad5a84c8SPhilip Reamesdeopt2: 152*ad5a84c8SPhilip Reames call void @unknown() 153*ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 154*ad5a84c8SPhilip Reames ret i32 %deoptret2 155*ad5a84c8SPhilip Reames 156*ad5a84c8SPhilip Reamesguarded: 157*ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 158*ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 159*ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 160*ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 161*ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 162*ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 163*ad5a84c8SPhilip Reames %continue = icmp ult i32 %i.next, %length 164*ad5a84c8SPhilip Reames br i1 %continue, label %loop, label %exit 165*ad5a84c8SPhilip Reames 166*ad5a84c8SPhilip Reamesexit: 167*ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded ] 168*ad5a84c8SPhilip Reames ret i32 %result 169*ad5a84c8SPhilip Reames} 170*ad5a84c8SPhilip Reames 171*ad5a84c8SPhilip Reames 172*ad5a84c8SPhilip Reamesdefine i32 @test_two_range_checks(i32* %array, i32 %length.1, i32 %length.2, i32 %n, i1 %cond_0) { 173*ad5a84c8SPhilip Reames; CHECK-LABEL: @test_two_range_checks( 174*ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 175*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 176*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[LENGTH_2:%.*]], [[LENGTH_1:%.*]] 177*ad5a84c8SPhilip Reames; CHECK-NEXT: [[UMIN:%.*]] = select i1 [[TMP0]], i32 [[LENGTH_2]], i32 [[LENGTH_1]] 178*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[N:%.*]], 1 179*ad5a84c8SPhilip Reames; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[TMP1]], i32 [[N]], i32 1 180*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[UMAX]], -1 181*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i32 [[UMIN]], [[TMP2]] 182*ad5a84c8SPhilip Reames; CHECK-NEXT: [[UMIN1:%.*]] = select i1 [[TMP3]], i32 [[UMIN]], i32 [[TMP2]] 183*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i32 [[LENGTH_1]], [[UMIN1]] 184*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP5:%.*]] = freeze i1 [[TMP4]] 185*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[COND_0:%.*]] 186*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP7:%.*]] = icmp ugt i32 [[LENGTH_2]], [[UMIN1]] 187*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP8:%.*]] = freeze i1 [[TMP7]] 188*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP9:%.*]] = and i1 [[TMP8]], [[TMP6]] 189*ad5a84c8SPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP9]], [[WIDENABLE_COND]] 190*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 191*ad5a84c8SPhilip Reames; CHECK: deopt: 192*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 193*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 194*ad5a84c8SPhilip Reames; CHECK: loop.preheader: 195*ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 196*ad5a84c8SPhilip Reames; CHECK: loop: 197*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 198*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ] 199*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 200*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]] 201*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0 202*ad5a84c8SPhilip Reames; CHECK: deopt2: 203*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 204*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 205*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 206*ad5a84c8SPhilip Reames; CHECK: guarded: 207*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]] 208*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0 209*ad5a84c8SPhilip Reames; CHECK: deopt3: 210*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 211*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 212*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET3]] 213*ad5a84c8SPhilip Reames; CHECK: guarded2: 214*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 215*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 216*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 217*ad5a84c8SPhilip Reames; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]] 218*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 219*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 220*ad5a84c8SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 221*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 222*ad5a84c8SPhilip Reames; CHECK: exit: 223*ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ] 224*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 225*ad5a84c8SPhilip Reames; 226*ad5a84c8SPhilip Reamesentry: 227*ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 228*ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 229*ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 230*ad5a84c8SPhilip Reames 231*ad5a84c8SPhilip Reamesdeopt: 232*ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 233*ad5a84c8SPhilip Reames ret i32 %deoptret 234*ad5a84c8SPhilip Reames 235*ad5a84c8SPhilip Reamesloop.preheader: 236*ad5a84c8SPhilip Reames br label %loop 237*ad5a84c8SPhilip Reames 238*ad5a84c8SPhilip Reamesloop: 239*ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ] 240*ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ] 241*ad5a84c8SPhilip Reames call void @unknown() 242*ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, %length.1 243*ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 244*ad5a84c8SPhilip Reames 245*ad5a84c8SPhilip Reamesdeopt2: 246*ad5a84c8SPhilip Reames call void @unknown() 247*ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 248*ad5a84c8SPhilip Reames ret i32 %deoptret2 249*ad5a84c8SPhilip Reames 250*ad5a84c8SPhilip Reamesguarded: 251*ad5a84c8SPhilip Reames %within.bounds2 = icmp ult i32 %i, %length.2 252*ad5a84c8SPhilip Reames br i1 %within.bounds2, label %guarded2, label %deopt3, !prof !0 253*ad5a84c8SPhilip Reames 254*ad5a84c8SPhilip Reamesdeopt3: 255*ad5a84c8SPhilip Reames call void @unknown() 256*ad5a84c8SPhilip Reames %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 257*ad5a84c8SPhilip Reames ret i32 %deoptret3 258*ad5a84c8SPhilip Reames 259*ad5a84c8SPhilip Reamesguarded2: 260*ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 261*ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 262*ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 263*ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 264*ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 265*ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 266*ad5a84c8SPhilip Reames %continue = icmp ult i32 %i.next, %n 267*ad5a84c8SPhilip Reames br i1 %continue, label %loop, label %exit 268*ad5a84c8SPhilip Reames 269*ad5a84c8SPhilip Reamesexit: 270*ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded2 ] 271*ad5a84c8SPhilip Reames ret i32 %result 272*ad5a84c8SPhilip Reames} 273*ad5a84c8SPhilip Reames 274*ad5a84c8SPhilip Reames@G = external global i32 275*ad5a84c8SPhilip Reames 276*ad5a84c8SPhilip Reamesdefine i32 @test_unanalyzeable_exit(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 277*ad5a84c8SPhilip Reames; CHECK-LABEL: @test_unanalyzeable_exit( 278*ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 279*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 280*ad5a84c8SPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]] 281*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 282*ad5a84c8SPhilip Reames; CHECK: deopt: 283*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 284*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 285*ad5a84c8SPhilip Reames; CHECK: loop.preheader: 286*ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 287*ad5a84c8SPhilip Reames; CHECK: loop: 288*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 289*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ] 290*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 291*ad5a84c8SPhilip Reames; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, i32* @G 292*ad5a84c8SPhilip Reames; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0 293*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0 294*ad5a84c8SPhilip Reames; CHECK: deopt3: 295*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 296*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 297*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET3]] 298*ad5a84c8SPhilip Reames; CHECK: guarded2: 299*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 300*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 301*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 302*ad5a84c8SPhilip Reames; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]] 303*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 304*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 305*ad5a84c8SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N:%.*]] 306*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 307*ad5a84c8SPhilip Reames; CHECK: exit: 308*ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ] 309*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 310*ad5a84c8SPhilip Reames; 311*ad5a84c8SPhilip Reamesentry: 312*ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 313*ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 314*ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 315*ad5a84c8SPhilip Reames 316*ad5a84c8SPhilip Reamesdeopt: 317*ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 318*ad5a84c8SPhilip Reames ret i32 %deoptret 319*ad5a84c8SPhilip Reames 320*ad5a84c8SPhilip Reamesloop.preheader: 321*ad5a84c8SPhilip Reames br label %loop 322*ad5a84c8SPhilip Reames 323*ad5a84c8SPhilip Reamesloop: 324*ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ] 325*ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ] 326*ad5a84c8SPhilip Reames call void @unknown() 327*ad5a84c8SPhilip Reames %vol = load volatile i32, i32* @G 328*ad5a84c8SPhilip Reames %unknown = icmp eq i32 %vol, 0 329*ad5a84c8SPhilip Reames br i1 %unknown, label %guarded2, label %deopt3, !prof !0 330*ad5a84c8SPhilip Reames 331*ad5a84c8SPhilip Reamesdeopt3: 332*ad5a84c8SPhilip Reames call void @unknown() 333*ad5a84c8SPhilip Reames %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 334*ad5a84c8SPhilip Reames ret i32 %deoptret3 335*ad5a84c8SPhilip Reames 336*ad5a84c8SPhilip Reamesguarded2: 337*ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 338*ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 339*ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 340*ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 341*ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 342*ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 343*ad5a84c8SPhilip Reames %continue = icmp ult i32 %i.next, %n 344*ad5a84c8SPhilip Reames br i1 %continue, label %loop, label %exit 345*ad5a84c8SPhilip Reames 346*ad5a84c8SPhilip Reamesexit: 347*ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded2 ] 348*ad5a84c8SPhilip Reames ret i32 %result 349*ad5a84c8SPhilip Reames} 350*ad5a84c8SPhilip Reames 351*ad5a84c8SPhilip Reamesdefine i32 @test_unanalyzeable_exit2(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 352*ad5a84c8SPhilip Reames; CHECK-LABEL: @test_unanalyzeable_exit2( 353*ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 354*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 355*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], 1 356*ad5a84c8SPhilip Reames; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1 357*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[UMAX]], -1 358*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[LENGTH:%.*]], [[TMP1]] 359*ad5a84c8SPhilip Reames; CHECK-NEXT: [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]] 360*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]] 361*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]] 362*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[COND_0:%.*]] 363*ad5a84c8SPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND]] 364*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 365*ad5a84c8SPhilip Reames; CHECK: deopt: 366*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 367*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 368*ad5a84c8SPhilip Reames; CHECK: loop.preheader: 369*ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 370*ad5a84c8SPhilip Reames; CHECK: loop: 371*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 372*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ] 373*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 374*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 375*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0 376*ad5a84c8SPhilip Reames; CHECK: deopt2: 377*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 378*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 379*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 380*ad5a84c8SPhilip Reames; CHECK: guarded: 381*ad5a84c8SPhilip Reames; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, i32* @G 382*ad5a84c8SPhilip Reames; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0 383*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0 384*ad5a84c8SPhilip Reames; CHECK: deopt3: 385*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 386*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 387*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET3]] 388*ad5a84c8SPhilip Reames; CHECK: guarded2: 389*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 390*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 391*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 392*ad5a84c8SPhilip Reames; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]] 393*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 394*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 395*ad5a84c8SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 396*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 397*ad5a84c8SPhilip Reames; CHECK: exit: 398*ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ] 399*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 400*ad5a84c8SPhilip Reames; 401*ad5a84c8SPhilip Reamesentry: 402*ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 403*ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 404*ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 405*ad5a84c8SPhilip Reames 406*ad5a84c8SPhilip Reamesdeopt: 407*ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 408*ad5a84c8SPhilip Reames ret i32 %deoptret 409*ad5a84c8SPhilip Reames 410*ad5a84c8SPhilip Reamesloop.preheader: 411*ad5a84c8SPhilip Reames br label %loop 412*ad5a84c8SPhilip Reames 413*ad5a84c8SPhilip Reamesloop: 414*ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ] 415*ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ] 416*ad5a84c8SPhilip Reames call void @unknown() 417*ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, %length 418*ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 419*ad5a84c8SPhilip Reames 420*ad5a84c8SPhilip Reamesdeopt2: 421*ad5a84c8SPhilip Reames call void @unknown() 422*ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 423*ad5a84c8SPhilip Reames ret i32 %deoptret2 424*ad5a84c8SPhilip Reames 425*ad5a84c8SPhilip Reamesguarded: 426*ad5a84c8SPhilip Reames %vol = load volatile i32, i32* @G 427*ad5a84c8SPhilip Reames %unknown = icmp eq i32 %vol, 0 428*ad5a84c8SPhilip Reames br i1 %unknown, label %guarded2, label %deopt3, !prof !0 429*ad5a84c8SPhilip Reames 430*ad5a84c8SPhilip Reamesdeopt3: 431*ad5a84c8SPhilip Reames call void @unknown() 432*ad5a84c8SPhilip Reames %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 433*ad5a84c8SPhilip Reames ret i32 %deoptret3 434*ad5a84c8SPhilip Reames 435*ad5a84c8SPhilip Reamesguarded2: 436*ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 437*ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 438*ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 439*ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 440*ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 441*ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 442*ad5a84c8SPhilip Reames %continue = icmp ult i32 %i.next, %n 443*ad5a84c8SPhilip Reames br i1 %continue, label %loop, label %exit 444*ad5a84c8SPhilip Reames 445*ad5a84c8SPhilip Reamesexit: 446*ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded2 ] 447*ad5a84c8SPhilip Reames ret i32 %result 448*ad5a84c8SPhilip Reames} 449*ad5a84c8SPhilip Reames 450*ad5a84c8SPhilip Reames 451*ad5a84c8SPhilip Reamesdefine i32 @test_unanalyzeable_latch(i32* %array, i32 %length, i32 %n, i1 %cond_0) { 452*ad5a84c8SPhilip Reames; CHECK-LABEL: @test_unanalyzeable_latch( 453*ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 454*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 455*ad5a84c8SPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]] 456*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 457*ad5a84c8SPhilip Reames; CHECK: deopt: 458*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 459*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 460*ad5a84c8SPhilip Reames; CHECK: loop.preheader: 461*ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 462*ad5a84c8SPhilip Reames; CHECK: loop: 463*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 464*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 465*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 466*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 467*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 468*ad5a84c8SPhilip Reames; CHECK: deopt2: 469*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 470*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 471*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 472*ad5a84c8SPhilip Reames; CHECK: guarded: 473*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 474*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 475*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 476*ad5a84c8SPhilip Reames; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]] 477*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 478*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 479*ad5a84c8SPhilip Reames; CHECK-NEXT: [[VOL:%.*]] = load volatile i32, i32* @G 480*ad5a84c8SPhilip Reames; CHECK-NEXT: [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0 481*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[UNKNOWN]], label [[LOOP]], label [[EXIT:%.*]] 482*ad5a84c8SPhilip Reames; CHECK: exit: 483*ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 484*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 485*ad5a84c8SPhilip Reames; 486*ad5a84c8SPhilip Reamesentry: 487*ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 488*ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 489*ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 490*ad5a84c8SPhilip Reames 491*ad5a84c8SPhilip Reamesdeopt: 492*ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 493*ad5a84c8SPhilip Reames ret i32 %deoptret 494*ad5a84c8SPhilip Reames 495*ad5a84c8SPhilip Reamesloop.preheader: 496*ad5a84c8SPhilip Reames br label %loop 497*ad5a84c8SPhilip Reames 498*ad5a84c8SPhilip Reamesloop: 499*ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 500*ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 501*ad5a84c8SPhilip Reames call void @unknown() 502*ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, %length 503*ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 504*ad5a84c8SPhilip Reames 505*ad5a84c8SPhilip Reamesdeopt2: 506*ad5a84c8SPhilip Reames call void @unknown() 507*ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 508*ad5a84c8SPhilip Reames ret i32 %deoptret2 509*ad5a84c8SPhilip Reames 510*ad5a84c8SPhilip Reamesguarded: 511*ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 512*ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 513*ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 514*ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 515*ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 516*ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 517*ad5a84c8SPhilip Reames %vol = load volatile i32, i32* @G 518*ad5a84c8SPhilip Reames %unknown = icmp eq i32 %vol, 0 519*ad5a84c8SPhilip Reames br i1 %unknown, label %loop, label %exit 520*ad5a84c8SPhilip Reames 521*ad5a84c8SPhilip Reamesexit: 522*ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded ] 523*ad5a84c8SPhilip Reames ret i32 %result 524*ad5a84c8SPhilip Reames} 525*ad5a84c8SPhilip Reames 526*ad5a84c8SPhilip Reames 527*ad5a84c8SPhilip Reamesdefine i32 @provably_taken(i32* %array, i1 %cond_0) { 528*ad5a84c8SPhilip Reames; CHECK-LABEL: @provably_taken( 529*ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 530*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 531*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 false 532*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]] 533*ad5a84c8SPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]] 534*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 535*ad5a84c8SPhilip Reames; CHECK: deopt: 536*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 537*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 538*ad5a84c8SPhilip Reames; CHECK: loop.preheader: 539*ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 540*ad5a84c8SPhilip Reames; CHECK: loop: 541*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 542*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 543*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 544*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 198 545*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 546*ad5a84c8SPhilip Reames; CHECK: deopt2: 547*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 548*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 549*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 550*ad5a84c8SPhilip Reames; CHECK: guarded: 551*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 552*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 553*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 554*ad5a84c8SPhilip Reames; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]] 555*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 556*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 557*ad5a84c8SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200 558*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 559*ad5a84c8SPhilip Reames; CHECK: exit: 560*ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 561*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 562*ad5a84c8SPhilip Reames; 563*ad5a84c8SPhilip Reamesentry: 564*ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 565*ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 566*ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 567*ad5a84c8SPhilip Reames 568*ad5a84c8SPhilip Reamesdeopt: 569*ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 570*ad5a84c8SPhilip Reames ret i32 %deoptret 571*ad5a84c8SPhilip Reames 572*ad5a84c8SPhilip Reamesloop.preheader: 573*ad5a84c8SPhilip Reames br label %loop 574*ad5a84c8SPhilip Reames 575*ad5a84c8SPhilip Reamesloop: 576*ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 577*ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 578*ad5a84c8SPhilip Reames call void @unknown() 579*ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, 198 580*ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 581*ad5a84c8SPhilip Reames 582*ad5a84c8SPhilip Reamesdeopt2: 583*ad5a84c8SPhilip Reames call void @unknown() 584*ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 585*ad5a84c8SPhilip Reames ret i32 %deoptret2 586*ad5a84c8SPhilip Reames 587*ad5a84c8SPhilip Reamesguarded: 588*ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 589*ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 590*ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 591*ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 592*ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 593*ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 594*ad5a84c8SPhilip Reames %continue = icmp ult i32 %i.next, 200 595*ad5a84c8SPhilip Reames br i1 %continue, label %loop, label %exit 596*ad5a84c8SPhilip Reames 597*ad5a84c8SPhilip Reamesexit: 598*ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded ] 599*ad5a84c8SPhilip Reames ret i32 %result 600*ad5a84c8SPhilip Reames} 601*ad5a84c8SPhilip Reames 602*ad5a84c8SPhilip Reamesdefine i32 @provably_not_taken(i32* %array, i1 %cond_0) { 603*ad5a84c8SPhilip Reames; CHECK-LABEL: @provably_not_taken( 604*ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 605*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 606*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP0:%.*]] = freeze i1 true 607*ad5a84c8SPhilip Reames; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]] 608*ad5a84c8SPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]] 609*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 610*ad5a84c8SPhilip Reames; CHECK: deopt: 611*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 612*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 613*ad5a84c8SPhilip Reames; CHECK: loop.preheader: 614*ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 615*ad5a84c8SPhilip Reames; CHECK: loop: 616*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 617*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 618*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 619*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 205 620*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 621*ad5a84c8SPhilip Reames; CHECK: deopt2: 622*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 623*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 624*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 625*ad5a84c8SPhilip Reames; CHECK: guarded: 626*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 627*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 628*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 629*ad5a84c8SPhilip Reames; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]] 630*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 631*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 632*ad5a84c8SPhilip Reames; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200 633*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]] 634*ad5a84c8SPhilip Reames; CHECK: exit: 635*ad5a84c8SPhilip Reames; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 636*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[RESULT]] 637*ad5a84c8SPhilip Reames; 638*ad5a84c8SPhilip Reamesentry: 639*ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 640*ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 641*ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 642*ad5a84c8SPhilip Reames 643*ad5a84c8SPhilip Reamesdeopt: 644*ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 645*ad5a84c8SPhilip Reames ret i32 %deoptret 646*ad5a84c8SPhilip Reames 647*ad5a84c8SPhilip Reamesloop.preheader: 648*ad5a84c8SPhilip Reames br label %loop 649*ad5a84c8SPhilip Reames 650*ad5a84c8SPhilip Reamesloop: 651*ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 652*ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 653*ad5a84c8SPhilip Reames call void @unknown() 654*ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, 205 655*ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 656*ad5a84c8SPhilip Reames 657*ad5a84c8SPhilip Reamesdeopt2: 658*ad5a84c8SPhilip Reames call void @unknown() 659*ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 660*ad5a84c8SPhilip Reames ret i32 %deoptret2 661*ad5a84c8SPhilip Reames 662*ad5a84c8SPhilip Reamesguarded: 663*ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 664*ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 665*ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 666*ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 667*ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 668*ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 669*ad5a84c8SPhilip Reames %continue = icmp ult i32 %i.next, 200 670*ad5a84c8SPhilip Reames br i1 %continue, label %loop, label %exit 671*ad5a84c8SPhilip Reames 672*ad5a84c8SPhilip Reamesexit: 673*ad5a84c8SPhilip Reames %result = phi i32 [ %loop.acc.next, %guarded ] 674*ad5a84c8SPhilip Reames ret i32 %result 675*ad5a84c8SPhilip Reames} 676*ad5a84c8SPhilip Reames 677*ad5a84c8SPhilip Reames 678*ad5a84c8SPhilip Reames 679*ad5a84c8SPhilip Reames 680*ad5a84c8SPhilip Reames 681*ad5a84c8SPhilip Reames 682*ad5a84c8SPhilip Reames 683*ad5a84c8SPhilip Reames 684*ad5a84c8SPhilip Reames; TODO: Non-latch exits can still be predicated 685*ad5a84c8SPhilip Reames; This is currently prevented by an overly restrictive profitability check. 686*ad5a84c8SPhilip Reamesdefine i32 @todo_unconditional_latch(i32* %array, i32 %length, i1 %cond_0) { 687*ad5a84c8SPhilip Reames; CHECK-LABEL: @todo_unconditional_latch( 688*ad5a84c8SPhilip Reames; CHECK-NEXT: entry: 689*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 690*ad5a84c8SPhilip Reames; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]] 691*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0 692*ad5a84c8SPhilip Reames; CHECK: deopt: 693*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 694*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET]] 695*ad5a84c8SPhilip Reames; CHECK: loop.preheader: 696*ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP:%.*]] 697*ad5a84c8SPhilip Reames; CHECK: loop: 698*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 699*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 700*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 701*ad5a84c8SPhilip Reames; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 702*ad5a84c8SPhilip Reames; CHECK-NEXT: br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0 703*ad5a84c8SPhilip Reames; CHECK: deopt2: 704*ad5a84c8SPhilip Reames; CHECK-NEXT: call void @unknown() 705*ad5a84c8SPhilip Reames; CHECK-NEXT: [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 706*ad5a84c8SPhilip Reames; CHECK-NEXT: ret i32 [[DEOPTRET2]] 707*ad5a84c8SPhilip Reames; CHECK: guarded: 708*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 709*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]] 710*ad5a84c8SPhilip Reames; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4 711*ad5a84c8SPhilip Reames; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]] 712*ad5a84c8SPhilip Reames; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 713*ad5a84c8SPhilip Reames; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 714*ad5a84c8SPhilip Reames; CHECK-NEXT: br label [[LOOP]] 715*ad5a84c8SPhilip Reames; 716*ad5a84c8SPhilip Reamesentry: 717*ad5a84c8SPhilip Reames %widenable_cond = call i1 @llvm.experimental.widenable.condition() 718*ad5a84c8SPhilip Reames %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond 719*ad5a84c8SPhilip Reames br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0 720*ad5a84c8SPhilip Reames 721*ad5a84c8SPhilip Reamesdeopt: 722*ad5a84c8SPhilip Reames %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 723*ad5a84c8SPhilip Reames ret i32 %deoptret 724*ad5a84c8SPhilip Reames 725*ad5a84c8SPhilip Reamesloop.preheader: 726*ad5a84c8SPhilip Reames br label %loop 727*ad5a84c8SPhilip Reames 728*ad5a84c8SPhilip Reamesloop: 729*ad5a84c8SPhilip Reames %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 730*ad5a84c8SPhilip Reames %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 731*ad5a84c8SPhilip Reames call void @unknown() 732*ad5a84c8SPhilip Reames %within.bounds = icmp ult i32 %i, %length 733*ad5a84c8SPhilip Reames br i1 %within.bounds, label %guarded, label %deopt2, !prof !0 734*ad5a84c8SPhilip Reames 735*ad5a84c8SPhilip Reamesdeopt2: 736*ad5a84c8SPhilip Reames call void @unknown() 737*ad5a84c8SPhilip Reames %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ] 738*ad5a84c8SPhilip Reames ret i32 %deoptret2 739*ad5a84c8SPhilip Reames 740*ad5a84c8SPhilip Reamesguarded: 741*ad5a84c8SPhilip Reames %i.i64 = zext i32 %i to i64 742*ad5a84c8SPhilip Reames %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 743*ad5a84c8SPhilip Reames %array.i = load i32, i32* %array.i.ptr, align 4 744*ad5a84c8SPhilip Reames store i32 0, i32* %array.i.ptr 745*ad5a84c8SPhilip Reames %loop.acc.next = add i32 %loop.acc, %array.i 746*ad5a84c8SPhilip Reames %i.next = add nuw i32 %i, 1 747*ad5a84c8SPhilip Reames br label %loop 748*ad5a84c8SPhilip Reames} 749*ad5a84c8SPhilip Reames 750*ad5a84c8SPhilip Reames 751*ad5a84c8SPhilip Reamesdeclare void @unknown() 752*ad5a84c8SPhilip Reames 753*ad5a84c8SPhilip Reamesdeclare i1 @llvm.experimental.widenable.condition() 754*ad5a84c8SPhilip Reamesdeclare i32 @llvm.experimental.deoptimize.i32(...) 755*ad5a84c8SPhilip Reames 756*ad5a84c8SPhilip Reames!0 = !{!"branch_weights", i32 1048576, i32 1} 757*ad5a84c8SPhilip Reames!1 = !{i32 1, i32 -2147483648} 758*ad5a84c8SPhilip Reames!2 = !{i32 0, i32 50} 759