Home | History | Annotate | Download | only in LoopIdiom
      1 ; RUN: opt -basicaa -loop-idiom < %s -S | FileCheck %s
      2 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
      3 
      4 target triple = "x86_64-apple-darwin10.0.0"
      5 
      6 %struct.foo = type { i32, i32 }
      7 %struct.foo1 = type { i32, i32, i32 }
      8 %struct.foo2 = type { i32, i16, i16 }
      9 
     10 ;void bar1(foo_t *f, unsigned n) {
     11 ;  for (unsigned i = 0; i < n; ++i) {
     12 ;    f[i].a = 0;
     13 ;    f[i].b = 0;
     14 ;  }
     15 ;}
     16 define void @bar1(%struct.foo* %f, i32 %n) nounwind ssp {
     17 entry:
     18   %cmp1 = icmp eq i32 %n, 0
     19   br i1 %cmp1, label %for.end, label %for.body.preheader
     20 
     21 for.body.preheader:                               ; preds = %entry
     22   br label %for.body
     23 
     24 for.body:                                         ; preds = %for.body.preheader, %for.body
     25   %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
     26   %a = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 0
     27   store i32 0, i32* %a, align 4
     28   %b = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 1
     29   store i32 0, i32* %b, align 4
     30   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
     31   %lftr.wideiv = trunc i64 %indvars.iv.next to i32
     32   %exitcond = icmp ne i32 %lftr.wideiv, %n
     33   br i1 %exitcond, label %for.body, label %for.end.loopexit
     34 
     35 for.end.loopexit:                                 ; preds = %for.body
     36   br label %for.end
     37 
     38 for.end:                                          ; preds = %for.end.loopexit, %entry
     39   ret void
     40 ; CHECK-LABEL: @bar1(
     41 ; CHECK: call void @llvm.memset
     42 ; CHECK-NOT: store
     43 }
     44 
     45 ;void bar2(foo_t *f, unsigned n) {
     46 ;  for (unsigned i = 0; i < n; ++i) {
     47 ;    f[i].b = 0;
     48 ;    f[i].a = 0;
     49 ;  }
     50 ;}
     51 define void @bar2(%struct.foo* %f, i32 %n) nounwind ssp {
     52 entry:
     53   %cmp1 = icmp eq i32 %n, 0
     54   br i1 %cmp1, label %for.end, label %for.body.preheader
     55 
     56 for.body.preheader:                               ; preds = %entry
     57   br label %for.body
     58 
     59 for.body:                                         ; preds = %for.body.preheader, %for.body
     60   %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
     61   %b = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 1
     62   store i32 0, i32* %b, align 4
     63   %a = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 0
     64   store i32 0, i32* %a, align 4
     65   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
     66   %lftr.wideiv = trunc i64 %indvars.iv.next to i32
     67   %exitcond = icmp ne i32 %lftr.wideiv, %n
     68   br i1 %exitcond, label %for.body, label %for.end.loopexit
     69 
     70 for.end.loopexit:                                 ; preds = %for.body
     71   br label %for.end
     72 
     73 for.end:                                          ; preds = %for.end.loopexit, %entry
     74   ret void
     75 ; CHECK-LABEL: @bar2(
     76 ; CHECK: call void @llvm.memset
     77 ; CHECK-NOT: store
     78 }
     79 
     80 ;void bar3(foo_t *f, unsigned n) {
     81 ;  for (unsigned i = n; i > 0; --i) {
     82 ;    f[i].a = 0;
     83 ;    f[i].b = 0;
     84 ;  }
     85 ;}
     86 define void @bar3(%struct.foo* nocapture %f, i32 %n) nounwind ssp {
     87 entry:
     88   %cmp1 = icmp eq i32 %n, 0
     89   br i1 %cmp1, label %for.end, label %for.body.preheader
     90 
     91 for.body.preheader:                               ; preds = %entry
     92   %0 = zext i32 %n to i64
     93   br label %for.body
     94 
     95 for.body:                                         ; preds = %for.body.preheader, %for.body
     96   %indvars.iv = phi i64 [ %0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
     97   %a = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 0
     98   store i32 0, i32* %a, align 4
     99   %b = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 1
    100   store i32 0, i32* %b, align 4
    101   %1 = trunc i64 %indvars.iv to i32
    102   %dec = add i32 %1, -1
    103   %cmp = icmp eq i32 %dec, 0
    104   %indvars.iv.next = add nsw i64 %indvars.iv, -1
    105   br i1 %cmp, label %for.end.loopexit, label %for.body
    106 
    107 for.end.loopexit:                                 ; preds = %for.body
    108   br label %for.end
    109 
    110 for.end:                                          ; preds = %for.end.loopexit, %entry
    111   ret void
    112 ; CHECK-LABEL: @bar3(
    113 ; CHECK: call void @llvm.memset
    114 ; CHECK-NOT: store
    115 }
    116 
    117 ;void bar4(foo_t *f, unsigned n) {
    118 ;  for (unsigned i = 0; i < n; ++i) {
    119 ;    f[i].a = 0;
    120 ;    f[i].b = 1;
    121 ;  }
    122 ;}
    123 define void @bar4(%struct.foo* nocapture %f, i32 %n) nounwind ssp {
    124 entry:
    125   %cmp1 = icmp eq i32 %n, 0
    126   br i1 %cmp1, label %for.end, label %for.body.preheader
    127 
    128 for.body.preheader:                               ; preds = %entry
    129   br label %for.body
    130 
    131 for.body:                                         ; preds = %for.body.preheader, %for.body
    132   %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
    133   %a = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 0
    134   store i32 0, i32* %a, align 4
    135   %b = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 1
    136   store i32 1, i32* %b, align 4
    137   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    138   %lftr.wideiv = trunc i64 %indvars.iv.next to i32
    139   %exitcond = icmp ne i32 %lftr.wideiv, %n
    140   br i1 %exitcond, label %for.body, label %for.end.loopexit
    141 
    142 for.end.loopexit:                                 ; preds = %for.body
    143   br label %for.end
    144 
    145 for.end:                                          ; preds = %for.end.loopexit, %entry
    146   ret void
    147 ; CHECK-LABEL: @bar4(
    148 ; CHECK-NOT: call void @llvm.memset 
    149 }
    150 
    151 ;void bar5(foo1_t *f, unsigned n) {
    152 ;  for (unsigned i = 0; i < n; ++i) {
    153 ;    f[i].a = 0;
    154 ;    f[i].b = 0;
    155 ;  }
    156 ;}
    157 define void @bar5(%struct.foo1* nocapture %f, i32 %n) nounwind ssp {
    158 entry:
    159   %cmp1 = icmp eq i32 %n, 0
    160   br i1 %cmp1, label %for.end, label %for.body.preheader
    161 
    162 for.body.preheader:                               ; preds = %entry
    163   br label %for.body
    164 
    165 for.body:                                         ; preds = %for.body.preheader, %for.body
    166   %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
    167   %a = getelementptr inbounds %struct.foo1, %struct.foo1* %f, i64 %indvars.iv, i32 0
    168   store i32 0, i32* %a, align 4
    169   %b = getelementptr inbounds %struct.foo1, %struct.foo1* %f, i64 %indvars.iv, i32 1
    170   store i32 0, i32* %b, align 4
    171   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    172   %lftr.wideiv = trunc i64 %indvars.iv.next to i32
    173   %exitcond = icmp ne i32 %lftr.wideiv, %n
    174   br i1 %exitcond, label %for.body, label %for.end.loopexit
    175 
    176 for.end.loopexit:                                 ; preds = %for.body
    177   br label %for.end
    178 
    179 for.end:                                          ; preds = %for.end.loopexit, %entry
    180   ret void
    181 ; CHECK-LABEL: @bar5(
    182 ; CHECK-NOT: call void @llvm.memset 
    183 }
    184 
    185 ;void bar6(foo2_t *f, unsigned n) {
    186 ;  for (unsigned i = 0; i < n; ++i) {
    187 ;    f[i].a = 0;
    188 ;    f[i].b = 0;
    189 ;    f[i].c = 0;
    190 ;  }
    191 ;}
    192 define void @bar6(%struct.foo2* nocapture %f, i32 %n) nounwind ssp {
    193 entry:
    194   %cmp1 = icmp eq i32 %n, 0
    195   br i1 %cmp1, label %for.end, label %for.body.preheader
    196 
    197 for.body.preheader:                               ; preds = %entry
    198   br label %for.body
    199 
    200 for.body:                                         ; preds = %for.body.preheader, %for.body
    201   %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
    202   %a = getelementptr inbounds %struct.foo2, %struct.foo2* %f, i64 %indvars.iv, i32 0
    203   store i32 0, i32* %a, align 4
    204   %b = getelementptr inbounds %struct.foo2, %struct.foo2* %f, i64 %indvars.iv, i32 1
    205   store i16 0, i16* %b, align 4
    206   %c = getelementptr inbounds %struct.foo2, %struct.foo2* %f, i64 %indvars.iv, i32 2
    207   store i16 0, i16* %c, align 2
    208   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
    209   %lftr.wideiv = trunc i64 %indvars.iv.next to i32
    210   %exitcond = icmp ne i32 %lftr.wideiv, %n
    211   br i1 %exitcond, label %for.body, label %for.end.loopexit
    212 
    213 for.end.loopexit:                                 ; preds = %for.body
    214   br label %for.end
    215 
    216 for.end:                                          ; preds = %for.end.loopexit, %entry
    217   ret void
    218 ; CHECK-LABEL: @bar6(
    219 ; CHECK: call void @llvm.memset
    220 ; CHECK-NOT: store
    221 }
    222