Silence -Wunused-variable in release builds.
[llvm/stm8.git] / test / Transforms / LoopIdiom / basic.ll
blob969541813aef443f6d341ad910d0131f5ed91070
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 target triple = "x86_64-apple-darwin10.0.0"
5 define void @test1(i8* %Base, i64 %Size) nounwind ssp {
6 bb.nph:                                           ; preds = %entry
7   br label %for.body
9 for.body:                                         ; preds = %bb.nph, %for.body
10   %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ]
11   %I.0.014 = getelementptr i8* %Base, i64 %indvar
12   store i8 0, i8* %I.0.014, align 1
13   %indvar.next = add i64 %indvar, 1
14   %exitcond = icmp eq i64 %indvar.next, %Size
15   br i1 %exitcond, label %for.end, label %for.body
17 for.end:                                          ; preds = %for.body, %entry
18   ret void
19 ; CHECK: @test1
20 ; CHECK: call void @llvm.memset.p0i8.i64(i8* %Base, i8 0, i64 %Size, i32 1, i1 false)
21 ; CHECK-NOT: store
24 ; This is a loop that was rotated but where the blocks weren't merged.  This
25 ; shouldn't perturb us.
26 define void @test1a(i8* %Base, i64 %Size) nounwind ssp {
27 bb.nph:                                           ; preds = %entry
28   br label %for.body
30 for.body:                                         ; preds = %bb.nph, %for.body
31   %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body.cont ]
32   %I.0.014 = getelementptr i8* %Base, i64 %indvar
33   store i8 0, i8* %I.0.014, align 1
34   %indvar.next = add i64 %indvar, 1
35   br label %for.body.cont
36 for.body.cont:
37   %exitcond = icmp eq i64 %indvar.next, %Size
38   br i1 %exitcond, label %for.end, label %for.body
40 for.end:                                          ; preds = %for.body, %entry
41   ret void
42 ; CHECK: @test1a
43 ; CHECK: call void @llvm.memset.p0i8.i64(i8* %Base, i8 0, i64 %Size, i32 1, i1 false)
44 ; CHECK-NOT: store
48 define void @test2(i32* %Base, i64 %Size) nounwind ssp {
49 entry:
50   %cmp10 = icmp eq i64 %Size, 0
51   br i1 %cmp10, label %for.end, label %for.body
53 for.body:                                         ; preds = %entry, %for.body
54   %i.011 = phi i64 [ %inc, %for.body ], [ 0, %entry ]
55   %add.ptr.i = getelementptr i32* %Base, i64 %i.011
56   store i32 16843009, i32* %add.ptr.i, align 4
57   %inc = add nsw i64 %i.011, 1
58   %exitcond = icmp eq i64 %inc, %Size
59   br i1 %exitcond, label %for.end, label %for.body
61 for.end:                                          ; preds = %for.body, %entry
62   ret void
63 ; CHECK: @test2
64 ; CHECK: br i1 %cmp10,
65 ; CHECK: %tmp = mul i64 %Size, 4
66 ; CHECK: call void @llvm.memset.p0i8.i64(i8* %Base1, i8 1, i64 %tmp, i32 4, i1 false)
67 ; CHECK-NOT: store
70 ; This is a case where there is an extra may-aliased store in the loop, we can't
71 ; promote the memset.
72 define void @test3(i32* %Base, i64 %Size, i8 *%MayAlias) nounwind ssp {
73 entry:
74   br label %for.body
76 for.body:                                         ; preds = %entry, %for.body
77   %i.011 = phi i64 [ %inc, %for.body ], [ 0, %entry ]
78   %add.ptr.i = getelementptr i32* %Base, i64 %i.011
79   store i32 16843009, i32* %add.ptr.i, align 4
80   
81   store i8 42, i8* %MayAlias
82   %inc = add nsw i64 %i.011, 1
83   %exitcond = icmp eq i64 %inc, %Size
84   br i1 %exitcond, label %for.end, label %for.body
86 for.end:                                          ; preds = %entry
87   ret void
88 ; CHECK: @test3
89 ; CHECK-NOT: memset
90 ; CHECK: ret void
94 ;; TODO: We should be able to promote this memset.  Not yet though.
95 define void @test4(i8* %Base) nounwind ssp {
96 bb.nph:                                           ; preds = %entry
97   %Base100 = getelementptr i8* %Base, i64 1000
98   br label %for.body
100 for.body:                                         ; preds = %bb.nph, %for.body
101   %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ]
102   %I.0.014 = getelementptr i8* %Base, i64 %indvar
103   store i8 0, i8* %I.0.014, align 1
104   
105   ;; Store beyond the range memset, should be safe to promote.
106   store i8 42, i8* %Base100
107   
108   %indvar.next = add i64 %indvar, 1
109   %exitcond = icmp eq i64 %indvar.next, 100
110   br i1 %exitcond, label %for.end, label %for.body
112 for.end:                                          ; preds = %for.body, %entry
113   ret void
114 ; CHECK-TODO: @test4
115 ; CHECK-TODO: call void @llvm.memset.p0i8.i64(i8* %Base, i8 0, i64 100, i32 1, i1 false)
116 ; CHECK-TODO-NOT: store
119 ; This can't be promoted: the memset is a store of a loop variant value.
120 define void @test5(i8* %Base, i64 %Size) nounwind ssp {
121 bb.nph:                                           ; preds = %entry
122   br label %for.body
124 for.body:                                         ; preds = %bb.nph, %for.body
125   %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ]
126   %I.0.014 = getelementptr i8* %Base, i64 %indvar
127   
128   %V = trunc i64 %indvar to i8
129   store i8 %V, i8* %I.0.014, align 1
130   %indvar.next = add i64 %indvar, 1
131   %exitcond = icmp eq i64 %indvar.next, %Size
132   br i1 %exitcond, label %for.end, label %for.body
134 for.end:                                          ; preds = %for.body, %entry
135   ret void
136 ; CHECK: @test5
137 ; CHECK-NOT: memset
138 ; CHECK: ret void
142 ;; memcpy formation
143 define void @test6(i64 %Size) nounwind ssp {
144 bb.nph:
145   %Base = alloca i8, i32 10000
146   %Dest = alloca i8, i32 10000
147   br label %for.body
149 for.body:                                         ; preds = %bb.nph, %for.body
150   %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ]
151   %I.0.014 = getelementptr i8* %Base, i64 %indvar
152   %DestI = getelementptr i8* %Dest, i64 %indvar
153   %V = load i8* %I.0.014, align 1
154   store i8 %V, i8* %DestI, align 1
155   %indvar.next = add i64 %indvar, 1
156   %exitcond = icmp eq i64 %indvar.next, %Size
157   br i1 %exitcond, label %for.end, label %for.body
159 for.end:                                          ; preds = %for.body, %entry
160   ret void
161 ; CHECK: @test6
162 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %Dest, i8* %Base, i64 %Size, i32 1, i1 false)
163 ; CHECK-NOT: store
164 ; CHECK: ret void
168 ; This is a loop that was rotated but where the blocks weren't merged.  This
169 ; shouldn't perturb us.
170 define void @test7(i8* %Base, i64 %Size) nounwind ssp {
171 bb.nph:                                           ; preds = %entry
172   br label %for.body
174 for.body:                                         ; preds = %bb.nph, %for.body
175   %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body.cont ]
176   br label %for.body.cont
177 for.body.cont:
178   %I.0.014 = getelementptr i8* %Base, i64 %indvar
179   store i8 0, i8* %I.0.014, align 1
180   %indvar.next = add i64 %indvar, 1
181   %exitcond = icmp eq i64 %indvar.next, %Size
182   br i1 %exitcond, label %for.end, label %for.body
184 for.end:                                          ; preds = %for.body, %entry
185   ret void
186 ; CHECK: @test7
187 ; CHECK: call void @llvm.memset.p0i8.i64(i8* %Base, i8 0, i64 %Size, i32 1, i1 false)
188 ; CHECK-NOT: store
191 ; This is a loop should not be transformed, it only executes one iteration.
192 define void @test8(i64* %Ptr, i64 %Size) nounwind ssp {
193 bb.nph:                                           ; preds = %entry
194   br label %for.body
196 for.body:                                         ; preds = %bb.nph, %for.body
197   %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ]
198   %PI = getelementptr i64* %Ptr, i64 %indvar
199   store i64 0, i64 *%PI
200   %indvar.next = add i64 %indvar, 1
201   %exitcond = icmp eq i64 %indvar.next, 1
202   br i1 %exitcond, label %for.end, label %for.body
204 for.end:                                          ; preds = %for.body, %entry
205   ret void
206 ; CHECK: @test8
207 ; CHECK: store i64 0, i64* %PI
210 declare i8* @external(i8*)
212 ;; This cannot be transformed into a memcpy, because the read-from location is
213 ;; mutated by the loop.
214 define void @test9(i64 %Size) nounwind ssp {
215 bb.nph:
216   %Base = alloca i8, i32 10000
217   %Dest = alloca i8, i32 10000
218   
219   %BaseAlias = call i8* @external(i8* %Base)
220   br label %for.body
222 for.body:                                         ; preds = %bb.nph, %for.body
223   %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body ]
224   %I.0.014 = getelementptr i8* %Base, i64 %indvar
225   %DestI = getelementptr i8* %Dest, i64 %indvar
226   %V = load i8* %I.0.014, align 1
227   store i8 %V, i8* %DestI, align 1
229   ;; This store can clobber the input.
230   store i8 4, i8* %BaseAlias
232   %indvar.next = add i64 %indvar, 1
233   %exitcond = icmp eq i64 %indvar.next, %Size
234   br i1 %exitcond, label %for.end, label %for.body
236 for.end:                                          ; preds = %for.body, %entry
237   ret void
238 ; CHECK: @test9
239 ; CHECK-NOT: llvm.memcpy
240 ; CHECK: ret void
243 ; Two dimensional nested loop should be promoted to one big memset.
244 define void @test10(i8* %X) nounwind ssp {
245 entry:
246   br label %bb.nph
248 bb.nph:                                           ; preds = %entry, %for.inc10
249   %i.04 = phi i32 [ 0, %entry ], [ %inc12, %for.inc10 ]
250   br label %for.body5
252 for.body5:                                        ; preds = %for.body5, %bb.nph
253   %j.02 = phi i32 [ 0, %bb.nph ], [ %inc, %for.body5 ]
254   %mul = mul nsw i32 %i.04, 100
255   %add = add nsw i32 %j.02, %mul
256   %idxprom = sext i32 %add to i64
257   %arrayidx = getelementptr inbounds i8* %X, i64 %idxprom
258   store i8 0, i8* %arrayidx, align 1
259   %inc = add nsw i32 %j.02, 1
260   %cmp4 = icmp eq i32 %inc, 100
261   br i1 %cmp4, label %for.inc10, label %for.body5
263 for.inc10:                                        ; preds = %for.body5
264   %inc12 = add nsw i32 %i.04, 1
265   %cmp = icmp eq i32 %inc12, 100
266   br i1 %cmp, label %for.end13, label %bb.nph
268 for.end13:                                        ; preds = %for.inc10
269   ret void
270 ; CHECK: @test10
271 ; CHECK: entry:
272 ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %X, i8 0, i64 10000, i32 1, i1 false)
273 ; CHECK-NOT: store
274 ; CHECK: ret void
277 ; On darwin10 (which is the triple in this .ll file) this loop can be turned
278 ; into a memset_pattern call.
279 ; rdar://9009151
280 define void @test11_pattern(i32* nocapture %P) nounwind ssp {
281 entry:
282   br label %for.body
284 for.body:                                         ; preds = %entry, %for.body
285   %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ]
286   %arrayidx = getelementptr i32* %P, i64 %indvar
287   store i32 1, i32* %arrayidx, align 4
288   %indvar.next = add i64 %indvar, 1
289   %exitcond = icmp eq i64 %indvar.next, 10000
290   br i1 %exitcond, label %for.end, label %for.body
292 for.end:                                          ; preds = %for.body
293   ret void
294 ; CHECK: @test11_pattern
295 ; CHECK-NEXT: entry:
296 ; CHECK-NEXT: bitcast
297 ; CHECK-NEXT: memset_pattern
298 ; CHECK-NOT: store
299 ; CHECK: ret void
302 ; Store of null should turn into memset of zero.
303 define void @test12(i32** nocapture %P) nounwind ssp {
304 entry:
305   br label %for.body
307 for.body:                                         ; preds = %entry, %for.body
308   %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ]
309   %arrayidx = getelementptr i32** %P, i64 %indvar
310   store i32* null, i32** %arrayidx, align 4
311   %indvar.next = add i64 %indvar, 1
312   %exitcond = icmp eq i64 %indvar.next, 10000
313   br i1 %exitcond, label %for.end, label %for.body
315 for.end:                                          ; preds = %for.body
316   ret void
317 ; CHECK: @test12
318 ; CHECK-NEXT: entry:
319 ; CHECK-NEXT: bitcast
320 ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %P1, i8 0, i64 80000, i32 4, i1 false)
321 ; CHECK-NOT: store
322 ; CHECK: ret void
325 @G = global i32 5
327 ; This store-of-address loop can be turned into a memset_pattern call.
328 ; rdar://9009151
329 define void @test13_pattern(i32** nocapture %P) nounwind ssp {
330 entry:
331   br label %for.body
333 for.body:                                         ; preds = %entry, %for.body
334   %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ]
335   %arrayidx = getelementptr i32** %P, i64 %indvar
336   store i32* @G, i32** %arrayidx, align 4
337   %indvar.next = add i64 %indvar, 1
338   %exitcond = icmp eq i64 %indvar.next, 10000
339   br i1 %exitcond, label %for.end, label %for.body
341 for.end:                                          ; preds = %for.body
342   ret void
343 ; CHECK: @test13_pattern
344 ; CHECK-NEXT: entry:
345 ; CHECK-NEXT: bitcast
346 ; CHECK-NEXT: memset_pattern
347 ; CHECK-NOT: store
348 ; CHECK: ret void
353 ; PR9815 - This is a partial overlap case that cannot be safely transformed
354 ; into a memcpy.
355 @g_50 = global [7 x i32] [i32 0, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0], align 16
357 define i32 @test14() nounwind {
358 entry:
359   br label %for.body
361 for.body:                                         ; preds = %for.inc, %for.body.lr.ph
362   %tmp5 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
363   %add = add nsw i32 %tmp5, 4
364   %idxprom = sext i32 %add to i64
365   %arrayidx = getelementptr inbounds [7 x i32]* @g_50, i32 0, i64 %idxprom
366   %tmp2 = load i32* %arrayidx, align 4
367   %add4 = add nsw i32 %tmp5, 5
368   %idxprom5 = sext i32 %add4 to i64
369   %arrayidx6 = getelementptr inbounds [7 x i32]* @g_50, i32 0, i64 %idxprom5
370   store i32 %tmp2, i32* %arrayidx6, align 4
371   %inc = add nsw i32 %tmp5, 1
372   %cmp = icmp slt i32 %inc, 2
373   br i1 %cmp, label %for.body, label %for.end
375 for.end:                                          ; preds = %for.inc
376   %tmp8 = load i32* getelementptr inbounds ([7 x i32]* @g_50, i32 0, i64 6), align 4
377   ret i32 %tmp8
378 ; CHECK: @test14
379 ; CHECK: for.body:
380 ; CHECK: load i32
381 ; CHECK: store i32
382 ; CHECK: br i1 %cmp