[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / Mips / funnel-shift-rot.ll
blob49532f246838ac9368eeed1163e42a5f3f86db7c
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=mips-linux-gnu -march=mips -mcpu=mips32 | FileCheck %s --check-prefixes=CHECK,CHECK-BE
3 ; RUN: llc < %s -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips32 | FileCheck %s --check-prefixes=CHECK,CHECK-LE
5 declare i8 @llvm.fshl.i8(i8, i8, i8)
6 declare i16 @llvm.fshl.i16(i16, i16, i16)
7 declare i32 @llvm.fshl.i32(i32, i32, i32)
8 declare i64 @llvm.fshl.i64(i64, i64, i64)
9 declare <4 x i32> @llvm.fshl.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
11 declare i8 @llvm.fshr.i8(i8, i8, i8)
12 declare i16 @llvm.fshr.i16(i16, i16, i16)
13 declare i32 @llvm.fshr.i32(i32, i32, i32)
14 declare i64 @llvm.fshr.i64(i64, i64, i64)
15 declare <4 x i32> @llvm.fshr.v4i32(<4 x i32>, <4 x i32>, <4 x i32>)
17 ; When first 2 operands match, it's a rotate.
19 define i8 @rotl_i8_const_shift(i8 %x) {
20 ; CHECK-LABEL: rotl_i8_const_shift:
21 ; CHECK:       # %bb.0:
22 ; CHECK-NEXT:    sll $1, $4, 3
23 ; CHECK-NEXT:    andi $2, $4, 224
24 ; CHECK-NEXT:    srl $2, $2, 5
25 ; CHECK-NEXT:    jr $ra
26 ; CHECK-NEXT:    or $2, $1, $2
27   %f = call i8 @llvm.fshl.i8(i8 %x, i8 %x, i8 3)
28   ret i8 %f
31 define i64 @rotl_i64_const_shift(i64 %x) {
32 ; CHECK-LABEL: rotl_i64_const_shift:
33 ; CHECK:       # %bb.0:
34 ; CHECK-NEXT:    srl $1, $5, 29
35 ; CHECK-NEXT:    sll $2, $4, 3
36 ; CHECK-NEXT:    or $2, $2, $1
37 ; CHECK-NEXT:    srl $1, $4, 29
38 ; CHECK-NEXT:    sll $3, $5, 3
39 ; CHECK-NEXT:    jr $ra
40 ; CHECK-NEXT:    or $3, $3, $1
41   %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 3)
42   ret i64 %f
45 ; When first 2 operands match, it's a rotate (by variable amount).
47 define i16 @rotl_i16(i16 %x, i16 %z) {
48 ; CHECK-LABEL: rotl_i16:
49 ; CHECK:       # %bb.0:
50 ; CHECK-NEXT:    andi $1, $5, 15
51 ; CHECK-NEXT:    sllv $1, $4, $1
52 ; CHECK-NEXT:    negu $2, $5
53 ; CHECK-NEXT:    andi $2, $2, 15
54 ; CHECK-NEXT:    andi $3, $4, 65535
55 ; CHECK-NEXT:    srlv $2, $3, $2
56 ; CHECK-NEXT:    jr $ra
57 ; CHECK-NEXT:    or $2, $1, $2
58   %f = call i16 @llvm.fshl.i16(i16 %x, i16 %x, i16 %z)
59   ret i16 %f
62 define i32 @rotl_i32(i32 %x, i32 %z) {
63 ; CHECK-LABEL: rotl_i32:
64 ; CHECK:       # %bb.0:
65 ; CHECK-NEXT:    andi $1, $5, 31
66 ; CHECK-NEXT:    sllv $1, $4, $1
67 ; CHECK-NEXT:    negu $2, $5
68 ; CHECK-NEXT:    andi $2, $2, 31
69 ; CHECK-NEXT:    srlv $2, $4, $2
70 ; CHECK-NEXT:    jr $ra
71 ; CHECK-NEXT:    or $2, $1, $2
72   %f = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %z)
73   ret i32 %f
76 define i64 @rotl_i64(i64 %x, i64 %z) {
77 ; CHECK-BE-LABEL: rotl_i64:
78 ; CHECK-BE:       # %bb.0:
79 ; CHECK-BE-NEXT:    negu $1, $7
80 ; CHECK-BE-NEXT:    andi $3, $1, 63
81 ; CHECK-BE-NEXT:    srlv $6, $4, $3
82 ; CHECK-BE-NEXT:    andi $1, $1, 32
83 ; CHECK-BE-NEXT:    andi $2, $7, 63
84 ; CHECK-BE-NEXT:    move $8, $6
85 ; CHECK-BE-NEXT:    movn $8, $zero, $1
86 ; CHECK-BE-NEXT:    sllv $9, $4, $2
87 ; CHECK-BE-NEXT:    srl $10, $5, 1
88 ; CHECK-BE-NEXT:    not $11, $2
89 ; CHECK-BE-NEXT:    srlv $10, $10, $11
90 ; CHECK-BE-NEXT:    or $9, $9, $10
91 ; CHECK-BE-NEXT:    sllv $10, $5, $2
92 ; CHECK-BE-NEXT:    andi $7, $7, 32
93 ; CHECK-BE-NEXT:    movn $9, $10, $7
94 ; CHECK-BE-NEXT:    or $2, $9, $8
95 ; CHECK-BE-NEXT:    srlv $5, $5, $3
96 ; CHECK-BE-NEXT:    not $3, $3
97 ; CHECK-BE-NEXT:    sll $4, $4, 1
98 ; CHECK-BE-NEXT:    sllv $3, $4, $3
99 ; CHECK-BE-NEXT:    or $3, $3, $5
100 ; CHECK-BE-NEXT:    movn $3, $6, $1
101 ; CHECK-BE-NEXT:    movn $10, $zero, $7
102 ; CHECK-BE-NEXT:    jr $ra
103 ; CHECK-BE-NEXT:    or $3, $10, $3
105 ; CHECK-LE-LABEL: rotl_i64:
106 ; CHECK-LE:       # %bb.0:
107 ; CHECK-LE-NEXT:    negu $1, $6
108 ; CHECK-LE-NEXT:    andi $2, $1, 63
109 ; CHECK-LE-NEXT:    srlv $7, $5, $2
110 ; CHECK-LE-NEXT:    andi $1, $1, 32
111 ; CHECK-LE-NEXT:    andi $3, $6, 63
112 ; CHECK-LE-NEXT:    move $8, $7
113 ; CHECK-LE-NEXT:    movn $8, $zero, $1
114 ; CHECK-LE-NEXT:    sllv $9, $5, $3
115 ; CHECK-LE-NEXT:    srl $10, $4, 1
116 ; CHECK-LE-NEXT:    not $11, $3
117 ; CHECK-LE-NEXT:    srlv $10, $10, $11
118 ; CHECK-LE-NEXT:    or $9, $9, $10
119 ; CHECK-LE-NEXT:    sllv $10, $4, $3
120 ; CHECK-LE-NEXT:    andi $6, $6, 32
121 ; CHECK-LE-NEXT:    movn $9, $10, $6
122 ; CHECK-LE-NEXT:    or $3, $9, $8
123 ; CHECK-LE-NEXT:    srlv $4, $4, $2
124 ; CHECK-LE-NEXT:    not $2, $2
125 ; CHECK-LE-NEXT:    sll $5, $5, 1
126 ; CHECK-LE-NEXT:    sllv $2, $5, $2
127 ; CHECK-LE-NEXT:    or $2, $2, $4
128 ; CHECK-LE-NEXT:    movn $2, $7, $1
129 ; CHECK-LE-NEXT:    movn $10, $zero, $6
130 ; CHECK-LE-NEXT:    jr $ra
131 ; CHECK-LE-NEXT:    or $2, $10, $2
132   %f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 %z)
133   ret i64 %f
136 ; Vector rotate.
138 define <4 x i32> @rotl_v4i32(<4 x i32> %x, <4 x i32> %z) {
139 ; CHECK-LABEL: rotl_v4i32:
140 ; CHECK:       # %bb.0:
141 ; CHECK-NEXT:    lw $1, 24($sp)
142 ; CHECK-NEXT:    negu $2, $1
143 ; CHECK-NEXT:    lw $3, 20($sp)
144 ; CHECK-NEXT:    negu $8, $3
145 ; CHECK-NEXT:    andi $8, $8, 31
146 ; CHECK-NEXT:    andi $2, $2, 31
147 ; CHECK-NEXT:    andi $3, $3, 31
148 ; CHECK-NEXT:    andi $1, $1, 31
149 ; CHECK-NEXT:    lw $9, 16($sp)
150 ; CHECK-NEXT:    sllv $1, $6, $1
151 ; CHECK-NEXT:    srlv $6, $6, $2
152 ; CHECK-NEXT:    sllv $3, $5, $3
153 ; CHECK-NEXT:    srlv $5, $5, $8
154 ; CHECK-NEXT:    andi $2, $9, 31
155 ; CHECK-NEXT:    sllv $2, $4, $2
156 ; CHECK-NEXT:    negu $8, $9
157 ; CHECK-NEXT:    andi $8, $8, 31
158 ; CHECK-NEXT:    srlv $4, $4, $8
159 ; CHECK-NEXT:    lw $8, 28($sp)
160 ; CHECK-NEXT:    or $2, $2, $4
161 ; CHECK-NEXT:    or $3, $3, $5
162 ; CHECK-NEXT:    or $4, $1, $6
163 ; CHECK-NEXT:    andi $1, $8, 31
164 ; CHECK-NEXT:    sllv $1, $7, $1
165 ; CHECK-NEXT:    negu $5, $8
166 ; CHECK-NEXT:    andi $5, $5, 31
167 ; CHECK-NEXT:    srlv $5, $7, $5
168 ; CHECK-NEXT:    jr $ra
169 ; CHECK-NEXT:    or $5, $1, $5
170   %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> %z)
171   ret <4 x i32> %f
174 ; Vector rotate by constant splat amount.
176 define <4 x i32> @rotl_v4i32_rotl_const_shift(<4 x i32> %x) {
177 ; CHECK-LABEL: rotl_v4i32_rotl_const_shift:
178 ; CHECK:       # %bb.0:
179 ; CHECK-NEXT:    srl $1, $5, 29
180 ; CHECK-NEXT:    sll $3, $5, 3
181 ; CHECK-NEXT:    srl $2, $4, 29
182 ; CHECK-NEXT:    sll $4, $4, 3
183 ; CHECK-NEXT:    or $2, $4, $2
184 ; CHECK-NEXT:    or $3, $3, $1
185 ; CHECK-NEXT:    srl $1, $6, 29
186 ; CHECK-NEXT:    sll $4, $6, 3
187 ; CHECK-NEXT:    or $4, $4, $1
188 ; CHECK-NEXT:    srl $1, $7, 29
189 ; CHECK-NEXT:    sll $5, $7, 3
190 ; CHECK-NEXT:    jr $ra
191 ; CHECK-NEXT:    or $5, $5, $1
192   %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 3, i32 3, i32 3, i32 3>)
193   ret <4 x i32> %f
196 ; Repeat everything for funnel shift right.
198 ; When first 2 operands match, it's a rotate.
200 define i8 @rotr_i8_const_shift(i8 %x) {
201 ; CHECK-LABEL: rotr_i8_const_shift:
202 ; CHECK:       # %bb.0:
203 ; CHECK-NEXT:    sll $1, $4, 5
204 ; CHECK-NEXT:    andi $2, $4, 248
205 ; CHECK-NEXT:    srl $2, $2, 3
206 ; CHECK-NEXT:    jr $ra
207 ; CHECK-NEXT:    or $2, $2, $1
208   %f = call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 3)
209   ret i8 %f
212 define i32 @rotr_i32_const_shift(i32 %x) {
213 ; CHECK-LABEL: rotr_i32_const_shift:
214 ; CHECK:       # %bb.0:
215 ; CHECK-NEXT:    sll $1, $4, 29
216 ; CHECK-NEXT:    srl $2, $4, 3
217 ; CHECK-NEXT:    jr $ra
218 ; CHECK-NEXT:    or $2, $2, $1
219   %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 3)
220   ret i32 %f
223 ; When first 2 operands match, it's a rotate (by variable amount).
225 define i16 @rotr_i16(i16 %x, i16 %z) {
226 ; CHECK-LABEL: rotr_i16:
227 ; CHECK:       # %bb.0:
228 ; CHECK-NEXT:    andi $1, $5, 15
229 ; CHECK-NEXT:    andi $2, $4, 65535
230 ; CHECK-NEXT:    srlv $1, $2, $1
231 ; CHECK-NEXT:    negu $2, $5
232 ; CHECK-NEXT:    andi $2, $2, 15
233 ; CHECK-NEXT:    sllv $2, $4, $2
234 ; CHECK-NEXT:    jr $ra
235 ; CHECK-NEXT:    or $2, $1, $2
236   %f = call i16 @llvm.fshr.i16(i16 %x, i16 %x, i16 %z)
237   ret i16 %f
240 define i32 @rotr_i32(i32 %x, i32 %z) {
241 ; CHECK-LABEL: rotr_i32:
242 ; CHECK:       # %bb.0:
243 ; CHECK-NEXT:    andi $1, $5, 31
244 ; CHECK-NEXT:    srlv $1, $4, $1
245 ; CHECK-NEXT:    negu $2, $5
246 ; CHECK-NEXT:    andi $2, $2, 31
247 ; CHECK-NEXT:    sllv $2, $4, $2
248 ; CHECK-NEXT:    jr $ra
249 ; CHECK-NEXT:    or $2, $1, $2
250   %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %z)
251   ret i32 %f
254 define i64 @rotr_i64(i64 %x, i64 %z) {
255 ; CHECK-BE-LABEL: rotr_i64:
256 ; CHECK-BE:       # %bb.0:
257 ; CHECK-BE-NEXT:    negu $1, $7
258 ; CHECK-BE-NEXT:    andi $2, $1, 63
259 ; CHECK-BE-NEXT:    sllv $6, $5, $2
260 ; CHECK-BE-NEXT:    andi $1, $1, 32
261 ; CHECK-BE-NEXT:    andi $3, $7, 63
262 ; CHECK-BE-NEXT:    move $8, $6
263 ; CHECK-BE-NEXT:    movn $8, $zero, $1
264 ; CHECK-BE-NEXT:    srlv $9, $5, $3
265 ; CHECK-BE-NEXT:    sll $10, $4, 1
266 ; CHECK-BE-NEXT:    not $11, $3
267 ; CHECK-BE-NEXT:    sllv $10, $10, $11
268 ; CHECK-BE-NEXT:    or $9, $10, $9
269 ; CHECK-BE-NEXT:    srlv $10, $4, $3
270 ; CHECK-BE-NEXT:    andi $7, $7, 32
271 ; CHECK-BE-NEXT:    movn $9, $10, $7
272 ; CHECK-BE-NEXT:    or $3, $9, $8
273 ; CHECK-BE-NEXT:    sllv $4, $4, $2
274 ; CHECK-BE-NEXT:    not $2, $2
275 ; CHECK-BE-NEXT:    srl $5, $5, 1
276 ; CHECK-BE-NEXT:    srlv $2, $5, $2
277 ; CHECK-BE-NEXT:    or $2, $4, $2
278 ; CHECK-BE-NEXT:    movn $2, $6, $1
279 ; CHECK-BE-NEXT:    movn $10, $zero, $7
280 ; CHECK-BE-NEXT:    jr $ra
281 ; CHECK-BE-NEXT:    or $2, $10, $2
283 ; CHECK-LE-LABEL: rotr_i64:
284 ; CHECK-LE:       # %bb.0:
285 ; CHECK-LE-NEXT:    negu $1, $6
286 ; CHECK-LE-NEXT:    andi $3, $1, 63
287 ; CHECK-LE-NEXT:    sllv $7, $4, $3
288 ; CHECK-LE-NEXT:    andi $1, $1, 32
289 ; CHECK-LE-NEXT:    andi $2, $6, 63
290 ; CHECK-LE-NEXT:    move $8, $7
291 ; CHECK-LE-NEXT:    movn $8, $zero, $1
292 ; CHECK-LE-NEXT:    srlv $9, $4, $2
293 ; CHECK-LE-NEXT:    sll $10, $5, 1
294 ; CHECK-LE-NEXT:    not $11, $2
295 ; CHECK-LE-NEXT:    sllv $10, $10, $11
296 ; CHECK-LE-NEXT:    or $9, $10, $9
297 ; CHECK-LE-NEXT:    srlv $10, $5, $2
298 ; CHECK-LE-NEXT:    andi $6, $6, 32
299 ; CHECK-LE-NEXT:    movn $9, $10, $6
300 ; CHECK-LE-NEXT:    or $2, $9, $8
301 ; CHECK-LE-NEXT:    sllv $5, $5, $3
302 ; CHECK-LE-NEXT:    not $3, $3
303 ; CHECK-LE-NEXT:    srl $4, $4, 1
304 ; CHECK-LE-NEXT:    srlv $3, $4, $3
305 ; CHECK-LE-NEXT:    or $3, $5, $3
306 ; CHECK-LE-NEXT:    movn $3, $7, $1
307 ; CHECK-LE-NEXT:    movn $10, $zero, $6
308 ; CHECK-LE-NEXT:    jr $ra
309 ; CHECK-LE-NEXT:    or $3, $10, $3
310   %f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 %z)
311   ret i64 %f
314 ; Vector rotate.
316 define <4 x i32> @rotr_v4i32(<4 x i32> %x, <4 x i32> %z) {
317 ; CHECK-LABEL: rotr_v4i32:
318 ; CHECK:       # %bb.0:
319 ; CHECK-NEXT:    lw $1, 24($sp)
320 ; CHECK-NEXT:    negu $2, $1
321 ; CHECK-NEXT:    lw $3, 20($sp)
322 ; CHECK-NEXT:    negu $8, $3
323 ; CHECK-NEXT:    andi $8, $8, 31
324 ; CHECK-NEXT:    andi $2, $2, 31
325 ; CHECK-NEXT:    andi $3, $3, 31
326 ; CHECK-NEXT:    andi $1, $1, 31
327 ; CHECK-NEXT:    lw $9, 16($sp)
328 ; CHECK-NEXT:    srlv $1, $6, $1
329 ; CHECK-NEXT:    sllv $6, $6, $2
330 ; CHECK-NEXT:    srlv $3, $5, $3
331 ; CHECK-NEXT:    sllv $5, $5, $8
332 ; CHECK-NEXT:    andi $2, $9, 31
333 ; CHECK-NEXT:    srlv $2, $4, $2
334 ; CHECK-NEXT:    negu $8, $9
335 ; CHECK-NEXT:    andi $8, $8, 31
336 ; CHECK-NEXT:    sllv $4, $4, $8
337 ; CHECK-NEXT:    lw $8, 28($sp)
338 ; CHECK-NEXT:    or $2, $2, $4
339 ; CHECK-NEXT:    or $3, $3, $5
340 ; CHECK-NEXT:    or $4, $1, $6
341 ; CHECK-NEXT:    andi $1, $8, 31
342 ; CHECK-NEXT:    srlv $1, $7, $1
343 ; CHECK-NEXT:    negu $5, $8
344 ; CHECK-NEXT:    andi $5, $5, 31
345 ; CHECK-NEXT:    sllv $5, $7, $5
346 ; CHECK-NEXT:    jr $ra
347 ; CHECK-NEXT:    or $5, $1, $5
348   %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> %z)
349   ret <4 x i32> %f
352 ; Vector rotate by constant splat amount.
354 define <4 x i32> @rotr_v4i32_const_shift(<4 x i32> %x) {
355 ; CHECK-LABEL: rotr_v4i32_const_shift:
356 ; CHECK:       # %bb.0:
357 ; CHECK-NEXT:    sll $1, $5, 29
358 ; CHECK-NEXT:    srl $3, $5, 3
359 ; CHECK-NEXT:    sll $2, $4, 29
360 ; CHECK-NEXT:    srl $4, $4, 3
361 ; CHECK-NEXT:    or $2, $4, $2
362 ; CHECK-NEXT:    or $3, $3, $1
363 ; CHECK-NEXT:    sll $1, $6, 29
364 ; CHECK-NEXT:    srl $4, $6, 3
365 ; CHECK-NEXT:    or $4, $4, $1
366 ; CHECK-NEXT:    sll $1, $7, 29
367 ; CHECK-NEXT:    srl $5, $7, 3
368 ; CHECK-NEXT:    jr $ra
369 ; CHECK-NEXT:    or $5, $5, $1
370   %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 3, i32 3, i32 3, i32 3>)
371   ret <4 x i32> %f
374 define i32 @rotl_i32_shift_by_bitwidth(i32 %x) {
375 ; CHECK-LABEL: rotl_i32_shift_by_bitwidth:
376 ; CHECK:       # %bb.0:
377 ; CHECK-NEXT:    jr $ra
378 ; CHECK-NEXT:    move $2, $4
379   %f = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 32)
380   ret i32 %f
383 define i32 @rotr_i32_shift_by_bitwidth(i32 %x) {
384 ; CHECK-LABEL: rotr_i32_shift_by_bitwidth:
385 ; CHECK:       # %bb.0:
386 ; CHECK-NEXT:    jr $ra
387 ; CHECK-NEXT:    move $2, $4
388   %f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 32)
389   ret i32 %f
392 define <4 x i32> @rotl_v4i32_shift_by_bitwidth(<4 x i32> %x) {
393 ; CHECK-LABEL: rotl_v4i32_shift_by_bitwidth:
394 ; CHECK:       # %bb.0:
395 ; CHECK-NEXT:    move $2, $4
396 ; CHECK-NEXT:    move $3, $5
397 ; CHECK-NEXT:    move $4, $6
398 ; CHECK-NEXT:    jr $ra
399 ; CHECK-NEXT:    move $5, $7
400   %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 32, i32 32, i32 32, i32 32>)
401   ret <4 x i32> %f
404 define <4 x i32> @rotr_v4i32_shift_by_bitwidth(<4 x i32> %x) {
405 ; CHECK-LABEL: rotr_v4i32_shift_by_bitwidth:
406 ; CHECK:       # %bb.0:
407 ; CHECK-NEXT:    move $2, $4
408 ; CHECK-NEXT:    move $3, $5
409 ; CHECK-NEXT:    move $4, $6
410 ; CHECK-NEXT:    jr $ra
411 ; CHECK-NEXT:    move $5, $7
412   %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %x, <4 x i32> <i32 32, i32 32, i32 32, i32 32>)
413   ret <4 x i32> %f