[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / LoopIdiom / struct.ll
blob5f7e1d96a855fb978b4cf85d3895921a84a5a70c
1 ; RUN: opt -basic-aa -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"
4 target triple = "x86_64-apple-darwin10.0.0"
6 %struct.foo = type { i32, i32 }
7 %struct.foo1 = type { i32, i32, i32 }
8 %struct.foo2 = type { i32, i16, i16 }
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 ;  }
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
21 for.body.preheader:                               ; preds = %entry
22   br label %for.body
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
35 for.end.loopexit:                                 ; preds = %for.body
36   br label %for.end
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
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 ;  }
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
56 for.body.preheader:                               ; preds = %entry
57   br label %for.body
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
70 for.end.loopexit:                                 ; preds = %for.body
71   br label %for.end
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
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 ;  }
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
91 for.body.preheader:                               ; preds = %entry
92   %0 = zext i32 %n to i64
93   br label %for.body
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
107 for.end.loopexit:                                 ; preds = %for.body
108   br label %for.end
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
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 ;  }
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
128 for.body.preheader:                               ; preds = %entry
129   br label %for.body
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
142 for.end.loopexit:                                 ; preds = %for.body
143   br label %for.end
145 for.end:                                          ; preds = %for.end.loopexit, %entry
146   ret void
147 ; CHECK-LABEL: @bar4(
148 ; CHECK-NOT: call void @llvm.memset 
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 ;  }
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
162 for.body.preheader:                               ; preds = %entry
163   br label %for.body
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
176 for.end.loopexit:                                 ; preds = %for.body
177   br label %for.end
179 for.end:                                          ; preds = %for.end.loopexit, %entry
180   ret void
181 ; CHECK-LABEL: @bar5(
182 ; CHECK-NOT: call void @llvm.memset 
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 ;  }
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
197 for.body.preheader:                               ; preds = %entry
198   br label %for.body
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
213 for.end.loopexit:                                 ; preds = %for.body
214   br label %for.end
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