blob: 3fa6eb900b4aea75d66cb67529f27e0c32c325e1 [file] [log] [blame]
Chris Lattnera64cbf02011-01-01 19:54:22 +00001; RUN: opt -basicaa -loop-idiom < %s -S | FileCheck %s
Chris Lattnera92ff912010-12-26 23:42:51 +00002target 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"
3target triple = "x86_64-apple-darwin10.0.0"
4
5define void @test1(i8* %Base, i64 %Size) nounwind ssp {
6bb.nph: ; preds = %entry
7 br label %for.body
8
9for.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
16
17for.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
22}
23
Chris Lattnercf078f22011-01-02 07:58:36 +000024; This is a loop that was rotated but where the blocks weren't merged. This
25; shouldn't perturb us.
26define void @test1a(i8* %Base, i64 %Size) nounwind ssp {
27bb.nph: ; preds = %entry
28 br label %for.body
29
30for.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
36for.body.cont:
37 %exitcond = icmp eq i64 %indvar.next, %Size
38 br i1 %exitcond, label %for.end, label %for.body
39
40for.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
45}
46
47
Chris Lattnera92ff912010-12-26 23:42:51 +000048define void @test2(i32* %Base, i64 %Size) nounwind ssp {
49entry:
50 %cmp10 = icmp eq i64 %Size, 0
51 br i1 %cmp10, label %for.end, label %for.body
52
53for.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
60
61for.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
68}
Chris Lattner30980b62011-01-01 19:39:01 +000069
70; This is a case where there is an extra may-aliased store in the loop, we can't
71; promote the memset.
72define void @test3(i32* %Base, i64 %Size, i8 *%MayAlias) nounwind ssp {
73entry:
74 br label %for.body
75
76for.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
85
86for.end: ; preds = %entry
87 ret void
88; CHECK: @test3
89; CHECK-NOT: memset
90; CHECK: ret void
91}
Chris Lattnera64cbf02011-01-01 19:54:22 +000092
93
94;; TODO: We should be able to promote this memset. Not yet though.
95define void @test4(i8* %Base) nounwind ssp {
96bb.nph: ; preds = %entry
97 %Base100 = getelementptr i8* %Base, i64 1000
98 br label %for.body
99
100for.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
111
112for.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
117}
Chris Lattnerbafa1172011-01-01 20:12:04 +0000118
119; This can't be promoted: the memset is a store of a loop variant value.
120define void @test5(i8* %Base, i64 %Size) nounwind ssp {
121bb.nph: ; preds = %entry
122 br label %for.body
123
124for.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
133
134for.end: ; preds = %for.body, %entry
135 ret void
136; CHECK: @test5
137; CHECK-NOT: memset
138; CHECK: ret void
139}
140
Chris Lattnere2c43922011-01-02 03:37:56 +0000141
142;; memcpy formation
143define void @test6(i64 %Size) nounwind ssp {
144bb.nph:
145 %Base = alloca i8, i32 10000
146 %Dest = alloca i8, i32 10000
147 br label %for.body
148
149for.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
158
159for.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
165}
166
167
Chris Lattner62c50fd2011-01-02 19:01:03 +0000168; This is a loop that was rotated but where the blocks weren't merged. This
169; shouldn't perturb us.
170define void @test7(i8* %Base, i64 %Size) nounwind ssp {
171bb.nph: ; preds = %entry
172 br label %for.body
173
174for.body: ; preds = %bb.nph, %for.body
175 %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %for.body.cont ]
176 br label %for.body.cont
177for.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
183
184for.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
189}
190
Chris Lattnere2c43922011-01-02 03:37:56 +0000191