Home | History | Annotate | Download | only in LoopInterchange
      1 ; RUN: opt < %s -basicaa -loop-interchange -pass-remarks-missed='loop-interchange' -pass-remarks-output=%t
      2 ; RUN: cat %t |  FileCheck --check-prefix REMARK %s
      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 @C = common global [100 x [100 x i32]] zeroinitializer
      9 @X = common global i32 0
     10 @Y = common global i64 0
     11 @F = common global float 0.0
     12 
     13 ; We cannot interchange this loop at the moment, because iv.outer.next is
     14 ; produced in the outer loop latch and used in the loop exit block. If the inner
     15 ; loop body is not executed, the outer loop latch won't be executed either
     16 ; after interchanging.
     17 ; REMARK: UnsupportedExitPHI
     18 ; REMARK-NEXT: lcssa_01
     19 
     20 define void @lcssa_01(){
     21 entry:
     22   %cmp21 = icmp sgt i64 100, 1
     23   br i1 %cmp21, label %outer.ph, label %for.end16
     24 
     25 outer.ph:
     26   %cmp218 = icmp sgt i64 100, 1
     27   br label %outer.header
     28 
     29 outer.header:
     30   %iv.outer= phi i64 [ 1, %outer.ph ], [ %iv.outer.next, %outer.inc ]
     31   br i1 %cmp218, label %for.body3, label %outer.inc
     32 
     33 for.body3:
     34   %iv.inner = phi i64 [ %iv.inner.next, %for.body3 ], [ 1, %outer.header ]
     35   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %iv.inner, i64 %iv.outer
     36   %vA = load i32, i32* %arrayidx5
     37   %arrayidx9 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @C, i64 0, i64 %iv.inner, i64 %iv.outer
     38   %vC = load i32, i32* %arrayidx9
     39   %add = add nsw i32 %vA, %vC
     40   store i32 %add, i32* %arrayidx5
     41   %iv.inner.next = add nuw nsw i64 %iv.inner, 1
     42   %exitcond = icmp eq i64 %iv.inner.next, 100
     43   br i1 %exitcond, label %outer.inc, label %for.body3
     44 
     45 outer.inc:
     46   %iv.outer.next = add nsw i64 %iv.outer, 1
     47   %cmp = icmp eq i64 %iv.outer.next, 100
     48   br i1 %cmp, label %outer.header, label %for.exit
     49 
     50 for.exit:
     51   store i64 %iv.outer.next, i64 * @Y
     52   br label %for.end16
     53 
     54 for.end16:
     55   ret void
     56 }
     57 
     58 ; REMARK: UnsupportedExitPHI
     59 ; REMARK-NEXT: lcssa_02
     60 define void @lcssa_02(){
     61 entry:
     62   %cmp21 = icmp sgt i64 100, 1
     63   br i1 %cmp21, label %outer.ph, label %for.end16
     64 
     65 outer.ph:
     66   %cmp218 = icmp sgt i64 100, 1
     67   br label %outer.header
     68 
     69 outer.header:
     70   %iv.outer= phi i64 [ 1, %outer.ph ], [ %iv.outer.next, %outer.inc ]
     71   br i1 %cmp218, label %for.body3, label %outer.inc
     72 
     73 for.body3:
     74   %iv.inner = phi i64 [ %iv.inner.next, %for.body3 ], [ 1, %outer.header ]
     75   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %iv.inner, i64 %iv.outer
     76   %vA = load i32, i32* %arrayidx5
     77   %arrayidx9 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @C, i64 0, i64 %iv.inner, i64 %iv.outer
     78   %vC = load i32, i32* %arrayidx9
     79   %add = add nsw i32 %vA, %vC
     80   store i32 %add, i32* %arrayidx5
     81   %iv.inner.next = add nuw nsw i64 %iv.inner, 1
     82   %exitcond = icmp eq i64 %iv.inner.next, 100
     83   br i1 %exitcond, label %outer.inc, label %for.body3
     84 
     85 outer.inc:
     86   %iv.inner.end = phi i64 [ 0, %outer.header ], [ %iv.inner.next, %for.body3 ]
     87   %iv.outer.next = add nsw i64 %iv.outer, 1
     88   %cmp = icmp eq i64 %iv.outer.next, 100
     89   br i1 %cmp, label %outer.header, label %for.exit
     90 
     91 for.exit:
     92   store i64 %iv.inner.end, i64 * @Y
     93   br label %for.end16
     94 
     95 for.end16:
     96   ret void
     97 }
     98 
     99 
    100 ; REMARK: Interchanged
    101 ; REMARK-NEXT: lcssa_03
    102 define void @lcssa_03(){
    103 entry:
    104   br label %outer.header
    105 
    106 outer.header:
    107   %iv.outer= phi i64 [ 1, %entry ], [ %iv.outer.next, %outer.inc ]
    108   br label %for.body3
    109 
    110 for.body3:
    111   %iv.inner = phi i64 [ %iv.inner.next, %for.body3 ], [ 1, %outer.header ]
    112   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %iv.inner, i64 %iv.outer
    113   %vA = load i32, i32* %arrayidx5
    114   %arrayidx9 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @C, i64 0, i64 %iv.inner, i64 %iv.outer
    115   %vC = load i32, i32* %arrayidx9
    116   %add = add nsw i32 %vA, %vC
    117   store i32 %add, i32* %arrayidx5
    118   %iv.inner.next = add nuw nsw i64 %iv.inner, 1
    119   %exitcond = icmp eq i64 %iv.inner.next, 100
    120   br i1 %exitcond, label %outer.inc, label %for.body3
    121 
    122 outer.inc:
    123   %iv.outer.next = add nsw i64 %iv.outer, 1
    124   %cmp = icmp eq i64 %iv.outer.next, 100
    125   br i1 %cmp, label %outer.header, label %for.exit
    126 
    127 for.exit:
    128   store i64 %iv.inner, i64 * @Y
    129   br label %for.end16
    130 
    131 for.end16:
    132   ret void
    133 }
    134 
    135 ; FIXME: We currently do not support LCSSA phi nodes involving floating point
    136 ;        types, as we fail to detect floating point reductions for now.
    137 ; REMARK: UnsupportedPHIOuter
    138 ; REMARK-NEXT: lcssa_04
    139 define void @lcssa_04(){
    140 entry:
    141   br label %outer.header
    142 
    143 outer.header:
    144   %iv.outer= phi i64 [ 1, %entry ], [ %iv.outer.next, %outer.inc ]
    145   %float.outer= phi float [ 1.0, %entry ], [ 2.0, %outer.inc ]
    146   br label %for.body3
    147 
    148 for.body3:
    149   %iv.inner = phi i64 [ %iv.inner.next, %for.body3 ], [ 1, %outer.header ]
    150   %arrayidx5 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @A, i64 0, i64 %iv.inner, i64 %iv.outer
    151   %vA = load i32, i32* %arrayidx5
    152   %arrayidx9 = getelementptr inbounds [100 x [100 x i32]], [100 x [100 x i32]]* @C, i64 0, i64 %iv.inner, i64 %iv.outer
    153   %vC = load i32, i32* %arrayidx9
    154   %add = add nsw i32 %vA, %vC
    155   store i32 %add, i32* %arrayidx5
    156   %iv.inner.next = add nuw nsw i64 %iv.inner, 1
    157   %exitcond = icmp eq i64 %iv.inner.next, 100
    158   br i1 %exitcond, label %outer.inc, label %for.body3
    159 
    160 outer.inc:
    161   %iv.outer.next = add nsw i64 %iv.outer, 1
    162   %cmp = icmp eq i64 %iv.outer.next, 100
    163   br i1 %cmp, label %outer.header, label %for.exit
    164 
    165 for.exit:
    166   store float %float.outer, float* @F
    167   br label %for.end16
    168 
    169 for.end16:
    170   ret void
    171 }
    172