[mips][msa] Added support for matching bsel and bseli from normal IR (i.e. not intrin...
[oota-llvm.git] / test / CodeGen / Mips / msa / basic_operations.ll
1 ; RUN: llc -march=mips -mattr=+msa < %s | FileCheck -check-prefix=MIPS32 %s
2
3 @v16i8 = global <16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>
4 @v8i16 = global <8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>
5 @v4i32 = global <4 x i32> <i32 0, i32 0, i32 0, i32 0>
6 @v2i64 = global <2 x i64> <i64 0, i64 0>
7 @i64 = global i64 0
8
9 define void @const_v16i8() nounwind {
10   ; MIPS32: const_v16i8:
11
12   store volatile <16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>, <16 x i8>*@v16i8
13   ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 0
14
15   store volatile <16 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>, <16 x i8>*@v16i8
16   ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 1
17
18   store volatile <16 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 31>, <16 x i8>*@v16i8
19   ; MIPS32: ld.b  [[R1:\$w[0-9]+]], %lo(
20
21   store volatile <16 x i8> <i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 9, i8 0, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6>, <16 x i8>*@v16i8
22   ; MIPS32: ld.b  [[R1:\$w[0-9]+]], %lo(
23
24   store volatile <16 x i8> <i8 1, i8 2, i8 1, i8 2, i8 1, i8 2, i8 1, i8 2, i8 1, i8 2, i8 1, i8 2, i8 1, i8 2, i8 1, i8 2>, <16 x i8>*@v16i8
25   ; MIPS32: ldi.h [[R1:\$w[0-9]+]], 258
26
27   store volatile <16 x i8> <i8 1, i8 2, i8 3, i8 4, i8 1, i8 2, i8 3, i8 4, i8 1, i8 2, i8 3, i8 4, i8 1, i8 2, i8 3, i8 4>, <16 x i8>*@v16i8
28   ; MIPS32-DAG: lui [[R2:\$[0-9]+]], 258
29   ; MIPS32-DAG: ori [[R2]], [[R2]], 772
30   ; MIPS32-DAG: fill.w [[R1:\$w[0-9]+]], [[R2]]
31
32   store volatile <16 x i8> <i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8>, <16 x i8>*@v16i8
33   ; MIPS32: ld.b  [[R1:\$w[0-9]+]], %lo(
34
35   ret void
36   ; MIPS32: .size const_v16i8
37 }
38
39 define void @const_v8i16() nounwind {
40   ; MIPS32: const_v8i16:
41
42   store volatile <8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>, <8 x i16>*@v8i16
43   ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 0
44
45   store volatile <8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <8 x i16>*@v8i16
46   ; MIPS32: ldi.h [[R1:\$w[0-9]+]], 1
47
48   store volatile <8 x i16> <i16 1, i16 1, i16 1, i16 2, i16 1, i16 1, i16 1, i16 31>, <8 x i16>*@v8i16
49   ; MIPS32: ld.h  [[R1:\$w[0-9]+]], %lo(
50
51   store volatile <8 x i16> <i16 1028, i16 1028, i16 1028, i16 1028, i16 1028, i16 1028, i16 1028, i16 1028>, <8 x i16>*@v8i16
52   ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 4
53
54   store volatile <8 x i16> <i16 1, i16 2, i16 1, i16 2, i16 1, i16 2, i16 1, i16 2>, <8 x i16>*@v8i16
55   ; MIPS32-DAG: lui [[R2:\$[0-9]+]], 1
56   ; MIPS32-DAG: ori [[R2]], [[R2]], 2
57   ; MIPS32-DAG: fill.w [[R1:\$w[0-9]+]], [[R2]]
58
59   store volatile <8 x i16> <i16 1, i16 2, i16 3, i16 4, i16 1, i16 2, i16 3, i16 4>, <8 x i16>*@v8i16
60   ; MIPS32: ld.h  [[R1:\$w[0-9]+]], %lo(
61
62   ret void
63   ; MIPS32: .size const_v8i16
64 }
65
66 define void @const_v4i32() nounwind {
67   ; MIPS32: const_v4i32:
68
69   store volatile <4 x i32> <i32 0, i32 0, i32 0, i32 0>, <4 x i32>*@v4i32
70   ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 0
71
72   store volatile <4 x i32> <i32 1, i32 1, i32 1, i32 1>, <4 x i32>*@v4i32
73   ; MIPS32: ldi.w [[R1:\$w[0-9]+]], 1
74
75   store volatile <4 x i32> <i32 1, i32 1, i32 1, i32 31>, <4 x i32>*@v4i32
76   ; MIPS32: ld.w  [[R1:\$w[0-9]+]], %lo(
77
78   store volatile <4 x i32> <i32 16843009, i32 16843009, i32 16843009, i32 16843009>, <4 x i32>*@v4i32
79   ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 1
80
81   store volatile <4 x i32> <i32 65537, i32 65537, i32 65537, i32 65537>, <4 x i32>*@v4i32
82   ; MIPS32: ldi.h [[R1:\$w[0-9]+]], 1
83
84   store volatile <4 x i32> <i32 1, i32 2, i32 1, i32 2>, <4 x i32>*@v4i32
85   ; MIPS32: ld.w  [[R1:\$w[0-9]+]], %lo(
86
87   store volatile <4 x i32> <i32 3, i32 4, i32 5, i32 6>, <4 x i32>*@v4i32
88   ; MIPS32: ld.w  [[R1:\$w[0-9]+]], %lo(
89
90   ret void
91   ; MIPS32: .size const_v4i32
92 }
93
94 define void @const_v2i64() nounwind {
95   ; MIPS32: const_v2i64:
96
97   store volatile <2 x i64> <i64 0, i64 0>, <2 x i64>*@v2i64
98   ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 0
99
100   store volatile <2 x i64> <i64 72340172838076673, i64 72340172838076673>, <2 x i64>*@v2i64
101   ; MIPS32: ldi.b [[R1:\$w[0-9]+]], 1
102
103   store volatile <2 x i64> <i64 281479271743489, i64 281479271743489>, <2 x i64>*@v2i64
104   ; MIPS32: ldi.h [[R1:\$w[0-9]+]], 1
105
106   store volatile <2 x i64> <i64 4294967297, i64 4294967297>, <2 x i64>*@v2i64
107   ; MIPS32: ldi.w [[R1:\$w[0-9]+]], 1
108
109   store volatile <2 x i64> <i64 1, i64 1>, <2 x i64>*@v2i64
110   ; MIPS32: ldi.d [[R1:\$w[0-9]+]], 1
111
112   store volatile <2 x i64> <i64 1, i64 31>, <2 x i64>*@v2i64
113   ; MIPS32: ld.w  [[R1:\$w[0-9]+]], %lo(
114
115   store volatile <2 x i64> <i64 3, i64 4>, <2 x i64>*@v2i64
116   ; MIPS32: ld.w  [[R1:\$w[0-9]+]], %lo(
117
118   ret void
119   ; MIPS32: .size const_v2i64
120 }
121
122 define i32 @extract_sext_v16i8() nounwind {
123   ; MIPS32: extract_sext_v16i8:
124
125   %1 = load <16 x i8>* @v16i8
126   ; MIPS32-DAG: ld.b [[R1:\$w[0-9]+]],
127
128   %2 = add <16 x i8> %1, %1
129   ; MIPS32-DAG: addv.b [[R2:\$w[0-9]+]], [[R1]], [[R1]]
130
131   %3 = extractelement <16 x i8> %2, i32 1
132   %4 = sext i8 %3 to i32
133   ; MIPS32-DAG: copy_s.b [[R3:\$[0-9]+]], [[R1]][1]
134   ; MIPS32-NOT: sll
135   ; MIPS32-NOT: sra
136
137   ret i32 %4
138   ; MIPS32: .size extract_sext_v16i8
139 }
140
141 define i32 @extract_sext_v8i16() nounwind {
142   ; MIPS32: extract_sext_v8i16:
143
144   %1 = load <8 x i16>* @v8i16
145   ; MIPS32-DAG: ld.h [[R1:\$w[0-9]+]],
146
147   %2 = add <8 x i16> %1, %1
148   ; MIPS32-DAG: addv.h [[R2:\$w[0-9]+]], [[R1]], [[R1]]
149
150   %3 = extractelement <8 x i16> %2, i32 1
151   %4 = sext i16 %3 to i32
152   ; MIPS32-DAG: copy_s.h [[R3:\$[0-9]+]], [[R1]][1]
153   ; MIPS32-NOT: sll
154   ; MIPS32-NOT: sra
155
156   ret i32 %4
157   ; MIPS32: .size extract_sext_v8i16
158 }
159
160 define i32 @extract_sext_v4i32() nounwind {
161   ; MIPS32: extract_sext_v4i32:
162
163   %1 = load <4 x i32>* @v4i32
164   ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]],
165
166   %2 = add <4 x i32> %1, %1
167   ; MIPS32-DAG: addv.w [[R2:\$w[0-9]+]], [[R1]], [[R1]]
168
169   %3 = extractelement <4 x i32> %2, i32 1
170   ; MIPS32-DAG: copy_s.w [[R3:\$[0-9]+]], [[R1]][1]
171
172   ret i32 %3
173   ; MIPS32: .size extract_sext_v4i32
174 }
175
176 define i64 @extract_sext_v2i64() nounwind {
177   ; MIPS32: extract_sext_v2i64:
178
179   %1 = load <2 x i64>* @v2i64
180   ; MIPS32-DAG: ld.d [[R1:\$w[0-9]+]],
181
182   %2 = add <2 x i64> %1, %1
183   ; MIPS32-DAG: addv.d [[R2:\$w[0-9]+]], [[R1]], [[R1]]
184
185   %3 = extractelement <2 x i64> %2, i32 1
186   ; MIPS32-DAG: copy_s.w [[R3:\$[0-9]+]], [[R1]][2]
187   ; MIPS32-DAG: copy_s.w [[R4:\$[0-9]+]], [[R1]][3]
188   ; MIPS32-NOT: sll
189   ; MIPS32-NOT: sra
190
191   ret i64 %3
192   ; MIPS32: .size extract_sext_v2i64
193 }
194
195 define i32 @extract_zext_v16i8() nounwind {
196   ; MIPS32: extract_zext_v16i8:
197
198   %1 = load <16 x i8>* @v16i8
199   ; MIPS32-DAG: ld.b [[R1:\$w[0-9]+]],
200
201   %2 = add <16 x i8> %1, %1
202   ; MIPS32-DAG: addv.b [[R2:\$w[0-9]+]], [[R1]], [[R1]]
203
204   %3 = extractelement <16 x i8> %2, i32 1
205   %4 = zext i8 %3 to i32
206   ; MIPS32-DAG: copy_u.b [[R3:\$[0-9]+]], [[R1]][1]
207   ; MIPS32-NOT: andi
208
209   ret i32 %4
210   ; MIPS32: .size extract_zext_v16i8
211 }
212
213 define i32 @extract_zext_v8i16() nounwind {
214   ; MIPS32: extract_zext_v8i16:
215
216   %1 = load <8 x i16>* @v8i16
217   ; MIPS32-DAG: ld.h [[R1:\$w[0-9]+]],
218
219   %2 = add <8 x i16> %1, %1
220   ; MIPS32-DAG: addv.h [[R2:\$w[0-9]+]], [[R1]], [[R1]]
221
222   %3 = extractelement <8 x i16> %2, i32 1
223   %4 = zext i16 %3 to i32
224   ; MIPS32-DAG: copy_u.h [[R3:\$[0-9]+]], [[R1]][1]
225   ; MIPS32-NOT: andi
226
227   ret i32 %4
228   ; MIPS32: .size extract_zext_v8i16
229 }
230
231 define i32 @extract_zext_v4i32() nounwind {
232   ; MIPS32: extract_zext_v4i32:
233
234   %1 = load <4 x i32>* @v4i32
235   ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]],
236
237   %2 = add <4 x i32> %1, %1
238   ; MIPS32-DAG: addv.w [[R2:\$w[0-9]+]], [[R1]], [[R1]]
239
240   %3 = extractelement <4 x i32> %2, i32 1
241   ; MIPS32-DAG: copy_{{[su]}}.w [[R3:\$[0-9]+]], [[R1]][1]
242
243   ret i32 %3
244   ; MIPS32: .size extract_zext_v4i32
245 }
246
247 define i64 @extract_zext_v2i64() nounwind {
248   ; MIPS32: extract_zext_v2i64:
249
250   %1 = load <2 x i64>* @v2i64
251   ; MIPS32-DAG: ld.d [[R1:\$w[0-9]+]],
252
253   %2 = add <2 x i64> %1, %1
254   ; MIPS32-DAG: addv.d [[R2:\$w[0-9]+]], [[R1]], [[R1]]
255
256   %3 = extractelement <2 x i64> %2, i32 1
257   ; MIPS32-DAG: copy_{{[su]}}.w [[R3:\$[0-9]+]], [[R1]][2]
258   ; MIPS32-DAG: copy_{{[su]}}.w [[R4:\$[0-9]+]], [[R1]][3]
259   ; MIPS32-NOT: andi
260
261   ret i64 %3
262   ; MIPS32: .size extract_zext_v2i64
263 }
264
265 define void @insert_v16i8(i32 %a) nounwind {
266   ; MIPS32: insert_v16i8:
267
268   %1 = load <16 x i8>* @v16i8
269   ; MIPS32-DAG: ld.b [[R1:\$w[0-9]+]],
270
271   %a2 = trunc i32 %a to i8
272   %a3 = sext i8 %a2 to i32
273   %a4 = trunc i32 %a3 to i8
274   ; MIPS32-NOT: andi
275   ; MIPS32-NOT: sra
276
277   %2 = insertelement <16 x i8> %1, i8 %a4, i32 1
278   ; MIPS32-DAG: insert.b [[R1]][1], $4
279
280   store <16 x i8> %2, <16 x i8>* @v16i8
281   ; MIPS32-DAG: st.b [[R1]]
282
283   ret void
284   ; MIPS32: .size insert_v16i8
285 }
286
287 define void @insert_v8i16(i32 %a) nounwind {
288   ; MIPS32: insert_v8i16:
289
290   %1 = load <8 x i16>* @v8i16
291   ; MIPS32-DAG: ld.h [[R1:\$w[0-9]+]],
292
293   %a2 = trunc i32 %a to i16
294   %a3 = sext i16 %a2 to i32
295   %a4 = trunc i32 %a3 to i16
296   ; MIPS32-NOT: andi
297   ; MIPS32-NOT: sra
298
299   %2 = insertelement <8 x i16> %1, i16 %a4, i32 1
300   ; MIPS32-DAG: insert.h [[R1]][1], $4
301
302   store <8 x i16> %2, <8 x i16>* @v8i16
303   ; MIPS32-DAG: st.h [[R1]]
304
305   ret void
306   ; MIPS32: .size insert_v8i16
307 }
308
309 define void @insert_v4i32(i32 %a) nounwind {
310   ; MIPS32: insert_v4i32:
311
312   %1 = load <4 x i32>* @v4i32
313   ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]],
314
315   ; MIPS32-NOT: andi
316   ; MIPS32-NOT: sra
317
318   %2 = insertelement <4 x i32> %1, i32 %a, i32 1
319   ; MIPS32-DAG: insert.w [[R1]][1], $4
320
321   store <4 x i32> %2, <4 x i32>* @v4i32
322   ; MIPS32-DAG: st.w [[R1]]
323
324   ret void
325   ; MIPS32: .size insert_v4i32
326 }
327
328 define void @insert_v2i64(i64 %a) nounwind {
329   ; MIPS32: insert_v2i64:
330
331   %1 = load <2 x i64>* @v2i64
332   ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]],
333
334   ; MIPS32-NOT: andi
335   ; MIPS32-NOT: sra
336
337   %2 = insertelement <2 x i64> %1, i64 %a, i32 1
338   ; MIPS32-DAG: insert.w [[R1]][2], $4
339   ; MIPS32-DAG: insert.w [[R1]][3], $5
340
341   store <2 x i64> %2, <2 x i64>* @v2i64
342   ; MIPS32-DAG: st.w [[R1]]
343
344   ret void
345   ; MIPS32: .size insert_v2i64
346 }