Home | History | Annotate | Download | only in LoopUnrollAndJam
      1 ; RUN: opt -loop-unroll-and-jam -allow-unroll-and-jam -unroll-and-jam-count=4 -pass-remarks=loop-unroll-and-jam < %s -S 2>&1 | FileCheck %s
      2 
      3 target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
      4 
      5 ;; Common check for all tests. None should be unroll and jammed
      6 ; CHECK-NOT: remark: {{.*}} unroll and jammed
      7 
      8 
      9 ; CHECK-LABEL: disabled1
     10 ; Tests for(i) { sum = A[i]; for(j) sum += B[j]; A[i+1] = sum; }
     11 ; A[i] to A[i+1] dependency should block unrollandjam
     12 define void @disabled1(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
     13 ; CHECK: %i.029 = phi i32 [ %add10, %for.latch ], [ 0, %for.preheader ]
     14 ; CHECK: %j.026 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
     15 entry:
     16   %cmp = icmp ne i32 %J, 0
     17   %cmp127 = icmp ne i32 %I, 0
     18   %or.cond = and i1 %cmp127, %cmp
     19   br i1 %or.cond, label %for.preheader, label %return
     20 
     21 for.preheader:
     22   br label %for.outer
     23 
     24 for.outer:
     25   %i.029 = phi i32 [ %add10, %for.latch ], [ 0, %for.preheader ]
     26   %b.028 = phi i32 [ %inc8, %for.latch ], [ 1, %for.preheader ]
     27   %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i.029
     28   %0 = load i32, i32* %arrayidx, align 4
     29   br label %for.inner
     30 
     31 for.inner:
     32   %j.026 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
     33   %sum1.025 = phi i32 [ %0, %for.outer ], [ %add, %for.inner ]
     34   %arrayidx6 = getelementptr inbounds i32, i32* %B, i32 %j.026
     35   %1 = load i32, i32* %arrayidx6, align 4
     36   %add = add i32 %1, %sum1.025
     37   %inc = add nuw i32 %j.026, 1
     38   %exitcond = icmp eq i32 %inc, %J
     39   br i1 %exitcond, label %for.latch, label %for.inner
     40 
     41 for.latch:
     42   %arrayidx7 = getelementptr inbounds i32, i32* %A, i32 %b.028
     43   store i32 %add, i32* %arrayidx7, align 4
     44   %inc8 = add nuw nsw i32 %b.028, 1
     45   %add10 = add nuw nsw i32 %i.029, 1
     46   %exitcond30 = icmp eq i32 %add10, %I
     47   br i1 %exitcond30, label %return, label %for.outer
     48 
     49 return:
     50   ret void
     51 }
     52 
     53 
     54 ; CHECK-LABEL: disabled2
     55 ; Tests an incompatible block layout (for.outer jumps past for.inner)
     56 ; FIXME: Make this work
     57 define void @disabled2(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
     58 ; CHECK: %i.032 = phi i32 [ %add13, %for.latch ], [ 0, %for.preheader ]
     59 ; CHECK: %j.030 = phi i32 [ %inc, %for.inner ], [ 0, %for.inner.preheader ]
     60 entry:
     61   %cmp = icmp ne i32 %J, 0
     62   %cmp131 = icmp ne i32 %I, 0
     63   %or.cond = and i1 %cmp131, %cmp
     64   br i1 %or.cond, label %for.preheader, label %for.end14
     65 
     66 for.preheader:
     67   br label %for.outer
     68 
     69 for.outer:
     70   %i.032 = phi i32 [ %add13, %for.latch ], [ 0, %for.preheader ]
     71   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %i.032
     72   %0 = load i32, i32* %arrayidx, align 4
     73   %tobool = icmp eq i32 %0, 0
     74   br i1 %tobool, label %for.latch, label %for.inner
     75 
     76 for.inner:
     77   %j.030 = phi i32 [ %inc, %for.inner ], [ 0, %for.outer ]
     78   %sum1.029 = phi i32 [ %sum1.1, %for.inner ], [ 0, %for.outer ]
     79   %arrayidx6 = getelementptr inbounds i32, i32* %B, i32 %j.030
     80   %1 = load i32, i32* %arrayidx6, align 4
     81   %tobool7 = icmp eq i32 %1, 0
     82   %sub = add i32 %sum1.029, 10
     83   %add = sub i32 %sub, %1
     84   %sum1.1 = select i1 %tobool7, i32 %sum1.029, i32 %add
     85   %inc = add nuw i32 %j.030, 1
     86   %exitcond = icmp eq i32 %inc, %J
     87   br i1 %exitcond, label %for.latch, label %for.inner
     88 
     89 for.latch:
     90   %sum1.1.lcssa = phi i32 [ 0, %for.outer ], [ %sum1.1, %for.inner ]
     91   %arrayidx11 = getelementptr inbounds i32, i32* %A, i32 %i.032
     92   store i32 %sum1.1.lcssa, i32* %arrayidx11, align 4
     93   %add13 = add nuw i32 %i.032, 1
     94   %exitcond33 = icmp eq i32 %add13, %I
     95   br i1 %exitcond33, label %for.end14, label %for.outer
     96 
     97 for.end14:
     98   ret void
     99 }
    100 
    101 
    102 ; CHECK-LABEL: disabled3
    103 ; Tests loop carry dependencies in an array S
    104 define void @disabled3(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
    105 ; CHECK: %i.029 = phi i32 [ 0, %for.preheader ], [ %add12, %for.latch ]
    106 ; CHECK: %j.027 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    107 entry:
    108   %S = alloca [4 x i32], align 4
    109   %cmp = icmp eq i32 %J, 0
    110   br i1 %cmp, label %return, label %if.end
    111 
    112 if.end:
    113   %0 = bitcast [4 x i32]* %S to i8*
    114   %cmp128 = icmp eq i32 %I, 0
    115   br i1 %cmp128, label %for.cond.cleanup, label %for.preheader
    116 
    117 for.preheader:
    118   %arrayidx9 = getelementptr inbounds [4 x i32], [4 x i32]* %S, i32 0, i32 0
    119   br label %for.outer
    120 
    121 for.cond.cleanup:
    122   br label %return
    123 
    124 for.outer:
    125   %i.029 = phi i32 [ 0, %for.preheader ], [ %add12, %for.latch ]
    126   br label %for.inner
    127 
    128 for.inner:
    129   %j.027 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    130   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j.027
    131   %l2 = load i32, i32* %arrayidx, align 4
    132   %add = add i32 %j.027, %i.029
    133   %rem = urem i32 %add, %J
    134   %arrayidx6 = getelementptr inbounds i32, i32* %B, i32 %rem
    135   %l3 = load i32, i32* %arrayidx6, align 4
    136   %mul = mul i32 %l3, %l2
    137   %rem7 = urem i32 %j.027, 3
    138   %arrayidx8 = getelementptr inbounds [4 x i32], [4 x i32]* %S, i32 0, i32 %rem7
    139   store i32 %mul, i32* %arrayidx8, align 4
    140   %inc = add nuw i32 %j.027, 1
    141   %exitcond = icmp eq i32 %inc, %J
    142   br i1 %exitcond, label %for.latch, label %for.inner
    143 
    144 for.latch:
    145   %l1 = load i32, i32* %arrayidx9, align 4
    146   %arrayidx10 = getelementptr inbounds i32, i32* %A, i32 %i.029
    147   store i32 %l1, i32* %arrayidx10, align 4
    148   %add12 = add nuw i32 %i.029, 1
    149   %exitcond31 = icmp eq i32 %add12, %I
    150   br i1 %exitcond31, label %for.cond.cleanup, label %for.outer
    151 
    152 return:
    153   ret void
    154 }
    155 
    156 
    157 ; CHECK-LABEL: disabled4
    158 ; Inner looop induction variable is not consistent
    159 ; ie for(i = 0..n) for (j = 0..i) sum+=B[j]
    160 define void @disabled4(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
    161 ; CHECK: %indvars.iv = phi i32 [ %indvars.iv.next, %for.latch ], [ 1, %for.preheader ]
    162 ; CHECK: %j.021 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    163 entry:
    164   %cmp = icmp ne i32 %J, 0
    165   %cmp122 = icmp ugt i32 %I, 1
    166   %or.cond = and i1 %cmp122, %cmp
    167   br i1 %or.cond, label %for.preheader, label %for.end9
    168 
    169 for.preheader:
    170   br label %for.outer
    171 
    172 for.outer:
    173   %indvars.iv = phi i32 [ %indvars.iv.next, %for.latch ], [ 1, %for.preheader ]
    174   br label %for.inner
    175 
    176 for.inner:
    177   %j.021 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    178   %sum1.020 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
    179   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j.021
    180   %0 = load i32, i32* %arrayidx, align 4
    181   %add = add i32 %0, %sum1.020
    182   %inc = add nuw i32 %j.021, 1
    183   %exitcond = icmp eq i32 %inc, %indvars.iv
    184   br i1 %exitcond, label %for.latch, label %for.inner
    185 
    186 for.latch:
    187   %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %indvars.iv
    188   store i32 %add, i32* %arrayidx6, align 4
    189   %indvars.iv.next = add nuw i32 %indvars.iv, 1
    190   %exitcond24 = icmp eq i32 %indvars.iv.next, %I
    191   br i1 %exitcond24, label %for.end9, label %for.outer
    192 
    193 for.end9:
    194   ret void
    195 }
    196 
    197 
    198 ; CHECK-LABEL: disabled5
    199 ; Test odd uses of phi nodes where the outer IV cannot be moved into Fore as it hits a PHI
    200 @f = hidden global i32 0, align 4
    201 define i32 @disabled5() #0 {
    202 ; CHECK: %0 = phi i32 [ %f.promoted10, %entry ], [ 2, %for.latch ]
    203 ; CHECK: %1 = phi i32 [ %0, %for.outer ], [ 2, %for.inner ]
    204 entry:
    205   %f.promoted10 = load i32, i32* @f, align 4
    206   br label %for.outer
    207 
    208 for.outer:
    209   %0 = phi i32 [ %f.promoted10, %entry ], [ 2, %for.latch ]
    210   %d.018 = phi i16 [ 0, %entry ], [ %odd.lcssa, %for.latch ]
    211   %inc5.sink9 = phi i32 [ 2, %entry ], [ %inc5, %for.latch ]
    212   br label %for.inner
    213 
    214 for.inner:
    215   %1 = phi i32 [ %0, %for.outer ], [ 2, %for.inner ]
    216   %inc.sink8 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    217   %inc = add nuw nsw i32 %inc.sink8, 1
    218   %exitcond = icmp ne i32 %inc, 7
    219   br i1 %exitcond, label %for.inner, label %for.latch
    220 
    221 for.latch:
    222   %.lcssa = phi i32 [ %1, %for.inner ]
    223   %odd.lcssa = phi i16 [ 1, %for.inner ]
    224   %inc5 = add nuw nsw i32 %inc5.sink9, 1
    225   %exitcond11 = icmp ne i32 %inc5, 7
    226   br i1 %exitcond11, label %for.outer, label %for.end
    227 
    228 for.end:
    229   %.lcssa.lcssa = phi i32 [ %.lcssa, %for.latch ]
    230   %inc.lcssa.lcssa = phi i32 [ 7, %for.latch ]
    231   ret i32 0
    232 }
    233 
    234 
    235 ; CHECK-LABEL: disabled6
    236 ; There is a dependency in here, between @d and %0 (=@f)
    237 @d6 = hidden global i16 5, align 2
    238 @f6 = hidden global i16* @d6, align 4
    239 define i32 @disabled6() #0 {
    240 ; CHECK: %inc8.sink14.i = phi i16 [ 1, %entry ], [ %inc8.i, %for.cond.cleanup.i ]
    241 ; CHECK: %c.013.i = phi i32 [ 0, %for.body.i ], [ %inc.i, %for.body6.i ]
    242 entry:
    243   store i16 1, i16* @d6, align 2
    244   %0 = load i16*, i16** @f6, align 4
    245   br label %for.body.i
    246 
    247 for.body.i:
    248   %inc8.sink14.i = phi i16 [ 1, %entry ], [ %inc8.i, %for.cond.cleanup.i ]
    249   %1 = load i16, i16* %0, align 2
    250   br label %for.body6.i
    251 
    252 for.cond.cleanup.i:
    253   %inc8.i = add nuw nsw i16 %inc8.sink14.i, 1
    254   store i16 %inc8.i, i16* @d6, align 2
    255   %cmp.i = icmp ult i16 %inc8.i, 6
    256   br i1 %cmp.i, label %for.body.i, label %test.exit
    257 
    258 for.body6.i:
    259   %c.013.i = phi i32 [ 0, %for.body.i ], [ %inc.i, %for.body6.i ]
    260   %inc.i = add nuw nsw i32 %c.013.i, 1
    261   %exitcond.i = icmp eq i32 %inc.i, 7
    262   br i1 %exitcond.i, label %for.cond.cleanup.i, label %for.body6.i
    263 
    264 test.exit:
    265   %conv2.i = sext i16 %1 to i32
    266   ret i32 0
    267 }
    268 
    269 
    270 ; CHECK-LABEL: disabled7
    271 ; Has negative output dependency
    272 define void @disabled7(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
    273 ; CHECK: %i.028 = phi i32 [ %add11, %for.cond3.for.cond.cleanup5_crit_edge ], [ 0, %for.body.preheader ]
    274 ; CHECK: %j.026 = phi i32 [ 0, %for.body ], [ %add9, %for.body6 ]
    275 entry:
    276   %cmp = icmp ne i32 %J, 0
    277   %cmp127 = icmp ne i32 %I, 0
    278   %or.cond = and i1 %cmp127, %cmp
    279   br i1 %or.cond, label %for.body.preheader, label %for.end12
    280 
    281 for.body.preheader:
    282   br label %for.body
    283 
    284 for.body:
    285   %i.028 = phi i32 [ %add11, %for.cond3.for.cond.cleanup5_crit_edge ], [ 0, %for.body.preheader ]
    286   %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i.028
    287   store i32 0, i32* %arrayidx, align 4
    288   %sub = add i32 %i.028, -1
    289   %arrayidx2 = getelementptr inbounds i32, i32* %A, i32 %sub
    290   store i32 2, i32* %arrayidx2, align 4
    291   br label %for.body6
    292 
    293 for.cond3.for.cond.cleanup5_crit_edge:
    294   store i32 %add, i32* %arrayidx, align 4
    295   %add11 = add nuw i32 %i.028, 1
    296   %exitcond29 = icmp eq i32 %add11, %I
    297   br i1 %exitcond29, label %for.end12, label %for.body
    298 
    299 for.body6:
    300   %0 = phi i32 [ 0, %for.body ], [ %add, %for.body6 ]
    301   %j.026 = phi i32 [ 0, %for.body ], [ %add9, %for.body6 ]
    302   %arrayidx7 = getelementptr inbounds i32, i32* %B, i32 %j.026
    303   %1 = load i32, i32* %arrayidx7, align 4
    304   %add = add i32 %1, %0
    305   %add9 = add nuw i32 %j.026, 1
    306   %exitcond = icmp eq i32 %add9, %J
    307   br i1 %exitcond, label %for.cond3.for.cond.cleanup5_crit_edge, label %for.body6
    308 
    309 for.end12:
    310   ret void
    311 }
    312 
    313 
    314 ; CHECK-LABEL: disabled8
    315 ; Same as above with an extra outer loop nest
    316 define void @disabled8(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
    317 ; CHECK: %i.036 = phi i32 [ %add15, %for.latch ], [ 0, %for.body ]
    318 ; CHECK: %j.034 = phi i32 [ 0, %for.outer ], [ %add13, %for.inner ]
    319 entry:
    320   %cmp = icmp eq i32 %J, 0
    321   %cmp335 = icmp eq i32 %I, 0
    322   %or.cond = or i1 %cmp, %cmp335
    323   br i1 %or.cond, label %for.end18, label %for.body.preheader
    324 
    325 for.body.preheader:
    326   br label %for.body
    327 
    328 for.body:
    329   %x.037 = phi i32 [ %inc, %for.cond.cleanup4 ], [ 0, %for.body.preheader ]
    330   br label %for.outer
    331 
    332 for.cond.cleanup4:
    333   %inc = add nuw nsw i32 %x.037, 1
    334   %exitcond40 = icmp eq i32 %inc, 5
    335   br i1 %exitcond40, label %for.end18, label %for.body
    336 
    337 for.outer:
    338   %i.036 = phi i32 [ %add15, %for.latch ], [ 0, %for.body ]
    339   %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i.036
    340   store i32 0, i32* %arrayidx, align 4
    341   %sub = add i32 %i.036, -1
    342   %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %sub
    343   store i32 2, i32* %arrayidx6, align 4
    344   br label %for.inner
    345 
    346 for.latch:
    347   store i32 %add, i32* %arrayidx, align 4
    348   %add15 = add nuw i32 %i.036, 1
    349   %exitcond38 = icmp eq i32 %add15, %I
    350   br i1 %exitcond38, label %for.cond.cleanup4, label %for.outer
    351 
    352 for.inner:
    353   %0 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
    354   %j.034 = phi i32 [ 0, %for.outer ], [ %add13, %for.inner ]
    355   %arrayidx11 = getelementptr inbounds i32, i32* %B, i32 %j.034
    356   %1 = load i32, i32* %arrayidx11, align 4
    357   %add = add i32 %1, %0
    358   %add13 = add nuw i32 %j.034, 1
    359   %exitcond = icmp eq i32 %add13, %J
    360   br i1 %exitcond, label %for.latch, label %for.inner
    361 
    362 for.end18:
    363   ret void
    364 }
    365 
    366 
    367 ; CHECK-LABEL: disabled9
    368 ; Can't prove alias between A and B
    369 define void @disabled9(i32 %I, i32 %J, i32* nocapture %A, i32* nocapture readonly %B) #0 {
    370 ; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
    371 ; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    372 entry:
    373   %cmp = icmp ne i32 %J, 0
    374   %cmp122 = icmp ne i32 %I, 0
    375   %or.cond = and i1 %cmp, %cmp122
    376   br i1 %or.cond, label %for.outer.preheader, label %for.end
    377 
    378 for.outer.preheader:
    379   br label %for.outer
    380 
    381 for.outer:
    382   %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
    383   br label %for.inner
    384 
    385 for.inner:
    386   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    387   %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
    388   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j
    389   %0 = load i32, i32* %arrayidx, align 4
    390   %add = add i32 %0, %sum1
    391   %inc = add nuw i32 %j, 1
    392   %exitcond = icmp eq i32 %inc, %J
    393   br i1 %exitcond, label %for.latch, label %for.inner
    394 
    395 for.latch:
    396   %add.lcssa = phi i32 [ %add, %for.inner ]
    397   %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
    398   store i32 %add.lcssa, i32* %arrayidx6, align 4
    399   %add8 = add nuw i32 %i, 1
    400   %exitcond25 = icmp eq i32 %add8, %I
    401   br i1 %exitcond25, label %for.end.loopexit, label %for.outer
    402 
    403 for.end.loopexit:
    404   br label %for.end
    405 
    406 for.end:
    407   ret void
    408 }
    409 
    410 
    411 ; CHECK-LABEL: disable10
    412 ; Simple call
    413 declare void @f10(i32, i32) #0
    414 define void @disable10(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
    415 ; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
    416 ; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    417 entry:
    418   %cmp = icmp ne i32 %J, 0
    419   %cmp122 = icmp ne i32 %I, 0
    420   %or.cond = and i1 %cmp, %cmp122
    421   br i1 %or.cond, label %for.outer.preheader, label %for.end
    422 
    423 for.outer.preheader:
    424   br label %for.outer
    425 
    426 for.outer:
    427   %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
    428   br label %for.inner
    429 
    430 for.inner:
    431   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    432   %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
    433   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j
    434   %0 = load i32, i32* %arrayidx, align 4
    435   %add = add i32 %0, %sum1
    436   %inc = add nuw i32 %j, 1
    437   %exitcond = icmp eq i32 %inc, %J
    438   tail call void @f10(i32 %i, i32 %j) nounwind
    439   br i1 %exitcond, label %for.latch, label %for.inner
    440 
    441 for.latch:
    442   %add.lcssa = phi i32 [ %add, %for.inner ]
    443   %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
    444   store i32 %add.lcssa, i32* %arrayidx6, align 4
    445   %add8 = add nuw i32 %i, 1
    446   %exitcond25 = icmp eq i32 %add8, %I
    447   br i1 %exitcond25, label %for.end.loopexit, label %for.outer
    448 
    449 for.end.loopexit:
    450   br label %for.end
    451 
    452 for.end:
    453   ret void
    454 }
    455 
    456 
    457 ; CHECK-LABEL: disable11
    458 ; volatile
    459 define void @disable11(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
    460 ; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
    461 ; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    462 entry:
    463   %cmp = icmp ne i32 %J, 0
    464   %cmp122 = icmp ne i32 %I, 0
    465   %or.cond = and i1 %cmp, %cmp122
    466   br i1 %or.cond, label %for.outer.preheader, label %for.end
    467 
    468 for.outer.preheader:
    469   br label %for.outer
    470 
    471 for.outer:
    472   %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
    473   br label %for.inner
    474 
    475 for.inner:
    476   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    477   %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
    478   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j
    479   %0 = load volatile i32, i32* %arrayidx, align 4
    480   %add = add i32 %0, %sum1
    481   %inc = add nuw i32 %j, 1
    482   %exitcond = icmp eq i32 %inc, %J
    483   br i1 %exitcond, label %for.latch, label %for.inner
    484 
    485 for.latch:
    486   %add.lcssa = phi i32 [ %add, %for.inner ]
    487   %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
    488   store i32 %add.lcssa, i32* %arrayidx6, align 4
    489   %add8 = add nuw i32 %i, 1
    490   %exitcond25 = icmp eq i32 %add8, %I
    491   br i1 %exitcond25, label %for.end.loopexit, label %for.outer
    492 
    493 for.end.loopexit:
    494   br label %for.end
    495 
    496 for.end:
    497   ret void
    498 }
    499 
    500 
    501 ; CHECK-LABEL: disable12
    502 ; Multiple aft blocks
    503 define void @disable12(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
    504 ; CHECK: %i = phi i32 [ %add8, %for.latch3 ], [ 0, %for.outer.preheader ]
    505 ; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    506 entry:
    507   %cmp = icmp ne i32 %J, 0
    508   %cmp122 = icmp ne i32 %I, 0
    509   %or.cond = and i1 %cmp, %cmp122
    510   br i1 %or.cond, label %for.outer.preheader, label %for.end
    511 
    512 for.outer.preheader:
    513   br label %for.outer
    514 
    515 for.outer:
    516   %i = phi i32 [ %add8, %for.latch3 ], [ 0, %for.outer.preheader ]
    517   br label %for.inner
    518 
    519 for.inner:
    520   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    521   %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
    522   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j
    523   %0 = load i32, i32* %arrayidx, align 4
    524   %add = add i32 %0, %sum1
    525   %inc = add nuw i32 %j, 1
    526   %exitcond = icmp eq i32 %inc, %J
    527   br i1 %exitcond, label %for.latch, label %for.inner
    528 
    529 for.latch:
    530   %add.lcssa = phi i32 [ %add, %for.inner ]
    531   %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
    532   store i32 %add.lcssa, i32* %arrayidx6, align 4
    533   %cmpl = icmp eq i32 %add.lcssa, 10
    534   br i1 %cmpl, label %for.latch2, label %for.latch3
    535 
    536 for.latch2:
    537   br label %for.latch3
    538 
    539 for.latch3:
    540   %add8 = add nuw i32 %i, 1
    541   %exitcond25 = icmp eq i32 %add8, %I
    542   br i1 %exitcond25, label %for.end.loopexit, label %for.outer
    543 
    544 for.end.loopexit:
    545   br label %for.end
    546 
    547 for.end:
    548   ret void
    549 }
    550 
    551 
    552 ; CHECK-LABEL: disable13
    553 ; Two subloops
    554 define void @disable13(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
    555 ; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
    556 ; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    557 ; CHECK: %j2 = phi i32 [ %inc2, %for.inner2 ], [ 0, %for.inner2.preheader ]
    558 entry:
    559   %cmp = icmp ne i32 %J, 0
    560   %cmp122 = icmp ne i32 %I, 0
    561   %or.cond = and i1 %cmp, %cmp122
    562   br i1 %or.cond, label %for.outer.preheader, label %for.end
    563 
    564 for.outer.preheader:
    565   br label %for.outer
    566 
    567 for.outer:
    568   %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
    569   br label %for.inner
    570 
    571 for.inner:
    572   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    573   %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
    574   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j
    575   %0 = load i32, i32* %arrayidx, align 4
    576   %add = add i32 %0, %sum1
    577   %inc = add nuw i32 %j, 1
    578   %exitcond = icmp eq i32 %inc, %J
    579   br i1 %exitcond, label %for.inner2, label %for.inner
    580 
    581 for.inner2:
    582   %j2 = phi i32 [ 0, %for.inner ], [ %inc2, %for.inner2 ]
    583   %sum12 = phi i32 [ 0, %for.inner ], [ %add2, %for.inner2 ]
    584   %arrayidx2 = getelementptr inbounds i32, i32* %B, i32 %j2
    585   %l0 = load i32, i32* %arrayidx2, align 4
    586   %add2 = add i32 %l0, %sum12
    587   %inc2 = add nuw i32 %j2, 1
    588   %exitcond2 = icmp eq i32 %inc2, %J
    589   br i1 %exitcond2, label %for.latch, label %for.inner2
    590 
    591 for.latch:
    592   %add.lcssa = phi i32 [ %add, %for.inner2 ]
    593   %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
    594   store i32 %add.lcssa, i32* %arrayidx6, align 4
    595   %add8 = add nuw i32 %i, 1
    596   %exitcond25 = icmp eq i32 %add8, %I
    597   br i1 %exitcond25, label %for.end.loopexit, label %for.outer
    598 
    599 for.end.loopexit:
    600   br label %for.end
    601 
    602 for.end:
    603   ret void
    604 }
    605 
    606 
    607 ; CHECK-LABEL: disable14
    608 ; Multiple exits blocks
    609 define void @disable14(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
    610 ; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
    611 ; CHECK: %j = phi i32 [ %inc, %for.inner ], [ 0, %for.inner.preheader ]
    612 entry:
    613   %cmp = icmp ne i32 %J, 0
    614   %cmp122 = icmp ne i32 %I, 0
    615   %or.cond = and i1 %cmp, %cmp122
    616   br i1 %or.cond, label %for.outer.preheader, label %for.end
    617 
    618 for.outer.preheader:
    619   br label %for.outer
    620 
    621 for.outer:
    622   %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
    623   %add8 = add nuw i32 %i, 1
    624   %exitcond23 = icmp eq i32 %add8, %I
    625   br i1 %exitcond23, label %for.end.loopexit, label %for.inner
    626 
    627 for.inner:
    628   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    629   %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
    630   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j
    631   %0 = load i32, i32* %arrayidx, align 4
    632   %add = add i32 %0, %sum1
    633   %inc = add nuw i32 %j, 1
    634   %exitcond = icmp eq i32 %inc, %J
    635   br i1 %exitcond, label %for.latch, label %for.inner
    636 
    637 for.latch:
    638   %add.lcssa = phi i32 [ %add, %for.inner ]
    639   %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
    640   store i32 %add.lcssa, i32* %arrayidx6, align 4
    641   %exitcond25 = icmp eq i32 %add8, %I
    642   br i1 %exitcond25, label %for.end.loopexit, label %for.outer
    643 
    644 for.end.loopexit:
    645   br label %for.end
    646 
    647 for.end:
    648   ret void
    649 }
    650 
    651 
    652 ; CHECK-LABEL: disable15
    653 ; Latch != exit
    654 define void @disable15(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
    655 ; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
    656 ; CHECK: %j = phi i32 [ %inc, %for.inner ], [ 0, %for.inner.preheader ]
    657 entry:
    658   %cmp = icmp ne i32 %J, 0
    659   %cmp122 = icmp ne i32 %I, 0
    660   %or.cond = and i1 %cmp, %cmp122
    661   br i1 %or.cond, label %for.outer.preheader, label %for.end
    662 
    663 for.outer.preheader:
    664   br label %for.outer
    665 
    666 for.outer:
    667   %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
    668   %add8 = add nuw i32 %i, 1
    669   %exitcond25 = icmp eq i32 %add8, %I
    670   br i1 %exitcond25, label %for.end.loopexit, label %for.inner
    671 
    672 for.inner:
    673   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    674   %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
    675   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j
    676   %0 = load i32, i32* %arrayidx, align 4
    677   %add = add i32 %0, %sum1
    678   %inc = add nuw i32 %j, 1
    679   %exitcond = icmp eq i32 %inc, %J
    680   br i1 %exitcond, label %for.latch, label %for.inner
    681 
    682 for.latch:
    683   %add.lcssa = phi i32 [ %add, %for.inner ]
    684   %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
    685   store i32 %add.lcssa, i32* %arrayidx6, align 4
    686   br label %for.outer
    687 
    688 for.end.loopexit:
    689   br label %for.end
    690 
    691 for.end:
    692   ret void
    693 }
    694 
    695 
    696 ; CHECK-LABEL: disable16
    697 ; Cannot move other before inner loop
    698 define void @disable16(i32 %I, i32 %J, i32* noalias nocapture %A, i32* noalias nocapture readonly %B) #0 {
    699 ; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
    700 ; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    701 entry:
    702   %cmp = icmp ne i32 %J, 0
    703   %cmp122 = icmp ne i32 %I, 0
    704   %or.cond = and i1 %cmp, %cmp122
    705   br i1 %or.cond, label %for.outer.preheader, label %for.end
    706 
    707 for.outer.preheader:
    708   br label %for.outer
    709 
    710 for.outer:
    711   %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
    712   %otherphi = phi i32 [ %other, %for.latch ], [ 0, %for.outer.preheader ]
    713   br label %for.inner
    714 
    715 for.inner:
    716   %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
    717   %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
    718   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %j
    719   %0 = load i32, i32* %arrayidx, align 4
    720   %add = add i32 %0, %sum1
    721   %inc = add nuw i32 %j, 1
    722   %exitcond = icmp eq i32 %inc, %J
    723   br i1 %exitcond, label %for.latch, label %for.inner
    724 
    725 for.latch:
    726   %add.lcssa = phi i32 [ %add, %for.inner ]
    727   %arrayidx6 = getelementptr inbounds i32, i32* %A, i32 %i
    728   store i32 %add.lcssa, i32* %arrayidx6, align 4
    729   %add8 = add nuw i32 %i, 1
    730   %exitcond25 = icmp eq i32 %add8, %I
    731   %loadarr = getelementptr inbounds i32, i32* %A, i32 %i
    732   %load = load i32, i32* %arrayidx6, align 4
    733   %other = add i32 %otherphi, %load
    734   br i1 %exitcond25, label %for.end.loopexit, label %for.outer
    735 
    736 for.end.loopexit:
    737   br label %for.end
    738 
    739 for.end:
    740   ret void
    741 }
    742