Home | History | Annotate | Download | only in LoopInterchange
      1 ; RUN: opt < %s -basicaa -loop-interchange -S | FileCheck %s
      2 ;; We test the complete .ll for adjustment in outer loop header/latch and inner loop header/latch.
      3 
      4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
      5 target triple = "x86_64-unknown-linux-gnu"
      6 
      7 @A = common global [100 x [100 x i32]] zeroinitializer
      8 @B = common global [100 x i32] zeroinitializer
      9 @C = common global [100 x [100 x i32]] zeroinitializer
     10 @D = common global [100 x [100 x [100 x i32]]] zeroinitializer
     11 
     12 declare void @foo(...)
     13 
     14 ;;--------------------------------------Test case 01------------------------------------
     15 ;;  for(int i=0;i<N;i++)
     16 ;;    for(int j=1;j<N;j++)
     17 ;;      A[j][i] = A[j][i]+k;
     18 
     19 define void @interchange_01(i32 %k, i32 %N) {
     20 entry:
     21   %cmp21 = icmp sgt i32 %N, 0
     22   br i1 %cmp21, label %for.cond1.preheader.lr.ph, label %for.end12
     23 
     24 for.cond1.preheader.lr.ph:
     25   %cmp219 = icmp sgt i32 %N, 1
     26   %0 = add i32 %N, -1
     27   br label %for.cond1.preheader
     28 
     29 for.cond1.preheader: 
     30   %indvars.iv23 = phi i64 [ 0, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next24, %for.inc10 ]
     31   br i1 %cmp219, label %for.body3, label %for.inc10
     32 
     33 for.body3:
     34   %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3 ], [ 1, %for.cond1.preheader ]
     35   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv, i64 %indvars.iv23
     36   %1 = load i32, i32* %arrayidx5
     37   %add = add nsw i32 %1, %k
     38   store i32 %add, i32* %arrayidx5
     39   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
     40   %lftr.wideiv = trunc i64 %indvars.iv to i32
     41   %exitcond = icmp eq i32 %lftr.wideiv, %0
     42   br i1 %exitcond, label %for.inc10, label %for.body3
     43 
     44 for.inc10:
     45   %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
     46   %lftr.wideiv25 = trunc i64 %indvars.iv23 to i32
     47   %exitcond26 = icmp eq i32 %lftr.wideiv25, %0
     48   br i1 %exitcond26, label %for.end12, label %for.cond1.preheader
     49 
     50 for.end12:
     51   ret void
     52 }
     53 
     54 ; CHECK-LABEL: @interchange_01
     55 ; CHECK: entry:
     56 ; CHECK:   %cmp21 = icmp sgt i32 %N, 0
     57 ; CHECK:   br i1 %cmp21, label %for.body3.preheader, label %for.end12
     58 ; CHECK: for.cond1.preheader.lr.ph:                        
     59 ; CHECK:   br label %for.cond1.preheader
     60 ; CHECK: for.cond1.preheader:                              
     61 ; CHECK:   %indvars.iv23 = phi i64 [ 0, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next24, %for.inc10 ]
     62 ; CHECK:   br i1 %cmp219, label %for.body3.split1, label %for.end12.loopexit
     63 ; CHECK: for.body3.preheader:                              
     64 ; CHECK:   %cmp219 = icmp sgt i32 %N, 1
     65 ; CHECK:   %0 = add i32 %N, -1
     66 ; CHECK:   br label %for.body3
     67 ; CHECK: for.body3:                                        
     68 ; CHECK:   %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3.split ], [ 1, %for.body3.preheader ]
     69 ; CHECK:   br label %for.cond1.preheader.lr.ph
     70 ; CHECK: for.body3.split1:                                 
     71 ; CHECK:   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv, i64 %indvars.iv23
     72 ; CHECK:   %1 = load i32, i32* %arrayidx5
     73 ; CHECK:   %add = add nsw i32 %1, %k
     74 ; CHECK:   store i32 %add, i32* %arrayidx5
     75 ; CHECK:   br label %for.inc10.loopexit
     76 ; CHECK: for.body3.split:                                  
     77 ; CHECK:   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
     78 ; CHECK:   %lftr.wideiv = trunc i64 %indvars.iv to i32
     79 ; CHECK:   %exitcond = icmp eq i32 %lftr.wideiv, %0
     80 ; CHECK:   br i1 %exitcond, label %for.end12.loopexit, label %for.body3
     81 ; CHECK: for.inc10.loopexit:                               
     82 ; CHECK:   br label %for.inc10
     83 ; CHECK: for.inc10:                                        
     84 ; CHECK:   %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
     85 ; CHECK:   %lftr.wideiv25 = trunc i64 %indvars.iv23 to i32
     86 ; CHECK:   %exitcond26 = icmp eq i32 %lftr.wideiv25, %0
     87 ; CHECK:   br i1 %exitcond26, label %for.body3.split, label %for.cond1.preheader
     88 ; CHECK: for.end12.loopexit:                               
     89 ; CHECK:   br label %for.end12
     90 ; CHECK: for.end12:                                        
     91 ; CHECK:   ret void
     92 
     93 ;;--------------------------------------Test case 02-------------------------------------
     94 
     95 ;; for(int i=0;i<100;i++)
     96 ;;   for(int j=100;j>=0;j--)
     97 ;;     A[j][i] = A[j][i]+k;
     98 
     99 define void @interchange_02(i32 %k) {
    100 entry:
    101   br label %for.cond1.preheader
    102 
    103 for.cond1.preheader:
    104   %indvars.iv19 = phi i64 [ 0, %entry ], [ %indvars.iv.next20, %for.inc10 ]
    105   br label %for.body3
    106 
    107 for.body3:
    108   %indvars.iv = phi i64 [ 100, %for.cond1.preheader ], [ %indvars.iv.next, %for.body3 ]
    109   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv, i64 %indvars.iv19
    110   %0 = load i32, i32* %arrayidx5
    111   %add = add nsw i32 %0, %k
    112   store i32 %add, i32* %arrayidx5
    113   %indvars.iv.next = add nsw i64 %indvars.iv, -1
    114   %cmp2 = icmp sgt i64 %indvars.iv, 0
    115   br i1 %cmp2, label %for.body3, label %for.inc10
    116 
    117 for.inc10:
    118   %indvars.iv.next20 = add nuw nsw i64 %indvars.iv19, 1
    119   %exitcond = icmp eq i64 %indvars.iv.next20, 100
    120   br i1 %exitcond, label %for.end11, label %for.cond1.preheader
    121 
    122 for.end11:
    123   ret void
    124 }
    125 
    126 ; CHECK-LABEL: @interchange_02
    127 ; CHECK: entry:
    128 ; CHECK:   br label %for.body3.preheader
    129 ; CHECK: for.cond1.preheader.preheader: 
    130 ; CHECK:   br label %for.cond1.preheader
    131 ; CHECK: for.cond1.preheader:  
    132 ; CHECK:   %indvars.iv19 = phi i64 [ %indvars.iv.next20, %for.inc10 ], [ 0, %for.cond1.preheader.preheader ]
    133 ; CHECK:   br label %for.body3.split1
    134 ; CHECK: for.body3.preheader: 
    135 ; CHECK:   br label %for.body3
    136 ; CHECK: for.body3: 
    137 ; CHECK:   %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3.split ], [ 100, %for.body3.preheader ]
    138 ; CHECK:   br label %for.cond1.preheader.preheader
    139 ; CHECK: for.body3.split1:                                 ; preds = %for.cond1.preheader
    140 ; CHECK:   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv, i64 %indvars.iv19
    141 ; CHECK:   %0 = load i32, i32* %arrayidx5
    142 ; CHECK:   %add = add nsw i32 %0, %k
    143 ; CHECK:   store i32 %add, i32* %arrayidx5
    144 ; CHECK:   br label %for.inc10
    145 ; CHECK: for.body3.split:
    146 ; CHECK:   %indvars.iv.next = add nsw i64 %indvars.iv, -1
    147 ; CHECK:   %cmp2 = icmp sgt i64 %indvars.iv, 0
    148 ; CHECK:   br i1 %cmp2, label %for.body3, label %for.end11
    149 ; CHECK: for.inc10:
    150 ; CHECK:   %indvars.iv.next20 = add nuw nsw i64 %indvars.iv19, 1
    151 ; CHECK:   %exitcond = icmp eq i64 %indvars.iv.next20, 100
    152 ; CHECK:   br i1 %exitcond, label %for.body3.split, label %for.cond1.preheader
    153 ; CHECK: for.end11: 
    154 ; CHECK:   ret void
    155 
    156 ;;--------------------------------------Test case 03-------------------------------------
    157 ;; Loops should not be interchanged in this case as it is not profitable.
    158 ;;  for(int i=0;i<100;i++)
    159 ;;    for(int j=0;j<100;j++)
    160 ;;      A[i][j] = A[i][j]+k;
    161 
    162 define void @interchange_03(i32 %k) {
    163 entry:
    164   br label %for.cond1.preheader
    165 
    166 for.cond1.preheader:
    167   %indvars.iv21 = phi i64 [ 0, %entry ], [ %indvars.iv.next22, %for.inc10 ]
    168   br label %for.body3
    169 
    170 for.body3:
    171   %indvars.iv = phi i64 [ 0, %for.cond1.preheader ], [ %indvars.iv.next, %for.body3 ]
    172   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv21, i64 %indvars.iv
    173   %0 = load i32, i32* %arrayidx5
    174   %add = add nsw i32 %0, %k
    175   store i32 %add, i32* %arrayidx5
    176   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    177   %exitcond = icmp eq i64 %indvars.iv.next, 100
    178   br i1 %exitcond, label %for.inc10, label %for.body3
    179 
    180 for.inc10:
    181   %indvars.iv.next22 = add nuw nsw i64 %indvars.iv21, 1
    182   %exitcond23 = icmp eq i64 %indvars.iv.next22, 100
    183   br i1 %exitcond23, label %for.end12, label %for.cond1.preheader
    184 
    185 for.end12:
    186   ret void
    187 }
    188 
    189 ; CHECK-LABEL: @interchange_03
    190 ; CHECK: entry:
    191 ; CHECK:   br label %for.cond1.preheader.preheader
    192 ; CHECK: for.cond1.preheader.preheader:                    ; preds = %entry
    193 ; CHECK:   br label %for.cond1.preheader
    194 ; CHECK: for.cond1.preheader:                              ; preds = %for.cond1.preheader.preheader, %for.inc10
    195 ; CHECK:   %indvars.iv21 = phi i64 [ %indvars.iv.next22, %for.inc10 ], [ 0, %for.cond1.preheader.preheader ]
    196 ; CHECK:  br label %for.body3.preheader
    197 ; CHECK: for.body3.preheader:                              ; preds = %for.cond1.preheader
    198 ; CHECK:   br label %for.body3
    199 ; CHECK: for.body3:                                        ; preds = %for.body3.preheader, %for.body3
    200 ; CHECK:   %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3 ], [ 0, %for.body3.preheader ]
    201 ; CHECK:   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv21, i64 %indvars.iv
    202 ; CHECK:   %0 = load i32, i32* %arrayidx5
    203 ; CHECK:   %add = add nsw i32 %0, %k
    204 ; CHECK:   store i32 %add, i32* %arrayidx5
    205 ; CHECK:   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    206 ; CHECK:   %exitcond = icmp eq i64 %indvars.iv.next, 100
    207 ; CHECK:   br i1 %exitcond, label %for.inc10, label %for.body3
    208 ; CHECK: for.inc10:                                        ; preds = %for.body3
    209 ; CHECK:   %indvars.iv.next22 = add nuw nsw i64 %indvars.iv21, 1
    210 ; CHECK:   %exitcond23 = icmp eq i64 %indvars.iv.next22, 100
    211 ; CHECK:   br i1 %exitcond23, label %for.end12, label %for.cond1.preheader
    212 ; CHECK: for.end12:                                        ; preds = %for.inc10
    213 ; CHECK:   ret void
    214 
    215 
    216 ;;--------------------------------------Test case 04-------------------------------------
    217 ;; Loops should not be interchanged in this case as it is not legal due to dependency.
    218 ;;  for(int j=0;j<99;j++)
    219 ;;   for(int i=0;i<99;i++)
    220 ;;       A[j][i+1] = A[j+1][i]+k;
    221 
    222 define void @interchange_04(i32 %k){
    223 entry:
    224   br label %for.cond1.preheader
    225 
    226 for.cond1.preheader:
    227   %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for.inc12 ]
    228   %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
    229   br label %for.body3
    230 
    231 for.body3:
    232   %indvars.iv = phi i64 [ 0, %for.cond1.preheader ], [ %indvars.iv.next, %for.body3 ]
    233   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv.next24, i64 %indvars.iv
    234   %0 = load i32, i32* %arrayidx5
    235   %add6 = add nsw i32 %0, %k
    236   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    237   %arrayidx11 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv23, i64 %indvars.iv.next
    238   store i32 %add6, i32* %arrayidx11
    239   %exitcond = icmp eq i64 %indvars.iv.next, 99
    240   br i1 %exitcond, label %for.inc12, label %for.body3
    241 
    242 for.inc12:
    243   %exitcond25 = icmp eq i64 %indvars.iv.next24, 99
    244   br i1 %exitcond25, label %for.end14, label %for.cond1.preheader
    245 
    246 for.end14:
    247   ret void
    248 }
    249 
    250 ; CHECK-LABEL: @interchange_04
    251 ; CHECK: entry:
    252 ; CHECK:   br label %for.cond1.preheader
    253 ; CHECK: for.cond1.preheader:                              ; preds = %for.inc12, %entry
    254 ; CHECK:   %indvars.iv23 = phi i64 [ 0, %entry ], [ %indvars.iv.next24, %for.inc12 ]
    255 ; CHECK:   %indvars.iv.next24 = add nuw nsw i64 %indvars.iv23, 1
    256 ; CHECK:   br label %for.body3
    257 ; CHECK: for.body3:                                        ; preds = %for.body3, %for.cond1.preheader
    258 ; CHECK:   %indvars.iv = phi i64 [ 0, %for.cond1.preheader ], [ %indvars.iv.next, %for.body3 ]
    259 ; CHECK:   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv.next24, i64 %indvars.iv
    260 ; CHECK:   %0 = load i32, i32* %arrayidx5
    261 ; CHECK:   %add6 = add nsw i32 %0, %k
    262 ; CHECK:   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    263 ; CHECK:   %arrayidx11 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv23, i64 %indvars.iv.next
    264 ; CHECK:   store i32 %add6, i32* %arrayidx11
    265 ; CHECK:   %exitcond = icmp eq i64 %indvars.iv.next, 99
    266 ; CHECK:   br i1 %exitcond, label %for.inc12, label %for.body3
    267 ; CHECK: for.inc12:                                        ; preds = %for.body3
    268 ; CHECK:   %exitcond25 = icmp eq i64 %indvars.iv.next24, 99
    269 ; CHECK:   br i1 %exitcond25, label %for.end14, label %for.cond1.preheader
    270 ; CHECK: for.end14:                                        ; preds = %for.inc12
    271 ; CHECK:   ret void
    272 
    273 
    274 
    275 ;;--------------------------------------Test case 05-------------------------------------
    276 ;; Loops not tightly nested are not interchanged
    277 ;;  for(int j=0;j<N;j++) {
    278 ;;    B[j] = j+k;
    279 ;;    for(int i=0;i<N;i++)
    280 ;;      A[j][i] = A[j][i]+B[j];
    281 ;;  }
    282 
    283 define void @interchange_05(i32 %k, i32 %N){
    284 entry:
    285   %cmp30 = icmp sgt i32 %N, 0
    286   br i1 %cmp30, label %for.body.lr.ph, label %for.end17
    287 
    288 for.body.lr.ph:
    289   %0 = add i32 %N, -1
    290   %1 = zext i32 %k to i64
    291   br label %for.body
    292 
    293 for.body:
    294   %indvars.iv32 = phi i64 [ 0, %for.body.lr.ph ], [ %indvars.iv.next33, %for.inc15 ]
    295   %2 = add nsw i64 %indvars.iv32, %1
    296   %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* @B, i64 0, i64 %indvars.iv32
    297   %3 = trunc i64 %2 to i32
    298   store i32 %3, i32* %arrayidx
    299   br label %for.body3
    300 
    301 for.body3:
    302   %indvars.iv = phi i64 [ 0, %for.body ], [ %indvars.iv.next, %for.body3 ]
    303   %arrayidx7 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv32, i64 %indvars.iv
    304   %4 = load i32, i32* %arrayidx7
    305   %add10 = add nsw i32 %3, %4
    306   store i32 %add10, i32* %arrayidx7
    307   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    308   %lftr.wideiv = trunc i64 %indvars.iv to i32
    309   %exitcond = icmp eq i32 %lftr.wideiv, %0
    310   br i1 %exitcond, label %for.inc15, label %for.body3
    311 
    312 for.inc15:
    313   %indvars.iv.next33 = add nuw nsw i64 %indvars.iv32, 1
    314   %lftr.wideiv35 = trunc i64 %indvars.iv32 to i32
    315   %exitcond36 = icmp eq i32 %lftr.wideiv35, %0
    316   br i1 %exitcond36, label %for.end17, label %for.body
    317 
    318 for.end17:
    319   ret void
    320 }
    321 
    322 ; CHECK-LABEL: @interchange_05
    323 ; CHECK: entry:
    324 ; CHECK: %cmp30 = icmp sgt i32 %N, 0
    325 ; CHECK: br i1 %cmp30, label %for.body.lr.ph, label %for.end17
    326 ; CHECK: for.body.lr.ph:
    327 ; CHECK: %0 = add i32 %N, -1
    328 ; CHECK: %1 = zext i32 %k to i64
    329 ; CHECK: br label %for.body
    330 ; CHECK: for.body:
    331 ; CHECK: %indvars.iv32 = phi i64 [ 0, %for.body.lr.ph ], [ %indvars.iv.next33, %for.inc15 ]
    332 ; CHECK: %2 = add nsw i64 %indvars.iv32, %1
    333 ; CHECK: %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* @B, i64 0, i64 %indvars.iv32
    334 ; CHECK: %3 = trunc i64 %2 to i32
    335 ; CHECK: store i32 %3, i32* %arrayidx
    336 ; CHECK: br label %for.body3.preheader
    337 ; CHECK: for.body3.preheader:
    338 ; CHECK: br label %for.body3
    339 ; CHECK: for.body3:
    340 ; CHECK: %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3 ], [ 0, %for.body3.preheader ]
    341 ; CHECK: %arrayidx7 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv32, i64 %indvars.iv
    342 ; CHECK: %4 = load i32, i32* %arrayidx7
    343 ; CHECK: %add10 = add nsw i32 %3, %4
    344 ; CHECK: store i32 %add10, i32* %arrayidx7
    345 ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    346 ; CHECK: %lftr.wideiv = trunc i64 %indvars.iv to i32
    347 ; CHECK: %exitcond = icmp eq i32 %lftr.wideiv, %0
    348 ; CHECK: br i1 %exitcond, label %for.inc15, label %for.body3
    349 ; CHECK: for.inc15:
    350 ; CHECK: %indvars.iv.next33 = add nuw nsw i64 %indvars.iv32, 1
    351 ; CHECK: %lftr.wideiv35 = trunc i64 %indvars.iv32 to i32
    352 ; CHECK: %exitcond36 = icmp eq i32 %lftr.wideiv35, %0
    353 ; CHECK: br i1 %exitcond36, label %for.end17.loopexit, label %for.body
    354 ; CHECK: for.end17.loopexit:
    355 ; CHECK: br label %for.end17
    356 ; CHECK: for.end17:
    357 ; CHECK: ret void
    358 
    359 
    360 ;;--------------------------------------Test case 06-------------------------------------
    361 ;; Loops not tightly nested are not interchanged
    362 ;;  for(int j=0;j<N;j++) {
    363 ;;    foo();
    364 ;;    for(int i=2;i<N;i++)
    365 ;;      A[j][i] = A[j][i]+k;
    366 ;;  }
    367 
    368 define void @interchange_06(i32 %k, i32 %N) {
    369 entry:
    370   %cmp22 = icmp sgt i32 %N, 0
    371   br i1 %cmp22, label %for.body.lr.ph, label %for.end12
    372 
    373 for.body.lr.ph:
    374   %0 = add i32 %N, -1
    375   br label %for.body
    376 
    377 for.body:
    378   %indvars.iv24 = phi i64 [ 0, %for.body.lr.ph ], [ %indvars.iv.next25, %for.inc10 ]
    379   tail call void (...) @foo()
    380   br label %for.body3
    381 
    382 for.body3:
    383   %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3 ], [ 2, %for.body ]
    384   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv24, i64 %indvars.iv
    385   %1 = load i32, i32* %arrayidx5
    386   %add = add nsw i32 %1, %k
    387   store i32 %add, i32* %arrayidx5
    388   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    389   %lftr.wideiv = trunc i64 %indvars.iv to i32
    390   %exitcond = icmp eq i32 %lftr.wideiv, %0
    391   br i1 %exitcond, label %for.inc10, label %for.body3
    392 
    393 for.inc10:
    394   %indvars.iv.next25 = add nuw nsw i64 %indvars.iv24, 1
    395   %lftr.wideiv26 = trunc i64 %indvars.iv24 to i32
    396   %exitcond27 = icmp eq i32 %lftr.wideiv26, %0
    397   br i1 %exitcond27, label %for.end12, label %for.body
    398 
    399 for.end12:
    400   ret void
    401 }
    402 ;; Here we are checking if the inner phi is not split then we have not interchanged.
    403 ; CHECK-LABEL: @interchange_06
    404 ; CHECK:  phi i64 [ %indvars.iv.next, %for.body3 ], [ 2, %for.body3.preheader ]
    405 ; CHECK-NEXT: getelementptr
    406 ; CHECK-NEXT: %1 = load
    407 
    408 ;;--------------------------------------Test case 07-------------------------------------
    409 ;; FIXME:
    410 ;; Test for interchange when we have an lcssa phi. This should ideally be interchanged but it is currently not supported.
    411 ;;     for(gi=1;gi<N;gi++)
    412 ;;       for(gj=1;gj<M;gj++)
    413 ;;         A[gj][gi] = A[gj - 1][gi] + C[gj][gi];
    414 
    415 @gi = common global i32 0
    416 @gj = common global i32 0
    417 
    418 define void @interchange_07(i32 %N, i32 %M){
    419 entry:
    420   store i32 1, i32* @gi
    421   %cmp21 = icmp sgt i32 %N, 1
    422   br i1 %cmp21, label %for.cond1.preheader.lr.ph, label %for.end16
    423 
    424 for.cond1.preheader.lr.ph: 
    425   %cmp218 = icmp sgt i32 %M, 1
    426   %gi.promoted = load i32, i32* @gi
    427   %0 = add i32 %M, -1
    428   %1 = sext i32 %gi.promoted to i64
    429   %2 = sext i32 %N to i64
    430   %3 = add i32 %gi.promoted, 1
    431   %4 = icmp slt i32 %3, %N
    432   %smax = select i1 %4, i32 %N, i32 %3
    433   br label %for.cond1.preheader
    434 
    435 for.cond1.preheader: 
    436   %indvars.iv25 = phi i64 [ %1, %for.cond1.preheader.lr.ph ], [ %indvars.iv.next26, %for.inc14 ]
    437   br i1 %cmp218, label %for.body3, label %for.inc14
    438 
    439 for.body3: 
    440   %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3 ], [ 1, %for.cond1.preheader ]
    441   %5 = add nsw i64 %indvars.iv, -1
    442   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %5, i64 %indvars.iv25
    443   %6 = load i32, i32* %arrayidx5
    444   %arrayidx9 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @C, i64 0, i64 %indvars.iv, i64 %indvars.iv25
    445   %7 = load i32, i32* %arrayidx9
    446   %add = add nsw i32 %7, %6
    447   %arrayidx13 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %indvars.iv, i64 %indvars.iv25
    448   store i32 %add, i32* %arrayidx13
    449   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    450   %lftr.wideiv = trunc i64 %indvars.iv to i32
    451   %exitcond = icmp eq i32 %lftr.wideiv, %0
    452   br i1 %exitcond, label %for.inc14, label %for.body3
    453 
    454 for.inc14: 
    455   %inc.lcssa23 = phi i32 [ 1, %for.cond1.preheader ], [ %M, %for.body3 ]
    456   %indvars.iv.next26 = add nsw i64 %indvars.iv25, 1
    457   %cmp = icmp slt i64 %indvars.iv.next26, %2
    458   br i1 %cmp, label %for.cond1.preheader, label %for.cond.for.end16_crit_edge
    459 
    460 for.cond.for.end16_crit_edge: 
    461   store i32 %inc.lcssa23, i32* @gj
    462   store i32 %smax, i32* @gi
    463   br label %for.end16
    464 
    465 for.end16:
    466   ret void
    467 }
    468 
    469 ; CHECK-LABEL: @interchange_07
    470 ; CHECK: for.body3:                                        ; preds = %for.body3.preheader, %for.body3
    471 ; CHECK:   %indvars.iv = phi i64 [ %indvars.iv.next, %for.body3 ], [ 1, %for.body3.preheader ]
    472 ; CHECK:   %5 = add nsw i64 %indvars.iv, -1
    473 ; CHECK:   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %5, i64 %indvars.iv25
    474 ; CHECK:   %6 = load i32, i32* %arrayidx5
    475 ; CHECK:   %arrayidx9 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @C, i64 0, i64 %indvars.iv, i64 %indvars.iv25
    476 
    477 ;;------------------------------------------------Test case 08-------------------------------
    478 ;; Test for interchange in loop nest greater than 2.
    479 ;;  for(int i=0;i<100;i++)
    480 ;;    for(int j=0;j<100;j++)
    481 ;;      for(int k=0;k<100;k++)
    482 ;;        D[i][k][j] = D[i][k][j]+t;
    483 
    484 define void @interchange_08(i32 %t){
    485 entry:
    486   br label %for.cond1.preheader
    487 
    488 for.cond1.preheader:                              ; preds = %for.inc15, %entry
    489   %i.028 = phi i32 [ 0, %entry ], [ %inc16, %for.inc15 ]
    490   br label %for.cond4.preheader
    491 
    492 for.cond4.preheader:                              ; preds = %for.inc12, %for.cond1.preheader
    493   %j.027 = phi i32 [ 0, %for.cond1.preheader ], [ %inc13, %for.inc12 ]
    494   br label %for.body6
    495 
    496 for.body6:                                        ; preds = %for.body6, %for.cond4.preheader
    497   %k.026 = phi i32 [ 0, %for.cond4.preheader ], [ %inc, %for.body6 ]
    498   %arrayidx8 = getelementptr inbounds [100 x [100 x [100 x i32]]], [100 x [100 x [100 x i32]]]* @D, i32 0, i32 %i.028, i32 %k.026, i32 %j.027
    499   %0 = load i32, i32* %arrayidx8
    500   %add = add nsw i32 %0, %t
    501   store i32 %add, i32* %arrayidx8
    502   %inc = add nuw nsw i32 %k.026, 1
    503   %exitcond = icmp eq i32 %inc, 100
    504   br i1 %exitcond, label %for.inc12, label %for.body6
    505 
    506 for.inc12:                                        ; preds = %for.body6
    507   %inc13 = add nuw nsw i32 %j.027, 1
    508   %exitcond29 = icmp eq i32 %inc13, 100
    509   br i1 %exitcond29, label %for.inc15, label %for.cond4.preheader
    510 
    511 for.inc15:                                        ; preds = %for.inc12
    512   %inc16 = add nuw nsw i32 %i.028, 1
    513   %exitcond30 = icmp eq i32 %inc16, 100
    514   br i1 %exitcond30, label %for.end17, label %for.cond1.preheader
    515 
    516 for.end17:                                        ; preds = %for.inc15
    517   ret void
    518 }
    519 ; CHECK-LABEL: @interchange_08
    520 ; CHECK:   entry:
    521 ; CHECK:     br label %for.cond1.preheader.preheader
    522 ; CHECK:   for.cond1.preheader.preheader:                    ; preds = %entry
    523 ; CHECK:     br label %for.cond1.preheader
    524 ; CHECK:   for.cond1.preheader:                              ; preds = %for.cond1.preheader.preheader, %for.inc15
    525 ; CHECK:     %i.028 = phi i32 [ %inc16, %for.inc15 ], [ 0, %for.cond1.preheader.preheader ]
    526 ; CHECK:     br label %for.body6.preheader
    527 ; CHECK:   for.cond4.preheader.preheader:                    ; preds = %for.body6
    528 ; CHECK:     br label %for.cond4.preheader
    529 ; CHECK:   for.cond4.preheader:                              ; preds = %for.cond4.preheader.preheader, %for.inc12
    530 ; CHECK:     %j.027 = phi i32 [ %inc13, %for.inc12 ], [ 0, %for.cond4.preheader.preheader ]
    531 ; CHECK:     br label %for.body6.split1
    532 ; CHECK:   for.body6.preheader:                              ; preds = %for.cond1.preheader
    533 ; CHECK:     br label %for.body6
    534 ; CHECK:   for.body6:                                        ; preds = %for.body6.preheader, %for.body6.split
    535 ; CHECK:     %k.026 = phi i32 [ %inc, %for.body6.split ], [ 0, %for.body6.preheader ]
    536 ; CHECK:     br label %for.cond4.preheader.preheader
    537 ; CHECK:   for.body6.split1:                                 ; preds = %for.cond4.preheader
    538 ; CHECK:     %arrayidx8 = getelementptr inbounds [100 x [100 x [100 x i32]]], [100 x [100 x [100 x i32]]]* @D, i32 0, i32 %i.028, i32 %k.026, i32 %j.027
    539 ; CHECK:     %0 = load i32, i32* %arrayidx8
    540 ; CHECK:     %add = add nsw i32 %0, %t
    541 ; CHECK:     store i32 %add, i32* %arrayidx8
    542 ; CHECK:     br label %for.inc12
    543 ; CHECK:   for.body6.split:                                  ; preds = %for.inc12
    544 ; CHECK:     %inc = add nuw nsw i32 %k.026, 1
    545 ; CHECK:     %exitcond = icmp eq i32 %inc, 100
    546 ; CHECK:     br i1 %exitcond, label %for.inc15, label %for.body6
    547 ; CHECK:   for.inc12:                                        ; preds = %for.body6.split1
    548 ; CHECK:     %inc13 = add nuw nsw i32 %j.027, 1
    549 ; CHECK:     %exitcond29 = icmp eq i32 %inc13, 100
    550 ; CHECK:     br i1 %exitcond29, label %for.body6.split, label %for.cond4.preheader
    551 ; CHECK:   for.inc15:                                        ; preds = %for.body6.split
    552 ; CHECK:     %inc16 = add nuw nsw i32 %i.028, 1
    553 ; CHECK:     %exitcond30 = icmp eq i32 %inc16, 100
    554 ; CHECK:     br i1 %exitcond30, label %for.end17, label %for.cond1.preheader
    555 ; CHECK:   for.end17:                                        ; preds = %for.inc15
    556 ; CHECK:     ret void
    557 
    558