1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=loop-predication -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s 3; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s 4; RUN: opt -S -passes='require<scalar-evolution>,require<branch-prob>,loop-mssa(loop-predication)' -verify-memoryssa -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s 5 6declare void @llvm.experimental.guard(i1, ...) 7 8define i32 @unsigned_loop_0_to_n_ult_check(ptr %array, i32 %length, i32 %n) { 9; CHECK-LABEL: @unsigned_loop_0_to_n_ult_check( 10; CHECK-NEXT: entry: 11; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 12; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 13; CHECK: loop.preheader: 14; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]] 15; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 16; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 17; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] 18; CHECK-NEXT: br label [[LOOP:%.*]] 19; CHECK: loop: 20; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 21; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 22; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 23; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 24; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 25; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]] 26; CHECK: deopt: 27; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 28; CHECK-NEXT: ret i32 [[DEOPTCALL]] 29; CHECK: guarded: 30; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 31; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 32; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 33; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 34; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 35; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 36; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 37; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1:![0-9]+]] 38; CHECK: exit.loopexit: 39; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 40; CHECK-NEXT: br label [[EXIT]] 41; CHECK: exit: 42; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 43; CHECK-NEXT: ret i32 [[RESULT]] 44; 45entry: 46 %tmp5 = icmp eq i32 %n, 0 47 br i1 %tmp5, label %exit, label %loop.preheader 48 49loop.preheader: ; preds = %entry 50 br label %loop 51 52loop: ; preds = %guarded, %loop.preheader 53 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 54 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 55 %within.bounds = icmp ult i32 %i, %length 56 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 57 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 58 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 59 60deopt: ; preds = %loop 61 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 62 ret i32 %deoptcall 63 64guarded: ; preds = %loop 65 %i.i64 = zext i32 %i to i64 66 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 67 %array.i = load i32, ptr %array.i.ptr, align 4 68 %loop.acc.next = add i32 %loop.acc, %array.i 69 %i.next = add nuw i32 %i, 1 70 %continue = icmp ult i32 %i.next, %n 71 br i1 %continue, label %loop, label %exit, !prof !2 72 73exit: ; preds = %guarded, %entry 74 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 75 ret i32 %result 76} 77 78define i32 @unsigned_loop_0_to_n_ule_latch_ult_check(ptr %array, i32 %length, i32 %n) { 79; CHECK-LABEL: @unsigned_loop_0_to_n_ule_latch_ult_check( 80; CHECK-NEXT: entry: 81; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 82; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 83; CHECK: loop.preheader: 84; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N]], [[LENGTH:%.*]] 85; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 86; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 87; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] 88; CHECK-NEXT: br label [[LOOP:%.*]] 89; CHECK: loop: 90; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 91; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 92; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 93; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 94; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 95; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 96; CHECK: deopt: 97; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 98; CHECK-NEXT: ret i32 [[DEOPTCALL]] 99; CHECK: guarded: 100; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 101; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 102; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 103; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 104; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 105; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 106; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ule i32 [[I_NEXT]], [[N]] 107; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 108; CHECK: exit.loopexit: 109; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 110; CHECK-NEXT: br label [[EXIT]] 111; CHECK: exit: 112; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 113; CHECK-NEXT: ret i32 [[RESULT]] 114; 115entry: 116 %tmp5 = icmp eq i32 %n, 0 117 br i1 %tmp5, label %exit, label %loop.preheader 118 119loop.preheader: ; preds = %entry 120 br label %loop 121 122loop: ; preds = %guarded, %loop.preheader 123 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 124 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 125 %within.bounds = icmp ult i32 %i, %length 126 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 127 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 128 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 129 130deopt: ; preds = %loop 131 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 132 ret i32 %deoptcall 133 134guarded: ; preds = %loop 135 %i.i64 = zext i32 %i to i64 136 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 137 %array.i = load i32, ptr %array.i.ptr, align 4 138 %loop.acc.next = add i32 %loop.acc, %array.i 139 %i.next = add nuw i32 %i, 1 140 %continue = icmp ule i32 %i.next, %n 141 br i1 %continue, label %loop, label %exit, !prof !2 142 143exit: ; preds = %guarded, %entry 144 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 145 ret i32 %result 146} 147 148define i32 @unsigned_loop_0_to_n_ugt_check(ptr %array, i32 %length, i32 %n) { 149; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check( 150; CHECK-NEXT: entry: 151; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 152; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 153; CHECK: loop.preheader: 154; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]] 155; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 156; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 157; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] 158; CHECK-NEXT: br label [[LOOP:%.*]] 159; CHECK: loop: 160; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 161; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 162; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ugt i32 [[LENGTH]], [[I]] 163; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 164; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 165; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 166; CHECK: deopt: 167; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 168; CHECK-NEXT: ret i32 [[DEOPTCALL]] 169; CHECK: guarded: 170; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 171; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 172; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 173; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 174; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 175; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 176; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 177; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 178; CHECK: exit.loopexit: 179; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 180; CHECK-NEXT: br label [[EXIT]] 181; CHECK: exit: 182; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 183; CHECK-NEXT: ret i32 [[RESULT]] 184; 185entry: 186 %tmp5 = icmp eq i32 %n, 0 187 br i1 %tmp5, label %exit, label %loop.preheader 188 189loop.preheader: ; preds = %entry 190 br label %loop 191 192loop: ; preds = %guarded, %loop.preheader 193 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 194 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 195 %within.bounds = icmp ugt i32 %length, %i 196 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 197 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 198 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 199 200deopt: ; preds = %loop 201 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 202 ret i32 %deoptcall 203 204guarded: ; preds = %loop 205 %i.i64 = zext i32 %i to i64 206 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 207 %array.i = load i32, ptr %array.i.ptr, align 4 208 %loop.acc.next = add i32 %loop.acc, %array.i 209 %i.next = add nuw i32 %i, 1 210 %continue = icmp ult i32 %i.next, %n 211 br i1 %continue, label %loop, label %exit, !prof !2 212 213exit: ; preds = %guarded, %entry 214 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 215 ret i32 %result 216} 217 218define i32 @signed_loop_0_to_n_ult_check(ptr %array, i32 %length, i32 %n) { 219; CHECK-LABEL: @signed_loop_0_to_n_ult_check( 220; CHECK-NEXT: entry: 221; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 222; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 223; CHECK: loop.preheader: 224; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]] 225; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 226; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 227; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] 228; CHECK-NEXT: br label [[LOOP:%.*]] 229; CHECK: loop: 230; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 231; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 232; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 233; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 234; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 235; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 236; CHECK: deopt: 237; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 238; CHECK-NEXT: ret i32 [[DEOPTCALL]] 239; CHECK: guarded: 240; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 241; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 242; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 243; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 244; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 245; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 246; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 247; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 248; CHECK: exit.loopexit: 249; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 250; CHECK-NEXT: br label [[EXIT]] 251; CHECK: exit: 252; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 253; CHECK-NEXT: ret i32 [[RESULT]] 254; 255 256entry: 257 %tmp5 = icmp sle i32 %n, 0 258 br i1 %tmp5, label %exit, label %loop.preheader 259 260loop.preheader: ; preds = %entry 261 br label %loop 262 263loop: ; preds = %guarded, %loop.preheader 264 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 265 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 266 %within.bounds = icmp ult i32 %i, %length 267 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 268 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 269 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 270 271deopt: ; preds = %loop 272 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 273 ret i32 %deoptcall 274 275guarded: ; preds = %loop 276 %i.i64 = zext i32 %i to i64 277 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 278 %array.i = load i32, ptr %array.i.ptr, align 4 279 %loop.acc.next = add i32 %loop.acc, %array.i 280 %i.next = add nuw i32 %i, 1 281 %continue = icmp slt i32 %i.next, %n 282 br i1 %continue, label %loop, label %exit, !prof !2 283 284exit: ; preds = %guarded, %entry 285 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 286 ret i32 %result 287} 288 289define i32 @signed_loop_0_to_n_ult_check_length_range_known(ptr %array, ptr %length.ptr, i32 %n) { 290; CHECK-LABEL: @signed_loop_0_to_n_ult_check_length_range_known( 291; CHECK-NEXT: entry: 292; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 293; CHECK-NEXT: [[LENGTH:%.*]] = load i32, ptr [[LENGTH_PTR:%.*]], align 4, !range [[RNG2:![0-9]+]] 294; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 295; CHECK: loop.preheader: 296; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH]] 297; CHECK-NEXT: [[TMP1:%.*]] = and i1 true, [[TMP0]] 298; CHECK-NEXT: [[TMP2:%.*]] = freeze i1 [[TMP1]] 299; CHECK-NEXT: br label [[LOOP:%.*]] 300; CHECK: loop: 301; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 302; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 303; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 304; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 305; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]] 306; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 307; CHECK: deopt: 308; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 309; CHECK-NEXT: ret i32 [[DEOPTCALL]] 310; CHECK: guarded: 311; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 312; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 313; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 314; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 315; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 316; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 317; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 318; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 319; CHECK: exit.loopexit: 320; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 321; CHECK-NEXT: br label [[EXIT]] 322; CHECK: exit: 323; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 324; CHECK-NEXT: ret i32 [[RESULT]] 325; 326entry: 327 %tmp5 = icmp sle i32 %n, 0 328 %length = load i32, ptr %length.ptr, !range !1 329 br i1 %tmp5, label %exit, label %loop.preheader 330 331loop.preheader: ; preds = %entry 332 br label %loop 333 334loop: ; preds = %guarded, %loop.preheader 335 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 336 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 337 %within.bounds = icmp ult i32 %i, %length 338 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 339 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 340 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 341 342deopt: ; preds = %loop 343 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 344 ret i32 %deoptcall 345 346guarded: ; preds = %loop 347 %i.i64 = zext i32 %i to i64 348 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 349 %array.i = load i32, ptr %array.i.ptr, align 4 350 %loop.acc.next = add i32 %loop.acc, %array.i 351 %i.next = add nuw i32 %i, 1 352 %continue = icmp slt i32 %i.next, %n 353 br i1 %continue, label %loop, label %exit, !prof !2 354 355exit: ; preds = %guarded, %entry 356 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 357 ret i32 %result 358} 359 360define i32 @signed_loop_0_to_n_inverse_latch_predicate(ptr %array, i32 %length, i32 %n) { 361; CHECK-LABEL: @signed_loop_0_to_n_inverse_latch_predicate( 362; CHECK-NEXT: entry: 363; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 364; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 365; CHECK: loop.preheader: 366; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]] 367; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 368; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 369; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] 370; CHECK-NEXT: br label [[LOOP:%.*]] 371; CHECK: loop: 372; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 373; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 374; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 375; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 376; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 377; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 378; CHECK: deopt: 379; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 380; CHECK-NEXT: ret i32 [[DEOPTCALL]] 381; CHECK: guarded: 382; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 383; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 384; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 385; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 386; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 387; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 388; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[I_NEXT]], [[N]] 389; CHECK-NEXT: br i1 [[CONTINUE]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]], !prof [[PROF1]] 390; CHECK: exit.loopexit: 391; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 392; CHECK-NEXT: br label [[EXIT]] 393; CHECK: exit: 394; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 395; CHECK-NEXT: ret i32 [[RESULT]] 396; 397entry: 398 %tmp5 = icmp sle i32 %n, 0 399 br i1 %tmp5, label %exit, label %loop.preheader 400 401loop.preheader: ; preds = %entry 402 br label %loop 403 404loop: ; preds = %guarded, %loop.preheader 405 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 406 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 407 %within.bounds = icmp ult i32 %i, %length 408 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 409 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 410 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 411 412deopt: ; preds = %loop 413 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 414 ret i32 %deoptcall 415 416guarded: ; preds = %loop 417 %i.i64 = zext i32 %i to i64 418 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 419 %array.i = load i32, ptr %array.i.ptr, align 4 420 %loop.acc.next = add i32 %loop.acc, %array.i 421 %i.next = add nuw i32 %i, 1 422 %continue = icmp sgt i32 %i.next, %n 423 br i1 %continue, label %exit, label %loop, !prof !2 424 425exit: ; preds = %guarded, %entry 426 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 427 ret i32 %result 428} 429 430define i32 @signed_loop_0_to_n_sle_latch_ult_check(ptr %array, i32 %length, i32 %n) { 431; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_ult_check( 432; CHECK-NEXT: entry: 433; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 434; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 435; CHECK: loop.preheader: 436; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]] 437; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 438; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 439; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] 440; CHECK-NEXT: br label [[LOOP:%.*]] 441; CHECK: loop: 442; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 443; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 444; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 445; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 446; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 447; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 448; CHECK: deopt: 449; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 450; CHECK-NEXT: ret i32 [[DEOPTCALL]] 451; CHECK: guarded: 452; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 453; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 454; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 455; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 456; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 457; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 458; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]] 459; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 460; CHECK: exit.loopexit: 461; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 462; CHECK-NEXT: br label [[EXIT]] 463; CHECK: exit: 464; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 465; CHECK-NEXT: ret i32 [[RESULT]] 466; 467entry: 468 %tmp5 = icmp sle i32 %n, 0 469 br i1 %tmp5, label %exit, label %loop.preheader 470 471loop.preheader: ; preds = %entry 472 br label %loop 473 474loop: ; preds = %guarded, %loop.preheader 475 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 476 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 477 %within.bounds = icmp ult i32 %i, %length 478 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 479 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 480 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 481 482deopt: ; preds = %loop 483 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 484 ret i32 %deoptcall 485 486guarded: ; preds = %loop 487 %i.i64 = zext i32 %i to i64 488 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 489 %array.i = load i32, ptr %array.i.ptr, align 4 490 %loop.acc.next = add i32 %loop.acc, %array.i 491 %i.next = add nuw i32 %i, 1 492 %continue = icmp sle i32 %i.next, %n 493 br i1 %continue, label %loop, label %exit, !prof !2 494 495exit: ; preds = %guarded, %entry 496 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 497 ret i32 %result 498} 499 500define i32 @signed_loop_0_to_n_preincrement_latch_check(ptr %array, i32 %length, i32 %n) { 501; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check( 502; CHECK-NEXT: entry: 503; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 504; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 505; CHECK: loop.preheader: 506; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1 507; CHECK-NEXT: [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]] 508; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]] 509; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] 510; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]] 511; CHECK-NEXT: br label [[LOOP:%.*]] 512; CHECK: loop: 513; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 514; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 515; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 516; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 517; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]] 518; CHECK-NEXT: br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 519; CHECK: deopt: 520; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 521; CHECK-NEXT: ret i32 [[DEOPTCALL]] 522; CHECK: guarded: 523; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 524; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 525; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 526; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 527; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 528; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 529; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]] 530; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 531; CHECK: exit.loopexit: 532; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 533; CHECK-NEXT: br label [[EXIT]] 534; CHECK: exit: 535; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 536; CHECK-NEXT: ret i32 [[RESULT]] 537; 538entry: 539 %tmp5 = icmp sle i32 %n, 0 540 br i1 %tmp5, label %exit, label %loop.preheader 541 542loop.preheader: ; preds = %entry 543 br label %loop 544 545loop: ; preds = %guarded, %loop.preheader 546 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 547 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 548 %within.bounds = icmp ult i32 %i, %length 549 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 550 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 551 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 552 553deopt: ; preds = %loop 554 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 555 ret i32 %deoptcall 556 557guarded: ; preds = %loop 558 %i.i64 = zext i32 %i to i64 559 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 560 %array.i = load i32, ptr %array.i.ptr, align 4 561 %loop.acc.next = add i32 %loop.acc, %array.i 562 %i.next = add i32 %i, 1 563 %continue = icmp slt i32 %i, %n 564 br i1 %continue, label %loop, label %exit, !prof !2 565 566exit: ; preds = %guarded, %entry 567 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 568 ret i32 %result 569} 570 571define i32 @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(ptr %array, i32 %length, i32 %n) { 572; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check( 573; CHECK-NEXT: entry: 574; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 575; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 576; CHECK: loop.preheader: 577; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -2 578; CHECK-NEXT: [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]] 579; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]] 580; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] 581; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]] 582; CHECK-NEXT: br label [[LOOP:%.*]] 583; CHECK: loop: 584; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 585; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 586; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 587; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]] 588; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 589; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]] 590; CHECK-NEXT: br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 591; CHECK: deopt: 592; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 593; CHECK-NEXT: ret i32 [[DEOPTCALL]] 594; CHECK: guarded: 595; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 596; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 597; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 598; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 599; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 600; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]] 601; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 602; CHECK: exit.loopexit: 603; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 604; CHECK-NEXT: br label [[EXIT]] 605; CHECK: exit: 606; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 607; CHECK-NEXT: ret i32 [[RESULT]] 608; 609entry: 610 %tmp5 = icmp sle i32 %n, 0 611 br i1 %tmp5, label %exit, label %loop.preheader 612 613loop.preheader: ; preds = %entry 614 br label %loop 615 616loop: ; preds = %guarded, %loop.preheader 617 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 618 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 619 %i.next = add i32 %i, 1 620 %within.bounds = icmp ult i32 %i.next, %length 621 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 622 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 623 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 624 625deopt: ; preds = %loop 626 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 627 ret i32 %deoptcall 628 629guarded: ; preds = %loop 630 %i.i64 = zext i32 %i to i64 631 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 632 %array.i = load i32, ptr %array.i.ptr, align 4 633 %loop.acc.next = add i32 %loop.acc, %array.i 634 %continue = icmp slt i32 %i, %n 635 br i1 %continue, label %loop, label %exit, !prof !2 636 637exit: ; preds = %guarded, %entry 638 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 639 ret i32 %result 640} 641 642define i32 @signed_loop_0_to_n_sle_latch_offset_ult_check(ptr %array, i32 %length, i32 %n) { 643; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_offset_ult_check( 644; CHECK-NEXT: entry: 645; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 646; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 647; CHECK: loop.preheader: 648; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1 649; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[N]], [[TMP0]] 650; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]] 651; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] 652; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]] 653; CHECK-NEXT: br label [[LOOP:%.*]] 654; CHECK: loop: 655; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 656; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 657; CHECK-NEXT: [[I_OFFSET:%.*]] = add i32 [[I]], 1 658; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_OFFSET]], [[LENGTH]] 659; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 660; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]] 661; CHECK-NEXT: br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 662; CHECK: deopt: 663; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 664; CHECK-NEXT: ret i32 [[DEOPTCALL]] 665; CHECK: guarded: 666; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 667; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 668; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 669; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 670; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 671; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 672; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]] 673; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 674; CHECK: exit.loopexit: 675; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 676; CHECK-NEXT: br label [[EXIT]] 677; CHECK: exit: 678; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 679; CHECK-NEXT: ret i32 [[RESULT]] 680; 681entry: 682 %tmp5 = icmp sle i32 %n, 0 683 br i1 %tmp5, label %exit, label %loop.preheader 684 685loop.preheader: ; preds = %entry 686 br label %loop 687 688loop: ; preds = %guarded, %loop.preheader 689 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 690 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 691 %i.offset = add i32 %i, 1 692 %within.bounds = icmp ult i32 %i.offset, %length 693 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 694 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 695 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 696 697deopt: ; preds = %loop 698 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 699 ret i32 %deoptcall 700 701guarded: ; preds = %loop 702 %i.i64 = zext i32 %i to i64 703 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 704 %array.i = load i32, ptr %array.i.ptr, align 4 705 %loop.acc.next = add i32 %loop.acc, %array.i 706 %i.next = add i32 %i, 1 707 %continue = icmp sle i32 %i.next, %n 708 br i1 %continue, label %loop, label %exit, !prof !2 709 710exit: ; preds = %guarded, %entry 711 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 712 ret i32 %result 713} 714 715define i32 @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(ptr %array, i32 %length, i32 %n) { 716; CHECK-LABEL: @signed_loop_0_to_n_offset_sle_latch_offset_ult_check( 717; CHECK-NEXT: entry: 718; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 719; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 720; CHECK: loop.preheader: 721; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]] 722; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 1, [[LENGTH]] 723; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 724; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] 725; CHECK-NEXT: br label [[LOOP:%.*]] 726; CHECK: loop: 727; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 728; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 729; CHECK-NEXT: [[I_OFFSET:%.*]] = add i32 [[I]], 1 730; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I_OFFSET]], [[LENGTH]] 731; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 732; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 733; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 734; CHECK: deopt: 735; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 736; CHECK-NEXT: ret i32 [[DEOPTCALL]] 737; CHECK: guarded: 738; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 739; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 740; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 741; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 742; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 743; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 744; CHECK-NEXT: [[I_NEXT_OFFSET:%.*]] = add i32 [[I_NEXT]], 1 745; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT_OFFSET]], [[N]] 746; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 747; CHECK: exit.loopexit: 748; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 749; CHECK-NEXT: br label [[EXIT]] 750; CHECK: exit: 751; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 752; CHECK-NEXT: ret i32 [[RESULT]] 753; 754entry: 755 %tmp5 = icmp sle i32 %n, 0 756 br i1 %tmp5, label %exit, label %loop.preheader 757 758loop.preheader: ; preds = %entry 759 br label %loop 760 761loop: ; preds = %guarded, %loop.preheader 762 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 763 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 764 %i.offset = add i32 %i, 1 765 %within.bounds = icmp ult i32 %i.offset, %length 766 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 767 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 768 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 769 770deopt: ; preds = %loop 771 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 772 ret i32 %deoptcall 773 774guarded: ; preds = %loop 775 %i.i64 = zext i32 %i to i64 776 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 777 %array.i = load i32, ptr %array.i.ptr, align 4 778 %loop.acc.next = add i32 %loop.acc, %array.i 779 %i.next = add i32 %i, 1 780 %i.next.offset = add i32 %i.next, 1 781 %continue = icmp sle i32 %i.next.offset, %n 782 br i1 %continue, label %loop, label %exit, !prof !2 783 784exit: ; preds = %guarded, %entry 785 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 786 ret i32 %result 787} 788 789define i32 @unsupported_latch_pred_loop_0_to_n(ptr %array, i32 %length, i32 %n) { 790; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n( 791; CHECK-NEXT: entry: 792; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 793; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 794; CHECK: loop.preheader: 795; CHECK-NEXT: br label [[LOOP:%.*]] 796; CHECK: loop: 797; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 798; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 799; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 800; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 801; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]] 802; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 803; CHECK: deopt: 804; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 805; CHECK-NEXT: ret i32 [[DEOPTCALL]] 806; CHECK: guarded: 807; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 808; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 809; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 810; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 811; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 812; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]] 813; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 814; CHECK: exit.loopexit: 815; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 816; CHECK-NEXT: br label [[EXIT]] 817; CHECK: exit: 818; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 819; CHECK-NEXT: ret i32 [[RESULT]] 820; 821entry: 822 %tmp5 = icmp sle i32 %n, 0 823 br i1 %tmp5, label %exit, label %loop.preheader 824 825loop.preheader: ; preds = %entry 826 br label %loop 827 828loop: ; preds = %guarded, %loop.preheader 829 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 830 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 831 %within.bounds = icmp ult i32 %i, %length 832 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 833 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 834 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 835 836deopt: ; preds = %loop 837 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 838 ret i32 %deoptcall 839 840guarded: ; preds = %loop 841 %i.i64 = zext i32 %i to i64 842 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 843 %array.i = load i32, ptr %array.i.ptr, align 4 844 %loop.acc.next = add i32 %loop.acc, %array.i 845 %i.next = add nsw i32 %i, 1 846 %continue = icmp ne i32 %i.next, %n 847 br i1 %continue, label %loop, label %exit, !prof !2 848 849exit: ; preds = %guarded, %entry 850 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 851 ret i32 %result 852} 853 854define i32 @signed_loop_0_to_n_unsupported_iv_step(ptr %array, i32 %length, i32 %n) { 855; CHECK-LABEL: @signed_loop_0_to_n_unsupported_iv_step( 856; CHECK-NEXT: entry: 857; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 858; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 859; CHECK: loop.preheader: 860; CHECK-NEXT: br label [[LOOP:%.*]] 861; CHECK: loop: 862; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 863; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 864; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 865; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 866; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]] 867; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 868; CHECK: deopt: 869; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 870; CHECK-NEXT: ret i32 [[DEOPTCALL]] 871; CHECK: guarded: 872; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 873; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 874; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 875; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 876; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 2 877; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 878; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 879; CHECK: exit.loopexit: 880; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 881; CHECK-NEXT: br label [[EXIT]] 882; CHECK: exit: 883; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 884; CHECK-NEXT: ret i32 [[RESULT]] 885; 886entry: 887 %tmp5 = icmp sle i32 %n, 0 888 br i1 %tmp5, label %exit, label %loop.preheader 889 890loop.preheader: ; preds = %entry 891 br label %loop 892 893loop: ; preds = %guarded, %loop.preheader 894 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 895 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 896 %within.bounds = icmp ult i32 %i, %length 897 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 898 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 899 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 900 901deopt: ; preds = %loop 902 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 903 ret i32 %deoptcall 904 905guarded: ; preds = %loop 906 %i.i64 = zext i32 %i to i64 907 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 908 %array.i = load i32, ptr %array.i.ptr, align 4 909 %loop.acc.next = add i32 %loop.acc, %array.i 910 %i.next = add nsw i32 %i, 2 911 %continue = icmp slt i32 %i.next, %n 912 br i1 %continue, label %loop, label %exit, !prof !2 913 914exit: ; preds = %guarded, %entry 915 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 916 ret i32 %result 917} 918 919define i32 @signed_loop_0_to_n_equal_iv_range_check(ptr %array, i32 %length, i32 %n) { 920; CHECK-LABEL: @signed_loop_0_to_n_equal_iv_range_check( 921; CHECK-NEXT: entry: 922; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 923; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 924; CHECK: loop.preheader: 925; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]] 926; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 927; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 928; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] 929; CHECK-NEXT: br label [[LOOP:%.*]] 930; CHECK: loop: 931; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 932; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 933; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 934; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]] 935; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 936; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 937; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 938; CHECK: deopt: 939; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 940; CHECK-NEXT: ret i32 [[DEOPTCALL]] 941; CHECK: guarded: 942; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 943; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 944; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 945; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 946; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 947; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 1 948; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 949; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 950; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 951; CHECK: exit.loopexit: 952; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 953; CHECK-NEXT: br label [[EXIT]] 954; CHECK: exit: 955; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 956; CHECK-NEXT: ret i32 [[RESULT]] 957; 958entry: 959 %tmp5 = icmp sle i32 %n, 0 960 br i1 %tmp5, label %exit, label %loop.preheader 961 962loop.preheader: ; preds = %entry 963 br label %loop 964 965loop: ; preds = %guarded, %loop.preheader 966 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 967 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 968 %j = phi i32 [ %j.next, %guarded ], [ 0, %loop.preheader ] 969 %within.bounds = icmp ult i32 %j, %length 970 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 971 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 972 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 973 974deopt: ; preds = %loop 975 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 976 ret i32 %deoptcall 977 978guarded: ; preds = %loop 979 %i.i64 = zext i32 %i to i64 980 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 981 %array.i = load i32, ptr %array.i.ptr, align 4 982 %loop.acc.next = add i32 %loop.acc, %array.i 983 %j.next = add nsw i32 %j, 1 984 %i.next = add nsw i32 %i, 1 985 %continue = icmp slt i32 %i.next, %n 986 br i1 %continue, label %loop, label %exit, !prof !2 987 988exit: ; preds = %guarded, %entry 989 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 990 ret i32 %result 991} 992 993define i32 @signed_loop_start_to_n_offset_iv_range_check(ptr %array, i32 %start.i, i32 %start.j, i32 %length, i32 %n) { 994; CHECK-LABEL: @signed_loop_start_to_n_offset_iv_range_check( 995; CHECK-NEXT: entry: 996; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 997; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 998; CHECK: loop.preheader: 999; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], [[START_I:%.*]] 1000; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], [[START_J:%.*]] 1001; CHECK-NEXT: [[TMP2:%.*]] = icmp sle i32 [[N]], [[TMP1]] 1002; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i32 [[START_J]], [[LENGTH]] 1003; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[TMP2]] 1004; CHECK-NEXT: [[TMP5:%.*]] = freeze i1 [[TMP4]] 1005; CHECK-NEXT: br label [[LOOP:%.*]] 1006; CHECK: loop: 1007; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 1008; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ [[START_I]], [[LOOP_PREHEADER]] ] 1009; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ [[START_J]], [[LOOP_PREHEADER]] ] 1010; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH]] 1011; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 1012; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND]] 1013; CHECK-NEXT: br i1 [[TMP6]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 1014; CHECK: deopt: 1015; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1016; CHECK-NEXT: ret i32 [[DEOPTCALL]] 1017; CHECK: guarded: 1018; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 1019; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1020; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 1021; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 1022; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1023; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1 1024; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 1025; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 1026; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 1027; CHECK: exit.loopexit: 1028; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 1029; CHECK-NEXT: br label [[EXIT]] 1030; CHECK: exit: 1031; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1032; CHECK-NEXT: ret i32 [[RESULT]] 1033; 1034entry: 1035 %tmp5 = icmp sle i32 %n, 0 1036 br i1 %tmp5, label %exit, label %loop.preheader 1037 1038loop.preheader: ; preds = %entry 1039 br label %loop 1040 1041loop: ; preds = %guarded, %loop.preheader 1042 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 1043 %i = phi i32 [ %i.next, %guarded ], [ %start.i, %loop.preheader ] 1044 %j = phi i32 [ %j.next, %guarded ], [ %start.j, %loop.preheader ] 1045 %within.bounds = icmp ult i32 %j, %length 1046 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 1047 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 1048 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 1049 1050deopt: ; preds = %loop 1051 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1052 ret i32 %deoptcall 1053 1054guarded: ; preds = %loop 1055 %i.i64 = zext i32 %i to i64 1056 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 1057 %array.i = load i32, ptr %array.i.ptr, align 4 1058 %loop.acc.next = add i32 %loop.acc, %array.i 1059 %j.next = add i32 %j, 1 1060 %i.next = add i32 %i, 1 1061 %continue = icmp slt i32 %i.next, %n 1062 br i1 %continue, label %loop, label %exit, !prof !2 1063 1064exit: ; preds = %guarded, %entry 1065 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 1066 ret i32 %result 1067} 1068 1069define i32 @signed_loop_0_to_n_different_iv_types(ptr %array, i16 %length, i32 %n) { 1070; CHECK-LABEL: @signed_loop_0_to_n_different_iv_types( 1071; CHECK-NEXT: entry: 1072; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 1073; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1074; CHECK: loop.preheader: 1075; CHECK-NEXT: br label [[LOOP:%.*]] 1076; CHECK: loop: 1077; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 1078; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 1079; CHECK-NEXT: [[J:%.*]] = phi i16 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 1080; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i16 [[J]], [[LENGTH:%.*]] 1081; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 1082; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]] 1083; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 1084; CHECK: deopt: 1085; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1086; CHECK-NEXT: ret i32 [[DEOPTCALL]] 1087; CHECK: guarded: 1088; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1089; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 1090; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 1091; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1092; CHECK-NEXT: [[J_NEXT]] = add i16 [[J]], 1 1093; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1 1094; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 1095; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 1096; CHECK: exit.loopexit: 1097; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 1098; CHECK-NEXT: br label [[EXIT]] 1099; CHECK: exit: 1100; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1101; CHECK-NEXT: ret i32 [[RESULT]] 1102; 1103entry: 1104 %tmp5 = icmp sle i32 %n, 0 1105 br i1 %tmp5, label %exit, label %loop.preheader 1106 1107loop.preheader: ; preds = %entry 1108 br label %loop 1109 1110loop: ; preds = %guarded, %loop.preheader 1111 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 1112 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 1113 %j = phi i16 [ %j.next, %guarded ], [ 0, %loop.preheader ] 1114 %within.bounds = icmp ult i16 %j, %length 1115 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 1116 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 1117 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 1118 1119deopt: ; preds = %loop 1120 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1121 ret i32 %deoptcall 1122 1123guarded: ; preds = %loop 1124 %i.i64 = zext i32 %i to i64 1125 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 1126 %array.i = load i32, ptr %array.i.ptr, align 4 1127 %loop.acc.next = add i32 %loop.acc, %array.i 1128 %j.next = add i16 %j, 1 1129 %i.next = add i32 %i, 1 1130 %continue = icmp slt i32 %i.next, %n 1131 br i1 %continue, label %loop, label %exit, !prof !2 1132 1133exit: ; preds = %guarded, %entry 1134 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 1135 ret i32 %result 1136} 1137 1138define i32 @signed_loop_0_to_n_different_iv_strides(ptr %array, i32 %length, i32 %n) { 1139; CHECK-LABEL: @signed_loop_0_to_n_different_iv_strides( 1140; CHECK-NEXT: entry: 1141; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 1142; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1143; CHECK: loop.preheader: 1144; CHECK-NEXT: br label [[LOOP:%.*]] 1145; CHECK: loop: 1146; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 1147; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 1148; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 1149; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH:%.*]] 1150; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 1151; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]] 1152; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 1153; CHECK: deopt: 1154; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1155; CHECK-NEXT: ret i32 [[DEOPTCALL]] 1156; CHECK: guarded: 1157; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1158; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 1159; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 1160; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1161; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 2 1162; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 1163; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 1164; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 1165; CHECK: exit.loopexit: 1166; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 1167; CHECK-NEXT: br label [[EXIT]] 1168; CHECK: exit: 1169; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1170; CHECK-NEXT: ret i32 [[RESULT]] 1171; 1172entry: 1173 %tmp5 = icmp sle i32 %n, 0 1174 br i1 %tmp5, label %exit, label %loop.preheader 1175 1176loop.preheader: ; preds = %entry 1177 br label %loop 1178 1179loop: ; preds = %guarded, %loop.preheader 1180 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 1181 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 1182 %j = phi i32 [ %j.next, %guarded ], [ 0, %loop.preheader ] 1183 %within.bounds = icmp ult i32 %j, %length 1184 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 1185 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 1186 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 1187 1188deopt: ; preds = %loop 1189 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1190 ret i32 %deoptcall 1191 1192guarded: ; preds = %loop 1193 %i.i64 = zext i32 %i to i64 1194 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 1195 %array.i = load i32, ptr %array.i.ptr, align 4 1196 %loop.acc.next = add i32 %loop.acc, %array.i 1197 %j.next = add nsw i32 %j, 2 1198 %i.next = add nsw i32 %i, 1 1199 %continue = icmp slt i32 %i.next, %n 1200 br i1 %continue, label %loop, label %exit, !prof !2 1201 1202exit: ; preds = %guarded, %entry 1203 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 1204 ret i32 %result 1205} 1206 1207define i32 @two_range_checks(ptr %array.1, i32 %length.1, ptr %array.2, i32 %length.2, i32 %n) { 1208; CHECK-LABEL: @two_range_checks( 1209; CHECK-NEXT: entry: 1210; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1211; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1212; CHECK: loop.preheader: 1213; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]] 1214; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_2]] 1215; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 1216; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] 1217; CHECK-NEXT: [[TMP4:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]] 1218; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i32 0, [[LENGTH_1]] 1219; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]] 1220; CHECK-NEXT: [[TMP7:%.*]] = freeze i1 [[TMP6]] 1221; CHECK-NEXT: br label [[LOOP:%.*]] 1222; CHECK: loop: 1223; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 1224; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 1225; CHECK-NEXT: [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]] 1226; CHECK-NEXT: [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]] 1227; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 1228; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[TMP3]], [[TMP7]] 1229; CHECK-NEXT: [[TMP9:%.*]] = and i1 [[TMP8]], [[WIDENABLE_COND]] 1230; CHECK-NEXT: br i1 [[TMP9]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 1231; CHECK: deopt: 1232; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1233; CHECK-NEXT: ret i32 [[DEOPTCALL]] 1234; CHECK: guarded: 1235; CHECK-NEXT: [[TMP10:%.*]] = and i1 [[WITHIN_BOUNDS_2]], [[WITHIN_BOUNDS_1]] 1236; CHECK-NEXT: call void @llvm.assume(i1 [[TMP10]]) 1237; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1238; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]] 1239; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 4 1240; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]] 1241; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_2:%.*]], i64 [[I_I64]] 1242; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, ptr [[ARRAY_2_I_PTR]], align 4 1243; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]] 1244; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1245; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1246; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 1247; CHECK: exit.loopexit: 1248; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 1249; CHECK-NEXT: br label [[EXIT]] 1250; CHECK: exit: 1251; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1252; CHECK-NEXT: ret i32 [[RESULT]] 1253; 1254entry: 1255 %tmp5 = icmp eq i32 %n, 0 1256 br i1 %tmp5, label %exit, label %loop.preheader 1257 1258loop.preheader: ; preds = %entry 1259 br label %loop 1260 1261loop: ; preds = %guarded, %loop.preheader 1262 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 1263 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 1264 %within.bounds.1 = icmp ult i32 %i, %length.1 1265 %within.bounds.2 = icmp ult i32 %i, %length.2 1266 %within.bounds = and i1 %within.bounds.1, %within.bounds.2 1267 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 1268 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 1269 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 1270 1271deopt: ; preds = %loop 1272 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1273 ret i32 %deoptcall 1274 1275guarded: ; preds = %loop 1276 %i.i64 = zext i32 %i to i64 1277 %array.1.i.ptr = getelementptr inbounds i32, ptr %array.1, i64 %i.i64 1278 %array.1.i = load i32, ptr %array.1.i.ptr, align 4 1279 %loop.acc.1 = add i32 %loop.acc, %array.1.i 1280 %array.2.i.ptr = getelementptr inbounds i32, ptr %array.2, i64 %i.i64 1281 %array.2.i = load i32, ptr %array.2.i.ptr, align 4 1282 %loop.acc.next = add i32 %loop.acc.1, %array.2.i 1283 %i.next = add nuw i32 %i, 1 1284 %continue = icmp ult i32 %i.next, %n 1285 br i1 %continue, label %loop, label %exit, !prof !2 1286 1287exit: ; preds = %guarded, %entry 1288 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 1289 ret i32 %result 1290} 1291 1292define i32 @three_range_checks(ptr %array.1, i32 %length.1, ptr %array.2, i32 %length.2, ptr %array.3, i32 %length.3, i32 %n) { 1293; CHECK-LABEL: @three_range_checks( 1294; CHECK-NEXT: entry: 1295; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1296; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1297; CHECK: loop.preheader: 1298; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]] 1299; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_3]] 1300; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 1301; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] 1302; CHECK-NEXT: [[TMP4:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]] 1303; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i32 0, [[LENGTH_2]] 1304; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]] 1305; CHECK-NEXT: [[TMP7:%.*]] = freeze i1 [[TMP6]] 1306; CHECK-NEXT: [[TMP8:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]] 1307; CHECK-NEXT: [[TMP9:%.*]] = icmp ult i32 0, [[LENGTH_1]] 1308; CHECK-NEXT: [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]] 1309; CHECK-NEXT: [[TMP11:%.*]] = freeze i1 [[TMP10]] 1310; CHECK-NEXT: br label [[LOOP:%.*]] 1311; CHECK: loop: 1312; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 1313; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 1314; CHECK-NEXT: [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]] 1315; CHECK-NEXT: [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]] 1316; CHECK-NEXT: [[WITHIN_BOUNDS_3:%.*]] = icmp ult i32 [[I]], [[LENGTH_3]] 1317; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 1318; CHECK-NEXT: [[TMP12:%.*]] = and i1 [[TMP3]], [[TMP7]] 1319; CHECK-NEXT: [[TMP13:%.*]] = and i1 [[TMP12]], [[TMP11]] 1320; CHECK-NEXT: [[TMP14:%.*]] = and i1 [[TMP13]], [[WIDENABLE_COND]] 1321; CHECK-NEXT: br i1 [[TMP14]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 1322; CHECK: deopt: 1323; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1324; CHECK-NEXT: ret i32 [[DEOPTCALL]] 1325; CHECK: guarded: 1326; CHECK-NEXT: [[TMP15:%.*]] = and i1 [[WITHIN_BOUNDS_3]], [[WITHIN_BOUNDS_2]] 1327; CHECK-NEXT: [[TMP16:%.*]] = and i1 [[TMP15]], [[WITHIN_BOUNDS_1]] 1328; CHECK-NEXT: call void @llvm.assume(i1 [[TMP16]]) 1329; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1330; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]] 1331; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 4 1332; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]] 1333; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_2:%.*]], i64 [[I_I64]] 1334; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, ptr [[ARRAY_2_I_PTR]], align 4 1335; CHECK-NEXT: [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]] 1336; CHECK-NEXT: [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_3:%.*]], i64 [[I_I64]] 1337; CHECK-NEXT: [[ARRAY_3_I:%.*]] = load i32, ptr [[ARRAY_3_I_PTR]], align 4 1338; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]] 1339; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1340; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1341; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 1342; CHECK: exit.loopexit: 1343; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 1344; CHECK-NEXT: br label [[EXIT]] 1345; CHECK: exit: 1346; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1347; CHECK-NEXT: ret i32 [[RESULT]] 1348; 1349entry: 1350 %tmp5 = icmp eq i32 %n, 0 1351 br i1 %tmp5, label %exit, label %loop.preheader 1352 1353loop.preheader: ; preds = %entry 1354 br label %loop 1355 1356loop: ; preds = %guarded, %loop.preheader 1357 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 1358 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 1359 %within.bounds.1 = icmp ult i32 %i, %length.1 1360 %within.bounds.2 = icmp ult i32 %i, %length.2 1361 %within.bounds.3 = icmp ult i32 %i, %length.3 1362 %within.bounds.1.and.2 = and i1 %within.bounds.1, %within.bounds.2 1363 %within.bounds = and i1 %within.bounds.1.and.2, %within.bounds.3 1364 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 1365 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 1366 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 1367 1368deopt: ; preds = %loop 1369 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1370 ret i32 %deoptcall 1371 1372guarded: ; preds = %loop 1373 %i.i64 = zext i32 %i to i64 1374 %array.1.i.ptr = getelementptr inbounds i32, ptr %array.1, i64 %i.i64 1375 %array.1.i = load i32, ptr %array.1.i.ptr, align 4 1376 %loop.acc.1 = add i32 %loop.acc, %array.1.i 1377 %array.2.i.ptr = getelementptr inbounds i32, ptr %array.2, i64 %i.i64 1378 %array.2.i = load i32, ptr %array.2.i.ptr, align 4 1379 %loop.acc.2 = add i32 %loop.acc.1, %array.2.i 1380 %array.3.i.ptr = getelementptr inbounds i32, ptr %array.3, i64 %i.i64 1381 %array.3.i = load i32, ptr %array.3.i.ptr, align 4 1382 %loop.acc.next = add i32 %loop.acc.2, %array.3.i 1383 %i.next = add nuw i32 %i, 1 1384 %continue = icmp ult i32 %i.next, %n 1385 br i1 %continue, label %loop, label %exit, !prof !2 1386 1387exit: ; preds = %guarded, %entry 1388 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 1389 ret i32 %result 1390} 1391 1392define i32 @three_guards(ptr %array.1, i32 %length.1, ptr %array.2, i32 %length.2, ptr %array.3, i32 %length.3, i32 %n) { 1393; CHECK-LABEL: @three_guards( 1394; CHECK-NEXT: entry: 1395; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1396; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1397; CHECK: loop.preheader: 1398; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]] 1399; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_1]] 1400; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 1401; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] 1402; CHECK-NEXT: [[TMP4:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]] 1403; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i32 0, [[LENGTH_2]] 1404; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]] 1405; CHECK-NEXT: [[TMP7:%.*]] = freeze i1 [[TMP6]] 1406; CHECK-NEXT: [[TMP8:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]] 1407; CHECK-NEXT: [[TMP9:%.*]] = icmp ult i32 0, [[LENGTH_3]] 1408; CHECK-NEXT: [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]] 1409; CHECK-NEXT: [[TMP11:%.*]] = freeze i1 [[TMP10]] 1410; CHECK-NEXT: br label [[LOOP:%.*]] 1411; CHECK: loop: 1412; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED6:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 1413; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED6]] ], [ 0, [[LOOP_PREHEADER]] ] 1414; CHECK-NEXT: [[WITHIN_BOUNDS_1:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]] 1415; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 1416; CHECK-NEXT: [[TMP12:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 1417; CHECK-NEXT: br i1 [[TMP12]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]] 1418; CHECK: deopt: 1419; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1420; CHECK-NEXT: ret i32 [[DEOPTCALL]] 1421; CHECK: guarded: 1422; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS_1]]) 1423; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1424; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_1:%.*]], i64 [[I_I64]] 1425; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, ptr [[ARRAY_1_I_PTR]], align 4 1426; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]] 1427; CHECK-NEXT: [[WITHIN_BOUNDS_2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]] 1428; CHECK-NEXT: [[WIDENABLE_COND4:%.*]] = call i1 @llvm.experimental.widenable.condition() 1429; CHECK-NEXT: [[TMP13:%.*]] = and i1 [[TMP7]], [[WIDENABLE_COND4]] 1430; CHECK-NEXT: br i1 [[TMP13]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]] 1431; CHECK: deopt2: 1432; CHECK-NEXT: [[DEOPTCALL3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1433; CHECK-NEXT: ret i32 [[DEOPTCALL3]] 1434; CHECK: guarded1: 1435; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS_2]]) 1436; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_2:%.*]], i64 [[I_I64]] 1437; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, ptr [[ARRAY_2_I_PTR]], align 4 1438; CHECK-NEXT: [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]] 1439; CHECK-NEXT: [[WITHIN_BOUNDS_3:%.*]] = icmp ult i32 [[I]], [[LENGTH_3]] 1440; CHECK-NEXT: [[WIDENABLE_COND9:%.*]] = call i1 @llvm.experimental.widenable.condition() 1441; CHECK-NEXT: [[TMP14:%.*]] = and i1 [[TMP11]], [[WIDENABLE_COND9]] 1442; CHECK-NEXT: br i1 [[TMP14]], label [[GUARDED6]], label [[DEOPT7:%.*]], !prof [[PROF0]] 1443; CHECK: deopt7: 1444; CHECK-NEXT: [[DEOPTCALL8:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1445; CHECK-NEXT: ret i32 [[DEOPTCALL8]] 1446; CHECK: guarded6: 1447; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS_3]]) 1448; CHECK-NEXT: [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY_3:%.*]], i64 [[I_I64]] 1449; CHECK-NEXT: [[ARRAY_3_I:%.*]] = load i32, ptr [[ARRAY_3_I_PTR]], align 4 1450; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]] 1451; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1452; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1453; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 1454; CHECK: exit.loopexit: 1455; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED6]] ] 1456; CHECK-NEXT: br label [[EXIT]] 1457; CHECK: exit: 1458; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1459; CHECK-NEXT: ret i32 [[RESULT]] 1460; 1461entry: 1462 %tmp5 = icmp eq i32 %n, 0 1463 br i1 %tmp5, label %exit, label %loop.preheader 1464 1465loop.preheader: ; preds = %entry 1466 br label %loop 1467 1468loop: ; preds = %guarded6, %loop.preheader 1469 %loop.acc = phi i32 [ %loop.acc.next, %guarded6 ], [ 0, %loop.preheader ] 1470 %i = phi i32 [ %i.next, %guarded6 ], [ 0, %loop.preheader ] 1471 %within.bounds.1 = icmp ult i32 %i, %length.1 1472 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 1473 %exiplicit_guard_cond = and i1 %within.bounds.1, %widenable_cond 1474 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 1475 1476deopt: ; preds = %loop 1477 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1478 ret i32 %deoptcall 1479 1480guarded: ; preds = %loop 1481 %i.i64 = zext i32 %i to i64 1482 %array.1.i.ptr = getelementptr inbounds i32, ptr %array.1, i64 %i.i64 1483 %array.1.i = load i32, ptr %array.1.i.ptr, align 4 1484 %loop.acc.1 = add i32 %loop.acc, %array.1.i 1485 %within.bounds.2 = icmp ult i32 %i, %length.2 1486 %widenable_cond4 = call i1 @llvm.experimental.widenable.condition() 1487 %exiplicit_guard_cond5 = and i1 %within.bounds.2, %widenable_cond4 1488 br i1 %exiplicit_guard_cond5, label %guarded1, label %deopt2, !prof !0 1489 1490deopt2: ; preds = %guarded 1491 %deoptcall3 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1492 ret i32 %deoptcall3 1493 1494guarded1: ; preds = %guarded 1495 %array.2.i.ptr = getelementptr inbounds i32, ptr %array.2, i64 %i.i64 1496 %array.2.i = load i32, ptr %array.2.i.ptr, align 4 1497 %loop.acc.2 = add i32 %loop.acc.1, %array.2.i 1498 %within.bounds.3 = icmp ult i32 %i, %length.3 1499 %widenable_cond9 = call i1 @llvm.experimental.widenable.condition() 1500 %exiplicit_guard_cond10 = and i1 %within.bounds.3, %widenable_cond9 1501 br i1 %exiplicit_guard_cond10, label %guarded6, label %deopt7, !prof !0 1502 1503deopt7: ; preds = %guarded1 1504 %deoptcall8 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1505 ret i32 %deoptcall8 1506 1507guarded6: ; preds = %guarded1 1508 %array.3.i.ptr = getelementptr inbounds i32, ptr %array.3, i64 %i.i64 1509 %array.3.i = load i32, ptr %array.3.i.ptr, align 4 1510 %loop.acc.next = add i32 %loop.acc.2, %array.3.i 1511 %i.next = add nuw i32 %i, 1 1512 %continue = icmp ult i32 %i.next, %n 1513 br i1 %continue, label %loop, label %exit, !prof !2 1514 1515exit: ; preds = %guarded6, %entry 1516 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded6 ] 1517 ret i32 %result 1518} 1519 1520define i32 @unsigned_loop_0_to_n_unrelated_condition(ptr %array, i32 %length, i32 %n, i32 %x) { 1521; CHECK-LABEL: @unsigned_loop_0_to_n_unrelated_condition( 1522; CHECK-NEXT: entry: 1523; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1524; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1525; CHECK: loop.preheader: 1526; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]] 1527; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 1528; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 1529; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] 1530; CHECK-NEXT: br label [[LOOP:%.*]] 1531; CHECK: loop: 1532; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 1533; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 1534; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 1535; CHECK-NEXT: [[UNRELATED_COND:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]] 1536; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 1537; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[UNRELATED_COND]], [[TMP3]] 1538; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]] 1539; CHECK-NEXT: br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 1540; CHECK: deopt: 1541; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1542; CHECK-NEXT: ret i32 [[DEOPTCALL]] 1543; CHECK: guarded: 1544; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 1545; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1546; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 1547; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 1548; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1549; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1550; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1551; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 1552; CHECK: exit.loopexit: 1553; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 1554; CHECK-NEXT: br label [[EXIT]] 1555; CHECK: exit: 1556; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1557; CHECK-NEXT: ret i32 [[RESULT]] 1558; 1559entry: 1560 %tmp5 = icmp eq i32 %n, 0 1561 br i1 %tmp5, label %exit, label %loop.preheader 1562 1563loop.preheader: ; preds = %entry 1564 br label %loop 1565 1566loop: ; preds = %guarded, %loop.preheader 1567 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 1568 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 1569 %within.bounds = icmp ult i32 %i, %length 1570 %unrelated.cond = icmp ult i32 %x, %length 1571 %guard.cond = and i1 %within.bounds, %unrelated.cond 1572 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 1573 %exiplicit_guard_cond = and i1 %guard.cond, %widenable_cond 1574 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 1575 1576deopt: ; preds = %loop 1577 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1578 ret i32 %deoptcall 1579 1580guarded: ; preds = %loop 1581 %i.i64 = zext i32 %i to i64 1582 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 1583 %array.i = load i32, ptr %array.i.ptr, align 4 1584 %loop.acc.next = add i32 %loop.acc, %array.i 1585 %i.next = add nuw i32 %i, 1 1586 %continue = icmp ult i32 %i.next, %n 1587 br i1 %continue, label %loop, label %exit, !prof !2 1588 1589exit: ; preds = %guarded, %entry 1590 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 1591 ret i32 %result 1592} 1593 1594define i32 @test_no_widened_conditions(ptr %array, i32 %length, i32 %n, i32 %x1, i32 %x2, i32 %x3) { 1595; CHECK-LABEL: @test_no_widened_conditions( 1596; CHECK-NEXT: entry: 1597; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1598; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1599; CHECK: loop.preheader: 1600; CHECK-NEXT: br label [[LOOP:%.*]] 1601; CHECK: loop: 1602; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 1603; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 1604; CHECK-NEXT: [[UNRELATED_COND_1:%.*]] = icmp eq i32 [[X1:%.*]], [[I]] 1605; CHECK-NEXT: [[UNRELATED_COND_2:%.*]] = icmp eq i32 [[X2:%.*]], [[I]] 1606; CHECK-NEXT: [[UNRELATED_COND_3:%.*]] = icmp eq i32 [[X3:%.*]], [[I]] 1607; CHECK-NEXT: [[UNRELATED_COND_AND_1:%.*]] = and i1 [[UNRELATED_COND_1]], [[UNRELATED_COND_2]] 1608; CHECK-NEXT: [[GUARD_COND:%.*]] = and i1 [[UNRELATED_COND_AND_1]], [[UNRELATED_COND_3]] 1609; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 1610; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]] 1611; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 1612; CHECK: deopt: 1613; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1614; CHECK-NEXT: ret i32 [[DEOPTCALL]] 1615; CHECK: guarded: 1616; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1617; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 1618; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 1619; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1620; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1621; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1622; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 1623; CHECK: exit.loopexit: 1624; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 1625; CHECK-NEXT: br label [[EXIT]] 1626; CHECK: exit: 1627; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1628; CHECK-NEXT: ret i32 [[RESULT]] 1629; 1630entry: 1631 %tmp5 = icmp eq i32 %n, 0 1632 br i1 %tmp5, label %exit, label %loop.preheader 1633 1634loop.preheader: ; preds = %entry 1635 br label %loop 1636 1637loop: ; preds = %guarded, %loop.preheader 1638 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 1639 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 1640 %unrelated.cond.1 = icmp eq i32 %x1, %i 1641 %unrelated.cond.2 = icmp eq i32 %x2, %i 1642 %unrelated.cond.3 = icmp eq i32 %x3, %i 1643 %unrelated.cond.and.1 = and i1 %unrelated.cond.1, %unrelated.cond.2 1644 %guard.cond = and i1 %unrelated.cond.and.1, %unrelated.cond.3 1645 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 1646 %exiplicit_guard_cond = and i1 %guard.cond, %widenable_cond 1647 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 1648 1649deopt: ; preds = %loop 1650 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1651 ret i32 %deoptcall 1652 1653guarded: ; preds = %loop 1654 %i.i64 = zext i32 %i to i64 1655 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 1656 %array.i = load i32, ptr %array.i.ptr, align 4 1657 %loop.acc.next = add i32 %loop.acc, %array.i 1658 %i.next = add nuw i32 %i, 1 1659 %continue = icmp ult i32 %i.next, %n 1660 br i1 %continue, label %loop, label %exit, !prof !2 1661 1662exit: ; preds = %guarded, %entry 1663 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 1664 ret i32 %result 1665} 1666 1667define i32 @signed_loop_start_to_n_loop_variant_bound(ptr %array, i32 %x, i32 %start, i32 %n) { 1668; CHECK-LABEL: @signed_loop_start_to_n_loop_variant_bound( 1669; CHECK-NEXT: entry: 1670; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 1671; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1672; CHECK: loop.preheader: 1673; CHECK-NEXT: br label [[LOOP:%.*]] 1674; CHECK: loop: 1675; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 1676; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ] 1677; CHECK-NEXT: [[BOUND:%.*]] = add i32 [[I]], [[X:%.*]] 1678; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[BOUND]] 1679; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 1680; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]] 1681; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 1682; CHECK: deopt: 1683; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1684; CHECK-NEXT: ret i32 [[DEOPTCALL]] 1685; CHECK: guarded: 1686; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1687; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 1688; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 1689; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1690; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 1691; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 1692; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 1693; CHECK: exit.loopexit: 1694; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 1695; CHECK-NEXT: br label [[EXIT]] 1696; CHECK: exit: 1697; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1698; CHECK-NEXT: ret i32 [[RESULT]] 1699; 1700entry: 1701 %tmp5 = icmp sle i32 %n, 0 1702 br i1 %tmp5, label %exit, label %loop.preheader 1703 1704loop.preheader: ; preds = %entry 1705 br label %loop 1706 1707loop: ; preds = %guarded, %loop.preheader 1708 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 1709 %i = phi i32 [ %i.next, %guarded ], [ %start, %loop.preheader ] 1710 %bound = add i32 %i, %x 1711 %within.bounds = icmp ult i32 %i, %bound 1712 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 1713 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 1714 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 1715 1716deopt: ; preds = %loop 1717 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1718 ret i32 %deoptcall 1719 1720guarded: ; preds = %loop 1721 %i.i64 = zext i32 %i to i64 1722 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 1723 %array.i = load i32, ptr %array.i.ptr, align 4 1724 %loop.acc.next = add i32 %loop.acc, %array.i 1725 %i.next = add nsw i32 %i, 1 1726 %continue = icmp slt i32 %i.next, %n 1727 br i1 %continue, label %loop, label %exit, !prof !2 1728 1729exit: ; preds = %guarded, %entry 1730 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 1731 ret i32 %result 1732} 1733 1734define i32 @signed_loop_start_to_n_non_monotonic_predicate(ptr %array, i32 %x, i32 %start, i32 %n) { 1735; CHECK-LABEL: @signed_loop_start_to_n_non_monotonic_predicate( 1736; CHECK-NEXT: entry: 1737; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0 1738; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1739; CHECK: loop.preheader: 1740; CHECK-NEXT: br label [[LOOP:%.*]] 1741; CHECK: loop: 1742; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 1743; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ] 1744; CHECK-NEXT: [[GUARD_COND:%.*]] = icmp eq i32 [[I]], [[X:%.*]] 1745; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 1746; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]] 1747; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 1748; CHECK: deopt: 1749; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1750; CHECK-NEXT: ret i32 [[DEOPTCALL]] 1751; CHECK: guarded: 1752; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1753; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 1754; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 1755; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1756; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1 1757; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]] 1758; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 1759; CHECK: exit.loopexit: 1760; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 1761; CHECK-NEXT: br label [[EXIT]] 1762; CHECK: exit: 1763; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1764; CHECK-NEXT: ret i32 [[RESULT]] 1765; 1766entry: 1767 %tmp5 = icmp sle i32 %n, 0 1768 br i1 %tmp5, label %exit, label %loop.preheader 1769 1770loop.preheader: ; preds = %entry 1771 br label %loop 1772 1773loop: ; preds = %guarded, %loop.preheader 1774 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 1775 %i = phi i32 [ %i.next, %guarded ], [ %start, %loop.preheader ] 1776 %guard.cond = icmp eq i32 %i, %x 1777 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 1778 %exiplicit_guard_cond = and i1 %guard.cond, %widenable_cond 1779 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 1780 1781deopt: ; preds = %loop 1782 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1783 ret i32 %deoptcall 1784 1785guarded: ; preds = %loop 1786 %i.i64 = zext i32 %i to i64 1787 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 1788 %array.i = load i32, ptr %array.i.ptr, align 4 1789 %loop.acc.next = add i32 %loop.acc, %array.i 1790 %i.next = add nsw i32 %i, 1 1791 %continue = icmp slt i32 %i.next, %n 1792 br i1 %continue, label %loop, label %exit, !prof !2 1793 1794exit: ; preds = %guarded, %entry 1795 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 1796 ret i32 %result 1797} 1798 1799define i32 @unsigned_loop_0_to_n_hoist_length(ptr %array, i16 %length.i16, i32 %n) { 1800; CHECK-LABEL: @unsigned_loop_0_to_n_hoist_length( 1801; CHECK-NEXT: entry: 1802; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1803; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1804; CHECK: loop.preheader: 1805; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[LENGTH_I16:%.*]] to i32 1806; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]] 1807; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[TMP0]] 1808; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] 1809; CHECK-NEXT: [[TMP4:%.*]] = freeze i1 [[TMP3]] 1810; CHECK-NEXT: br label [[LOOP:%.*]] 1811; CHECK: loop: 1812; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 1813; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 1814; CHECK-NEXT: [[LENGTH:%.*]] = zext i16 [[LENGTH_I16]] to i32 1815; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 1816; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 1817; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]] 1818; CHECK-NEXT: br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 1819; CHECK: deopt: 1820; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1821; CHECK-NEXT: ret i32 [[DEOPTCALL]] 1822; CHECK: guarded: 1823; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 1824; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1825; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 1826; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 1827; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1828; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1829; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1830; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 1831; CHECK: exit.loopexit: 1832; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 1833; CHECK-NEXT: br label [[EXIT]] 1834; CHECK: exit: 1835; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1836; CHECK-NEXT: ret i32 [[RESULT]] 1837; 1838entry: 1839 %tmp5 = icmp eq i32 %n, 0 1840 br i1 %tmp5, label %exit, label %loop.preheader 1841 1842loop.preheader: ; preds = %entry 1843 br label %loop 1844 1845loop: ; preds = %guarded, %loop.preheader 1846 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 1847 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 1848 %length = zext i16 %length.i16 to i32 1849 %within.bounds = icmp ult i32 %i, %length 1850 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 1851 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 1852 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 1853 1854deopt: ; preds = %loop 1855 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1856 ret i32 %deoptcall 1857 1858guarded: ; preds = %loop 1859 %i.i64 = zext i32 %i to i64 1860 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 1861 %array.i = load i32, ptr %array.i.ptr, align 4 1862 %loop.acc.next = add i32 %loop.acc, %array.i 1863 %i.next = add nuw i32 %i, 1 1864 %continue = icmp ult i32 %i.next, %n 1865 br i1 %continue, label %loop, label %exit, !prof !2 1866 1867exit: ; preds = %guarded, %entry 1868 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 1869 ret i32 %result 1870} 1871 1872define i32 @unsigned_loop_0_to_n_cant_hoist_length(ptr %array, i32 %length, i32 %divider, i32 %n) { 1873; CHECK-LABEL: @unsigned_loop_0_to_n_cant_hoist_length( 1874; CHECK-NEXT: entry: 1875; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1876; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1877; CHECK: loop.preheader: 1878; CHECK-NEXT: br label [[LOOP:%.*]] 1879; CHECK: loop: 1880; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 1881; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 1882; CHECK-NEXT: [[LENGTH_UDIV:%.*]] = udiv i32 [[LENGTH:%.*]], [[DIVIDER:%.*]] 1883; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_UDIV]] 1884; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 1885; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_UDIV]] 1886; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_UDIV]] 1887; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 1888; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] 1889; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 1890; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 1891; CHECK: deopt: 1892; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1893; CHECK-NEXT: ret i32 [[DEOPTCALL]] 1894; CHECK: guarded: 1895; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 1896; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1897; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 1898; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 1899; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 1900; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1901; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1902; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 1903; CHECK: exit.loopexit: 1904; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 1905; CHECK-NEXT: br label [[EXIT]] 1906; CHECK: exit: 1907; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 1908; CHECK-NEXT: ret i32 [[RESULT]] 1909; 1910entry: 1911 %tmp5 = icmp eq i32 %n, 0 1912 br i1 %tmp5, label %exit, label %loop.preheader 1913 1914loop.preheader: ; preds = %entry 1915 br label %loop 1916 1917loop: ; preds = %guarded, %loop.preheader 1918 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 1919 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 1920 %length.udiv = udiv i32 %length, %divider 1921 %within.bounds = icmp ult i32 %i, %length.udiv 1922 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 1923 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 1924 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 1925 1926deopt: ; preds = %loop 1927 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1928 ret i32 %deoptcall 1929 1930guarded: ; preds = %loop 1931 %i.i64 = zext i32 %i to i64 1932 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 1933 %array.i = load i32, ptr %array.i.ptr, align 4 1934 %loop.acc.next = add i32 %loop.acc, %array.i 1935 %i.next = add nuw i32 %i, 1 1936 %continue = icmp ult i32 %i.next, %n 1937 br i1 %continue, label %loop, label %exit, !prof !2 1938 1939exit: ; preds = %guarded, %entry 1940 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 1941 ret i32 %result 1942} 1943 1944; Make sure that if we're going to consider a branch widenable, that the 1945; call to widenable condition is actually present. 1946define i32 @negative_WC_required(ptr %array, i32 %length, i32 %n, i1 %unrelated) { 1947; CHECK-LABEL: @negative_WC_required( 1948; CHECK-NEXT: entry: 1949; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 1950; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 1951; CHECK: loop.preheader: 1952; CHECK-NEXT: br label [[LOOP:%.*]] 1953; CHECK: loop: 1954; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 1955; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]] 1956; CHECK-NEXT: [[NOT_WIDENABLE:%.*]] = and i1 [[WITHIN_BOUNDS]], [[UNRELATED:%.*]] 1957; CHECK-NEXT: br i1 [[NOT_WIDENABLE]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 1958; CHECK: deopt: 1959; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1960; CHECK-NEXT: ret i32 [[DEOPTCALL]] 1961; CHECK: guarded: 1962; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 1963; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 1964; CHECK-NEXT: store i32 0, ptr [[ARRAY_I_PTR]], align 4 1965; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 1966; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 1967; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 1968; CHECK: exit.loopexit: 1969; CHECK-NEXT: br label [[EXIT]] 1970; CHECK: exit: 1971; CHECK-NEXT: ret i32 0 1972; 1973entry: 1974 %tmp5 = icmp eq i32 %n, 0 1975 br i1 %tmp5, label %exit, label %loop.preheader 1976 1977loop.preheader: ; preds = %entry 1978 br label %loop 1979 1980loop: 1981 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 1982 %within.bounds = icmp ult i32 %i, %length 1983 %not_widenable = and i1 %within.bounds, %unrelated 1984 br i1 %not_widenable, label %guarded, label %deopt, !prof !0 1985 1986deopt: 1987 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 1988 ret i32 %deoptcall 1989 1990guarded: ; preds = %loop 1991 %i.i64 = zext i32 %i to i64 1992 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 1993 store i32 0, ptr %array.i.ptr, align 4 1994 %i.next = add nuw i32 %i, 1 1995 %continue = icmp ult i32 %i.next, %n 1996 br i1 %continue, label %loop, label %exit, !prof !2 1997 1998exit: ; preds = %guarded, %entry 1999 ret i32 0 2000} 2001 2002define i32 @swapped_wb(ptr %array, i32 %length, i32 %n) { 2003; CHECK-LABEL: @swapped_wb( 2004; CHECK-NEXT: entry: 2005; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 2006; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 2007; CHECK: loop.preheader: 2008; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 2009; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]] 2010; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 2011; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 2012; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] 2013; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 2014; CHECK-NEXT: br label [[LOOP:%.*]] 2015; CHECK: loop: 2016; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 2017; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 2018; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 2019; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 2020; CHECK: deopt: 2021; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 2022; CHECK-NEXT: ret i32 [[DEOPTCALL]] 2023; CHECK: guarded: 2024; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 2025; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 2026; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 2027; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 2028; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 2029; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 2030; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 2031; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 2032; CHECK: exit.loopexit: 2033; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 2034; CHECK-NEXT: br label [[EXIT]] 2035; CHECK: exit: 2036; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 2037; CHECK-NEXT: ret i32 [[RESULT]] 2038; 2039entry: 2040 %tmp5 = icmp eq i32 %n, 0 2041 br i1 %tmp5, label %exit, label %loop.preheader 2042 2043loop.preheader: ; preds = %entry 2044 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 2045 br label %loop 2046 2047loop: ; preds = %guarded, %loop.preheader 2048 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 2049 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 2050 %within.bounds = icmp ult i32 %i, %length 2051 %exiplicit_guard_cond = and i1 %widenable_cond, %within.bounds 2052 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 2053 2054deopt: ; preds = %loop 2055 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 2056 ret i32 %deoptcall 2057 2058guarded: ; preds = %loop 2059 %i.i64 = zext i32 %i to i64 2060 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 2061 %array.i = load i32, ptr %array.i.ptr, align 4 2062 %loop.acc.next = add i32 %loop.acc, %array.i 2063 %i.next = add nuw i32 %i, 1 2064 %continue = icmp ult i32 %i.next, %n 2065 br i1 %continue, label %loop, label %exit, !prof !2 2066 2067exit: ; preds = %guarded, %entry 2068 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 2069 ret i32 %result 2070} 2071 2072define i32 @unsigned_loop_0_to_n_ult_check_deep_deopt(ptr %array, i32 %length, i32 %n) { 2073; CHECK-LABEL: @unsigned_loop_0_to_n_ult_check_deep_deopt( 2074; CHECK-NEXT: entry: 2075; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0 2076; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]] 2077; CHECK: loop.preheader: 2078; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]] 2079; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]] 2080; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]] 2081; CHECK-NEXT: [[TMP3:%.*]] = freeze i1 [[TMP2]] 2082; CHECK-NEXT: br label [[LOOP:%.*]] 2083; CHECK: loop: 2084; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 2085; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ] 2086; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]] 2087; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition() 2088; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]] 2089; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]] 2090; CHECK: deopt: 2091; CHECK-NEXT: br label [[REAL_DEOPT:%.*]] 2092; CHECK: real_deopt: 2093; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 2094; CHECK-NEXT: ret i32 [[DEOPTCALL]] 2095; CHECK: guarded: 2096; CHECK-NEXT: call void @llvm.assume(i1 [[WITHIN_BOUNDS]]) 2097; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64 2098; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, ptr [[ARRAY:%.*]], i64 [[I_I64]] 2099; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4 2100; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]] 2101; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1 2102; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]] 2103; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]] 2104; CHECK: exit.loopexit: 2105; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ] 2106; CHECK-NEXT: br label [[EXIT]] 2107; CHECK: exit: 2108; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ] 2109; CHECK-NEXT: ret i32 [[RESULT]] 2110; 2111entry: 2112 %tmp5 = icmp eq i32 %n, 0 2113 br i1 %tmp5, label %exit, label %loop.preheader 2114 2115loop.preheader: ; preds = %entry 2116 br label %loop 2117 2118loop: ; preds = %guarded, %loop.preheader 2119 %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ] 2120 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ] 2121 %within.bounds = icmp ult i32 %i, %length 2122 %widenable_cond = call i1 @llvm.experimental.widenable.condition() 2123 %exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond 2124 br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0 2125 2126deopt: ; preds = %loop 2127 br label %real_deopt 2128 2129real_deopt: ; preds = %deopt 2130 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 2131 ret i32 %deoptcall 2132 2133guarded: ; preds = %loop 2134 %i.i64 = zext i32 %i to i64 2135 %array.i.ptr = getelementptr inbounds i32, ptr %array, i64 %i.i64 2136 %array.i = load i32, ptr %array.i.ptr, align 4 2137 %loop.acc.next = add i32 %loop.acc, %array.i 2138 %i.next = add nuw i32 %i, 1 2139 %continue = icmp ult i32 %i.next, %n 2140 br i1 %continue, label %loop, label %exit, !prof !2 2141 2142exit: ; preds = %guarded, %entry 2143 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ] 2144 ret i32 %result 2145} 2146 2147; TODO: Support widenable branch in the form of br((wc and cond0) and cond1) 2148; At present LoopPredication assumes the form of br(wc && (...)) only. 2149define i32 @wc_deep_in_expression_tree(i1 %cond0, i1 %cond1, i32 %limit) { 2150; CHECK-LABEL: @wc_deep_in_expression_tree( 2151; CHECK-NEXT: entry: 2152; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() 2153; CHECK-NEXT: [[AND0:%.*]] = and i1 [[WC]], [[COND0:%.*]] 2154; CHECK-NEXT: [[AND1:%.*]] = and i1 [[AND0]], [[COND1:%.*]] 2155; CHECK-NEXT: br i1 [[AND1]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]] 2156; CHECK: loop.preheader: 2157; CHECK-NEXT: br label [[LOOP:%.*]] 2158; CHECK: loop: 2159; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ] 2160; CHECK-NEXT: [[GUARD_COND:%.*]] = icmp sgt i32 [[IV]], 100 2161; CHECK-NEXT: br i1 [[GUARD_COND]], label [[DEOPT_LOOPEXIT:%.*]], label [[GUARDED]] 2162; CHECK: guarded: 2163; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 2164; CHECK-NEXT: [[EXIT_COND:%.*]] = icmp ult i32 [[IV]], [[LIMIT:%.*]] 2165; CHECK-NEXT: br i1 [[EXIT_COND]], label [[LOOP]], label [[EXIT:%.*]] 2166; CHECK: deopt.loopexit: 2167; CHECK-NEXT: br label [[DEOPT]] 2168; CHECK: deopt: 2169; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 2170; CHECK-NEXT: ret i32 [[DEOPTCALL]] 2171; CHECK: exit: 2172; CHECK-NEXT: ret i32 0 2173; 2174entry: 2175 %wc = call i1 @llvm.experimental.widenable.condition() 2176 %and0 = and i1 %wc, %cond0 2177 %and1 = and i1 %and0, %cond1 2178 br i1 %and1, label %loop, label %deopt 2179 2180loop: 2181 %iv = phi i32 [ %iv.next, %guarded ], [ 0, %entry ] 2182 %guard.cond = icmp sgt i32 %iv, 100 2183 br i1 %guard.cond, label %deopt, label %guarded 2184 2185guarded: 2186 %iv.next = add i32 %iv, 1 2187 %exit.cond = icmp ult i32 %iv, %limit 2188 br i1 %exit.cond, label %loop, label %exit 2189 2190deopt: 2191 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ] 2192 ret i32 %deoptcall 2193exit: 2194 ret i32 0 2195} 2196 2197declare i32 @llvm.experimental.deoptimize.i32(...) 2198 2199; Function Attrs: inaccessiblememonly nounwind 2200declare i1 @llvm.experimental.widenable.condition() #0 2201 2202attributes #0 = { inaccessiblememonly nounwind } 2203 2204!0 = !{!"branch_weights", i32 1048576, i32 1} 2205!1 = !{i32 1, i32 -2147483648} 2206!2 = !{!"branch_weights", i32 1024, i32 1} 2207