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"
4 ; CHECK: @.memset_pattern = private unnamed_addr constant [4 x i32] [i32 2, i32 2, i32 2, i32 2], align 16
5 ; CHECK: @.memset_pattern.1 = private unnamed_addr constant [4 x i32] [i32 2, i32 2, i32 2, i32 2], align 16
6 ; CHECK: @.memset_pattern.2 = private unnamed_addr constant [4 x i32] [i32 2, i32 2, i32 2, i32 2], align 16
8 target triple = "x86_64-apple-darwin10.0.0"
10 %struct.foo = type { i32, i32 }
11 %struct.foo1 = type { i32, i32, i32 }
13 ;void bar1(foo_t *f, unsigned n) {
14 ; for (unsigned i = 0; i < n; ++i) {
19 define void @bar1(%struct.foo* %f, i32 %n) nounwind ssp {
21 %cmp1 = icmp eq i32 %n, 0
22 br i1 %cmp1, label %for.end, label %for.body.preheader
24 for.body.preheader: ; preds = %entry
27 for.body: ; preds = %for.body.preheader, %for.body
28 %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
29 %a = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 0
30 store i32 2, i32* %a, align 4
31 %b = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 1
32 store i32 2, i32* %b, align 4
33 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
34 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
35 %exitcond = icmp ne i32 %lftr.wideiv, %n
36 br i1 %exitcond, label %for.body, label %for.end.loopexit
38 for.end.loopexit: ; preds = %for.body
41 for.end: ; preds = %for.end.loopexit, %entry
44 ; CHECK: call void @memset_pattern16
48 ;void bar2(foo_t *f, unsigned n) {
49 ; for (unsigned i = 0; i < n; ++i) {
54 define void @bar2(%struct.foo* %f, i32 %n) nounwind ssp {
56 %cmp1 = icmp eq i32 %n, 0
57 br i1 %cmp1, label %for.end, label %for.body.preheader
59 for.body.preheader: ; preds = %entry
62 for.body: ; preds = %for.body.preheader, %for.body
63 %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
64 %b = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 1
65 store i32 2, i32* %b, align 4
66 %a = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 0
67 store i32 2, i32* %a, align 4
68 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
69 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
70 %exitcond = icmp ne i32 %lftr.wideiv, %n
71 br i1 %exitcond, label %for.body, label %for.end.loopexit
73 for.end.loopexit: ; preds = %for.body
76 for.end: ; preds = %for.end.loopexit, %entry
79 ; CHECK: call void @memset_pattern16
83 ;void bar3(foo_t *f, unsigned n) {
84 ; for (unsigned i = n; i > 0; --i) {
89 define void @bar3(%struct.foo* nocapture %f, i32 %n) nounwind ssp {
91 %cmp1 = icmp eq i32 %n, 0
92 br i1 %cmp1, label %for.end, label %for.body.preheader
94 for.body.preheader: ; preds = %entry
95 %0 = zext i32 %n to i64
98 for.body: ; preds = %for.body.preheader, %for.body
99 %indvars.iv = phi i64 [ %0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
100 %a = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 0
101 store i32 2, i32* %a, align 4
102 %b = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 1
103 store i32 2, i32* %b, align 4
104 %1 = trunc i64 %indvars.iv to i32
105 %dec = add i32 %1, -1
106 %cmp = icmp eq i32 %dec, 0
107 %indvars.iv.next = add nsw i64 %indvars.iv, -1
108 br i1 %cmp, label %for.end.loopexit, label %for.body
110 for.end.loopexit: ; preds = %for.body
113 for.end: ; preds = %for.end.loopexit, %entry
115 ; CHECK-LABEL: @bar3(
116 ; CHECK: call void @memset_pattern16
120 ;void bar4(foo_t *f, unsigned n) {
121 ; for (unsigned i = 0; i < n; ++i) {
126 define void @bar4(%struct.foo* nocapture %f, i32 %n) nounwind ssp {
128 %cmp1 = icmp eq i32 %n, 0
129 br i1 %cmp1, label %for.end, label %for.body.preheader
131 for.body.preheader: ; preds = %entry
134 for.body: ; preds = %for.body.preheader, %for.body
135 %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
136 %a = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 0
137 store i32 0, i32* %a, align 4
138 %b = getelementptr inbounds %struct.foo, %struct.foo* %f, i64 %indvars.iv, i32 1
139 store i32 1, i32* %b, align 4
140 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
141 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
142 %exitcond = icmp ne i32 %lftr.wideiv, %n
143 br i1 %exitcond, label %for.body, label %for.end.loopexit
145 for.end.loopexit: ; preds = %for.body
148 for.end: ; preds = %for.end.loopexit, %entry
150 ; CHECK-LABEL: @bar4(
151 ; CHECK-NOT: call void @memset_pattern16
154 ;void bar5(foo1_t *f, unsigned n) {
155 ; for (unsigned i = 0; i < n; ++i) {
160 define void @bar5(%struct.foo1* nocapture %f, i32 %n) nounwind ssp {
162 %cmp1 = icmp eq i32 %n, 0
163 br i1 %cmp1, label %for.end, label %for.body.preheader
165 for.body.preheader: ; preds = %entry
168 for.body: ; preds = %for.body.preheader, %for.body
169 %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
170 %a = getelementptr inbounds %struct.foo1, %struct.foo1* %f, i64 %indvars.iv, i32 0
171 store i32 1, i32* %a, align 4
172 %b = getelementptr inbounds %struct.foo1, %struct.foo1* %f, i64 %indvars.iv, i32 1
173 store i32 1, i32* %b, align 4
174 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
175 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
176 %exitcond = icmp ne i32 %lftr.wideiv, %n
177 br i1 %exitcond, label %for.body, label %for.end.loopexit
179 for.end.loopexit: ; preds = %for.body
182 for.end: ; preds = %for.end.loopexit, %entry
184 ; CHECK-LABEL: @bar5(
185 ; CHECK-NOT: call void @memset_pattern16