Home | History | Annotate | Download | only in LoopPredication
      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