Home | History | Annotate | Download | only in LoopUnroll
      1 ; RUN: opt -S -loop-unroll < %s | FileCheck %s
      2 ; RUN: opt -S -passes='require<opt-remark-emit>,loop(unroll-full)' < %s | FileCheck %s
      3 
      4 ; Unroll twice, with first loop exit kept
      5 ; CHECK-LABEL: @s32_max1
      6 ; CHECK: do.body:
      7 ; CHECK:  store
      8 ; CHECK:  br i1 %cmp, label %do.body.1, label %do.end
      9 ; CHECK: do.end:
     10 ; CHECK:  ret void
     11 ; CHECK: do.body.1:
     12 ; CHECK:  store
     13 ; CHECK:  br label %do.end
     14 define void @s32_max1(i32 %n, i32* %p) {
     15 entry:
     16   %add = add i32 %n, 1
     17   br label %do.body
     18 
     19 do.body:
     20   %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
     21   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
     22   store i32 %i.0, i32* %arrayidx, align 4
     23   %inc = add i32 %i.0, 1
     24   %cmp = icmp slt i32 %i.0, %add
     25   br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 1 times
     26 
     27 do.end:
     28   ret void
     29 }
     30 
     31 ; Unroll thrice, with first loop exit kept
     32 ; CHECK-LABEL: @s32_max2
     33 ; CHECK: do.body:
     34 ; CHECK:  store
     35 ; CHECK:  br i1 %cmp, label %do.body.1, label %do.end
     36 ; CHECK: do.end:
     37 ; CHECK:  ret void
     38 ; CHECK: do.body.1:
     39 ; CHECK:  store
     40 ; CHECK:  store
     41 ; CHECK:  br label %do.end
     42 define void @s32_max2(i32 %n, i32* %p) {
     43 entry:
     44   %add = add i32 %n, 2
     45   br label %do.body
     46 
     47 do.body:
     48   %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
     49   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
     50   store i32 %i.0, i32* %arrayidx, align 4
     51   %inc = add i32 %i.0, 1
     52   %cmp = icmp slt i32 %i.0, %add
     53   br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 2 times
     54 
     55 do.end:
     56   ret void
     57 }
     58 
     59 ; Should not be unrolled
     60 ; CHECK-LABEL: @s32_maxx
     61 ; CHECK: do.body:
     62 ; CHECK: do.end:
     63 ; CHECK-NOT: do.body.1:
     64 define void @s32_maxx(i32 %n, i32 %x, i32* %p) {
     65 entry:
     66   %add = add i32 %x, %n
     67   br label %do.body
     68 
     69 do.body:
     70   %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
     71   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
     72   store i32 %i.0, i32* %arrayidx, align 4
     73   %inc = add i32 %i.0, 1
     74   %cmp = icmp slt i32 %i.0, %add
     75   br i1 %cmp, label %do.body, label %do.end ; taken either 0 or x times
     76 
     77 do.end:
     78   ret void
     79 }
     80 
     81 ; Should not be unrolled
     82 ; CHECK-LABEL: @s32_max2_unpredictable_exit
     83 ; CHECK: do.body:
     84 ; CHECK: do.end:
     85 ; CHECK-NOT: do.body.1:
     86 define void @s32_max2_unpredictable_exit(i32 %n, i32 %x, i32* %p) {
     87 entry:
     88   %add = add i32 %n, 2
     89   br label %do.body
     90 
     91 do.body:
     92   %i.0 = phi i32 [ %n, %entry ], [ %inc, %if.end ]
     93   %cmp = icmp eq i32 %i.0, %x
     94   br i1 %cmp, label %do.end, label %if.end ; unpredictable
     95 
     96 if.end:
     97   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
     98   store i32 %i.0, i32* %arrayidx, align 4
     99   %inc = add i32 %i.0, 1
    100   %cmp1 = icmp slt i32 %i.0, %add
    101   br i1 %cmp1, label %do.body, label %do.end ; taken either 0 or 2 times
    102 
    103 do.end:
    104   ret void
    105 }
    106 
    107 ; Unroll twice, with first loop exit kept
    108 ; CHECK-LABEL: @u32_max1
    109 ; CHECK: do.body:
    110 ; CHECK:  store
    111 ; CHECK:  br i1 %cmp, label %do.body.1, label %do.end
    112 ; CHECK: do.end:
    113 ; CHECK:  ret void
    114 ; CHECK: do.body.1:
    115 ; CHECK:  store
    116 ; CHECK:  br label %do.end
    117 define void @u32_max1(i32 %n, i32* %p) {
    118 entry:
    119   %add = add i32 %n, 1
    120   br label %do.body
    121 
    122 do.body:
    123   %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
    124   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
    125   store i32 %i.0, i32* %arrayidx, align 4
    126   %inc = add i32 %i.0, 1
    127   %cmp = icmp ult i32 %i.0, %add
    128   br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 1 times
    129 
    130 do.end:
    131   ret void
    132 }
    133 
    134 ; Unroll thrice, with first loop exit kept
    135 ; CHECK-LABEL: @u32_max2
    136 ; CHECK: do.body:
    137 ; CHECK:  store
    138 ; CHECK:  br i1 %cmp, label %do.body.1, label %do.end
    139 ; CHECK: do.end:
    140 ; CHECK:  ret void
    141 ; CHECK: do.body.1:
    142 ; CHECK:  store
    143 ; CHECK:  store
    144 ; CHECK:  br label %do.end
    145 define void @u32_max2(i32 %n, i32* %p) {
    146 entry:
    147   %add = add i32 %n, 2
    148   br label %do.body
    149 
    150 do.body:
    151   %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
    152   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
    153   store i32 %i.0, i32* %arrayidx, align 4
    154   %inc = add i32 %i.0, 1
    155   %cmp = icmp ult i32 %i.0, %add
    156   br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 2 times
    157 
    158 do.end:
    159   ret void
    160 }
    161 
    162 ; Should not be unrolled
    163 ; CHECK-LABEL: @u32_maxx
    164 ; CHECK: do.body:
    165 ; CHECK: do.end:
    166 ; CHECK-NOT: do.body.1:
    167 define void @u32_maxx(i32 %n, i32 %x, i32* %p) {
    168 entry:
    169   %add = add i32 %x, %n
    170   br label %do.body
    171 
    172 do.body:
    173   %i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
    174   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
    175   store i32 %i.0, i32* %arrayidx, align 4
    176   %inc = add i32 %i.0, 1
    177   %cmp = icmp ult i32 %i.0, %add
    178   br i1 %cmp, label %do.body, label %do.end ; taken either 0 or x times
    179 
    180 do.end:
    181   ret void
    182 }
    183 
    184 ; Should not be unrolled
    185 ; CHECK-LABEL: @u32_max2_unpredictable_exit
    186 ; CHECK: do.body:
    187 ; CHECK: do.end:
    188 ; CHECK-NOT: do.body.1:
    189 define void @u32_max2_unpredictable_exit(i32 %n, i32 %x, i32* %p) {
    190 entry:
    191   %add = add i32 %n, 2
    192   br label %do.body
    193 
    194 do.body:
    195   %i.0 = phi i32 [ %n, %entry ], [ %inc, %if.end ]
    196   %cmp = icmp eq i32 %i.0, %x
    197   br i1 %cmp, label %do.end, label %if.end ; unpredictable
    198 
    199 if.end:
    200   %arrayidx = getelementptr i32, i32* %p, i32 %i.0
    201   store i32 %i.0, i32* %arrayidx, align 4
    202   %inc = add i32 %i.0, 1
    203   %cmp1 = icmp ult i32 %i.0, %add
    204   br i1 %cmp1, label %do.body, label %do.end ; taken either 0 or 2 times
    205 
    206 do.end:
    207   ret void
    208 }
    209