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 4 declare void @llvm.experimental.guard(i1, ...) 5 6 define i32 @unsigned_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) { 7 ; CHECK-LABEL: @unsigned_loop_0_to_n_ult_check 8 entry: 9 %tmp5 = icmp eq i32 %n, 0 10 br i1 %tmp5, label %exit, label %loop.preheader 11 12 loop.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 20 loop: 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 37 exit: 38 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 39 ret i32 %result 40 } 41 42 define 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 44 entry: 45 %tmp5 = icmp eq i32 %n, 0 46 br i1 %tmp5, label %exit, label %loop.preheader 47 48 loop.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 56 loop: 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 73 exit: 74 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 75 ret i32 %result 76 } 77 78 define i32 @unsigned_loop_0_to_n_ugt_check(i32* %array, i32 %length, i32 %n) { 79 ; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check 80 entry: 81 %tmp5 = icmp eq i32 %n, 0 82 br i1 %tmp5, label %exit, label %loop.preheader 83 84 loop.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 92 loop: 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 109 exit: 110 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 111 ret i32 %result 112 } 113 114 define i32 @signed_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) { 115 ; CHECK-LABEL: @signed_loop_0_to_n_ult_check 116 entry: 117 %tmp5 = icmp sle i32 %n, 0 118 br i1 %tmp5, label %exit, label %loop.preheader 119 120 loop.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 128 loop: 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 145 exit: 146 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 147 ret i32 %result 148 } 149 150 define 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 152 entry: 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 157 loop.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 164 loop: 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 181 exit: 182 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 183 ret i32 %result 184 } 185 186 define 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 188 entry: 189 %tmp5 = icmp sle i32 %n, 0 190 br i1 %tmp5, label %exit, label %loop.preheader 191 192 loop.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 200 loop: 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 217 exit: 218 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 219 ret i32 %result 220 } 221 222 define 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 224 entry: 225 %tmp5 = icmp sle i32 %n, 0 226 br i1 %tmp5, label %exit, label %loop.preheader 227 228 loop.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 236 loop: 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 253 exit: 254 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 255 ret i32 %result 256 } 257 258 define 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 260 entry: 261 %tmp5 = icmp sle i32 %n, 0 262 br i1 %tmp5, label %exit, label %loop.preheader 263 264 loop.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 273 loop: 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 290 exit: 291 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 292 ret i32 %result 293 } 294 295 define 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 297 entry: 298 %tmp5 = icmp sle i32 %n, 0 299 br i1 %tmp5, label %exit, label %loop.preheader 300 301 loop.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 310 loop: 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 328 exit: 329 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 330 ret i32 %result 331 } 332 333 define 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 335 entry: 336 %tmp5 = icmp sle i32 %n, 0 337 br i1 %tmp5, label %exit, label %loop.preheader 338 339 loop.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 348 loop: 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 366 exit: 367 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 368 ret i32 %result 369 } 370 371 define 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 373 entry: 374 %tmp5 = icmp sle i32 %n, 0 375 br i1 %tmp5, label %exit, label %loop.preheader 376 377 loop.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 385 loop: 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 404 exit: 405 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 406 ret i32 %result 407 } 408 409 define i32 @unsupported_latch_pred_loop_0_to_n(i32* %array, i32 %length, i32 %n) { 410 ; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n 411 entry: 412 %tmp5 = icmp sle i32 %n, 0 413 br i1 %tmp5, label %exit, label %loop.preheader 414 415 loop.preheader: 416 ; CHECK: loop.preheader: 417 ; CHECK-NEXT: br label %loop 418 br label %loop 419 420 loop: 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 438 exit: 439 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 440 ret i32 %result 441 } 442 443 define 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 445 entry: 446 %tmp5 = icmp sle i32 %n, 0 447 br i1 %tmp5, label %exit, label %loop.preheader 448 449 loop.preheader: 450 ; CHECK: loop.preheader: 451 ; CHECK-NEXT: br label %loop 452 br label %loop 453 454 loop: 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 472 exit: 473 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 474 ret i32 %result 475 } 476 477 define 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 479 entry: 480 %tmp5 = icmp sle i32 %n, 0 481 br i1 %tmp5, label %exit, label %loop.preheader 482 483 loop.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 491 loop: 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 511 exit: 512 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 513 ret i32 %result 514 } 515 516 define 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 520 entry: 521 %tmp5 = icmp sle i32 %n, 0 522 br i1 %tmp5, label %exit, label %loop.preheader 523 524 loop.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 534 loop: 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 554 exit: 555 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 556 ret i32 %result 557 } 558 559 define 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 561 entry: 562 %tmp5 = icmp sle i32 %n, 0 563 br i1 %tmp5, label %exit, label %loop.preheader 564 565 loop.preheader: 566 ; CHECK: loop.preheader: 567 ; CHECK-NEXT: br label %loop 568 br label %loop 569 570 loop: 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 591 exit: 592 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 593 ret i32 %result 594 } 595 596 define 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 598 entry: 599 %tmp5 = icmp sle i32 %n, 0 600 br i1 %tmp5, label %exit, label %loop.preheader 601 602 loop.preheader: 603 ; CHECK: loop.preheader: 604 ; CHECK-NEXT: br label %loop 605 br label %loop 606 607 loop: 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 628 exit: 629 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 630 ret i32 %result 631 } 632 633 define 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 636 entry: 637 %tmp5 = icmp eq i32 %n, 0 638 br i1 %tmp5, label %exit, label %loop.preheader 639 640 loop.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 651 loop: 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 675 exit: 676 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 677 ret i32 %result 678 } 679 680 define 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 684 entry: 685 %tmp5 = icmp eq i32 %n, 0 686 br i1 %tmp5, label %exit, label %loop.preheader 687 688 loop.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 702 loop: 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 733 exit: 734 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 735 ret i32 %result 736 } 737 738 define 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 742 entry: 743 %tmp5 = icmp eq i32 %n, 0 744 br i1 %tmp5, label %exit, label %loop.preheader 745 746 loop.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 760 loop: 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 795 exit: 796 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 797 ret i32 %result 798 } 799 800 define 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 802 entry: 803 %tmp5 = icmp eq i32 %n, 0 804 br i1 %tmp5, label %exit, label %loop.preheader 805 806 loop.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 814 loop: 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 835 exit: 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 841 define i32 @test_no_widened_conditions(i32* %array, i32 %length, i32 %n, i32 %x1, i32 %x2, i32 %x3) { 842 ; CHECK-LABEL: @test_no_widened_conditions 843 entry: 844 %tmp5 = icmp eq i32 %n, 0 845 br i1 %tmp5, label %exit, label %loop.preheader 846 847 loop.preheader: 848 ; CHECK: loop.preheader: 849 ; CHECK-NEXT: br label %loop 850 br label %loop 851 852 loop: 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 879 exit: 880 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 881 ret i32 %result 882 } 883 884 define 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 886 entry: 887 %tmp5 = icmp sle i32 %n, 0 888 br i1 %tmp5, label %exit, label %loop.preheader 889 890 loop.preheader: 891 ; CHECK: loop.preheader: 892 ; CHECK-NEXT: br label %loop 893 br label %loop 894 895 loop: 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 915 exit: 916 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 917 ret i32 %result 918 } 919 920 define 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 922 entry: 923 %tmp5 = icmp sle i32 %n, 0 924 br i1 %tmp5, label %exit, label %loop.preheader 925 926 loop.preheader: 927 ; CHECK: loop.preheader: 928 ; CHECK-NEXT: br label %loop 929 br label %loop 930 931 loop: 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 949 exit: 950 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 951 ret i32 %result 952 } 953 954 define 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 956 entry: 957 %tmp5 = icmp eq i32 %n, 0 958 br i1 %tmp5, label %exit, label %loop.preheader 959 960 loop.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 969 loop: 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 987 exit: 988 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 989 ret i32 %result 990 } 991 992 define 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 994 entry: 995 %tmp5 = icmp eq i32 %n, 0 996 br i1 %tmp5, label %exit, label %loop.preheader 997 998 loop.preheader: 999 ; CHECK: loop.preheader: 1000 ; CHECK-NEXT: br label %loop 1001 br label %loop 1002 1003 loop: 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 1025 exit: 1026 %result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ] 1027 ret i32 %result 1028 } 1029