[mips][msa] Added support for matching and, or, and xor from normal IR (i.e. not...
[oota-llvm.git] / test / CodeGen / Mips / msa / bitwise.ll
1 ; RUN: llc -march=mips -mattr=+msa < %s | FileCheck %s
2
3 define void @and_v16i8(<16 x i8>* %c, <16 x i8>* %a, <16 x i8>* %b) nounwind {
4   ; CHECK: and_v16i8:
5
6   %1 = load <16 x i8>* %a
7   ; CHECK-DAG: ld.b [[R1:\$w[0-9]+]], 0($5)
8   %2 = load <16 x i8>* %b
9   ; CHECK-DAG: ld.b [[R2:\$w[0-9]+]], 0($6)
10   %3 = and <16 x i8> %1, %2
11   ; CHECK-DAG: and.v [[R3:\$w[0-9]+]], [[R1]], [[R2]]
12   store <16 x i8> %3, <16 x i8>* %c
13   ; CHECK-DAG: st.b [[R3]], 0($4)
14
15   ret void
16   ; CHECK: .size and_v16i8
17 }
18
19 define void @and_v8i16(<8 x i16>* %c, <8 x i16>* %a, <8 x i16>* %b) nounwind {
20   ; CHECK: and_v8i16:
21
22   %1 = load <8 x i16>* %a
23   ; CHECK-DAG: ld.h [[R1:\$w[0-9]+]], 0($5)
24   %2 = load <8 x i16>* %b
25   ; CHECK-DAG: ld.h [[R2:\$w[0-9]+]], 0($6)
26   %3 = and <8 x i16> %1, %2
27   ; CHECK-DAG: and.v [[R3:\$w[0-9]+]], [[R1]], [[R2]]
28   store <8 x i16> %3, <8 x i16>* %c
29   ; CHECK-DAG: st.h [[R3]], 0($4)
30
31   ret void
32   ; CHECK: .size and_v8i16
33 }
34
35 define void @and_v4i32(<4 x i32>* %c, <4 x i32>* %a, <4 x i32>* %b) nounwind {
36   ; CHECK: and_v4i32:
37
38   %1 = load <4 x i32>* %a
39   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
40   %2 = load <4 x i32>* %b
41   ; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6)
42   %3 = and <4 x i32> %1, %2
43   ; CHECK-DAG: and.v [[R3:\$w[0-9]+]], [[R1]], [[R2]]
44   store <4 x i32> %3, <4 x i32>* %c
45   ; CHECK-DAG: st.w [[R3]], 0($4)
46
47   ret void
48   ; CHECK: .size and_v4i32
49 }
50
51 define void @and_v2i64(<2 x i64>* %c, <2 x i64>* %a, <2 x i64>* %b) nounwind {
52   ; CHECK: and_v2i64:
53
54   %1 = load <2 x i64>* %a
55   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
56   %2 = load <2 x i64>* %b
57   ; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6)
58   %3 = and <2 x i64> %1, %2
59   ; CHECK-DAG: and.v [[R3:\$w[0-9]+]], [[R1]], [[R2]]
60   store <2 x i64> %3, <2 x i64>* %c
61   ; CHECK-DAG: st.d [[R3]], 0($4)
62
63   ret void
64   ; CHECK: .size and_v2i64
65 }
66
67 define void @or_v16i8(<16 x i8>* %c, <16 x i8>* %a, <16 x i8>* %b) nounwind {
68   ; CHECK: or_v16i8:
69
70   %1 = load <16 x i8>* %a
71   ; CHECK-DAG: ld.b [[R1:\$w[0-9]+]], 0($5)
72   %2 = load <16 x i8>* %b
73   ; CHECK-DAG: ld.b [[R2:\$w[0-9]+]], 0($6)
74   %3 = or <16 x i8> %1, %2
75   ; CHECK-DAG: or.v [[R3:\$w[0-9]+]], [[R1]], [[R2]]
76   store <16 x i8> %3, <16 x i8>* %c
77   ; CHECK-DAG: st.b [[R3]], 0($4)
78
79   ret void
80   ; CHECK: .size or_v16i8
81 }
82
83 define void @or_v8i16(<8 x i16>* %c, <8 x i16>* %a, <8 x i16>* %b) nounwind {
84   ; CHECK: or_v8i16:
85
86   %1 = load <8 x i16>* %a
87   ; CHECK-DAG: ld.h [[R1:\$w[0-9]+]], 0($5)
88   %2 = load <8 x i16>* %b
89   ; CHECK-DAG: ld.h [[R2:\$w[0-9]+]], 0($6)
90   %3 = or <8 x i16> %1, %2
91   ; CHECK-DAG: or.v [[R3:\$w[0-9]+]], [[R1]], [[R2]]
92   store <8 x i16> %3, <8 x i16>* %c
93   ; CHECK-DAG: st.h [[R3]], 0($4)
94
95   ret void
96   ; CHECK: .size or_v8i16
97 }
98
99 define void @or_v4i32(<4 x i32>* %c, <4 x i32>* %a, <4 x i32>* %b) nounwind {
100   ; CHECK: or_v4i32:
101
102   %1 = load <4 x i32>* %a
103   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
104   %2 = load <4 x i32>* %b
105   ; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6)
106   %3 = or <4 x i32> %1, %2
107   ; CHECK-DAG: or.v [[R3:\$w[0-9]+]], [[R1]], [[R2]]
108   store <4 x i32> %3, <4 x i32>* %c
109   ; CHECK-DAG: st.w [[R3]], 0($4)
110
111   ret void
112   ; CHECK: .size or_v4i32
113 }
114
115 define void @or_v2i64(<2 x i64>* %c, <2 x i64>* %a, <2 x i64>* %b) nounwind {
116   ; CHECK: or_v2i64:
117
118   %1 = load <2 x i64>* %a
119   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
120   %2 = load <2 x i64>* %b
121   ; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6)
122   %3 = or <2 x i64> %1, %2
123   ; CHECK-DAG: or.v [[R3:\$w[0-9]+]], [[R1]], [[R2]]
124   store <2 x i64> %3, <2 x i64>* %c
125   ; CHECK-DAG: st.d [[R3]], 0($4)
126
127   ret void
128   ; CHECK: .size or_v2i64
129 }
130
131 define void @xor_v16i8(<16 x i8>* %c, <16 x i8>* %a, <16 x i8>* %b) nounwind {
132   ; CHECK: xor_v16i8:
133
134   %1 = load <16 x i8>* %a
135   ; CHECK-DAG: ld.b [[R1:\$w[0-9]+]], 0($5)
136   %2 = load <16 x i8>* %b
137   ; CHECK-DAG: ld.b [[R2:\$w[0-9]+]], 0($6)
138   %3 = xor <16 x i8> %1, %2
139   ; CHECK-DAG: xor.v [[R3:\$w[0-9]+]], [[R1]], [[R2]]
140   store <16 x i8> %3, <16 x i8>* %c
141   ; CHECK-DAG: st.b [[R3]], 0($4)
142
143   ret void
144   ; CHECK: .size xor_v16i8
145 }
146
147 define void @xor_v8i16(<8 x i16>* %c, <8 x i16>* %a, <8 x i16>* %b) nounwind {
148   ; CHECK: xor_v8i16:
149
150   %1 = load <8 x i16>* %a
151   ; CHECK-DAG: ld.h [[R1:\$w[0-9]+]], 0($5)
152   %2 = load <8 x i16>* %b
153   ; CHECK-DAG: ld.h [[R2:\$w[0-9]+]], 0($6)
154   %3 = xor <8 x i16> %1, %2
155   ; CHECK-DAG: xor.v [[R3:\$w[0-9]+]], [[R1]], [[R2]]
156   store <8 x i16> %3, <8 x i16>* %c
157   ; CHECK-DAG: st.h [[R3]], 0($4)
158
159   ret void
160   ; CHECK: .size xor_v8i16
161 }
162
163 define void @xor_v4i32(<4 x i32>* %c, <4 x i32>* %a, <4 x i32>* %b) nounwind {
164   ; CHECK: xor_v4i32:
165
166   %1 = load <4 x i32>* %a
167   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
168   %2 = load <4 x i32>* %b
169   ; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6)
170   %3 = xor <4 x i32> %1, %2
171   ; CHECK-DAG: xor.v [[R3:\$w[0-9]+]], [[R1]], [[R2]]
172   store <4 x i32> %3, <4 x i32>* %c
173   ; CHECK-DAG: st.w [[R3]], 0($4)
174
175   ret void
176   ; CHECK: .size xor_v4i32
177 }
178
179 define void @xor_v2i64(<2 x i64>* %c, <2 x i64>* %a, <2 x i64>* %b) nounwind {
180   ; CHECK: xor_v2i64:
181
182   %1 = load <2 x i64>* %a
183   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
184   %2 = load <2 x i64>* %b
185   ; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6)
186   %3 = xor <2 x i64> %1, %2
187   ; CHECK-DAG: xor.v [[R3:\$w[0-9]+]], [[R1]], [[R2]]
188   store <2 x i64> %3, <2 x i64>* %c
189   ; CHECK-DAG: st.d [[R3]], 0($4)
190
191   ret void
192   ; CHECK: .size xor_v2i64
193 }
194
195 define void @sll_v16i8(<16 x i8>* %c, <16 x i8>* %a, <16 x i8>* %b) nounwind {
196   ; CHECK: sll_v16i8:
197
198   %1 = load <16 x i8>* %a
199   ; CHECK-DAG: ld.b [[R1:\$w[0-9]+]], 0($5)
200   %2 = load <16 x i8>* %b
201   ; CHECK-DAG: ld.b [[R2:\$w[0-9]+]], 0($6)
202   %3 = shl <16 x i8> %1, %2
203   ; CHECK-DAG: sll.b [[R3:\$w[0-9]+]], [[R1]], [[R2]]
204   store <16 x i8> %3, <16 x i8>* %c
205   ; CHECK-DAG: st.b [[R3]], 0($4)
206
207   ret void
208   ; CHECK: .size sll_v16i8
209 }
210
211 define void @sll_v8i16(<8 x i16>* %c, <8 x i16>* %a, <8 x i16>* %b) nounwind {
212   ; CHECK: sll_v8i16:
213
214   %1 = load <8 x i16>* %a
215   ; CHECK-DAG: ld.h [[R1:\$w[0-9]+]], 0($5)
216   %2 = load <8 x i16>* %b
217   ; CHECK-DAG: ld.h [[R2:\$w[0-9]+]], 0($6)
218   %3 = shl <8 x i16> %1, %2
219   ; CHECK-DAG: sll.h [[R3:\$w[0-9]+]], [[R1]], [[R2]]
220   store <8 x i16> %3, <8 x i16>* %c
221   ; CHECK-DAG: st.h [[R3]], 0($4)
222
223   ret void
224   ; CHECK: .size sll_v8i16
225 }
226
227 define void @sll_v4i32(<4 x i32>* %c, <4 x i32>* %a, <4 x i32>* %b) nounwind {
228   ; CHECK: sll_v4i32:
229
230   %1 = load <4 x i32>* %a
231   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
232   %2 = load <4 x i32>* %b
233   ; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6)
234   %3 = shl <4 x i32> %1, %2
235   ; CHECK-DAG: sll.w [[R3:\$w[0-9]+]], [[R1]], [[R2]]
236   store <4 x i32> %3, <4 x i32>* %c
237   ; CHECK-DAG: st.w [[R3]], 0($4)
238
239   ret void
240   ; CHECK: .size sll_v4i32
241 }
242
243 define void @sll_v2i64(<2 x i64>* %c, <2 x i64>* %a, <2 x i64>* %b) nounwind {
244   ; CHECK: sll_v2i64:
245
246   %1 = load <2 x i64>* %a
247   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
248   %2 = load <2 x i64>* %b
249   ; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6)
250   %3 = shl <2 x i64> %1, %2
251   ; CHECK-DAG: sll.d [[R3:\$w[0-9]+]], [[R1]], [[R2]]
252   store <2 x i64> %3, <2 x i64>* %c
253   ; CHECK-DAG: st.d [[R3]], 0($4)
254
255   ret void
256   ; CHECK: .size sll_v2i64
257 }
258
259 define void @sra_v16i8(<16 x i8>* %c, <16 x i8>* %a, <16 x i8>* %b) nounwind {
260   ; CHECK: sra_v16i8:
261
262   %1 = load <16 x i8>* %a
263   ; CHECK-DAG: ld.b [[R1:\$w[0-9]+]], 0($5)
264   %2 = load <16 x i8>* %b
265   ; CHECK-DAG: ld.b [[R2:\$w[0-9]+]], 0($6)
266   %3 = ashr <16 x i8> %1, %2
267   ; CHECK-DAG: sra.b [[R3:\$w[0-9]+]], [[R1]], [[R2]]
268   store <16 x i8> %3, <16 x i8>* %c
269   ; CHECK-DAG: st.b [[R3]], 0($4)
270
271   ret void
272   ; CHECK: .size sra_v16i8
273 }
274
275 define void @sra_v8i16(<8 x i16>* %c, <8 x i16>* %a, <8 x i16>* %b) nounwind {
276   ; CHECK: sra_v8i16:
277
278   %1 = load <8 x i16>* %a
279   ; CHECK-DAG: ld.h [[R1:\$w[0-9]+]], 0($5)
280   %2 = load <8 x i16>* %b
281   ; CHECK-DAG: ld.h [[R2:\$w[0-9]+]], 0($6)
282   %3 = ashr <8 x i16> %1, %2
283   ; CHECK-DAG: sra.h [[R3:\$w[0-9]+]], [[R1]], [[R2]]
284   store <8 x i16> %3, <8 x i16>* %c
285   ; CHECK-DAG: st.h [[R3]], 0($4)
286
287   ret void
288   ; CHECK: .size sra_v8i16
289 }
290
291 define void @sra_v4i32(<4 x i32>* %c, <4 x i32>* %a, <4 x i32>* %b) nounwind {
292   ; CHECK: sra_v4i32:
293
294   %1 = load <4 x i32>* %a
295   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
296   %2 = load <4 x i32>* %b
297   ; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6)
298   %3 = ashr <4 x i32> %1, %2
299   ; CHECK-DAG: sra.w [[R3:\$w[0-9]+]], [[R1]], [[R2]]
300   store <4 x i32> %3, <4 x i32>* %c
301   ; CHECK-DAG: st.w [[R3]], 0($4)
302
303   ret void
304   ; CHECK: .size sra_v4i32
305 }
306
307 define void @sra_v2i64(<2 x i64>* %c, <2 x i64>* %a, <2 x i64>* %b) nounwind {
308   ; CHECK: sra_v2i64:
309
310   %1 = load <2 x i64>* %a
311   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
312   %2 = load <2 x i64>* %b
313   ; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6)
314   %3 = ashr <2 x i64> %1, %2
315   ; CHECK-DAG: sra.d [[R3:\$w[0-9]+]], [[R1]], [[R2]]
316   store <2 x i64> %3, <2 x i64>* %c
317   ; CHECK-DAG: st.d [[R3]], 0($4)
318
319   ret void
320   ; CHECK: .size sra_v2i64
321 }
322
323 define void @srl_v16i8(<16 x i8>* %c, <16 x i8>* %a, <16 x i8>* %b) nounwind {
324   ; CHECK: srl_v16i8:
325
326   %1 = load <16 x i8>* %a
327   ; CHECK-DAG: ld.b [[R1:\$w[0-9]+]], 0($5)
328   %2 = load <16 x i8>* %b
329   ; CHECK-DAG: ld.b [[R2:\$w[0-9]+]], 0($6)
330   %3 = lshr <16 x i8> %1, %2
331   ; CHECK-DAG: srl.b [[R3:\$w[0-9]+]], [[R1]], [[R2]]
332   store <16 x i8> %3, <16 x i8>* %c
333   ; CHECK-DAG: st.b [[R3]], 0($4)
334
335   ret void
336   ; CHECK: .size srl_v16i8
337 }
338
339 define void @srl_v8i16(<8 x i16>* %c, <8 x i16>* %a, <8 x i16>* %b) nounwind {
340   ; CHECK: srl_v8i16:
341
342   %1 = load <8 x i16>* %a
343   ; CHECK-DAG: ld.h [[R1:\$w[0-9]+]], 0($5)
344   %2 = load <8 x i16>* %b
345   ; CHECK-DAG: ld.h [[R2:\$w[0-9]+]], 0($6)
346   %3 = lshr <8 x i16> %1, %2
347   ; CHECK-DAG: srl.h [[R3:\$w[0-9]+]], [[R1]], [[R2]]
348   store <8 x i16> %3, <8 x i16>* %c
349   ; CHECK-DAG: st.h [[R3]], 0($4)
350
351   ret void
352   ; CHECK: .size srl_v8i16
353 }
354
355 define void @srl_v4i32(<4 x i32>* %c, <4 x i32>* %a, <4 x i32>* %b) nounwind {
356   ; CHECK: srl_v4i32:
357
358   %1 = load <4 x i32>* %a
359   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
360   %2 = load <4 x i32>* %b
361   ; CHECK-DAG: ld.w [[R2:\$w[0-9]+]], 0($6)
362   %3 = lshr <4 x i32> %1, %2
363   ; CHECK-DAG: srl.w [[R3:\$w[0-9]+]], [[R1]], [[R2]]
364   store <4 x i32> %3, <4 x i32>* %c
365   ; CHECK-DAG: st.w [[R3]], 0($4)
366
367   ret void
368   ; CHECK: .size srl_v4i32
369 }
370
371 define void @srl_v2i64(<2 x i64>* %c, <2 x i64>* %a, <2 x i64>* %b) nounwind {
372   ; CHECK: srl_v2i64:
373
374   %1 = load <2 x i64>* %a
375   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
376   %2 = load <2 x i64>* %b
377   ; CHECK-DAG: ld.d [[R2:\$w[0-9]+]], 0($6)
378   %3 = lshr <2 x i64> %1, %2
379   ; CHECK-DAG: srl.d [[R3:\$w[0-9]+]], [[R1]], [[R2]]
380   store <2 x i64> %3, <2 x i64>* %c
381   ; CHECK-DAG: st.d [[R3]], 0($4)
382
383   ret void
384   ; CHECK: .size srl_v2i64
385 }
386
387 define void @ctlz_v16i8(<16 x i8>* %c, <16 x i8>* %a) nounwind {
388   ; CHECK: ctlz_v16i8:
389
390   %1 = load <16 x i8>* %a
391   ; CHECK-DAG: ld.b [[R1:\$w[0-9]+]], 0($5)
392   %2 = tail call <16 x i8> @llvm.ctlz.v16i8 (<16 x i8> %1)
393   ; CHECK-DAG: nlzc.b [[R3:\$w[0-9]+]], [[R1]]
394   store <16 x i8> %2, <16 x i8>* %c
395   ; CHECK-DAG: st.b [[R3]], 0($4)
396
397   ret void
398   ; CHECK: .size ctlz_v16i8
399 }
400
401 define void @ctlz_v8i16(<8 x i16>* %c, <8 x i16>* %a) nounwind {
402   ; CHECK: ctlz_v8i16:
403
404   %1 = load <8 x i16>* %a
405   ; CHECK-DAG: ld.h [[R1:\$w[0-9]+]], 0($5)
406   %2 = tail call <8 x i16> @llvm.ctlz.v8i16 (<8 x i16> %1)
407   ; CHECK-DAG: nlzc.h [[R3:\$w[0-9]+]], [[R1]]
408   store <8 x i16> %2, <8 x i16>* %c
409   ; CHECK-DAG: st.h [[R3]], 0($4)
410
411   ret void
412   ; CHECK: .size ctlz_v8i16
413 }
414
415 define void @ctlz_v4i32(<4 x i32>* %c, <4 x i32>* %a) nounwind {
416   ; CHECK: ctlz_v4i32:
417
418   %1 = load <4 x i32>* %a
419   ; CHECK-DAG: ld.w [[R1:\$w[0-9]+]], 0($5)
420   %2 = tail call <4 x i32> @llvm.ctlz.v4i32 (<4 x i32> %1)
421   ; CHECK-DAG: nlzc.w [[R3:\$w[0-9]+]], [[R1]]
422   store <4 x i32> %2, <4 x i32>* %c
423   ; CHECK-DAG: st.w [[R3]], 0($4)
424
425   ret void
426   ; CHECK: .size ctlz_v4i32
427 }
428
429 define void @ctlz_v2i64(<2 x i64>* %c, <2 x i64>* %a) nounwind {
430   ; CHECK: ctlz_v2i64:
431
432   %1 = load <2 x i64>* %a
433   ; CHECK-DAG: ld.d [[R1:\$w[0-9]+]], 0($5)
434   %2 = tail call <2 x i64> @llvm.ctlz.v2i64 (<2 x i64> %1)
435   ; CHECK-DAG: nlzc.d [[R3:\$w[0-9]+]], [[R1]]
436   store <2 x i64> %2, <2 x i64>* %c
437   ; CHECK-DAG: st.d [[R3]], 0($4)
438
439   ret void
440   ; CHECK: .size ctlz_v2i64
441 }
442
443 declare <16 x i8> @llvm.ctlz.v16i8(<16 x i8> %val)
444 declare <8 x i16> @llvm.ctlz.v8i16(<8 x i16> %val)
445 declare <4 x i32> @llvm.ctlz.v4i32(<4 x i32> %val)
446 declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %val)