[mips][msa] Test basic operations for the N32 ABI too.
[oota-llvm.git] / test / CodeGen / Mips / msa / basic_operations.ll
1 ; RUN: llc -march=mips -mattr=+msa,+fp64 < %s | FileCheck -check-prefix=ALL -check-prefix=O32 -check-prefix=MIPS32 -check-prefix=ALL-BE %s
2 ; RUN: llc -march=mipsel -mattr=+msa,+fp64 < %s | FileCheck -check-prefix=ALL -check-prefix=O32 -check-prefix=MIPS32 -check-prefix=ALL-LE %s
3 ; RUN: llc -march=mips64 -target-abi n32 -mattr=+msa,+fp64 < %s | FileCheck -check-prefix=ALL -check-prefix=N32 -check-prefix=MIPS64 -check-prefix=ALL-BE %s
4 ; RUN: llc -march=mips64el -target-abi n32 -mattr=+msa,+fp64 < %s | FileCheck -check-prefix=ALL -check-prefix=N32 -check-prefix=MIPS64 -check-prefix=ALL-LE %s
5
6 @v4i8 = global <4 x i8> <i8 0, i8 0, i8 0, i8 0>
7 @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>
8 @v8i16 = global <8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>
9 @v4i32 = global <4 x i32> <i32 0, i32 0, i32 0, i32 0>
10 @v2i64 = global <2 x i64> <i64 0, i64 0>
11 @i32 = global i32 0
12 @i64 = global i64 0
13
14 define void @const_v16i8() nounwind {
15   ; ALL-LABEL: const_v16i8:
16
17   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
18   ; ALL: ldi.b [[R1:\$w[0-9]+]], 0
19
20   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
21   ; ALL: ldi.b [[R1:\$w[0-9]+]], 1
22
23   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
24   ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
25   ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
26   ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
27   ; ALL: ld.b  [[R1:\$w[0-9]+]], 0([[G_PTR]])
28
29   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
30   ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
31   ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
32   ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
33   ; ALL: ld.b  [[R1:\$w[0-9]+]], 0([[G_PTR]])
34
35   store volatile <16 x i8> <i8 1, i8 0, i8 1, i8 0, i8 1, i8 0, i8 1, i8 0, i8 1, i8 0, i8 1, i8 0, i8 1, i8 0, i8 1, i8 0>, <16 x i8>*@v16i8
36   ; ALL-BE: ldi.h [[R1:\$w[0-9]+]], 256
37   ; ALL-LE: ldi.h [[R1:\$w[0-9]+]], 1
38
39   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
40   ; ALL-BE-DAG: lui [[R2:\$[0-9]+]], 258
41   ; ALL-LE-DAG: lui [[R2:\$[0-9]+]], 1027
42   ; ALL-BE-DAG: ori [[R2]], [[R2]], 772
43   ; ALL-LE-DAG: ori [[R2]], [[R2]], 513
44   ; ALL-DAG: fill.w [[R1:\$w[0-9]+]], [[R2]]
45
46   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
47   ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
48   ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
49   ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
50   ; ALL: ld.b  [[R1:\$w[0-9]+]], 0([[G_PTR]])
51
52   ret void
53 }
54
55 define void @const_v8i16() nounwind {
56   ; ALL-LABEL: const_v8i16:
57
58   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
59   ; ALL: ldi.b [[R1:\$w[0-9]+]], 0
60
61   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
62   ; ALL: ldi.h [[R1:\$w[0-9]+]], 1
63
64   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
65   ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
66   ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
67   ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
68   ; ALL: ld.h  [[R1:\$w[0-9]+]], 0([[G_PTR]])
69
70   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
71   ; ALL: ldi.b [[R1:\$w[0-9]+]], 4
72
73   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
74   ; ALL-BE-DAG: lui [[R2:\$[0-9]+]], 1
75   ; ALL-LE-DAG: lui [[R2:\$[0-9]+]], 2
76   ; ALL-BE-DAG: ori [[R2]], [[R2]], 2
77   ; ALL-LE-DAG: ori [[R2]], [[R2]], 1
78   ; ALL-DAG: fill.w [[R1:\$w[0-9]+]], [[R2]]
79
80   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
81   ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
82   ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
83   ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
84   ; ALL: ld.h  [[R1:\$w[0-9]+]], 0([[G_PTR]])
85
86   ret void
87 }
88
89 define void @const_v4i32() nounwind {
90   ; ALL-LABEL: const_v4i32:
91
92   store volatile <4 x i32> <i32 0, i32 0, i32 0, i32 0>, <4 x i32>*@v4i32
93   ; ALL: ldi.b [[R1:\$w[0-9]+]], 0
94
95   store volatile <4 x i32> <i32 1, i32 1, i32 1, i32 1>, <4 x i32>*@v4i32
96   ; ALL: ldi.w [[R1:\$w[0-9]+]], 1
97
98   store volatile <4 x i32> <i32 1, i32 1, i32 1, i32 31>, <4 x i32>*@v4i32
99   ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
100   ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
101   ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
102   ; ALL: ld.w  [[R1:\$w[0-9]+]], 0([[G_PTR]])
103
104   store volatile <4 x i32> <i32 16843009, i32 16843009, i32 16843009, i32 16843009>, <4 x i32>*@v4i32
105   ; ALL: ldi.b [[R1:\$w[0-9]+]], 1
106
107   store volatile <4 x i32> <i32 65537, i32 65537, i32 65537, i32 65537>, <4 x i32>*@v4i32
108   ; ALL: ldi.h [[R1:\$w[0-9]+]], 1
109
110   store volatile <4 x i32> <i32 1, i32 2, i32 1, i32 2>, <4 x i32>*@v4i32
111   ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
112   ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
113   ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
114   ; ALL: ld.w  [[R1:\$w[0-9]+]], 0([[G_PTR]])
115
116   store volatile <4 x i32> <i32 3, i32 4, i32 5, i32 6>, <4 x i32>*@v4i32
117   ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
118   ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
119   ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
120   ; ALL: ld.w  [[R1:\$w[0-9]+]], 0([[G_PTR]])
121
122   ret void
123 }
124
125 define void @const_v2i64() nounwind {
126   ; ALL-LABEL: const_v2i64:
127
128   store volatile <2 x i64> <i64 0, i64 0>, <2 x i64>*@v2i64
129   ; ALL: ldi.b [[R1:\$w[0-9]+]], 0
130
131   store volatile <2 x i64> <i64 72340172838076673, i64 72340172838076673>, <2 x i64>*@v2i64
132   ; ALL: ldi.b [[R1:\$w[0-9]+]], 1
133
134   store volatile <2 x i64> <i64 281479271743489, i64 281479271743489>, <2 x i64>*@v2i64
135   ; ALL: ldi.h [[R1:\$w[0-9]+]], 1
136
137   store volatile <2 x i64> <i64 4294967297, i64 4294967297>, <2 x i64>*@v2i64
138   ; ALL: ldi.w [[R1:\$w[0-9]+]], 1
139
140   store volatile <2 x i64> <i64 1, i64 1>, <2 x i64>*@v2i64
141   ; ALL: ldi.d [[R1:\$w[0-9]+]], 1
142
143   store volatile <2 x i64> <i64 1, i64 31>, <2 x i64>*@v2i64
144   ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
145   ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
146   ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
147   ; MIPS32: ld.w [[R1:\$w[0-9]+]], 0([[G_PTR]])
148   ; MIPS64: ld.d [[R1:\$w[0-9]+]], 0([[G_PTR]])
149
150   store volatile <2 x i64> <i64 3, i64 4>, <2 x i64>*@v2i64
151   ; O32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %lo($
152   ; N32: addiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
153   ; N64: daddiu [[G_PTR:\$[0-9]+]], {{.*}}, %got_ofst($
154   ; MIPS32: ld.w  [[R1:\$w[0-9]+]], 0([[G_PTR]])
155   ; MIPS64: ld.d  [[R1:\$w[0-9]+]], 0([[G_PTR]])
156
157   ret void
158 }
159
160 define void @nonconst_v16i8(i8 signext %a, i8 signext %b, i8 signext %c, i8 signext %d, i8 signext %e, i8 signext %f, i8 signext %g, i8 signext %h) nounwind {
161   ; ALL-LABEL: nonconst_v16i8:
162
163   %1 = insertelement <16 x i8> undef, i8 %a, i32 0
164   %2 = insertelement <16 x i8> %1, i8 %b, i32 1
165   %3 = insertelement <16 x i8> %2, i8 %c, i32 2
166   %4 = insertelement <16 x i8> %3, i8 %d, i32 3
167   %5 = insertelement <16 x i8> %4, i8 %e, i32 4
168   %6 = insertelement <16 x i8> %5, i8 %f, i32 5
169   %7 = insertelement <16 x i8> %6, i8 %g, i32 6
170   %8 = insertelement <16 x i8> %7, i8 %h, i32 7
171   %9 = insertelement <16 x i8> %8, i8 %h, i32 8
172   %10 = insertelement <16 x i8> %9, i8 %h, i32 9
173   %11 = insertelement <16 x i8> %10, i8 %h, i32 10
174   %12 = insertelement <16 x i8> %11, i8 %h, i32 11
175   %13 = insertelement <16 x i8> %12, i8 %h, i32 12
176   %14 = insertelement <16 x i8> %13, i8 %h, i32 13
177   %15 = insertelement <16 x i8> %14, i8 %h, i32 14
178   %16 = insertelement <16 x i8> %15, i8 %h, i32 15
179   ; ALL-DAG: insert.b [[R1:\$w[0-9]+]][0], $4
180   ; ALL-DAG: insert.b [[R1]][1], $5
181   ; ALL-DAG: insert.b [[R1]][2], $6
182   ; ALL-DAG: insert.b [[R1]][3], $7
183   ; MIPS32-DAG: lw [[R2:\$[0-9]+]], 16($sp)
184   ; MIPS32-DAG: insert.b [[R1]][4], [[R2]]
185   ; MIPS64-DAG: insert.b [[R1]][4], $8
186   ; MIPS32-DAG: lw [[R3:\$[0-9]+]], 20($sp)
187   ; MIPS32-DAG: insert.b [[R1]][5], [[R3]]
188   ; MIPS64-DAG: insert.b [[R1]][5], $9
189   ; MIPS32-DAG: lw [[R4:\$[0-9]+]], 24($sp)
190   ; MIPS32-DAG: insert.b [[R1]][6], [[R4]]
191   ; MIPS64-DAG: insert.b [[R1]][6], $10
192   ; MIPS32-DAG: lw [[R5:\$[0-9]+]], 28($sp)
193   ; MIPS32-DAG: insert.b [[R1]][7], [[R5]]
194   ; MIPS64-DAG: insert.b [[R1]][7], [[R5:\$11]]
195   ; ALL-DAG: insert.b [[R1]][8], [[R5]]
196   ; ALL-DAG: insert.b [[R1]][9], [[R5]]
197   ; ALL-DAG: insert.b [[R1]][10], [[R5]]
198   ; ALL-DAG: insert.b [[R1]][11], [[R5]]
199   ; ALL-DAG: insert.b [[R1]][12], [[R5]]
200   ; ALL-DAG: insert.b [[R1]][13], [[R5]]
201   ; ALL-DAG: insert.b [[R1]][14], [[R5]]
202   ; ALL-DAG: insert.b [[R1]][15], [[R5]]
203
204   store volatile <16 x i8> %16, <16 x i8>*@v16i8
205
206   ret void
207 }
208
209 define void @nonconst_v8i16(i16 signext %a, i16 signext %b, i16 signext %c, i16 signext %d, i16 signext %e, i16 signext %f, i16 signext %g, i16 signext %h) nounwind {
210   ; ALL-LABEL: nonconst_v8i16:
211
212   %1 = insertelement <8 x i16> undef, i16 %a, i32 0
213   %2 = insertelement <8 x i16> %1, i16 %b, i32 1
214   %3 = insertelement <8 x i16> %2, i16 %c, i32 2
215   %4 = insertelement <8 x i16> %3, i16 %d, i32 3
216   %5 = insertelement <8 x i16> %4, i16 %e, i32 4
217   %6 = insertelement <8 x i16> %5, i16 %f, i32 5
218   %7 = insertelement <8 x i16> %6, i16 %g, i32 6
219   %8 = insertelement <8 x i16> %7, i16 %h, i32 7
220   ; ALL-DAG: insert.h [[R1:\$w[0-9]+]][0], $4
221   ; ALL-DAG: insert.h [[R1]][1], $5
222   ; ALL-DAG: insert.h [[R1]][2], $6
223   ; ALL-DAG: insert.h [[R1]][3], $7
224   ; MIPS32-DAG: lw [[R2:\$[0-9]+]], 16($sp)
225   ; MIPS32-DAG: insert.h [[R1]][4], [[R2]]
226   ; MIPS64-DAG: insert.h [[R1]][4], $8
227   ; MIPS32-DAG: lw [[R2:\$[0-9]+]], 20($sp)
228   ; MIPS32-DAG: insert.h [[R1]][5], [[R2]]
229   ; MIPS64-DAG: insert.h [[R1]][5], $9
230   ; MIPS32-DAG: lw [[R2:\$[0-9]+]], 24($sp)
231   ; MIPS32-DAG: insert.h [[R1]][6], [[R2]]
232   ; MIPS64-DAG: insert.h [[R1]][6], $10
233   ; MIPS32-DAG: lw [[R2:\$[0-9]+]], 28($sp)
234   ; MIPS32-DAG: insert.h [[R1]][7], [[R2]]
235   ; MIPS64-DAG: insert.h [[R1]][7], $11
236
237   store volatile <8 x i16> %8, <8 x i16>*@v8i16
238
239   ret void
240 }
241
242 define void @nonconst_v4i32(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d) nounwind {
243   ; ALL-LABEL: nonconst_v4i32:
244
245   %1 = insertelement <4 x i32> undef, i32 %a, i32 0
246   %2 = insertelement <4 x i32> %1, i32 %b, i32 1
247   %3 = insertelement <4 x i32> %2, i32 %c, i32 2
248   %4 = insertelement <4 x i32> %3, i32 %d, i32 3
249   ; ALL: insert.w [[R1:\$w[0-9]+]][0], $4
250   ; ALL: insert.w [[R1]][1], $5
251   ; ALL: insert.w [[R1]][2], $6
252   ; ALL: insert.w [[R1]][3], $7
253
254   store volatile <4 x i32> %4, <4 x i32>*@v4i32
255
256   ret void
257 }
258
259 define void @nonconst_v2i64(i64 signext %a, i64 signext %b) nounwind {
260   ; ALL-LABEL: nonconst_v2i64:
261
262   %1 = insertelement <2 x i64> undef, i64 %a, i32 0
263   %2 = insertelement <2 x i64> %1, i64 %b, i32 1
264   ; MIPS32: insert.w [[R1:\$w[0-9]+]][0], $4
265   ; MIPS32: insert.w [[R1]][1], $5
266   ; MIPS32: insert.w [[R1]][2], $6
267   ; MIPS32: insert.w [[R1]][3], $7
268   ; MIPS64: insert.d [[R1:\$w[0-9]+]][0], $4
269   ; MIPS64: insert.d [[R1]][1], $5
270
271   store volatile <2 x i64> %2, <2 x i64>*@v2i64
272
273   ret void
274 }
275
276 define i32 @extract_sext_v16i8() nounwind {
277   ; ALL-LABEL: extract_sext_v16i8:
278
279   %1 = load <16 x i8>, <16 x i8>* @v16i8
280   ; ALL-DAG: ld.b [[R1:\$w[0-9]+]],
281
282   %2 = add <16 x i8> %1, %1
283   ; ALL-DAG: addv.b [[R2:\$w[0-9]+]], [[R1]], [[R1]]
284
285   %3 = extractelement <16 x i8> %2, i32 1
286   %4 = sext i8 %3 to i32
287   ; ALL-DAG: copy_s.b [[R3:\$[0-9]+]], [[R1]][1]
288   ; ALL-NOT: sll
289   ; ALL-NOT: sra
290
291   ret i32 %4
292 }
293
294 define i32 @extract_sext_v8i16() nounwind {
295   ; ALL-LABEL: extract_sext_v8i16:
296
297   %1 = load <8 x i16>, <8 x i16>* @v8i16
298   ; ALL-DAG: ld.h [[R1:\$w[0-9]+]],
299
300   %2 = add <8 x i16> %1, %1
301   ; ALL-DAG: addv.h [[R2:\$w[0-9]+]], [[R1]], [[R1]]
302
303   %3 = extractelement <8 x i16> %2, i32 1
304   %4 = sext i16 %3 to i32
305   ; ALL-DAG: copy_s.h [[R3:\$[0-9]+]], [[R1]][1]
306   ; ALL-NOT: sll
307   ; ALL-NOT: sra
308
309   ret i32 %4
310 }
311
312 define i32 @extract_sext_v4i32() nounwind {
313   ; ALL-LABEL: extract_sext_v4i32:
314
315   %1 = load <4 x i32>, <4 x i32>* @v4i32
316   ; ALL-DAG: ld.w [[R1:\$w[0-9]+]],
317
318   %2 = add <4 x i32> %1, %1
319   ; ALL-DAG: addv.w [[R2:\$w[0-9]+]], [[R1]], [[R1]]
320
321   %3 = extractelement <4 x i32> %2, i32 1
322   ; ALL-DAG: copy_s.w [[R3:\$[0-9]+]], [[R1]][1]
323
324   ret i32 %3
325 }
326
327 define i64 @extract_sext_v2i64() nounwind {
328   ; ALL-LABEL: extract_sext_v2i64:
329
330   %1 = load <2 x i64>, <2 x i64>* @v2i64
331   ; ALL-DAG: ld.d [[R1:\$w[0-9]+]],
332
333   %2 = add <2 x i64> %1, %1
334   ; ALL-DAG: addv.d [[R2:\$w[0-9]+]], [[R1]], [[R1]]
335
336   %3 = extractelement <2 x i64> %2, i32 1
337   ; MIPS32-DAG: copy_s.w [[R3:\$[0-9]+]], [[R1]][2]
338   ; MIPS32-DAG: copy_s.w [[R4:\$[0-9]+]], [[R1]][3]
339   ; MIPS64-DAG: copy_s.d [[R3:\$[0-9]+]], [[R1]][1]
340   ; ALL-NOT: sll
341   ; ALL-NOT: sra
342
343   ret i64 %3
344 }
345
346 define i32 @extract_zext_v16i8() nounwind {
347   ; ALL-LABEL: extract_zext_v16i8:
348
349   %1 = load <16 x i8>, <16 x i8>* @v16i8
350   ; ALL-DAG: ld.b [[R1:\$w[0-9]+]],
351
352   %2 = add <16 x i8> %1, %1
353   ; ALL-DAG: addv.b [[R2:\$w[0-9]+]], [[R1]], [[R1]]
354
355   %3 = extractelement <16 x i8> %2, i32 1
356   %4 = zext i8 %3 to i32
357   ; ALL-DAG: copy_u.b [[R3:\$[0-9]+]], [[R1]][1]
358   ; ALL-NOT: andi
359
360   ret i32 %4
361 }
362
363 define i32 @extract_zext_v8i16() nounwind {
364   ; ALL-LABEL: extract_zext_v8i16:
365
366   %1 = load <8 x i16>, <8 x i16>* @v8i16
367   ; ALL-DAG: ld.h [[R1:\$w[0-9]+]],
368
369   %2 = add <8 x i16> %1, %1
370   ; ALL-DAG: addv.h [[R2:\$w[0-9]+]], [[R1]], [[R1]]
371
372   %3 = extractelement <8 x i16> %2, i32 1
373   %4 = zext i16 %3 to i32
374   ; ALL-DAG: copy_u.h [[R3:\$[0-9]+]], [[R1]][1]
375   ; ALL-NOT: andi
376
377   ret i32 %4
378 }
379
380 define i32 @extract_zext_v4i32() nounwind {
381   ; ALL-LABEL: extract_zext_v4i32:
382
383   %1 = load <4 x i32>, <4 x i32>* @v4i32
384   ; ALL-DAG: ld.w [[R1:\$w[0-9]+]],
385
386   %2 = add <4 x i32> %1, %1
387   ; ALL-DAG: addv.w [[R2:\$w[0-9]+]], [[R1]], [[R1]]
388
389   %3 = extractelement <4 x i32> %2, i32 1
390   ; ALL-DAG: copy_{{[su]}}.w [[R3:\$[0-9]+]], [[R1]][1]
391
392   ret i32 %3
393 }
394
395 define i64 @extract_zext_v2i64() nounwind {
396   ; ALL-LABEL: extract_zext_v2i64:
397
398   %1 = load <2 x i64>, <2 x i64>* @v2i64
399   ; ALL-DAG: ld.d [[R1:\$w[0-9]+]],
400
401   %2 = add <2 x i64> %1, %1
402   ; ALL-DAG: addv.d [[R2:\$w[0-9]+]], [[R1]], [[R1]]
403
404   %3 = extractelement <2 x i64> %2, i32 1
405   ; MIPS32-DAG: copy_{{[su]}}.w [[R3:\$[0-9]+]], [[R1]][2]
406   ; MIPS32-DAG: copy_{{[su]}}.w [[R4:\$[0-9]+]], [[R1]][3]
407   ; MIPS64-DAG: copy_{{[su]}}.d [[R3:\$[0-9]+]], [[R1]][1]
408   ; ALL-NOT: andi
409
410   ret i64 %3
411 }
412
413 define i32 @extract_sext_v16i8_vidx() nounwind {
414   ; ALL-LABEL: extract_sext_v16i8_vidx:
415
416   %1 = load <16 x i8>, <16 x i8>* @v16i8
417   ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v16i8)(
418   ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v16i8)(
419   ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v16i8)(
420   ; ALL-DAG: ld.b [[R1:\$w[0-9]+]], 0([[PTR_V]])
421
422   %2 = add <16 x i8> %1, %1
423   ; ALL-DAG: addv.b [[R2:\$w[0-9]+]], [[R1]], [[R1]]
424
425   %3 = load i32, i32* @i32
426   ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
427   ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
428   ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
429   ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
430
431   %4 = extractelement <16 x i8> %2, i32 %3
432   %5 = sext i8 %4 to i32
433   ; ALL-DAG: splat.b $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]]
434   ; ALL-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]]
435   ; ALL-DAG: sra [[R6:\$[0-9]+]], [[R5]], 24
436
437   ret i32 %5
438 }
439
440 define i32 @extract_sext_v8i16_vidx() nounwind {
441   ; ALL-LABEL: extract_sext_v8i16_vidx:
442
443   %1 = load <8 x i16>, <8 x i16>* @v8i16
444   ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v8i16)(
445   ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v8i16)(
446   ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v8i16)(
447   ; ALL-DAG: ld.h [[R1:\$w[0-9]+]], 0([[PTR_V]])
448
449   %2 = add <8 x i16> %1, %1
450   ; ALL-DAG: addv.h [[R2:\$w[0-9]+]], [[R1]], [[R1]]
451
452   %3 = load i32, i32* @i32
453   ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
454   ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
455   ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
456   ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
457
458   %4 = extractelement <8 x i16> %2, i32 %3
459   %5 = sext i16 %4 to i32
460   ; ALL-DAG: splat.h $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]]
461   ; ALL-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]]
462   ; ALL-DAG: sra [[R6:\$[0-9]+]], [[R5]], 16
463
464   ret i32 %5
465 }
466
467 define i32 @extract_sext_v4i32_vidx() nounwind {
468   ; ALL-LABEL: extract_sext_v4i32_vidx:
469
470   %1 = load <4 x i32>, <4 x i32>* @v4i32
471   ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v4i32)(
472   ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v4i32)(
473   ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v4i32)(
474   ; ALL-DAG: ld.w [[R1:\$w[0-9]+]], 0([[PTR_V]])
475
476   %2 = add <4 x i32> %1, %1
477   ; ALL-DAG: addv.w [[R2:\$w[0-9]+]], [[R1]], [[R1]]
478
479   %3 = load i32, i32* @i32
480   ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
481   ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
482   ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
483   ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
484
485   %4 = extractelement <4 x i32> %2, i32 %3
486   ; ALL-DAG: splat.w $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]]
487   ; ALL-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]]
488   ; ALL-NOT: sra
489
490   ret i32 %4
491 }
492
493 define i64 @extract_sext_v2i64_vidx() nounwind {
494   ; ALL-LABEL: extract_sext_v2i64_vidx:
495
496   %1 = load <2 x i64>, <2 x i64>* @v2i64
497   ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v2i64)(
498   ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v2i64)(
499   ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v2i64)(
500   ; ALL-DAG: ld.d [[R1:\$w[0-9]+]], 0([[PTR_V]])
501
502   %2 = add <2 x i64> %1, %1
503   ; ALL-DAG: addv.d [[R2:\$w[0-9]+]], [[R1]], [[R1]]
504
505   %3 = load i32, i32* @i32
506   ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
507   ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
508   ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
509   ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
510
511   %4 = extractelement <2 x i64> %2, i32 %3
512   ; MIPS32-DAG: splat.w $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]]
513   ; MIPS32-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]]
514   ; MIPS32-DAG: splat.w $w[[R4:[0-9]+]], [[R1]]{{\[}}[[IDX]]]
515   ; MIPS32-DAG: mfc1 [[R6:\$[0-9]+]], $f[[R4]]
516   ; MIPS64-DAG: splat.d $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]]
517   ; MIPS64-DAG: dmfc1 [[R5:\$[0-9]+]], $f[[R3]]
518   ; ALL-NOT: sra
519
520   ret i64 %4
521 }
522
523 define i32 @extract_zext_v16i8_vidx() nounwind {
524   ; ALL-LABEL: extract_zext_v16i8_vidx:
525
526   %1 = load <16 x i8>, <16 x i8>* @v16i8
527   ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v16i8)(
528   ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v16i8)(
529   ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v16i8)(
530   ; ALL-DAG: ld.b [[R1:\$w[0-9]+]], 0([[PTR_V]])
531
532   %2 = add <16 x i8> %1, %1
533   ; ALL-DAG: addv.b [[R2:\$w[0-9]+]], [[R1]], [[R1]]
534
535   %3 = load i32, i32* @i32
536   ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
537   ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
538   ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
539   ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
540
541   %4 = extractelement <16 x i8> %2, i32 %3
542   %5 = zext i8 %4 to i32
543   ; ALL-DAG: splat.b $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]]
544   ; ALL-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]]
545   ; ALL-DAG: srl [[R6:\$[0-9]+]], [[R5]], 24
546
547   ret i32 %5
548 }
549
550 define i32 @extract_zext_v8i16_vidx() nounwind {
551   ; ALL-LABEL: extract_zext_v8i16_vidx:
552
553   %1 = load <8 x i16>, <8 x i16>* @v8i16
554   ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v8i16)(
555   ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v8i16)(
556   ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v8i16)(
557   ; ALL-DAG: ld.h [[R1:\$w[0-9]+]], 0([[PTR_V]])
558
559   %2 = add <8 x i16> %1, %1
560   ; ALL-DAG: addv.h [[R2:\$w[0-9]+]], [[R1]], [[R1]]
561
562   %3 = load i32, i32* @i32
563   ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
564   ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
565   ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
566   ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
567
568   %4 = extractelement <8 x i16> %2, i32 %3
569   %5 = zext i16 %4 to i32
570   ; ALL-DAG: splat.h $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]]
571   ; ALL-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]]
572   ; ALL-DAG: srl [[R6:\$[0-9]+]], [[R5]], 16
573
574   ret i32 %5
575 }
576
577 define i32 @extract_zext_v4i32_vidx() nounwind {
578   ; ALL-LABEL: extract_zext_v4i32_vidx:
579
580   %1 = load <4 x i32>, <4 x i32>* @v4i32
581   ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v4i32)(
582   ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v4i32)(
583   ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v4i32)(
584   ; ALL-DAG: ld.w [[R1:\$w[0-9]+]], 0([[PTR_V]])
585
586   %2 = add <4 x i32> %1, %1
587   ; ALL-DAG: addv.w [[R2:\$w[0-9]+]], [[R1]], [[R1]]
588
589   %3 = load i32, i32* @i32
590   ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
591   ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
592   ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
593   ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
594
595   %4 = extractelement <4 x i32> %2, i32 %3
596   ; ALL-DAG: splat.w $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]]
597   ; ALL-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]]
598   ; ALL-NOT: srl
599
600   ret i32 %4
601 }
602
603 define i64 @extract_zext_v2i64_vidx() nounwind {
604   ; ALL-LABEL: extract_zext_v2i64_vidx:
605
606   %1 = load <2 x i64>, <2 x i64>* @v2i64
607   ; O32-DAG: lw [[PTR_V:\$[0-9]+]], %got(v2i64)(
608   ; N32-DAG: lw [[PTR_V:\$[0-9]+]], %got_disp(v2i64)(
609   ; N64-DAG: ld [[PTR_V:\$[0-9]+]], %got_disp(v2i64)(
610   ; ALL-DAG: ld.d [[R1:\$w[0-9]+]], 0([[PTR_V]])
611
612   %2 = add <2 x i64> %1, %1
613   ; ALL-DAG: addv.d [[R2:\$w[0-9]+]], [[R1]], [[R1]]
614
615   %3 = load i32, i32* @i32
616   ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
617   ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
618   ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
619   ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
620
621   %4 = extractelement <2 x i64> %2, i32 %3
622   ; MIPS32-DAG: splat.w $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]]
623   ; MIPS32-DAG: mfc1 [[R5:\$[0-9]+]], $f[[R3]]
624   ; MIPS32-DAG: splat.w $w[[R4:[0-9]+]], [[R1]]{{\[}}[[IDX]]]
625   ; MIPS32-DAG: mfc1 [[R6:\$[0-9]+]], $f[[R4]]
626   ; MIPS64-DAG: splat.d $w[[R3:[0-9]+]], [[R1]]{{\[}}[[IDX]]]
627   ; MIPS64-DAG: dmfc1 [[R5:\$[0-9]+]], $f[[R3]]
628   ; ALL-NOT: srl
629
630   ret i64 %4
631 }
632
633 define void @insert_v16i8(i32 signext %a) nounwind {
634   ; ALL-LABEL: insert_v16i8:
635
636   %1 = load <16 x i8>, <16 x i8>* @v16i8
637   ; ALL-DAG: ld.b [[R1:\$w[0-9]+]],
638
639   %a2 = trunc i32 %a to i8
640   %a3 = sext i8 %a2 to i32
641   %a4 = trunc i32 %a3 to i8
642   ; ALL-NOT: andi
643   ; ALL-NOT: sra
644
645   %2 = insertelement <16 x i8> %1, i8 %a4, i32 1
646   ; ALL-DAG: insert.b [[R1]][1], $4
647
648   store <16 x i8> %2, <16 x i8>* @v16i8
649   ; ALL-DAG: st.b [[R1]]
650
651   ret void
652 }
653
654 define void @insert_v8i16(i32 signext %a) nounwind {
655   ; ALL-LABEL: insert_v8i16:
656
657   %1 = load <8 x i16>, <8 x i16>* @v8i16
658   ; ALL-DAG: ld.h [[R1:\$w[0-9]+]],
659
660   %a2 = trunc i32 %a to i16
661   %a3 = sext i16 %a2 to i32
662   %a4 = trunc i32 %a3 to i16
663   ; ALL-NOT: andi
664   ; ALL-NOT: sra
665
666   %2 = insertelement <8 x i16> %1, i16 %a4, i32 1
667   ; ALL-DAG: insert.h [[R1]][1], $4
668
669   store <8 x i16> %2, <8 x i16>* @v8i16
670   ; ALL-DAG: st.h [[R1]]
671
672   ret void
673 }
674
675 define void @insert_v4i32(i32 signext %a) nounwind {
676   ; ALL-LABEL: insert_v4i32:
677
678   %1 = load <4 x i32>, <4 x i32>* @v4i32
679   ; ALL-DAG: ld.w [[R1:\$w[0-9]+]],
680
681   ; ALL-NOT: andi
682   ; ALL-NOT: sra
683
684   %2 = insertelement <4 x i32> %1, i32 %a, i32 1
685   ; ALL-DAG: insert.w [[R1]][1], $4
686
687   store <4 x i32> %2, <4 x i32>* @v4i32
688   ; ALL-DAG: st.w [[R1]]
689
690   ret void
691 }
692
693 define void @insert_v2i64(i64 signext %a) nounwind {
694   ; ALL-LABEL: insert_v2i64:
695
696   %1 = load <2 x i64>, <2 x i64>* @v2i64
697   ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]],
698   ; MIPS64-DAG: ld.d [[R1:\$w[0-9]+]],
699
700   ; ALL-NOT: andi
701   ; ALL-NOT: sra
702
703   %2 = insertelement <2 x i64> %1, i64 %a, i32 1
704   ; MIPS32-DAG: insert.w [[R1]][2], $4
705   ; MIPS32-DAG: insert.w [[R1]][3], $5
706   ; MIPS64-DAG: insert.d [[R1]][1], $4
707
708   store <2 x i64> %2, <2 x i64>* @v2i64
709   ; MIPS32-DAG: st.w [[R1]]
710   ; MIPS64-DAG: st.d [[R1]]
711
712   ret void
713 }
714
715 define void @insert_v16i8_vidx(i32 signext %a) nounwind {
716   ; ALL-LABEL: insert_v16i8_vidx:
717
718   %1 = load <16 x i8>, <16 x i8>* @v16i8
719   ; ALL-DAG: ld.b [[R1:\$w[0-9]+]],
720
721   %2 = load i32, i32* @i32
722   ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
723   ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
724   ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
725   ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
726
727   %a2 = trunc i32 %a to i8
728   %a3 = sext i8 %a2 to i32
729   %a4 = trunc i32 %a3 to i8
730   ; ALL-NOT: andi
731   ; ALL-NOT: sra
732
733   %3 = insertelement <16 x i8> %1, i8 %a4, i32 %2
734   ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[IDX]]]
735   ; ALL-DAG: insert.b [[R1]][0], $4
736   ; O32-DAG: neg [[NIDX:\$[0-9]+]], [[IDX]]
737   ; N32-DAG: neg [[NIDX:\$[0-9]+]], [[IDX]]
738   ; N64-DAG: dneg [[NIDX:\$[0-9]+]], [[IDX]]
739   ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]]
740
741   store <16 x i8> %3, <16 x i8>* @v16i8
742   ; ALL-DAG: st.b [[R1]]
743
744   ret void
745 }
746
747 define void @insert_v8i16_vidx(i32 signext %a) nounwind {
748   ; ALL-LABEL: insert_v8i16_vidx:
749
750   %1 = load <8 x i16>, <8 x i16>* @v8i16
751   ; ALL-DAG: ld.h [[R1:\$w[0-9]+]],
752
753   %2 = load i32, i32* @i32
754   ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
755   ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
756   ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
757   ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
758
759   %a2 = trunc i32 %a to i16
760   %a3 = sext i16 %a2 to i32
761   %a4 = trunc i32 %a3 to i16
762   ; ALL-NOT: andi
763   ; ALL-NOT: sra
764
765   %3 = insertelement <8 x i16> %1, i16 %a4, i32 %2
766   ; ALL-DAG: sll [[BIDX:\$[0-9]+]], [[IDX]], 1
767   ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[BIDX]]]
768   ; ALL-DAG: insert.h [[R1]][0], $4
769   ; O32-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]]
770   ; N32-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]]
771   ; N64-DAG: dneg [[NIDX:\$[0-9]+]], [[BIDX]]
772   ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]]
773
774   store <8 x i16> %3, <8 x i16>* @v8i16
775   ; ALL-DAG: st.h [[R1]]
776
777   ret void
778 }
779
780 define void @insert_v4i32_vidx(i32 signext %a) nounwind {
781   ; ALL-LABEL: insert_v4i32_vidx:
782
783   %1 = load <4 x i32>, <4 x i32>* @v4i32
784   ; ALL-DAG: ld.w [[R1:\$w[0-9]+]],
785
786   %2 = load i32, i32* @i32
787   ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
788   ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
789   ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
790   ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
791
792   ; ALL-NOT: andi
793   ; ALL-NOT: sra
794
795   %3 = insertelement <4 x i32> %1, i32 %a, i32 %2
796   ; ALL-DAG: sll [[BIDX:\$[0-9]+]], [[IDX]], 2
797   ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[BIDX]]]
798   ; ALL-DAG: insert.w [[R1]][0], $4
799   ; ALL-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]]
800   ; ALL-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]]
801
802   store <4 x i32> %3, <4 x i32>* @v4i32
803   ; ALL-DAG: st.w [[R1]]
804
805   ret void
806 }
807
808 define void @insert_v2i64_vidx(i64 signext %a) nounwind {
809   ; ALL-LABEL: insert_v2i64_vidx:
810
811   %1 = load <2 x i64>, <2 x i64>* @v2i64
812   ; MIPS32-DAG: ld.w [[R1:\$w[0-9]+]],
813   ; MIPS64-DAG: ld.d [[R1:\$w[0-9]+]],
814
815   %2 = load i32, i32* @i32
816   ; O32-DAG: lw [[PTR_I:\$[0-9]+]], %got(i32)(
817   ; N32-DAG: lw [[PTR_I:\$[0-9]+]], %got_disp(i32)(
818   ; N64-DAG: ld [[PTR_I:\$[0-9]+]], %got_disp(i32)(
819   ; ALL-DAG: lw [[IDX:\$[0-9]+]], 0([[PTR_I]])
820
821   ; ALL-NOT: andi
822   ; ALL-NOT: sra
823
824   %3 = insertelement <2 x i64> %1, i64 %a, i32 %2
825   ; TODO: This code could be a lot better but it works. The legalizer splits
826   ; 64-bit inserts into two 32-bit inserts because there is no i64 type on
827   ; MIPS32. The obvious optimisation is to perform both insert.w's at once while
828   ; the vector is rotated.
829   ; MIPS32-DAG: sll [[BIDX:\$[0-9]+]], [[IDX]], 2
830   ; MIPS32-DAG: sld.b [[R1]], [[R1]]{{\[}}[[BIDX]]]
831   ; MIPS32-DAG: insert.w [[R1]][0], $4
832   ; MIPS32-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]]
833   ; MIPS32-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]]
834   ; MIPS32-DAG: addiu [[IDX2:\$[0-9]+]], [[IDX]], 1
835   ; MIPS32-DAG: sll [[BIDX:\$[0-9]+]], [[IDX2]], 2
836   ; MIPS32-DAG: sld.b [[R1]], [[R1]]{{\[}}[[BIDX]]]
837   ; MIPS32-DAG: insert.w [[R1]][0], $5
838   ; MIPS32-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]]
839   ; MIPS32-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]]
840
841   ; MIPS64-DAG: sll [[BIDX:\$[0-9]+]], [[IDX]], 3
842   ; MIPS64-DAG: sld.b [[R1]], [[R1]]{{\[}}[[BIDX]]]
843   ; MIPS64-DAG: insert.d [[R1]][0], $4
844   ; N32-DAG: neg [[NIDX:\$[0-9]+]], [[BIDX]]
845   ; N64-DAG: dneg [[NIDX:\$[0-9]+]], [[BIDX]]
846   ; MIPS64-DAG: sld.b [[R1]], [[R1]]{{\[}}[[NIDX]]]
847
848   store <2 x i64> %3, <2 x i64>* @v2i64
849   ; MIPS32-DAG: st.w [[R1]]
850   ; MIPS64-DAG: st.d [[R1]]
851
852   ret void
853 }
854
855 define void @truncstore() nounwind {
856   ; ALL-LABEL: truncstore:
857
858   store volatile <4 x i8> <i8 -1, i8 -1, i8 -1, i8 -1>, <4 x i8>*@v4i8
859   ; TODO: What code should be emitted?
860
861   ret void
862 }