e1a3d8836a1a556fa96b13b04d86535e30256482
[oota-llvm.git] / test / Transforms / BBVectorize / simple-int.ll
1 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"
2 ; RUN: opt < %s -bb-vectorize -bb-vectorize-req-chain-depth=3 -bb-vectorize-ignore-target-info -instcombine -gvn -S | FileCheck %s
3
4 declare double @llvm.fma.f64(double, double, double)
5 declare double @llvm.fmuladd.f64(double, double, double)
6 declare double @llvm.cos.f64(double)
7 declare double @llvm.powi.f64(double, i32)
8 declare double @llvm.round.f64(double)
9 declare double @llvm.copysign.f64(double, double)
10 declare double @llvm.ceil.f64(double)
11 declare double @llvm.nearbyint.f64(double)
12 declare double @llvm.rint.f64(double)
13 declare double @llvm.trunc.f64(double)
14 declare double @llvm.floor.f64(double)
15 declare double @llvm.fabs.f64(double)
16
17 ; Basic depth-3 chain with fma
18 define double @test1(double %A1, double %A2, double %B1, double %B2, double %C1, double %C2) {
19         %X1 = fsub double %A1, %B1
20         %X2 = fsub double %A2, %B2
21         %Y1 = call double @llvm.fma.f64(double %X1, double %A1, double %C1)
22         %Y2 = call double @llvm.fma.f64(double %X2, double %A2, double %C2)
23         %Z1 = fadd double %Y1, %B1
24         %Z2 = fadd double %Y2, %B2
25         %R  = fmul double %Z1, %Z2
26         ret double %R
27 ; CHECK-LABEL: @test1(
28 ; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
29 ; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
30 ; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
31 ; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
32 ; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
33 ; CHECK: %Y1.v.i2.1 = insertelement <2 x double> undef, double %C1, i32 0
34 ; CHECK: %Y1.v.i2.2 = insertelement <2 x double> %Y1.v.i2.1, double %C2, i32 1
35 ; CHECK: %Y1 = call <2 x double> @llvm.fma.v2f64(<2 x double> %X1, <2 x double> %X1.v.i0.2, <2 x double> %Y1.v.i2.2)
36 ; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
37 ; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
38 ; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
39 ; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
40 ; CHECK: ret double %R
41 }
42
43 ; Basic depth-3 chain with fmuladd
44 define double @test1a(double %A1, double %A2, double %B1, double %B2, double %C1, double %C2) {
45         %X1 = fsub double %A1, %B1
46         %X2 = fsub double %A2, %B2
47         %Y1 = call double @llvm.fmuladd.f64(double %X1, double %A1, double %C1)
48         %Y2 = call double @llvm.fmuladd.f64(double %X2, double %A2, double %C2)
49         %Z1 = fadd double %Y1, %B1
50         %Z2 = fadd double %Y2, %B2
51         %R  = fmul double %Z1, %Z2
52         ret double %R
53 ; CHECK-LABEL: @test1a(
54 ; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
55 ; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
56 ; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
57 ; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
58 ; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
59 ; CHECK: %Y1.v.i2.1 = insertelement <2 x double> undef, double %C1, i32 0
60 ; CHECK: %Y1.v.i2.2 = insertelement <2 x double> %Y1.v.i2.1, double %C2, i32 1
61 ; CHECK: %Y1 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %X1, <2 x double> %X1.v.i0.2, <2 x double> %Y1.v.i2.2)
62 ; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
63 ; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
64 ; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
65 ; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
66 ; CHECK: ret double %R
67 }
68
69 ; Basic depth-3 chain with cos
70 define double @test2(double %A1, double %A2, double %B1, double %B2) {
71         %X1 = fsub double %A1, %B1
72         %X2 = fsub double %A2, %B2
73         %Y1 = call double @llvm.cos.f64(double %X1)
74         %Y2 = call double @llvm.cos.f64(double %X2)
75         %Z1 = fadd double %Y1, %B1
76         %Z2 = fadd double %Y2, %B2
77         %R  = fmul double %Z1, %Z2
78         ret double %R
79 ; CHECK-LABEL: @test2(
80 ; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
81 ; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
82 ; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
83 ; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
84 ; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
85 ; CHECK: %Y1 = call <2 x double> @llvm.cos.v2f64(<2 x double> %X1)
86 ; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
87 ; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
88 ; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
89 ; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
90 ; CHECK: ret double %R
91 }
92
93 ; Basic depth-3 chain with powi
94 define double @test3(double %A1, double %A2, double %B1, double %B2, i32 %P) {
95
96         %X1 = fsub double %A1, %B1
97         %X2 = fsub double %A2, %B2
98         %Y1 = call double @llvm.powi.f64(double %X1, i32 %P)
99         %Y2 = call double @llvm.powi.f64(double %X2, i32 %P)
100         %Z1 = fadd double %Y1, %B1
101         %Z2 = fadd double %Y2, %B2
102         %R  = fmul double %Z1, %Z2
103         ret double %R
104 ; CHECK-LABEL: @test3(
105 ; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
106 ; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
107 ; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
108 ; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
109 ; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
110 ; CHECK: %Y1 = call <2 x double> @llvm.powi.v2f64(<2 x double> %X1, i32 %P)
111 ; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
112 ; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
113 ; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
114 ; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
115 ; CHECK: ret double %R
116 }
117
118 ; Basic depth-3 chain with powi (different powers: should not vectorize)
119 define double @test4(double %A1, double %A2, double %B1, double %B2, i32 %P) {
120
121         %X1 = fsub double %A1, %B1
122         %X2 = fsub double %A2, %B2
123         %P2 = add i32 %P, 1
124         %Y1 = call double @llvm.powi.f64(double %X1, i32 %P)
125         %Y2 = call double @llvm.powi.f64(double %X2, i32 %P2)
126         %Z1 = fadd double %Y1, %B1
127         %Z2 = fadd double %Y2, %B2
128         %R  = fmul double %Z1, %Z2
129         ret double %R
130 ; CHECK-LABEL: @test4(
131 ; CHECK-NOT: <2 x double>
132 ; CHECK: ret double %R
133 }
134
135 ; Basic depth-3 chain with round
136 define double @testround(double %A1, double %A2, double %B1, double %B2) {
137         %X1 = fsub double %A1, %B1
138         %X2 = fsub double %A2, %B2
139         %Y1 = call double @llvm.round.f64(double %X1)
140         %Y2 = call double @llvm.round.f64(double %X2)
141         %Z1 = fadd double %Y1, %B1
142         %Z2 = fadd double %Y2, %B2
143         %R  = fmul double %Z1, %Z2
144         ret double %R
145 ; CHECK: @testround
146 ; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
147 ; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
148 ; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
149 ; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
150 ; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
151 ; CHECK: %Y1 = call <2 x double> @llvm.round.v2f64(<2 x double> %X1)
152 ; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
153 ; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
154 ; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
155 ; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
156 ; CHECK: ret double %R
157
158 }
159
160 ; Basic depth-3 chain with copysign
161 define double @testcopysign(double %A1, double %A2, double %B1, double %B2) {
162         %X1 = fsub double %A1, %B1
163         %X2 = fsub double %A2, %B2
164         %Y1 = call double @llvm.copysign.f64(double %X1, double %A1)
165         %Y2 = call double @llvm.copysign.f64(double %X2, double %A1)
166         %Z1 = fadd double %Y1, %B1
167         %Z2 = fadd double %Y2, %B2
168         %R  = fmul double %Z1, %Z2
169         ret double %R
170 ; CHECK: @testcopysign
171 ; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
172 ; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
173 ; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
174 ; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
175 ; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
176 ; CHECK: %Y1.v.i1.2 = insertelement <2 x double> %X1.v.i0.1, double %A1, i32 1
177 ; CHECK: %Y1 = call <2 x double> @llvm.copysign.v2f64(<2 x double> %X1, <2 x double> %Y1.v.i1.2)
178 ; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
179 ; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
180 ; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
181 ; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
182 ; CHECK: ret double %R
183
184 }
185
186 ; Basic depth-3 chain with ceil
187 define double @testceil(double %A1, double %A2, double %B1, double %B2) {
188         %X1 = fsub double %A1, %B1
189         %X2 = fsub double %A2, %B2
190         %Y1 = call double @llvm.ceil.f64(double %X1)
191         %Y2 = call double @llvm.ceil.f64(double %X2)
192         %Z1 = fadd double %Y1, %B1
193         %Z2 = fadd double %Y2, %B2
194         %R  = fmul double %Z1, %Z2
195         ret double %R
196 ; CHECK: @testceil
197 ; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
198 ; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
199 ; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
200 ; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
201 ; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
202 ; CHECK: %Y1 = call <2 x double> @llvm.ceil.v2f64(<2 x double> %X1)
203 ; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
204 ; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
205 ; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
206 ; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
207 ; CHECK: ret double %R
208
209 }
210
211 ; Basic depth-3 chain with nearbyint
212 define double @testnearbyint(double %A1, double %A2, double %B1, double %B2) {
213         %X1 = fsub double %A1, %B1
214         %X2 = fsub double %A2, %B2
215         %Y1 = call double @llvm.nearbyint.f64(double %X1)
216         %Y2 = call double @llvm.nearbyint.f64(double %X2)
217         %Z1 = fadd double %Y1, %B1
218         %Z2 = fadd double %Y2, %B2
219         %R  = fmul double %Z1, %Z2
220         ret double %R
221 ; CHECK: @testnearbyint
222 ; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
223 ; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
224 ; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
225 ; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
226 ; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
227 ; CHECK: %Y1 = call <2 x double> @llvm.nearbyint.v2f64(<2 x double> %X1)
228 ; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
229 ; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
230 ; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
231 ; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
232 ; CHECK: ret double %R
233
234 }
235
236 ; Basic depth-3 chain with rint
237 define double @testrint(double %A1, double %A2, double %B1, double %B2) {
238         %X1 = fsub double %A1, %B1
239         %X2 = fsub double %A2, %B2
240         %Y1 = call double @llvm.rint.f64(double %X1)
241         %Y2 = call double @llvm.rint.f64(double %X2)
242         %Z1 = fadd double %Y1, %B1
243         %Z2 = fadd double %Y2, %B2
244         %R  = fmul double %Z1, %Z2
245         ret double %R
246 ; CHECK: @testrint
247 ; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
248 ; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
249 ; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
250 ; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
251 ; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
252 ; CHECK: %Y1 = call <2 x double> @llvm.rint.v2f64(<2 x double> %X1)
253 ; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
254 ; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
255 ; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
256 ; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
257 ; CHECK: ret double %R
258
259 }
260
261 ; Basic depth-3 chain with trunc
262 define double @testtrunc(double %A1, double %A2, double %B1, double %B2) {
263         %X1 = fsub double %A1, %B1
264         %X2 = fsub double %A2, %B2
265         %Y1 = call double @llvm.trunc.f64(double %X1)
266         %Y2 = call double @llvm.trunc.f64(double %X2)
267         %Z1 = fadd double %Y1, %B1
268         %Z2 = fadd double %Y2, %B2
269         %R  = fmul double %Z1, %Z2
270         ret double %R
271 ; CHECK: @testtrunc
272 ; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
273 ; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
274 ; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
275 ; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
276 ; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
277 ; CHECK: %Y1 = call <2 x double> @llvm.trunc.v2f64(<2 x double> %X1)
278 ; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
279 ; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
280 ; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
281 ; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
282 ; CHECK: ret double %R
283
284 }
285
286 ; Basic depth-3 chain with floor
287 define double @testfloor(double %A1, double %A2, double %B1, double %B2) {
288         %X1 = fsub double %A1, %B1
289         %X2 = fsub double %A2, %B2
290         %Y1 = call double @llvm.floor.f64(double %X1)
291         %Y2 = call double @llvm.floor.f64(double %X2)
292         %Z1 = fadd double %Y1, %B1
293         %Z2 = fadd double %Y2, %B2
294         %R  = fmul double %Z1, %Z2
295         ret double %R
296 ; CHECK: @testfloor
297 ; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
298 ; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
299 ; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
300 ; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
301 ; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
302 ; CHECK: %Y1 = call <2 x double> @llvm.floor.v2f64(<2 x double> %X1)
303 ; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
304 ; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
305 ; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
306 ; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
307 ; CHECK: ret double %R
308
309 }
310
311 ; Basic depth-3 chain with fabs
312 define double @testfabs(double %A1, double %A2, double %B1, double %B2) {
313         %X1 = fsub double %A1, %B1
314         %X2 = fsub double %A2, %B2
315         %Y1 = call double @llvm.fabs.f64(double %X1)
316         %Y2 = call double @llvm.fabs.f64(double %X2)
317         %Z1 = fadd double %Y1, %B1
318         %Z2 = fadd double %Y2, %B2
319         %R  = fmul double %Z1, %Z2
320         ret double %R
321 ; CHECK: @testfabs
322 ; CHECK: %X1.v.i1.1 = insertelement <2 x double> undef, double %B1, i32 0
323 ; CHECK: %X1.v.i1.2 = insertelement <2 x double> %X1.v.i1.1, double %B2, i32 1
324 ; CHECK: %X1.v.i0.1 = insertelement <2 x double> undef, double %A1, i32 0
325 ; CHECK: %X1.v.i0.2 = insertelement <2 x double> %X1.v.i0.1, double %A2, i32 1
326 ; CHECK: %X1 = fsub <2 x double> %X1.v.i0.2, %X1.v.i1.2
327 ; CHECK: %Y1 = call <2 x double> @llvm.fabs.v2f64(<2 x double> %X1)
328 ; CHECK: %Z1 = fadd <2 x double> %Y1, %X1.v.i1.2
329 ; CHECK: %Z1.v.r1 = extractelement <2 x double> %Z1, i32 0
330 ; CHECK: %Z1.v.r2 = extractelement <2 x double> %Z1, i32 1
331 ; CHECK: %R = fmul double %Z1.v.r1, %Z1.v.r2
332 ; CHECK: ret double %R
333
334 }
335
336
337 ; CHECK: declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>) #0
338 ; CHECK: declare <2 x double> @llvm.fmuladd.v2f64(<2 x double>, <2 x double>, <2 x double>) #0
339 ; CHECK: declare <2 x double> @llvm.cos.v2f64(<2 x double>) #0
340 ; CHECK: declare <2 x double> @llvm.powi.v2f64(<2 x double>, i32) #0
341 ; CHECK: declare <2 x double> @llvm.round.v2f64(<2 x double>) #0
342 ; CHECK: declare <2 x double> @llvm.copysign.v2f64(<2 x double>, <2 x double>) #0
343 ; CHECK: declare <2 x double> @llvm.ceil.v2f64(<2 x double>) #0
344 ; CHECK: declare <2 x double> @llvm.nearbyint.v2f64(<2 x double>) #0
345 ; CHECK: declare <2 x double> @llvm.rint.v2f64(<2 x double>) #0
346 ; CHECK: declare <2 x double> @llvm.trunc.v2f64(<2 x double>) #0
347 ; CHECK: declare <2 x double> @llvm.floor.v2f64(<2 x double>) #0
348 ; CHECK: declare <2 x double> @llvm.fabs.v2f64(<2 x double>) #0
349 ; CHECK: attributes #0 = { nounwind readnone }