1; RUN: opt -S -loop-predication < %s 2>&1 | FileCheck %s 2; RUN: opt -S -passes='require<scalar-evolution>,loop(loop-predication)' < %s 2>&1 | FileCheck %s 3 4declare void @llvm.experimental.guard(i1, ...) 5 6define i32 @unsigned_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) { 7; CHECK-LABEL: @unsigned_loop_0_to_n_ult_check 8entry: 9 %tmp5 = icmp eq i32 %n, 0 10 br i1 %tmp5, label %exit, label %loop.preheader 11 12loop.preheader: 13; CHECK: loop.preheader: 14; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length 15; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length 16; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]] 17; CHECK-NEXT: br label %loop 18 br label %loop 19 20loop: 21; CHECK: loop: 22; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 23 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 24 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 25 %within.bounds = icmp ult i32 %i, %length 26 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 27 28 %i.i64 = zext i32 %i to i64 29 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 30 %array.i = load i32, i32* %array.i.ptr, align 4 31 %loop.acc.next = add i32 %loop.acc, %array.i 32 33 %i.next = add nuw i32 %i, 1 34 %continue = icmp ult i32 %i.next, %n 35 br i1 %continue, label %loop, label %exit 36 37exit: 38 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 39 ret i32 %result 40} 41 42define i32 @unsigned_loop_0_to_n_ule_latch_ult_check(i32* %array, i32 %length, i32 %n) { 43; CHECK-LABEL: @unsigned_loop_0_to_n_ule_latch_ult_check 44entry: 45 %tmp5 = icmp eq i32 %n, 0 46 br i1 %tmp5, label %exit, label %loop.preheader 47 48loop.preheader: 49; CHECK: loop.preheader: 50; CHECK: [[limit_check:[^ ]+]] = icmp ult i32 %n, %length 51; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length 52; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]] 53; CHECK-NEXT: br label %loop 54 br label %loop 55 56loop: 57; CHECK: loop: 58; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 59 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 60 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 61 %within.bounds = icmp ult i32 %i, %length 62 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 63 64 %i.i64 = zext i32 %i to i64 65 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 66 %array.i = load i32, i32* %array.i.ptr, align 4 67 %loop.acc.next = add i32 %loop.acc, %array.i 68 69 %i.next = add nuw i32 %i, 1 70 %continue = icmp ule i32 %i.next, %n 71 br i1 %continue, label %loop, label %exit 72 73exit: 74 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 75 ret i32 %result 76} 77 78define i32 @unsigned_loop_0_to_n_ugt_check(i32* %array, i32 %length, i32 %n) { 79; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check 80entry: 81 %tmp5 = icmp eq i32 %n, 0 82 br i1 %tmp5, label %exit, label %loop.preheader 83 84loop.preheader: 85; CHECK: loop.preheader: 86; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length 87; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length 88; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]] 89; CHECK-NEXT: br label %loop 90 br label %loop 91 92loop: 93; CHECK: loop: 94; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 95 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 96 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 97 %within.bounds = icmp ugt i32 %length, %i 98 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 99 100 %i.i64 = zext i32 %i to i64 101 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 102 %array.i = load i32, i32* %array.i.ptr, align 4 103 %loop.acc.next = add i32 %loop.acc, %array.i 104 105 %i.next = add nuw i32 %i, 1 106 %continue = icmp ult i32 %i.next, %n 107 br i1 %continue, label %loop, label %exit 108 109exit: 110 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 111 ret i32 %result 112} 113 114define i32 @signed_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) { 115; CHECK-LABEL: @signed_loop_0_to_n_ult_check 116entry: 117 %tmp5 = icmp sle i32 %n, 0 118 br i1 %tmp5, label %exit, label %loop.preheader 119 120loop.preheader: 121; CHECK: loop.preheader: 122; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length 123; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length 124; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]] 125; CHECK-NEXT: br label %loop 126 br label %loop 127 128loop: 129; CHECK: loop: 130; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 131 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 132 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 133 %within.bounds = icmp ult i32 %i, %length 134 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 135 136 %i.i64 = zext i32 %i to i64 137 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 138 %array.i = load i32, i32* %array.i.ptr, align 4 139 %loop.acc.next = add i32 %loop.acc, %array.i 140 141 %i.next = add nuw i32 %i, 1 142 %continue = icmp slt i32 %i.next, %n 143 br i1 %continue, label %loop, label %exit 144 145exit: 146 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 147 ret i32 %result 148} 149 150define i32 @signed_loop_0_to_n_ult_check_length_range_known(i32* %array, i32* %length.ptr, i32 %n) { 151; CHECK-LABEL: @signed_loop_0_to_n_ult_check_length_range_known 152entry: 153 %tmp5 = icmp sle i32 %n, 0 154 %length = load i32, i32* %length.ptr, !range !{i32 1, i32 2147483648} 155 br i1 %tmp5, label %exit, label %loop.preheader 156 157loop.preheader: 158; CHECK: loop.preheader: 159; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length 160; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 true, [[limit_check]] 161; CHECK-NEXT: br label %loop 162 br label %loop 163 164loop: 165; CHECK: loop: 166; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 167 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 168 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 169 %within.bounds = icmp ult i32 %i, %length 170 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 171 172 %i.i64 = zext i32 %i to i64 173 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 174 %array.i = load i32, i32* %array.i.ptr, align 4 175 %loop.acc.next = add i32 %loop.acc, %array.i 176 177 %i.next = add nuw i32 %i, 1 178 %continue = icmp slt i32 %i.next, %n 179 br i1 %continue, label %loop, label %exit 180 181exit: 182 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 183 ret i32 %result 184} 185 186define i32 @signed_loop_0_to_n_inverse_latch_predicate(i32* %array, i32 %length, i32 %n) { 187; CHECK-LABEL: @signed_loop_0_to_n_inverse_latch_predicate 188entry: 189 %tmp5 = icmp sle i32 %n, 0 190 br i1 %tmp5, label %exit, label %loop.preheader 191 192loop.preheader: 193; CHECK: loop.preheader: 194; CHECK: [[limit_check:[^ ]+]] = icmp slt i32 %n, %length 195; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length 196; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]] 197; CHECK-NEXT: br label %loop 198 br label %loop 199 200loop: 201; CHECK: loop: 202; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 203 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 204 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 205 %within.bounds = icmp ult i32 %i, %length 206 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 207 208 %i.i64 = zext i32 %i to i64 209 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 210 %array.i = load i32, i32* %array.i.ptr, align 4 211 %loop.acc.next = add i32 %loop.acc, %array.i 212 213 %i.next = add nuw i32 %i, 1 214 %continue = icmp sgt i32 %i.next, %n 215 br i1 %continue, label %exit, label %loop 216 217exit: 218 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 219 ret i32 %result 220} 221 222define i32 @signed_loop_0_to_n_sle_latch_ult_check(i32* %array, i32 %length, i32 %n) { 223; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_ult_check 224entry: 225 %tmp5 = icmp sle i32 %n, 0 226 br i1 %tmp5, label %exit, label %loop.preheader 227 228loop.preheader: 229; CHECK: loop.preheader: 230; CHECK: [[limit_check:[^ ]+]] = icmp slt i32 %n, %length 231; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length 232; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]] 233; CHECK-NEXT: br label %loop 234 br label %loop 235 236loop: 237; CHECK: loop: 238; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 239 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 240 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 241 %within.bounds = icmp ult i32 %i, %length 242 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 243 244 %i.i64 = zext i32 %i to i64 245 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 246 %array.i = load i32, i32* %array.i.ptr, align 4 247 %loop.acc.next = add i32 %loop.acc, %array.i 248 249 %i.next = add nuw i32 %i, 1 250 %continue = icmp sle i32 %i.next, %n 251 br i1 %continue, label %loop, label %exit 252 253exit: 254 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 255 ret i32 %result 256} 257 258define i32 @signed_loop_0_to_n_preincrement_latch_check(i32* %array, i32 %length, i32 %n) { 259; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check 260entry: 261 %tmp5 = icmp sle i32 %n, 0 262 br i1 %tmp5, label %exit, label %loop.preheader 263 264loop.preheader: 265; CHECK: loop.preheader: 266; CHECK: [[length_minus_1:[^ ]+]] = add i32 %length, -1 267; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp sle i32 %n, [[length_minus_1]] 268; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length 269; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]] 270; CHECK-NEXT: br label %loop 271 br label %loop 272 273loop: 274; CHECK: loop: 275; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 276 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 277 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 278 %within.bounds = icmp ult i32 %i, %length 279 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 280 281 %i.i64 = zext i32 %i to i64 282 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 283 %array.i = load i32, i32* %array.i.ptr, align 4 284 %loop.acc.next = add i32 %loop.acc, %array.i 285 286 %i.next = add i32 %i, 1 287 %continue = icmp slt i32 %i, %n 288 br i1 %continue, label %loop, label %exit 289 290exit: 291 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 292 ret i32 %result 293} 294 295define i32 @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(i32* %array, i32 %length, i32 %n) { 296; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check 297entry: 298 %tmp5 = icmp sle i32 %n, 0 299 br i1 %tmp5, label %exit, label %loop.preheader 300 301loop.preheader: 302; CHECK: loop.preheader: 303; CHECK: [[length_minus_2:[^ ]+]] = add i32 %length, -2 304; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp sle i32 %n, [[length_minus_2]] 305; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 1, %length 306; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]] 307; CHECK-NEXT: br label %loop 308 br label %loop 309 310loop: 311; CHECK: loop: 312; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 313 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 314 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 315 316 %i.next = add i32 %i, 1 317 %within.bounds = icmp ult i32 %i.next, %length 318 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 319 320 %i.i64 = zext i32 %i to i64 321 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 322 %array.i = load i32, i32* %array.i.ptr, align 4 323 %loop.acc.next = add i32 %loop.acc, %array.i 324 325 %continue = icmp slt i32 %i, %n 326 br i1 %continue, label %loop, label %exit 327 328exit: 329 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 330 ret i32 %result 331} 332 333define i32 @signed_loop_0_to_n_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) { 334; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_offset_ult_check 335entry: 336 %tmp5 = icmp sle i32 %n, 0 337 br i1 %tmp5, label %exit, label %loop.preheader 338 339loop.preheader: 340; CHECK: loop.preheader: 341; CHECK: [[length_minus_1:[^ ]+]] = add i32 %length, -1 342; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp slt i32 %n, [[length_minus_1]] 343; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 1, %length 344; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]] 345; CHECK-NEXT: br label %loop 346 br label %loop 347 348loop: 349; CHECK: loop: 350; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 351 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 352 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 353 %i.offset = add i32 %i, 1 354 %within.bounds = icmp ult i32 %i.offset, %length 355 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 356 357 %i.i64 = zext i32 %i to i64 358 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 359 %array.i = load i32, i32* %array.i.ptr, align 4 360 %loop.acc.next = add i32 %loop.acc, %array.i 361 362 %i.next = add i32 %i, 1 363 %continue = icmp sle i32 %i.next, %n 364 br i1 %continue, label %loop, label %exit 365 366exit: 367 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 368 ret i32 %result 369} 370 371define i32 @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) { 372; CHECK-LABEL: @signed_loop_0_to_n_offset_sle_latch_offset_ult_check 373entry: 374 %tmp5 = icmp sle i32 %n, 0 375 br i1 %tmp5, label %exit, label %loop.preheader 376 377loop.preheader: 378; CHECK: loop.preheader: 379; CHECK: [[limit_check:[^ ]+]] = icmp slt i32 %n, %length 380; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 1, %length 381; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]] 382; CHECK-NEXT: br label %loop 383 br label %loop 384 385loop: 386; CHECK: loop: 387; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 388 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 389 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 390 %i.offset = add i32 %i, 1 391 %within.bounds = icmp ult i32 %i.offset, %length 392 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 393 394 %i.i64 = zext i32 %i to i64 395 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 396 %array.i = load i32, i32* %array.i.ptr, align 4 397 %loop.acc.next = add i32 %loop.acc, %array.i 398 399 %i.next = add i32 %i, 1 400 %i.next.offset = add i32 %i.next, 1 401 %continue = icmp sle i32 %i.next.offset, %n 402 br i1 %continue, label %loop, label %exit 403 404exit: 405 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 406 ret i32 %result 407} 408 409define i32 @unsupported_latch_pred_loop_0_to_n(i32* %array, i32 %length, i32 %n) { 410; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n 411entry: 412 %tmp5 = icmp sle i32 %n, 0 413 br i1 %tmp5, label %exit, label %loop.preheader 414 415loop.preheader: 416; CHECK: loop.preheader: 417; CHECK-NEXT: br label %loop 418 br label %loop 419 420loop: 421; CHECK: loop: 422; CHECK: %within.bounds = icmp ult i32 %i, %length 423; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 424 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 425 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 426 %within.bounds = icmp ult i32 %i, %length 427 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 428 429 %i.i64 = zext i32 %i to i64 430 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 431 %array.i = load i32, i32* %array.i.ptr, align 4 432 %loop.acc.next = add i32 %loop.acc, %array.i 433 434 %i.next = add nsw i32 %i, 1 435 %continue = icmp ne i32 %i.next, %n 436 br i1 %continue, label %loop, label %exit 437 438exit: 439 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 440 ret i32 %result 441} 442 443define i32 @signed_loop_0_to_n_unsupported_iv_step(i32* %array, i32 %length, i32 %n) { 444; CHECK-LABEL: @signed_loop_0_to_n_unsupported_iv_step 445entry: 446 %tmp5 = icmp sle i32 %n, 0 447 br i1 %tmp5, label %exit, label %loop.preheader 448 449loop.preheader: 450; CHECK: loop.preheader: 451; CHECK-NEXT: br label %loop 452 br label %loop 453 454loop: 455; CHECK: loop: 456; CHECK: %within.bounds = icmp ult i32 %i, %length 457; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 458 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 459 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 460 %within.bounds = icmp ult i32 %i, %length 461 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 462 463 %i.i64 = zext i32 %i to i64 464 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 465 %array.i = load i32, i32* %array.i.ptr, align 4 466 %loop.acc.next = add i32 %loop.acc, %array.i 467 468 %i.next = add nsw i32 %i, 2 469 %continue = icmp slt i32 %i.next, %n 470 br i1 %continue, label %loop, label %exit 471 472exit: 473 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 474 ret i32 %result 475} 476 477define i32 @signed_loop_0_to_n_equal_iv_range_check(i32* %array, i32 %length, i32 %n) { 478; CHECK-LABEL: @signed_loop_0_to_n_equal_iv_range_check 479entry: 480 %tmp5 = icmp sle i32 %n, 0 481 br i1 %tmp5, label %exit, label %loop.preheader 482 483loop.preheader: 484; CHECK: loop.preheader: 485; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length 486; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length 487; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]] 488; CHECK-NEXT: br label %loop 489 br label %loop 490 491loop: 492; CHECK: loop: 493; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 494 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 495 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 496 %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ] 497 498 %within.bounds = icmp ult i32 %j, %length 499 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 500 501 %i.i64 = zext i32 %i to i64 502 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 503 %array.i = load i32, i32* %array.i.ptr, align 4 504 %loop.acc.next = add i32 %loop.acc, %array.i 505 506 %j.next = add nsw i32 %j, 1 507 %i.next = add nsw i32 %i, 1 508 %continue = icmp slt i32 %i.next, %n 509 br i1 %continue, label %loop, label %exit 510 511exit: 512 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 513 ret i32 %result 514} 515 516define i32 @signed_loop_start_to_n_offset_iv_range_check(i32* %array, i32 %start.i, 517 i32 %start.j, i32 %length, 518 i32 %n) { 519; CHECK-LABEL: @signed_loop_start_to_n_offset_iv_range_check 520entry: 521 %tmp5 = icmp sle i32 %n, 0 522 br i1 %tmp5, label %exit, label %loop.preheader 523 524loop.preheader: 525; CHECK: loop.preheader: 526; CHECK: [[length_plus_start_i:[^ ]+]] = add i32 %length, %start.i 527; CHECK-NEXT: [[limit:[^ ]+]] = sub i32 [[length_plus_start_i]], %start.j 528; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp sle i32 %n, [[limit]] 529; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 %start.j, %length 530; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]] 531; CHECK-NEXT: br label %loop 532 br label %loop 533 534loop: 535; CHECK: loop: 536; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 537 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 538 %i = phi i32 [ %i.next, %loop ], [ %start.i, %loop.preheader ] 539 %j = phi i32 [ %j.next, %loop ], [ %start.j, %loop.preheader ] 540 541 %within.bounds = icmp ult i32 %j, %length 542 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 543 544 %i.i64 = zext i32 %i to i64 545 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 546 %array.i = load i32, i32* %array.i.ptr, align 4 547 %loop.acc.next = add i32 %loop.acc, %array.i 548 549 %j.next = add i32 %j, 1 550 %i.next = add i32 %i, 1 551 %continue = icmp slt i32 %i.next, %n 552 br i1 %continue, label %loop, label %exit 553 554exit: 555 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 556 ret i32 %result 557} 558 559define i32 @signed_loop_0_to_n_different_iv_types(i32* %array, i16 %length, i32 %n) { 560; CHECK-LABEL: @signed_loop_0_to_n_different_iv_types 561entry: 562 %tmp5 = icmp sle i32 %n, 0 563 br i1 %tmp5, label %exit, label %loop.preheader 564 565loop.preheader: 566; CHECK: loop.preheader: 567; CHECK-NEXT: br label %loop 568 br label %loop 569 570loop: 571; CHECK: loop: 572; CHECK: %within.bounds = icmp ult i16 %j, %length 573; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 574 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 575 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 576 %j = phi i16 [ %j.next, %loop ], [ 0, %loop.preheader ] 577 578 %within.bounds = icmp ult i16 %j, %length 579 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 580 581 %i.i64 = zext i32 %i to i64 582 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 583 %array.i = load i32, i32* %array.i.ptr, align 4 584 %loop.acc.next = add i32 %loop.acc, %array.i 585 586 %j.next = add i16 %j, 1 587 %i.next = add i32 %i, 1 588 %continue = icmp slt i32 %i.next, %n 589 br i1 %continue, label %loop, label %exit 590 591exit: 592 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 593 ret i32 %result 594} 595 596define i32 @signed_loop_0_to_n_different_iv_strides(i32* %array, i32 %length, i32 %n) { 597; CHECK-LABEL: @signed_loop_0_to_n_different_iv_strides 598entry: 599 %tmp5 = icmp sle i32 %n, 0 600 br i1 %tmp5, label %exit, label %loop.preheader 601 602loop.preheader: 603; CHECK: loop.preheader: 604; CHECK-NEXT: br label %loop 605 br label %loop 606 607loop: 608; CHECK: loop: 609; CHECK: %within.bounds = icmp ult i32 %j, %length 610; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 611 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 612 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 613 %j = phi i32 [ %j.next, %loop ], [ 0, %loop.preheader ] 614 615 %within.bounds = icmp ult i32 %j, %length 616 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 617 618 %i.i64 = zext i32 %i to i64 619 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 620 %array.i = load i32, i32* %array.i.ptr, align 4 621 %loop.acc.next = add i32 %loop.acc, %array.i 622 623 %j.next = add nsw i32 %j, 2 624 %i.next = add nsw i32 %i, 1 625 %continue = icmp slt i32 %i.next, %n 626 br i1 %continue, label %loop, label %exit 627 628exit: 629 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 630 ret i32 %result 631} 632 633define i32 @two_range_checks(i32* %array.1, i32 %length.1, 634 i32* %array.2, i32 %length.2, i32 %n) { 635; CHECK-LABEL: @two_range_checks 636entry: 637 %tmp5 = icmp eq i32 %n, 0 638 br i1 %tmp5, label %exit, label %loop.preheader 639 640loop.preheader: 641; CHECK: loop.preheader: 642; CHECK: [[limit_check_1:[^ ]+]] = icmp ule i32 %n, %length.{{1|2}} 643; CHECK-NEXT: [[first_iteration_check_1:[^ ]+]] = icmp ult i32 0, %length.{{1|2}} 644; CHECK-NEXT: [[wide_cond_1:[^ ]+]] = and i1 [[first_iteration_check_1]], [[limit_check_1]] 645; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2}} 646; CHECK-NEXT: [[first_iteration_check_2:[^ ]+]] = icmp ult i32 0, %length.{{1|2}} 647; CHECK-NEXT: [[wide_cond_2:[^ ]+]] = and i1 [[first_iteration_check_2]], [[limit_check_2]] 648; CHECK-NEXT: br label %loop 649 br label %loop 650 651loop: 652; CHECK: loop: 653; CHECK: [[wide_cond:[^ ]+]] = and i1 [[wide_cond_1]], [[wide_cond_2]] 654; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 655 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 656 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 657 %within.bounds.1 = icmp ult i32 %i, %length.1 658 %within.bounds.2 = icmp ult i32 %i, %length.2 659 %within.bounds = and i1 %within.bounds.1, %within.bounds.2 660 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 661 662 %i.i64 = zext i32 %i to i64 663 %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64 664 %array.1.i = load i32, i32* %array.1.i.ptr, align 4 665 %loop.acc.1 = add i32 %loop.acc, %array.1.i 666 667 %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64 668 %array.2.i = load i32, i32* %array.2.i.ptr, align 4 669 %loop.acc.next = add i32 %loop.acc.1, %array.2.i 670 671 %i.next = add nuw i32 %i, 1 672 %continue = icmp ult i32 %i.next, %n 673 br i1 %continue, label %loop, label %exit 674 675exit: 676 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 677 ret i32 %result 678} 679 680define i32 @three_range_checks(i32* %array.1, i32 %length.1, 681 i32* %array.2, i32 %length.2, 682 i32* %array.3, i32 %length.3, i32 %n) { 683; CHECK-LABEL: @three_range_checks 684entry: 685 %tmp5 = icmp eq i32 %n, 0 686 br i1 %tmp5, label %exit, label %loop.preheader 687 688loop.preheader: 689; CHECK: loop.preheader: 690; CHECK: [[limit_check_1:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}} 691; CHECK-NEXT: [[first_iteration_check_1:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}} 692; CHECK-NEXT: [[wide_cond_1:[^ ]+]] = and i1 [[first_iteration_check_1]], [[limit_check_1]] 693; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}} 694; CHECK-NEXT: [[first_iteration_check_2:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}} 695; CHECK-NEXT: [[wide_cond_2:[^ ]+]] = and i1 [[first_iteration_check_2]], [[limit_check_2]] 696; CHECK-NEXT: [[limit_check_3:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}} 697; CHECK-NEXT: [[first_iteration_check_3:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}} 698; CHECK-NEXT: [[wide_cond_3:[^ ]+]] = and i1 [[first_iteration_check_3]], [[limit_check_3]] 699; CHECK-NEXT: br label %loop 700 br label %loop 701 702loop: 703; CHECK: loop: 704; CHECK: [[wide_cond_and:[^ ]+]] = and i1 [[wide_cond_1]], [[wide_cond_2]] 705; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[wide_cond_and]], [[wide_cond_3]] 706; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 707 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 708 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 709 %within.bounds.1 = icmp ult i32 %i, %length.1 710 %within.bounds.2 = icmp ult i32 %i, %length.2 711 %within.bounds.3 = icmp ult i32 %i, %length.3 712 %within.bounds.1.and.2 = and i1 %within.bounds.1, %within.bounds.2 713 %within.bounds = and i1 %within.bounds.1.and.2, %within.bounds.3 714 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 715 716 %i.i64 = zext i32 %i to i64 717 %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64 718 %array.1.i = load i32, i32* %array.1.i.ptr, align 4 719 %loop.acc.1 = add i32 %loop.acc, %array.1.i 720 721 %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64 722 %array.2.i = load i32, i32* %array.2.i.ptr, align 4 723 %loop.acc.2 = add i32 %loop.acc.1, %array.2.i 724 725 %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64 726 %array.3.i = load i32, i32* %array.3.i.ptr, align 4 727 %loop.acc.next = add i32 %loop.acc.2, %array.3.i 728 729 %i.next = add nuw i32 %i, 1 730 %continue = icmp ult i32 %i.next, %n 731 br i1 %continue, label %loop, label %exit 732 733exit: 734 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 735 ret i32 %result 736} 737 738define i32 @three_guards(i32* %array.1, i32 %length.1, 739 i32* %array.2, i32 %length.2, 740 i32* %array.3, i32 %length.3, i32 %n) { 741; CHECK-LABEL: @three_guards 742entry: 743 %tmp5 = icmp eq i32 %n, 0 744 br i1 %tmp5, label %exit, label %loop.preheader 745 746loop.preheader: 747; CHECK: loop.preheader: 748; CHECK: [[limit_check_1:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}} 749; CHECK-NEXT: [[first_iteration_check_1:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}} 750; CHECK-NEXT: [[wide_cond_1:[^ ]+]] = and i1 [[first_iteration_check_1]], [[limit_check_1]] 751; CHECK-NEXT: [[limit_check_2:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}} 752; CHECK-NEXT: [[first_iteration_check_2:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}} 753; CHECK-NEXT: [[wide_cond_2:[^ ]+]] = and i1 [[first_iteration_check_2]], [[limit_check_2]] 754; CHECK-NEXT: [[limit_check_3:[^ ]+]] = icmp ule i32 %n, %length.{{1|2|3}} 755; CHECK-NEXT: [[first_iteration_check_3:[^ ]+]] = icmp ult i32 0, %length.{{1|2|3}} 756; CHECK-NEXT: [[wide_cond_3:[^ ]+]] = and i1 [[first_iteration_check_3]], [[limit_check_3]] 757; CHECK-NEXT: br label %loop 758 br label %loop 759 760loop: 761; CHECK: loop: 762; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond_1]], i32 9) [ "deopt"() ] 763; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond_2]], i32 9) [ "deopt"() ] 764; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond_3]], i32 9) [ "deopt"() ] 765 766 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 767 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 768 769 %within.bounds.1 = icmp ult i32 %i, %length.1 770 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.1, i32 9) [ "deopt"() ] 771 772 %i.i64 = zext i32 %i to i64 773 %array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64 774 %array.1.i = load i32, i32* %array.1.i.ptr, align 4 775 %loop.acc.1 = add i32 %loop.acc, %array.1.i 776 777 %within.bounds.2 = icmp ult i32 %i, %length.2 778 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.2, i32 9) [ "deopt"() ] 779 780 %array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64 781 %array.2.i = load i32, i32* %array.2.i.ptr, align 4 782 %loop.acc.2 = add i32 %loop.acc.1, %array.2.i 783 784 %within.bounds.3 = icmp ult i32 %i, %length.3 785 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds.3, i32 9) [ "deopt"() ] 786 787 %array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64 788 %array.3.i = load i32, i32* %array.3.i.ptr, align 4 789 %loop.acc.next = add i32 %loop.acc.2, %array.3.i 790 791 %i.next = add nuw i32 %i, 1 792 %continue = icmp ult i32 %i.next, %n 793 br i1 %continue, label %loop, label %exit 794 795exit: 796 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 797 ret i32 %result 798} 799 800define i32 @unsigned_loop_0_to_n_unrelated_condition(i32* %array, i32 %length, i32 %n, i32 %x) { 801; CHECK-LABEL: @unsigned_loop_0_to_n_unrelated_condition 802entry: 803 %tmp5 = icmp eq i32 %n, 0 804 br i1 %tmp5, label %exit, label %loop.preheader 805 806loop.preheader: 807; CHECK: loop.preheader: 808; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length 809; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length 810; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]] 811; CHECK-NEXT: br label %loop 812 br label %loop 813 814loop: 815; CHECK: loop: 816; CHECK: %unrelated.cond = icmp ult i32 %x, %length 817; CHECK: [[guard_cond:[^ ]+]] = and i1 %unrelated.cond, [[wide_cond]] 818; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[guard_cond]], i32 9) [ "deopt"() ] 819 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 820 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 821 %within.bounds = icmp ult i32 %i, %length 822 %unrelated.cond = icmp ult i32 %x, %length 823 %guard.cond = and i1 %within.bounds, %unrelated.cond 824 call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ] 825 826 %i.i64 = zext i32 %i to i64 827 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 828 %array.i = load i32, i32* %array.i.ptr, align 4 829 %loop.acc.next = add i32 %loop.acc, %array.i 830 831 %i.next = add nuw i32 %i, 1 832 %continue = icmp ult i32 %i.next, %n 833 br i1 %continue, label %loop, label %exit 834 835exit: 836 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 837 ret i32 %result 838} 839 840; Don't change the guard condition if there were no widened subconditions 841define i32 @test_no_widened_conditions(i32* %array, i32 %length, i32 %n, i32 %x1, i32 %x2, i32 %x3) { 842; CHECK-LABEL: @test_no_widened_conditions 843entry: 844 %tmp5 = icmp eq i32 %n, 0 845 br i1 %tmp5, label %exit, label %loop.preheader 846 847loop.preheader: 848; CHECK: loop.preheader: 849; CHECK-NEXT: br label %loop 850 br label %loop 851 852loop: 853; CHECK: loop: 854; CHECK: %unrelated.cond.1 = icmp eq i32 %x1, %i 855; CHECK-NEXT: %unrelated.cond.2 = icmp eq i32 %x2, %i 856; CHECK-NEXT: %unrelated.cond.3 = icmp eq i32 %x3, %i 857; CHECK-NEXT: %unrelated.cond.and.1 = and i1 %unrelated.cond.1, %unrelated.cond.2 858; CHECK-NEXT: %guard.cond = and i1 %unrelated.cond.and.1, %unrelated.cond.3 859; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ] 860 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 861 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 862 %unrelated.cond.1 = icmp eq i32 %x1, %i 863 %unrelated.cond.2 = icmp eq i32 %x2, %i 864 %unrelated.cond.3 = icmp eq i32 %x3, %i 865 %unrelated.cond.and.1 = and i1 %unrelated.cond.1, %unrelated.cond.2 866 %guard.cond = and i1 %unrelated.cond.and.1, %unrelated.cond.3 867 868 call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ] 869 870 %i.i64 = zext i32 %i to i64 871 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 872 %array.i = load i32, i32* %array.i.ptr, align 4 873 %loop.acc.next = add i32 %loop.acc, %array.i 874 875 %i.next = add nuw i32 %i, 1 876 %continue = icmp ult i32 %i.next, %n 877 br i1 %continue, label %loop, label %exit 878 879exit: 880 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 881 ret i32 %result 882} 883 884define i32 @signed_loop_start_to_n_loop_variant_bound(i32* %array, i32 %x, i32 %start, i32 %n) { 885; CHECK-LABEL: @signed_loop_start_to_n_loop_variant_bound 886entry: 887 %tmp5 = icmp sle i32 %n, 0 888 br i1 %tmp5, label %exit, label %loop.preheader 889 890loop.preheader: 891; CHECK: loop.preheader: 892; CHECK-NEXT: br label %loop 893 br label %loop 894 895loop: 896; CHECK: loop: 897; CHECK: %bound = add i32 %i, %x 898; CHECK-NEXT: %within.bounds = icmp ult i32 %i, %bound 899; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 900 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 901 %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ] 902 %bound = add i32 %i, %x 903 %within.bounds = icmp ult i32 %i, %bound 904 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 905 906 %i.i64 = zext i32 %i to i64 907 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 908 %array.i = load i32, i32* %array.i.ptr, align 4 909 %loop.acc.next = add i32 %loop.acc, %array.i 910 911 %i.next = add nsw i32 %i, 1 912 %continue = icmp slt i32 %i.next, %n 913 br i1 %continue, label %loop, label %exit 914 915exit: 916 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 917 ret i32 %result 918} 919 920define i32 @signed_loop_start_to_n_non_monotonic_predicate(i32* %array, i32 %x, i32 %start, i32 %n) { 921; CHECK-LABEL: @signed_loop_start_to_n_non_monotonic_predicate 922entry: 923 %tmp5 = icmp sle i32 %n, 0 924 br i1 %tmp5, label %exit, label %loop.preheader 925 926loop.preheader: 927; CHECK: loop.preheader: 928; CHECK-NEXT: br label %loop 929 br label %loop 930 931loop: 932; CHECK: loop: 933; CHECK: %guard.cond = icmp eq i32 %i, %x 934; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ] 935 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 936 %i = phi i32 [ %i.next, %loop ], [ %start, %loop.preheader ] 937 %guard.cond = icmp eq i32 %i, %x 938 call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond, i32 9) [ "deopt"() ] 939 940 %i.i64 = zext i32 %i to i64 941 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 942 %array.i = load i32, i32* %array.i.ptr, align 4 943 %loop.acc.next = add i32 %loop.acc, %array.i 944 945 %i.next = add nsw i32 %i, 1 946 %continue = icmp slt i32 %i.next, %n 947 br i1 %continue, label %loop, label %exit 948 949exit: 950 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 951 ret i32 %result 952} 953 954define i32 @unsigned_loop_0_to_n_hoist_length(i32* %array, i16 %length.i16, i32 %n) { 955; CHECK-LABEL: @unsigned_loop_0_to_n_hoist_length 956entry: 957 %tmp5 = icmp eq i32 %n, 0 958 br i1 %tmp5, label %exit, label %loop.preheader 959 960loop.preheader: 961; CHECK: loop.preheader: 962; CHECK: [[length:[^ ]+]] = zext i16 %length.i16 to i32 963; CHECK-NEXT: [[limit_check:[^ ]+]] = icmp ule i32 %n, [[length]] 964; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, [[length]] 965; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]] 966; CHECK-NEXT: br label %loop 967 br label %loop 968 969loop: 970; CHECK: loop: 971; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ] 972 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 973 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 974 %length = zext i16 %length.i16 to i32 975 %within.bounds = icmp ult i32 %i, %length 976 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 977 978 %i.i64 = zext i32 %i to i64 979 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 980 %array.i = load i32, i32* %array.i.ptr, align 4 981 %loop.acc.next = add i32 %loop.acc, %array.i 982 983 %i.next = add nuw i32 %i, 1 984 %continue = icmp ult i32 %i.next, %n 985 br i1 %continue, label %loop, label %exit 986 987exit: 988 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 989 ret i32 %result 990} 991 992define i32 @unsigned_loop_0_to_n_cant_hoist_length(i32* %array, i32 %length, i32 %divider, i32 %n) { 993; CHECK-LABEL: @unsigned_loop_0_to_n_cant_hoist_length 994entry: 995 %tmp5 = icmp eq i32 %n, 0 996 br i1 %tmp5, label %exit, label %loop.preheader 997 998loop.preheader: 999; CHECK: loop.preheader: 1000; CHECK-NEXT: br label %loop 1001 br label %loop 1002 1003loop: 1004; CHECK: loop: 1005; CHECK-NEXT: %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1006; CHECK-NEXT: %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1007; CHECK-NEXT: %length.udiv = udiv i32 %length, %divider 1008; CHECK-NEXT: %within.bounds = icmp ult i32 %i, %length.udiv 1009; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1010 %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] 1011 %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] 1012 %length.udiv = udiv i32 %length, %divider 1013 %within.bounds = icmp ult i32 %i, %length.udiv 1014 call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] 1015 1016 %i.i64 = zext i32 %i to i64 1017 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64 1018 %array.i = load i32, i32* %array.i.ptr, align 4 1019 %loop.acc.next = add i32 %loop.acc, %array.i 1020 1021 %i.next = add nuw i32 %i, 1 1022 %continue = icmp ult i32 %i.next, %n 1023 br i1 %continue, label %loop, label %exit 1024 1025exit: 1026 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1027 ret i32 %result 1028} 1029