[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / LoopIdiom / struct_pattern.ll
blob91cda98d50c60aec81d930482ab388c834ae3870
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 ; 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) {
15 ;    f[i].a = 2;
16 ;    f[i].b = 2;
17 ;  }
19 define void @bar1(%struct.foo* %f, i32 %n) nounwind ssp {
20 entry:
21   %cmp1 = icmp eq i32 %n, 0
22   br i1 %cmp1, label %for.end, label %for.body.preheader
24 for.body.preheader:                               ; preds = %entry
25   br label %for.body
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
39   br label %for.end
41 for.end:                                          ; preds = %for.end.loopexit, %entry
42   ret void
43 ; CHECK-LABEL: @bar1(
44 ; CHECK: call void @memset_pattern16
45 ; CHECK-NOT: store
48 ;void bar2(foo_t *f, unsigned n) {
49 ;  for (unsigned i = 0; i < n; ++i) {
50 ;    f[i].b = 2;
51 ;    f[i].a = 2;
52 ;  }
54 define void @bar2(%struct.foo* %f, i32 %n) nounwind ssp {
55 entry:
56   %cmp1 = icmp eq i32 %n, 0
57   br i1 %cmp1, label %for.end, label %for.body.preheader
59 for.body.preheader:                               ; preds = %entry
60   br label %for.body
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
74   br label %for.end
76 for.end:                                          ; preds = %for.end.loopexit, %entry
77   ret void
78 ; CHECK-LABEL: @bar2(
79 ; CHECK: call void @memset_pattern16
80 ; CHECK-NOT: store
83 ;void bar3(foo_t *f, unsigned n) {
84 ;  for (unsigned i = n; i > 0; --i) {
85 ;    f[i].a = 2;
86 ;    f[i].b = 2;
87 ;  }
89 define void @bar3(%struct.foo* nocapture %f, i32 %n) nounwind ssp {
90 entry:
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
96   br label %for.body
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
111   br label %for.end
113 for.end:                                          ; preds = %for.end.loopexit, %entry
114   ret void
115 ; CHECK-LABEL: @bar3(
116 ; CHECK: call void @memset_pattern16
117 ; CHECK-NOT: store
120 ;void bar4(foo_t *f, unsigned n) {
121 ;  for (unsigned i = 0; i < n; ++i) {
122 ;    f[i].a = 0;
123 ;    f[i].b = 1;
124 ;  }
126 define void @bar4(%struct.foo* nocapture %f, i32 %n) nounwind ssp {
127 entry:
128   %cmp1 = icmp eq i32 %n, 0
129   br i1 %cmp1, label %for.end, label %for.body.preheader
131 for.body.preheader:                               ; preds = %entry
132   br label %for.body
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
146   br label %for.end
148 for.end:                                          ; preds = %for.end.loopexit, %entry
149   ret void
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) {
156 ;    f[i].a = 1;
157 ;    f[i].b = 1;
158 ;  }
160 define void @bar5(%struct.foo1* nocapture %f, i32 %n) nounwind ssp {
161 entry:
162   %cmp1 = icmp eq i32 %n, 0
163   br i1 %cmp1, label %for.end, label %for.body.preheader
165 for.body.preheader:                               ; preds = %entry
166   br label %for.body
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
180   br label %for.end
182 for.end:                                          ; preds = %for.end.loopexit, %entry
183   ret void
184 ; CHECK-LABEL: @bar5(
185 ; CHECK-NOT: call void @memset_pattern16