[mips][msa] Added support for matching fmadd.[wd] from normal IR (i.e. not intrinsics)
[oota-llvm.git] / test / CodeGen / Mips / msa / arithmetic_float.ll
1 ; RUN: llc -march=mips -mattr=+msa,+fp64 < %s | FileCheck %s
2
3 define void @add_v4f32(<4 x float>* %c, <4 x float>* %a, <4 x float>* %b) nounwind {
4   ; CHECK: add_v4f32:
5
6   %1 = load <4 x float>* %a
7   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
8   %2 = load <4 x float>* %b
9   ; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6)
10   %3 = fadd <4 x float> %1, %2
11   ; CHECK-DAG: fadd.w [[R3:\$w[0-9]+]], [[R1]], [[R2]]
12   store <4 x float> %3, <4 x float>* %c
13   ; CHECK-DAG: st.w [[R3]], 0($4)
14
15   ret void
16   ; CHECK: .size add_v4f32
17 }
18
19 define void @add_v2f64(<2 x double>* %c, <2 x double>* %a, <2 x double>* %b) nounwind {
20   ; CHECK: add_v2f64:
21
22   %1 = load <2 x double>* %a
23   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
24   %2 = load <2 x double>* %b
25   ; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6)
26   %3 = fadd <2 x double> %1, %2
27   ; CHECK-DAG: fadd.d [[R3:\$w[0-9]+]], [[R1]], [[R2]]
28   store <2 x double> %3, <2 x double>* %c
29   ; CHECK-DAG: st.d [[R3]], 0($4)
30
31   ret void
32   ; CHECK: .size add_v2f64
33 }
34
35 define void @sub_v4f32(<4 x float>* %c, <4 x float>* %a, <4 x float>* %b) nounwind {
36   ; CHECK: sub_v4f32:
37
38   %1 = load <4 x float>* %a
39   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
40   %2 = load <4 x float>* %b
41   ; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6)
42   %3 = fsub <4 x float> %1, %2
43   ; CHECK-DAG: fsub.w [[R3:\$w[0-9]+]], [[R1]], [[R2]]
44   store <4 x float> %3, <4 x float>* %c
45   ; CHECK-DAG: st.w [[R3]], 0($4)
46
47   ret void
48   ; CHECK: .size sub_v4f32
49 }
50
51 define void @sub_v2f64(<2 x double>* %c, <2 x double>* %a, <2 x double>* %b) nounwind {
52   ; CHECK: sub_v2f64:
53
54   %1 = load <2 x double>* %a
55   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
56   %2 = load <2 x double>* %b
57   ; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6)
58   %3 = fsub <2 x double> %1, %2
59   ; CHECK-DAG: fsub.d [[R3:\$w[0-9]+]], [[R1]], [[R2]]
60   store <2 x double> %3, <2 x double>* %c
61   ; CHECK-DAG: st.d [[R3]], 0($4)
62
63   ret void
64   ; CHECK: .size sub_v2f64
65 }
66
67 define void @mul_v4f32(<4 x float>* %c, <4 x float>* %a, <4 x float>* %b) nounwind {
68   ; CHECK: mul_v4f32:
69
70   %1 = load <4 x float>* %a
71   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
72   %2 = load <4 x float>* %b
73   ; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6)
74   %3 = fmul <4 x float> %1, %2
75   ; CHECK-DAG: fmul.w [[R3:\$w[0-9]+]], [[R1]], [[R2]]
76   store <4 x float> %3, <4 x float>* %c
77   ; CHECK-DAG: st.w [[R3]], 0($4)
78
79   ret void
80   ; CHECK: .size mul_v4f32
81 }
82
83 define void @mul_v2f64(<2 x double>* %c, <2 x double>* %a, <2 x double>* %b) nounwind {
84   ; CHECK: mul_v2f64:
85
86   %1 = load <2 x double>* %a
87   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
88   %2 = load <2 x double>* %b
89   ; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6)
90   %3 = fmul <2 x double> %1, %2
91   ; CHECK-DAG: fmul.d [[R3:\$w[0-9]+]], [[R1]], [[R2]]
92   store <2 x double> %3, <2 x double>* %c
93   ; CHECK-DAG: st.d [[R3]], 0($4)
94
95   ret void
96   ; CHECK: .size mul_v2f64
97 }
98
99 define void @fma_v4f32(<4 x float>* %d, <4 x float>* %a, <4 x float>* %b,
100                        <4 x float>* %c) nounwind {
101   ; CHECK: fma_v4f32:
102
103   %1 = load <4 x float>* %a
104   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
105   %2 = load <4 x float>* %b
106   ; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6)
107   %3 = load <4 x float>* %c
108   ; CHECK-DAG: ld.w [[R3:\$w[0-9]+]], 0($7)
109   %4 = tail call <4 x float> @llvm.fma.v4f32 (<4 x float> %1, <4 x float> %2,
110                                               <4 x float> %3)
111   ; CHECK-DAG: fmadd.w [[R1]], [[R2]], [[R3]]
112   store <4 x float> %4, <4 x float>* %d
113   ; CHECK-DAG: st.w [[R1]], 0($4)
114
115   ret void
116   ; CHECK: .size fma_v4f32
117 }
118
119 define void @fma_v2f64(<2 x double>* %d, <2 x double>* %a, <2 x double>* %b,
120                        <2 x double>* %c) nounwind {
121   ; CHECK: fma_v2f64:
122
123   %1 = load <2 x double>* %a
124   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
125   %2 = load <2 x double>* %b
126   ; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6)
127   %3 = load <2 x double>* %c
128   ; CHECK-DAG: ld.d [[R3:\$w[0-9]+]], 0($7)
129   %4 = tail call <2 x double> @llvm.fma.v2f64 (<2 x double> %1, <2 x double> %2,
130                                                <2 x double> %3)
131   ; CHECK-DAG: fmadd.d [[R1]], [[R2]], [[R3]]
132   store <2 x double> %4, <2 x double>* %d
133   ; CHECK-DAG: st.d [[R1]], 0($4)
134
135   ret void
136   ; CHECK: .size fma_v2f64
137 }
138
139 define void @fdiv_v4f32(<4 x float>* %c, <4 x float>* %a, <4 x float>* %b) nounwind {
140   ; CHECK: fdiv_v4f32:
141
142   %1 = load <4 x float>* %a
143   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
144   %2 = load <4 x float>* %b
145   ; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6)
146   %3 = fdiv <4 x float> %1, %2
147   ; CHECK-DAG: fdiv.w [[R3:\$w[0-9]+]], [[R1]], [[R2]]
148   store <4 x float> %3, <4 x float>* %c
149   ; CHECK-DAG: st.w [[R3]], 0($4)
150
151   ret void
152   ; CHECK: .size fdiv_v4f32
153 }
154
155 define void @fdiv_v2f64(<2 x double>* %c, <2 x double>* %a, <2 x double>* %b) nounwind {
156   ; CHECK: fdiv_v2f64:
157
158   %1 = load <2 x double>* %a
159   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
160   %2 = load <2 x double>* %b
161   ; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6)
162   %3 = fdiv <2 x double> %1, %2
163   ; CHECK-DAG: fdiv.d [[R3:\$w[0-9]+]], [[R1]], [[R2]]
164   store <2 x double> %3, <2 x double>* %c
165   ; CHECK-DAG: st.d [[R3]], 0($4)
166
167   ret void
168   ; CHECK: .size fdiv_v2f64
169 }
170
171 define void @fabs_v4f32(<4 x float>* %c, <4 x float>* %a) nounwind {
172   ; CHECK: fabs_v4f32:
173
174   %1 = load <4 x float>* %a
175   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
176   %2 = tail call <4 x float> @llvm.fabs.v4f32 (<4 x float> %1)
177   ; CHECK-DAG: fmax_a.w [[R3:\$w[0-9]+]], [[R1]], [[R1]]
178   store <4 x float> %2, <4 x float>* %c
179   ; CHECK-DAG: st.w [[R3]], 0($4)
180
181   ret void
182   ; CHECK: .size fabs_v4f32
183 }
184
185 define void @fabs_v2f64(<2 x double>* %c, <2 x double>* %a) nounwind {
186   ; CHECK: fabs_v2f64:
187
188   %1 = load <2 x double>* %a
189   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
190   %2 = tail call <2 x double> @llvm.fabs.v2f64 (<2 x double> %1)
191   ; CHECK-DAG: fmax_a.d [[R3:\$w[0-9]+]], [[R1]], [[R1]]
192   store <2 x double> %2, <2 x double>* %c
193   ; CHECK-DAG: st.d [[R3]], 0($4)
194
195   ret void
196   ; CHECK: .size fabs_v2f64
197 }
198
199 define void @fsqrt_v4f32(<4 x float>* %c, <4 x float>* %a) nounwind {
200   ; CHECK: fsqrt_v4f32:
201
202   %1 = load <4 x float>* %a
203   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
204   %2 = tail call <4 x float> @llvm.sqrt.v4f32 (<4 x float> %1)
205   ; CHECK-DAG: fsqrt.w [[R3:\$w[0-9]+]], [[R1]]
206   store <4 x float> %2, <4 x float>* %c
207   ; CHECK-DAG: st.w [[R3]], 0($4)
208
209   ret void
210   ; CHECK: .size fsqrt_v4f32
211 }
212
213 define void @fsqrt_v2f64(<2 x double>* %c, <2 x double>* %a) nounwind {
214   ; CHECK: fsqrt_v2f64:
215
216   %1 = load <2 x double>* %a
217   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
218   %2 = tail call <2 x double> @llvm.sqrt.v2f64 (<2 x double> %1)
219   ; CHECK-DAG: fsqrt.d [[R3:\$w[0-9]+]], [[R1]]
220   store <2 x double> %2, <2 x double>* %c
221   ; CHECK-DAG: st.d [[R3]], 0($4)
222
223   ret void
224   ; CHECK: .size fsqrt_v2f64
225 }
226
227 define void @ffint_u_v4f32(<4 x float>* %c, <4 x i32>* %a) nounwind {
228   ; CHECK: ffint_u_v4f32:
229
230   %1 = load <4 x i32>* %a
231   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
232   %2 = uitofp <4 x i32> %1 to <4 x float>
233   ; CHECK-DAG: ffint_u.w [[R3:\$w[0-9]+]], [[R1]]
234   store <4 x float> %2, <4 x float>* %c
235   ; CHECK-DAG: st.w [[R3]], 0($4)
236
237   ret void
238   ; CHECK: .size ffint_u_v4f32
239 }
240
241 define void @ffint_u_v2f64(<2 x double>* %c, <2 x i64>* %a) nounwind {
242   ; CHECK: ffint_u_v2f64:
243
244   %1 = load <2 x i64>* %a
245   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
246   %2 = uitofp <2 x i64> %1 to <2 x double>
247   ; CHECK-DAG: ffint_u.d [[R3:\$w[0-9]+]], [[R1]]
248   store <2 x double> %2, <2 x double>* %c
249   ; CHECK-DAG: st.d [[R3]], 0($4)
250
251   ret void
252   ; CHECK: .size ffint_u_v2f64
253 }
254
255 define void @ffint_s_v4f32(<4 x float>* %c, <4 x i32>* %a) nounwind {
256   ; CHECK: ffint_s_v4f32:
257
258   %1 = load <4 x i32>* %a
259   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
260   %2 = sitofp <4 x i32> %1 to <4 x float>
261   ; CHECK-DAG: ffint_s.w [[R3:\$w[0-9]+]], [[R1]]
262   store <4 x float> %2, <4 x float>* %c
263   ; CHECK-DAG: st.w [[R3]], 0($4)
264
265   ret void
266   ; CHECK: .size ffint_s_v4f32
267 }
268
269 define void @ffint_s_v2f64(<2 x double>* %c, <2 x i64>* %a) nounwind {
270   ; CHECK: ffint_s_v2f64:
271
272   %1 = load <2 x i64>* %a
273   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
274   %2 = sitofp <2 x i64> %1 to <2 x double>
275   ; CHECK-DAG: ffint_s.d [[R3:\$w[0-9]+]], [[R1]]
276   store <2 x double> %2, <2 x double>* %c
277   ; CHECK-DAG: st.d [[R3]], 0($4)
278
279   ret void
280   ; CHECK: .size ffint_s_v2f64
281 }
282
283 define void @ftrunc_u_v4f32(<4 x i32>* %c, <4 x float>* %a) nounwind {
284   ; CHECK: ftrunc_u_v4f32:
285
286   %1 = load <4 x float>* %a
287   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
288   %2 = fptoui <4 x float> %1 to <4 x i32>
289   ; CHECK-DAG: ftrunc_u.w [[R3:\$w[0-9]+]], [[R1]]
290   store <4 x i32> %2, <4 x i32>* %c
291   ; CHECK-DAG: st.w [[R3]], 0($4)
292
293   ret void
294   ; CHECK: .size ftrunc_u_v4f32
295 }
296
297 define void @ftrunc_u_v2f64(<2 x i64>* %c, <2 x double>* %a) nounwind {
298   ; CHECK: ftrunc_u_v2f64:
299
300   %1 = load <2 x double>* %a
301   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
302   %2 = fptoui <2 x double> %1 to <2 x i64>
303   ; CHECK-DAG: ftrunc_u.d [[R3:\$w[0-9]+]], [[R1]]
304   store <2 x i64> %2, <2 x i64>* %c
305   ; CHECK-DAG: st.d [[R3]], 0($4)
306
307   ret void
308   ; CHECK: .size ftrunc_u_v2f64
309 }
310
311 define void @ftrunc_s_v4f32(<4 x i32>* %c, <4 x float>* %a) nounwind {
312   ; CHECK: ftrunc_s_v4f32:
313
314   %1 = load <4 x float>* %a
315   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
316   %2 = fptosi <4 x float> %1 to <4 x i32>
317   ; CHECK-DAG: ftrunc_s.w [[R3:\$w[0-9]+]], [[R1]]
318   store <4 x i32> %2, <4 x i32>* %c
319   ; CHECK-DAG: st.w [[R3]], 0($4)
320
321   ret void
322   ; CHECK: .size ftrunc_s_v4f32
323 }
324
325 define void @ftrunc_s_v2f64(<2 x i64>* %c, <2 x double>* %a) nounwind {
326   ; CHECK: ftrunc_s_v2f64:
327
328   %1 = load <2 x double>* %a
329   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
330   %2 = fptosi <2 x double> %1 to <2 x i64>
331   ; CHECK-DAG: ftrunc_s.d [[R3:\$w[0-9]+]], [[R1]]
332   store <2 x i64> %2, <2 x i64>* %c
333   ; CHECK-DAG: st.d [[R3]], 0($4)
334
335   ret void
336   ; CHECK: .size ftrunc_s_v2f64
337 }
338
339 declare <4 x float>  @llvm.fabs.v4f32(<4 x float>  %Val)
340 declare <2 x double> @llvm.fabs.v2f64(<2 x double> %Val)
341 declare <4 x float>  @llvm.fma.v4f32(<4 x float>  %a, <4 x float>  %b,
342                                      <4 x float>  %c)
343 declare <2 x double> @llvm.fma.v2f64(<2 x double> %a, <2 x double> %b,
344                                      <2 x double> %c)
345 declare <4 x float>  @llvm.sqrt.v4f32(<4 x float>  %Val)
346 declare <2 x double> @llvm.sqrt.v2f64(<2 x double> %Val)