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) {
16 define void @bar1(%struct.foo* %f, i32 %n) nounwind ssp {
18 %cmp1 = icmp eq i32 %n, 0
19 br i1 %cmp1, label %for.end, label %for.body.preheader
21 for.body.preheader: ; preds = %entry
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
38 for.end: ; preds = %for.end.loopexit, %entry
41 ; CHECK: call void @llvm.memset
45 ;void bar2(foo_t *f, unsigned n) {
46 ; for (unsigned i = 0; i < n; ++i) {
51 define void @bar2(%struct.foo* %f, i32 %n) nounwind ssp {
53 %cmp1 = icmp eq i32 %n, 0
54 br i1 %cmp1, label %for.end, label %for.body.preheader
56 for.body.preheader: ; preds = %entry
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
73 for.end: ; preds = %for.end.loopexit, %entry
76 ; CHECK: call void @llvm.memset
80 ;void bar3(foo_t *f, unsigned n) {
81 ; for (unsigned i = n; i > 0; --i) {
86 define void @bar3(%struct.foo* nocapture %f, i32 %n) nounwind ssp {
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
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
110 for.end: ; preds = %for.end.loopexit, %entry
112 ; CHECK-LABEL: @bar3(
113 ; CHECK: call void @llvm.memset
117 ;void bar4(foo_t *f, unsigned n) {
118 ; for (unsigned i = 0; i < n; ++i) {
123 define void @bar4(%struct.foo* nocapture %f, i32 %n) nounwind ssp {
125 %cmp1 = icmp eq i32 %n, 0
126 br i1 %cmp1, label %for.end, label %for.body.preheader
128 for.body.preheader: ; preds = %entry
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
145 for.end: ; preds = %for.end.loopexit, %entry
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) {
157 define void @bar5(%struct.foo1* nocapture %f, i32 %n) nounwind ssp {
159 %cmp1 = icmp eq i32 %n, 0
160 br i1 %cmp1, label %for.end, label %for.body.preheader
162 for.body.preheader: ; preds = %entry
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
179 for.end: ; preds = %for.end.loopexit, %entry
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) {
192 define void @bar6(%struct.foo2* nocapture %f, i32 %n) nounwind ssp {
194 %cmp1 = icmp eq i32 %n, 0
195 br i1 %cmp1, label %for.end, label %for.body.preheader
197 for.body.preheader: ; preds = %entry
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
216 for.end: ; preds = %for.end.loopexit, %entry
218 ; CHECK-LABEL: @bar6(
219 ; CHECK: call void @llvm.memset