Home | History | Annotate | Download | only in LoopUnroll
      1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
      2 ; RUN: opt < %s -S -loop-unroll -verify-dom-info | FileCheck %s
      3 
      4 declare void @f1()
      5 declare void @f2()
      6 
      7 ; Check that we can peel off iterations that make conditions true.
      8 define void @test1(i32 %k) {
      9 ; CHECK-LABEL: @test1(
     10 ; CHECK-NEXT:  for.body.lr.ph:
     11 ; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]
     12 ; CHECK:       for.body.peel.begin:
     13 ; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]
     14 ; CHECK:       for.body.peel:
     15 ; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp ult i32 0, 2
     16 ; CHECK-NEXT:    br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_ELSE_PEEL:%.*]]
     17 ; CHECK:       if.else.peel:
     18 ; CHECK-NEXT:    call void @f2()
     19 ; CHECK-NEXT:    br label [[FOR_INC_PEEL:%.*]]
     20 ; CHECK:       if.then.peel:
     21 ; CHECK-NEXT:    call void @f1()
     22 ; CHECK-NEXT:    br label [[FOR_INC_PEEL]]
     23 ; CHECK:       for.inc.peel:
     24 ; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nsw i32 0, 1
     25 ; CHECK-NEXT:    [[CMP_PEEL:%.*]] = icmp slt i32 [[INC_PEEL]], [[K:%.*]]
     26 ; CHECK-NEXT:    br i1 [[CMP_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_END:%.*]]
     27 ; CHECK:       for.body.peel.next:
     28 ; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]
     29 ; CHECK:       for.body.peel2:
     30 ; CHECK-NEXT:    [[CMP1_PEEL3:%.*]] = icmp ult i32 [[INC_PEEL]], 2
     31 ; CHECK-NEXT:    br i1 [[CMP1_PEEL3]], label [[IF_THEN_PEEL5:%.*]], label [[IF_ELSE_PEEL4:%.*]]
     32 ; CHECK:       if.else.peel4:
     33 ; CHECK-NEXT:    call void @f2()
     34 ; CHECK-NEXT:    br label [[FOR_INC_PEEL6:%.*]]
     35 ; CHECK:       if.then.peel5:
     36 ; CHECK-NEXT:    call void @f1()
     37 ; CHECK-NEXT:    br label [[FOR_INC_PEEL6]]
     38 ; CHECK:       for.inc.peel6:
     39 ; CHECK-NEXT:    [[INC_PEEL7:%.*]] = add nsw i32 [[INC_PEEL]], 1
     40 ; CHECK-NEXT:    [[CMP_PEEL8:%.*]] = icmp slt i32 [[INC_PEEL7]], [[K]]
     41 ; CHECK-NEXT:    br i1 [[CMP_PEEL8]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_END]]
     42 ; CHECK:       for.body.peel.next1:
     43 ; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT9:%.*]]
     44 ; CHECK:       for.body.peel.next9:
     45 ; CHECK-NEXT:    br label [[FOR_BODY_LR_PH_PEEL_NEWPH:%.*]]
     46 ; CHECK:       for.body.lr.ph.peel.newph:
     47 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
     48 ; CHECK:       for.body:
     49 ; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ [[INC_PEEL7]], [[FOR_BODY_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
     50 ; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
     51 ; CHECK:       if.then:
     52 ; CHECK-NEXT:    call void @f1()
     53 ; CHECK-NEXT:    br label [[FOR_INC]]
     54 ; CHECK:       if.else:
     55 ; CHECK-NEXT:    call void @f2()
     56 ; CHECK-NEXT:    br label [[FOR_INC]]
     57 ; CHECK:       for.inc:
     58 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_05]], 1
     59 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K]]
     60 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]], !llvm.loop !0
     61 ; CHECK:       for.end.loopexit:
     62 ; CHECK-NEXT:    br label [[FOR_END]]
     63 ; CHECK:       for.end:
     64 ; CHECK-NEXT:    ret void
     65 ;
     66 for.body.lr.ph:
     67   br label %for.body
     68 
     69 for.body:
     70   %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]
     71   %cmp1 = icmp ult i32 %i.05, 2
     72   br i1 %cmp1, label %if.then, label %if.else
     73 
     74 if.then:
     75   call void @f1()
     76   br label %for.inc
     77 
     78 if.else:
     79   call void @f2()
     80   br label %for.inc
     81 
     82 for.inc:
     83   %inc = add nsw i32 %i.05, 1
     84   %cmp = icmp slt i32 %inc, %k
     85   br i1 %cmp, label %for.body, label %for.end
     86 
     87 for.end:
     88   ret void
     89 }
     90 
     91 ; Check we peel off the maximum number of iterations that make conditions true.
     92 define void @test2(i32 %k) {
     93 ; CHECK-LABEL: @test2(
     94 ; CHECK-NEXT:  for.body.lr.ph:
     95 ; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]
     96 ; CHECK:       for.body.peel.begin:
     97 ; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]
     98 ; CHECK:       for.body.peel:
     99 ; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp ult i32 0, 2
    100 ; CHECK-NEXT:    br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_ELSE_PEEL:%.*]]
    101 ; CHECK:       if.else.peel:
    102 ; CHECK-NEXT:    call void @f2()
    103 ; CHECK-NEXT:    br label [[IF2_PEEL:%.*]]
    104 ; CHECK:       if.then.peel:
    105 ; CHECK-NEXT:    call void @f1()
    106 ; CHECK-NEXT:    br label [[IF2_PEEL]]
    107 ; CHECK:       if2.peel:
    108 ; CHECK-NEXT:    [[CMP2_PEEL:%.*]] = icmp ult i32 0, 4
    109 ; CHECK-NEXT:    br i1 [[CMP2_PEEL]], label [[IF_THEN2_PEEL:%.*]], label [[FOR_INC_PEEL:%.*]]
    110 ; CHECK:       if.then2.peel:
    111 ; CHECK-NEXT:    call void @f1()
    112 ; CHECK-NEXT:    br label [[FOR_INC_PEEL]]
    113 ; CHECK:       for.inc.peel:
    114 ; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nsw i32 0, 1
    115 ; CHECK-NEXT:    [[CMP_PEEL:%.*]] = icmp slt i32 [[INC_PEEL]], [[K:%.*]]
    116 ; CHECK-NEXT:    br i1 [[CMP_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_END:%.*]]
    117 ; CHECK:       for.body.peel.next:
    118 ; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]
    119 ; CHECK:       for.body.peel2:
    120 ; CHECK-NEXT:    [[CMP1_PEEL3:%.*]] = icmp ult i32 [[INC_PEEL]], 2
    121 ; CHECK-NEXT:    br i1 [[CMP1_PEEL3]], label [[IF_THEN_PEEL5:%.*]], label [[IF_ELSE_PEEL4:%.*]]
    122 ; CHECK:       if.else.peel4:
    123 ; CHECK-NEXT:    call void @f2()
    124 ; CHECK-NEXT:    br label [[IF2_PEEL6:%.*]]
    125 ; CHECK:       if.then.peel5:
    126 ; CHECK-NEXT:    call void @f1()
    127 ; CHECK-NEXT:    br label [[IF2_PEEL6]]
    128 ; CHECK:       if2.peel6:
    129 ; CHECK-NEXT:    [[CMP2_PEEL7:%.*]] = icmp ult i32 [[INC_PEEL]], 4
    130 ; CHECK-NEXT:    br i1 [[CMP2_PEEL7]], label [[IF_THEN2_PEEL8:%.*]], label [[FOR_INC_PEEL9:%.*]]
    131 ; CHECK:       if.then2.peel8:
    132 ; CHECK-NEXT:    call void @f1()
    133 ; CHECK-NEXT:    br label [[FOR_INC_PEEL9]]
    134 ; CHECK:       for.inc.peel9:
    135 ; CHECK-NEXT:    [[INC_PEEL10:%.*]] = add nsw i32 [[INC_PEEL]], 1
    136 ; CHECK-NEXT:    [[CMP_PEEL11:%.*]] = icmp slt i32 [[INC_PEEL10]], [[K]]
    137 ; CHECK-NEXT:    br i1 [[CMP_PEEL11]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_END]]
    138 ; CHECK:       for.body.peel.next1:
    139 ; CHECK-NEXT:    br label [[FOR_BODY_PEEL13:%.*]]
    140 ; CHECK:       for.body.peel13:
    141 ; CHECK-NEXT:    [[CMP1_PEEL14:%.*]] = icmp ult i32 [[INC_PEEL10]], 2
    142 ; CHECK-NEXT:    br i1 [[CMP1_PEEL14]], label [[IF_THEN_PEEL16:%.*]], label [[IF_ELSE_PEEL15:%.*]]
    143 ; CHECK:       if.else.peel15:
    144 ; CHECK-NEXT:    call void @f2()
    145 ; CHECK-NEXT:    br label [[IF2_PEEL17:%.*]]
    146 ; CHECK:       if.then.peel16:
    147 ; CHECK-NEXT:    call void @f1()
    148 ; CHECK-NEXT:    br label [[IF2_PEEL17]]
    149 ; CHECK:       if2.peel17:
    150 ; CHECK-NEXT:    [[CMP2_PEEL18:%.*]] = icmp ult i32 [[INC_PEEL10]], 4
    151 ; CHECK-NEXT:    br i1 [[CMP2_PEEL18]], label [[IF_THEN2_PEEL19:%.*]], label [[FOR_INC_PEEL20:%.*]]
    152 ; CHECK:       if.then2.peel19:
    153 ; CHECK-NEXT:    call void @f1()
    154 ; CHECK-NEXT:    br label [[FOR_INC_PEEL20]]
    155 ; CHECK:       for.inc.peel20:
    156 ; CHECK-NEXT:    [[INC_PEEL21:%.*]] = add nsw i32 [[INC_PEEL10]], 1
    157 ; CHECK-NEXT:    [[CMP_PEEL22:%.*]] = icmp slt i32 [[INC_PEEL21]], [[K]]
    158 ; CHECK-NEXT:    br i1 [[CMP_PEEL22]], label [[FOR_BODY_PEEL_NEXT12:%.*]], label [[FOR_END]]
    159 ; CHECK:       for.body.peel.next12:
    160 ; CHECK-NEXT:    br label [[FOR_BODY_PEEL24:%.*]]
    161 ; CHECK:       for.body.peel24:
    162 ; CHECK-NEXT:    [[CMP1_PEEL25:%.*]] = icmp ult i32 [[INC_PEEL21]], 2
    163 ; CHECK-NEXT:    br i1 [[CMP1_PEEL25]], label [[IF_THEN_PEEL27:%.*]], label [[IF_ELSE_PEEL26:%.*]]
    164 ; CHECK:       if.else.peel26:
    165 ; CHECK-NEXT:    call void @f2()
    166 ; CHECK-NEXT:    br label [[IF2_PEEL28:%.*]]
    167 ; CHECK:       if.then.peel27:
    168 ; CHECK-NEXT:    call void @f1()
    169 ; CHECK-NEXT:    br label [[IF2_PEEL28]]
    170 ; CHECK:       if2.peel28:
    171 ; CHECK-NEXT:    [[CMP2_PEEL29:%.*]] = icmp ult i32 [[INC_PEEL21]], 4
    172 ; CHECK-NEXT:    br i1 [[CMP2_PEEL29]], label [[IF_THEN2_PEEL30:%.*]], label [[FOR_INC_PEEL31:%.*]]
    173 ; CHECK:       if.then2.peel30:
    174 ; CHECK-NEXT:    call void @f1()
    175 ; CHECK-NEXT:    br label [[FOR_INC_PEEL31]]
    176 ; CHECK:       for.inc.peel31:
    177 ; CHECK-NEXT:    [[INC_PEEL32:%.*]] = add nsw i32 [[INC_PEEL21]], 1
    178 ; CHECK-NEXT:    [[CMP_PEEL33:%.*]] = icmp slt i32 [[INC_PEEL32]], [[K]]
    179 ; CHECK-NEXT:    br i1 [[CMP_PEEL33]], label [[FOR_BODY_PEEL_NEXT23:%.*]], label [[FOR_END]]
    180 ; CHECK:       for.body.peel.next23:
    181 ; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT34:%.*]]
    182 ; CHECK:       for.body.peel.next34:
    183 ; CHECK-NEXT:    br label [[FOR_BODY_LR_PH_PEEL_NEWPH:%.*]]
    184 ; CHECK:       for.body.lr.ph.peel.newph:
    185 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
    186 ; CHECK:       for.body:
    187 ; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ [[INC_PEEL32]], [[FOR_BODY_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
    188 ; CHECK-NEXT:    br i1 false, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
    189 ; CHECK:       if.then:
    190 ; CHECK-NEXT:    call void @f1()
    191 ; CHECK-NEXT:    br label [[IF2:%.*]]
    192 ; CHECK:       if.else:
    193 ; CHECK-NEXT:    call void @f2()
    194 ; CHECK-NEXT:    br label [[IF2]]
    195 ; CHECK:       if2:
    196 ; CHECK-NEXT:    br i1 false, label [[IF_THEN2:%.*]], label [[FOR_INC]]
    197 ; CHECK:       if.then2:
    198 ; CHECK-NEXT:    call void @f1()
    199 ; CHECK-NEXT:    br label [[FOR_INC]]
    200 ; CHECK:       for.inc:
    201 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_05]], 1
    202 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K]]
    203 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]], !llvm.loop !2
    204 ; CHECK:       for.end.loopexit:
    205 ; CHECK-NEXT:    br label [[FOR_END]]
    206 ; CHECK:       for.end:
    207 ; CHECK-NEXT:    ret void
    208 ;
    209 for.body.lr.ph:
    210   br label %for.body
    211 
    212 for.body:
    213   %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]
    214   %cmp1 = icmp ult i32 %i.05, 2
    215   br i1 %cmp1, label %if.then, label %if.else
    216 
    217 if.then:
    218   call void @f1()
    219   br label %if2
    220 
    221 if.else:
    222   call void @f2()
    223   br label %if2
    224 
    225 if2:
    226   %cmp2 = icmp ult i32 %i.05, 4
    227   br i1 %cmp2, label %if.then2, label %for.inc
    228 
    229 if.then2:
    230   call void @f1()
    231   br label %for.inc
    232 
    233 for.inc:
    234   %inc = add nsw i32 %i.05, 1
    235   %cmp = icmp slt i32 %inc, %k
    236   br i1 %cmp, label %for.body, label %for.end
    237 
    238 for.end:
    239   ret void
    240 }
    241 
    242 ; Check that we can peel off iterations that make a condition false.
    243 define void @test3(i32 %k) {
    244 ; CHECK-LABEL: @test3(
    245 ; CHECK-NEXT:  for.body.lr.ph:
    246 ; CHECK-NEXT:    br label [[FOR_BODY_PEEL_BEGIN:%.*]]
    247 ; CHECK:       for.body.peel.begin:
    248 ; CHECK-NEXT:    br label [[FOR_BODY_PEEL:%.*]]
    249 ; CHECK:       for.body.peel:
    250 ; CHECK-NEXT:    [[CMP1_PEEL:%.*]] = icmp ugt i32 0, 2
    251 ; CHECK-NEXT:    br i1 [[CMP1_PEEL]], label [[IF_THEN_PEEL:%.*]], label [[IF_ELSE_PEEL:%.*]]
    252 ; CHECK:       if.else.peel:
    253 ; CHECK-NEXT:    call void @f2()
    254 ; CHECK-NEXT:    br label [[FOR_INC_PEEL:%.*]]
    255 ; CHECK:       if.then.peel:
    256 ; CHECK-NEXT:    call void @f1()
    257 ; CHECK-NEXT:    br label [[FOR_INC_PEEL]]
    258 ; CHECK:       for.inc.peel:
    259 ; CHECK-NEXT:    [[INC_PEEL:%.*]] = add nsw i32 0, 1
    260 ; CHECK-NEXT:    [[CMP_PEEL:%.*]] = icmp slt i32 [[INC_PEEL]], [[K:%.*]]
    261 ; CHECK-NEXT:    br i1 [[CMP_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_END:%.*]]
    262 ; CHECK:       for.body.peel.next:
    263 ; CHECK-NEXT:    br label [[FOR_BODY_PEEL2:%.*]]
    264 ; CHECK:       for.body.peel2:
    265 ; CHECK-NEXT:    [[CMP1_PEEL3:%.*]] = icmp ugt i32 [[INC_PEEL]], 2
    266 ; CHECK-NEXT:    br i1 [[CMP1_PEEL3]], label [[IF_THEN_PEEL5:%.*]], label [[IF_ELSE_PEEL4:%.*]]
    267 ; CHECK:       if.else.peel4:
    268 ; CHECK-NEXT:    call void @f2()
    269 ; CHECK-NEXT:    br label [[FOR_INC_PEEL6:%.*]]
    270 ; CHECK:       if.then.peel5:
    271 ; CHECK-NEXT:    call void @f1()
    272 ; CHECK-NEXT:    br label [[FOR_INC_PEEL6]]
    273 ; CHECK:       for.inc.peel6:
    274 ; CHECK-NEXT:    [[INC_PEEL7:%.*]] = add nsw i32 [[INC_PEEL]], 1
    275 ; CHECK-NEXT:    [[CMP_PEEL8:%.*]] = icmp slt i32 [[INC_PEEL7]], [[K]]
    276 ; CHECK-NEXT:    br i1 [[CMP_PEEL8]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_END]]
    277 ; CHECK:       for.body.peel.next1:
    278 ; CHECK-NEXT:    br label [[FOR_BODY_PEEL10:%.*]]
    279 ; CHECK:       for.body.peel10:
    280 ; CHECK-NEXT:    [[CMP1_PEEL11:%.*]] = icmp ugt i32 [[INC_PEEL7]], 2
    281 ; CHECK-NEXT:    br i1 [[CMP1_PEEL11]], label [[IF_THEN_PEEL13:%.*]], label [[IF_ELSE_PEEL12:%.*]]
    282 ; CHECK:       if.else.peel12:
    283 ; CHECK-NEXT:    call void @f2()
    284 ; CHECK-NEXT:    br label [[FOR_INC_PEEL14:%.*]]
    285 ; CHECK:       if.then.peel13:
    286 ; CHECK-NEXT:    call void @f1()
    287 ; CHECK-NEXT:    br label [[FOR_INC_PEEL14]]
    288 ; CHECK:       for.inc.peel14:
    289 ; CHECK-NEXT:    [[INC_PEEL15:%.*]] = add nsw i32 [[INC_PEEL7]], 1
    290 ; CHECK-NEXT:    [[CMP_PEEL16:%.*]] = icmp slt i32 [[INC_PEEL15]], [[K]]
    291 ; CHECK-NEXT:    br i1 [[CMP_PEEL16]], label [[FOR_BODY_PEEL_NEXT9:%.*]], label [[FOR_END]]
    292 ; CHECK:       for.body.peel.next9:
    293 ; CHECK-NEXT:    br label [[FOR_BODY_PEEL_NEXT17:%.*]]
    294 ; CHECK:       for.body.peel.next17:
    295 ; CHECK-NEXT:    br label [[FOR_BODY_LR_PH_PEEL_NEWPH:%.*]]
    296 ; CHECK:       for.body.lr.ph.peel.newph:
    297 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
    298 ; CHECK:       for.body:
    299 ; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ [[INC_PEEL15]], [[FOR_BODY_LR_PH_PEEL_NEWPH]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
    300 ; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
    301 ; CHECK:       if.then:
    302 ; CHECK-NEXT:    call void @f1()
    303 ; CHECK-NEXT:    br label [[FOR_INC]]
    304 ; CHECK:       if.else:
    305 ; CHECK-NEXT:    call void @f2()
    306 ; CHECK-NEXT:    br label [[FOR_INC]]
    307 ; CHECK:       for.inc:
    308 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_05]], 1
    309 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K]]
    310 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]], !llvm.loop !3
    311 ; CHECK:       for.end.loopexit:
    312 ; CHECK-NEXT:    br label [[FOR_END]]
    313 ; CHECK:       for.end:
    314 ; CHECK-NEXT:    ret void
    315 ;
    316 for.body.lr.ph:
    317   br label %for.body
    318 
    319 for.body:
    320   %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]
    321   %cmp1 = icmp ugt i32 %i.05, 2
    322   br i1 %cmp1, label %if.then, label %if.else
    323 
    324 if.then:
    325   call void @f1()
    326   br label %for.inc
    327 
    328 if.else:
    329   call void @f2()
    330   br label %for.inc
    331 
    332 for.inc:
    333   %inc = add nsw i32 %i.05, 1
    334   %cmp = icmp slt i32 %inc, %k
    335   br i1 %cmp, label %for.body, label %for.end
    336 
    337 for.end:
    338   ret void
    339 }
    340 
    341 ; Test that we only peel off iterations if it simplifies a condition in the
    342 ; loop body after peeling at most MaxPeelCount iterations.
    343 define void @test4(i32 %k) {
    344 ; CHECK-LABEL: @test4(
    345 ; CHECK-NEXT:  for.body.lr.ph:
    346 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
    347 ; CHECK:       for.body:
    348 ; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
    349 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i32 [[I_05]], 9999
    350 ; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]
    351 ; CHECK:       if.then:
    352 ; CHECK-NEXT:    call void @f1()
    353 ; CHECK-NEXT:    br label [[FOR_INC]]
    354 ; CHECK:       for.inc:
    355 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_05]], 1
    356 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]]
    357 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
    358 ; CHECK:       for.end:
    359 ; CHECK-NEXT:    ret void
    360 ;
    361 for.body.lr.ph:
    362   br label %for.body
    363 
    364 for.body:
    365   %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]
    366   %cmp1 = icmp ugt i32 %i.05, 9999
    367   br i1 %cmp1, label %if.then, label %for.inc
    368 
    369 if.then:
    370   call void @f1()
    371   br label %for.inc
    372 
    373 for.inc:
    374   %inc = add nsw i32 %i.05, 1
    375   %cmp = icmp slt i32 %inc, %k
    376   br i1 %cmp, label %for.body, label %for.end
    377 
    378 for.end:
    379   ret void
    380 }
    381 
    382 ; In this case we cannot peel the inner loop, because the condition involves
    383 ; the outer induction variable.
    384 define void @test5(i32 %k) {
    385 ; CHECK-LABEL: @test5(
    386 ; CHECK-NEXT:  for.body.lr.ph:
    387 ; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
    388 ; CHECK:       outer.header:
    389 ; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH:%.*]] ], [ [[J_INC:%.*]], [[OUTER_INC:%.*]] ]
    390 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
    391 ; CHECK:       for.body:
    392 ; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ 0, [[OUTER_HEADER]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
    393 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[J]], 2
    394 ; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
    395 ; CHECK:       if.then:
    396 ; CHECK-NEXT:    call void @f1()
    397 ; CHECK-NEXT:    br label [[FOR_INC]]
    398 ; CHECK:       if.else:
    399 ; CHECK-NEXT:    call void @f2()
    400 ; CHECK-NEXT:    br label [[FOR_INC]]
    401 ; CHECK:       for.inc:
    402 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_05]], 1
    403 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]]
    404 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[OUTER_INC]]
    405 ; CHECK:       outer.inc:
    406 ; CHECK-NEXT:    [[J_INC]] = add nsw i32 [[J]], 1
    407 ; CHECK-NEXT:    [[OUTER_CMP:%.*]] = icmp slt i32 [[J_INC]], [[K]]
    408 ; CHECK-NEXT:    br i1 [[OUTER_CMP]], label [[OUTER_HEADER]], label [[FOR_END:%.*]]
    409 ; CHECK:       for.end:
    410 ; CHECK-NEXT:    ret void
    411 ;
    412 for.body.lr.ph:
    413   br label %outer.header
    414 
    415 outer.header:
    416   %j = phi i32 [ 0, %for.body.lr.ph ], [ %j.inc, %outer.inc ]
    417   br label %for.body
    418 
    419 for.body:
    420   %i.05 = phi i32 [ 0, %outer.header ], [ %inc, %for.inc ]
    421   %cmp1 = icmp ult i32 %j, 2
    422   br i1 %cmp1, label %if.then, label %if.else
    423 
    424 if.then:
    425   call void @f1()
    426   br label %for.inc
    427 
    428 if.else:
    429   call void @f2()
    430   br label %for.inc
    431 
    432 for.inc:
    433   %inc = add nsw i32 %i.05, 1
    434   %cmp = icmp slt i32 %inc, %k
    435   br i1 %cmp, label %for.body, label %outer.inc
    436 
    437 outer.inc:
    438   %j.inc = add nsw i32 %j, 1
    439   %outer.cmp = icmp slt i32 %j.inc, %k
    440   br i1 %outer.cmp, label %outer.header, label %for.end
    441 
    442 
    443 for.end:
    444   ret void
    445 }
    446 
    447 ; In this test, the condition involves 2 AddRecs. Without evaluating both
    448 ; AddRecs, we cannot prove that the condition becomes known in the loop body
    449 ; after peeling.
    450 define void @test6(i32 %k) {
    451 ; CHECK-LABEL: @test6(
    452 ; CHECK-NEXT:  entry:
    453 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
    454 ; CHECK:       for.body:
    455 ; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
    456 ; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 4, [[ENTRY]] ], [ [[J_INC:%.*]], [[FOR_INC]] ]
    457 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[I_05]], [[J]]
    458 ; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
    459 ; CHECK:       if.then:
    460 ; CHECK-NEXT:    call void @f1()
    461 ; CHECK-NEXT:    br label [[FOR_INC]]
    462 ; CHECK:       if.else:
    463 ; CHECK-NEXT:    call void @f2()
    464 ; CHECK-NEXT:    br label [[FOR_INC]]
    465 ; CHECK:       for.inc:
    466 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_05]], 2
    467 ; CHECK-NEXT:    [[J_INC]] = add nsw i32 [[J]], 1
    468 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]]
    469 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
    470 ; CHECK:       for.end:
    471 ; CHECK-NEXT:    ret void
    472 ;
    473 entry:
    474   br label %for.body
    475 
    476 for.body:
    477   %i.05 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
    478   %j = phi i32 [ 4, %entry ], [ %j.inc, %for.inc ]
    479   %cmp1 = icmp ult i32 %i.05, %j
    480   br i1 %cmp1, label %if.then, label %if.else
    481 
    482 if.then:
    483   call void @f1()
    484   br label %for.inc
    485 
    486 if.else:
    487   call void @f2()
    488   br label %for.inc
    489 
    490 for.inc:
    491   %inc = add nsw i32 %i.05, 2
    492   %j.inc = add nsw i32 %j, 1
    493   %cmp = icmp slt i32 %inc, %k
    494   br i1 %cmp, label %for.body, label %for.end
    495 
    496 for.end:
    497   ret void
    498 }
    499 
    500 define void @test7(i32 %k) {
    501 ; FIXME: Could simplify loop body by peeling one additional iteration after
    502 ;        i != 3 becomes false
    503 ; CHECK-LABEL: @test7(
    504 ; CHECK-NEXT:  for.body.lr.ph:
    505 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
    506 ; CHECK:       for.body:
    507 ; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
    508 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[I_05]], 3
    509 ; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]
    510 ; CHECK:       if.then:
    511 ; CHECK-NEXT:    call void @f1()
    512 ; CHECK-NEXT:    br label [[FOR_INC]]
    513 ; CHECK:       for.inc:
    514 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_05]], 1
    515 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]]
    516 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
    517 ; CHECK:       for.end:
    518 ; CHECK-NEXT:    ret void
    519 ;
    520 for.body.lr.ph:
    521   br label %for.body
    522 
    523 for.body:
    524   %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]
    525   %cmp1 = icmp ne i32 %i.05, 3
    526   br i1 %cmp1, label %if.then, label %for.inc
    527 
    528 if.then:
    529   call void @f1()
    530   br label %for.inc
    531 
    532 for.inc:
    533   %inc = add nsw i32 %i.05, 1
    534   %cmp = icmp slt i32 %inc, %k
    535   br i1 %cmp, label %for.body, label %for.end
    536 
    537 for.end:
    538   ret void
    539 }
    540 
    541 define void @test8(i32 %k) {
    542 ; FIXME: Could simplify loop body by peeling one additional iteration after
    543 ;        i == 3 becomes true.
    544 ; CHECK-LABEL: @test8(
    545 ; CHECK-NEXT:  for.body.lr.ph:
    546 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
    547 ; CHECK:       for.body:
    548 ; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
    549 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[I_05]], 3
    550 ; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]
    551 ; CHECK:       if.then:
    552 ; CHECK-NEXT:    call void @f1()
    553 ; CHECK-NEXT:    br label [[FOR_INC]]
    554 ; CHECK:       for.inc:
    555 ; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_05]], 1
    556 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]]
    557 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
    558 ; CHECK:       for.end:
    559 ; CHECK-NEXT:    ret void
    560 ;
    561 for.body.lr.ph:
    562   br label %for.body
    563 
    564 for.body:
    565   %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]
    566   %cmp1 = icmp eq i32 %i.05, 3
    567   br i1 %cmp1, label %if.then, label %for.inc
    568 
    569 if.then:
    570   call void @f1()
    571   br label %for.inc
    572 
    573 for.inc:
    574   %inc = add nsw i32 %i.05, 1
    575   %cmp = icmp slt i32 %inc, %k
    576   br i1 %cmp, label %for.body, label %for.end
    577 
    578 for.end:
    579   ret void
    580 }
    581 
    582 ; Comparison with non-monotonic predicate due to possible wrapping, loop
    583 ; body cannot be simplified.
    584 define void @test9(i32 %k) {
    585 ; CHECK-LABEL: @test9(
    586 ; CHECK-NEXT:  for.body.lr.ph:
    587 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
    588 ; CHECK:       for.body:
    589 ; CHECK-NEXT:    [[I_05:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
    590 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[I_05]], 3
    591 ; CHECK-NEXT:    br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]
    592 ; CHECK:       if.then:
    593 ; CHECK-NEXT:    call void @f1()
    594 ; CHECK-NEXT:    br label [[FOR_INC]]
    595 ; CHECK:       for.inc:
    596 ; CHECK-NEXT:    [[INC]] = add i32 [[I_05]], 1
    597 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K:%.*]]
    598 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
    599 ; CHECK:       for.end:
    600 ; CHECK-NEXT:    ret void
    601 ;
    602 for.body.lr.ph:
    603   br label %for.body
    604 
    605 for.body:
    606   %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]
    607   %cmp1 = icmp slt i32 %i.05, 3
    608   br i1 %cmp1, label %if.then, label %for.inc
    609 
    610 if.then:
    611   call void @f1()
    612   br label %for.inc
    613 
    614 for.inc:
    615   %inc = add i32 %i.05, 1
    616   %cmp = icmp slt i32 %inc, %k
    617   br i1 %cmp, label %for.body, label %for.end
    618 
    619 for.end:
    620   ret void
    621 }
    622