[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / Mips / funnel-shift.ll
blob99029b7b9410c7b65163ea51a4eda937af985afc
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 ; General case - all operands can be variables.
19 define i16 @fshl_i16(i16 %x, i16 %y, i16 %z) {
20 ; CHECK-LABEL: fshl_i16:
21 ; CHECK:       # %bb.0:
22 ; CHECK-NEXT:    andi $1, $5, 65535
23 ; CHECK-NEXT:    sll $2, $4, 16
24 ; CHECK-NEXT:    or $1, $2, $1
25 ; CHECK-NEXT:    andi $2, $6, 15
26 ; CHECK-NEXT:    sllv $1, $1, $2
27 ; CHECK-NEXT:    jr $ra
28 ; CHECK-NEXT:    srl $2, $1, 16
29   %f = call i16 @llvm.fshl.i16(i16 %x, i16 %y, i16 %z)
30   ret i16 %f
33 define i32 @fshl_i32(i32 %x, i32 %y, i32 %z) {
34 ; CHECK-LABEL: fshl_i32:
35 ; CHECK:       # %bb.0:
36 ; CHECK-NEXT:    andi $1, $6, 31
37 ; CHECK-NEXT:    sllv $1, $4, $1
38 ; CHECK-NEXT:    srl $2, $5, 1
39 ; CHECK-NEXT:    not $3, $6
40 ; CHECK-NEXT:    andi $3, $3, 31
41 ; CHECK-NEXT:    srlv $2, $2, $3
42 ; CHECK-NEXT:    jr $ra
43 ; CHECK-NEXT:    or $2, $1, $2
44   %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %z)
45   ret i32 %f
48 ; Verify that weird types are minimally supported.
49 declare i37 @llvm.fshl.i37(i37, i37, i37)
50 define i37 @fshl_i37(i37 %x, i37 %y, i37 %z) {
51 ; CHECK-BE-LABEL: fshl_i37:
52 ; CHECK-BE:       # %bb.0:
53 ; CHECK-BE-NEXT:    addiu $sp, $sp, -40
54 ; CHECK-BE-NEXT:    .cfi_def_cfa_offset 40
55 ; CHECK-BE-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
56 ; CHECK-BE-NEXT:    sw $19, 32($sp) # 4-byte Folded Spill
57 ; CHECK-BE-NEXT:    sw $18, 28($sp) # 4-byte Folded Spill
58 ; CHECK-BE-NEXT:    sw $17, 24($sp) # 4-byte Folded Spill
59 ; CHECK-BE-NEXT:    sw $16, 20($sp) # 4-byte Folded Spill
60 ; CHECK-BE-NEXT:    .cfi_offset 31, -4
61 ; CHECK-BE-NEXT:    .cfi_offset 19, -8
62 ; CHECK-BE-NEXT:    .cfi_offset 18, -12
63 ; CHECK-BE-NEXT:    .cfi_offset 17, -16
64 ; CHECK-BE-NEXT:    .cfi_offset 16, -20
65 ; CHECK-BE-NEXT:    move $16, $7
66 ; CHECK-BE-NEXT:    move $17, $6
67 ; CHECK-BE-NEXT:    move $18, $5
68 ; CHECK-BE-NEXT:    move $19, $4
69 ; CHECK-BE-NEXT:    lw $4, 56($sp)
70 ; CHECK-BE-NEXT:    lw $5, 60($sp)
71 ; CHECK-BE-NEXT:    addiu $6, $zero, 0
72 ; CHECK-BE-NEXT:    jal __umoddi3
73 ; CHECK-BE-NEXT:    addiu $7, $zero, 37
74 ; CHECK-BE-NEXT:    not $1, $3
75 ; CHECK-BE-NEXT:    andi $2, $3, 63
76 ; CHECK-BE-NEXT:    not $4, $2
77 ; CHECK-BE-NEXT:    srl $5, $18, 1
78 ; CHECK-BE-NEXT:    sllv $6, $19, $2
79 ; CHECK-BE-NEXT:    srlv $4, $5, $4
80 ; CHECK-BE-NEXT:    andi $5, $1, 63
81 ; CHECK-BE-NEXT:    srl $7, $16, 5
82 ; CHECK-BE-NEXT:    sll $8, $17, 27
83 ; CHECK-BE-NEXT:    or $7, $8, $7
84 ; CHECK-BE-NEXT:    srl $8, $7, 1
85 ; CHECK-BE-NEXT:    srlv $9, $8, $5
86 ; CHECK-BE-NEXT:    andi $1, $1, 32
87 ; CHECK-BE-NEXT:    move $10, $9
88 ; CHECK-BE-NEXT:    movn $10, $zero, $1
89 ; CHECK-BE-NEXT:    or $4, $6, $4
90 ; CHECK-BE-NEXT:    sllv $6, $18, $2
91 ; CHECK-BE-NEXT:    andi $3, $3, 32
92 ; CHECK-BE-NEXT:    movn $4, $6, $3
93 ; CHECK-BE-NEXT:    sll $7, $7, 31
94 ; CHECK-BE-NEXT:    sll $2, $16, 27
95 ; CHECK-BE-NEXT:    srl $11, $2, 1
96 ; CHECK-BE-NEXT:    or $2, $4, $10
97 ; CHECK-BE-NEXT:    movn $6, $zero, $3
98 ; CHECK-BE-NEXT:    or $3, $11, $7
99 ; CHECK-BE-NEXT:    srlv $3, $3, $5
100 ; CHECK-BE-NEXT:    not $4, $5
101 ; CHECK-BE-NEXT:    sll $5, $8, 1
102 ; CHECK-BE-NEXT:    sllv $4, $5, $4
103 ; CHECK-BE-NEXT:    or $3, $4, $3
104 ; CHECK-BE-NEXT:    movn $3, $9, $1
105 ; CHECK-BE-NEXT:    or $3, $6, $3
106 ; CHECK-BE-NEXT:    lw $16, 20($sp) # 4-byte Folded Reload
107 ; CHECK-BE-NEXT:    lw $17, 24($sp) # 4-byte Folded Reload
108 ; CHECK-BE-NEXT:    lw $18, 28($sp) # 4-byte Folded Reload
109 ; CHECK-BE-NEXT:    lw $19, 32($sp) # 4-byte Folded Reload
110 ; CHECK-BE-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
111 ; CHECK-BE-NEXT:    jr $ra
112 ; CHECK-BE-NEXT:    addiu $sp, $sp, 40
114 ; CHECK-LE-LABEL: fshl_i37:
115 ; CHECK-LE:       # %bb.0:
116 ; CHECK-LE-NEXT:    addiu $sp, $sp, -40
117 ; CHECK-LE-NEXT:    .cfi_def_cfa_offset 40
118 ; CHECK-LE-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
119 ; CHECK-LE-NEXT:    sw $19, 32($sp) # 4-byte Folded Spill
120 ; CHECK-LE-NEXT:    sw $18, 28($sp) # 4-byte Folded Spill
121 ; CHECK-LE-NEXT:    sw $17, 24($sp) # 4-byte Folded Spill
122 ; CHECK-LE-NEXT:    sw $16, 20($sp) # 4-byte Folded Spill
123 ; CHECK-LE-NEXT:    .cfi_offset 31, -4
124 ; CHECK-LE-NEXT:    .cfi_offset 19, -8
125 ; CHECK-LE-NEXT:    .cfi_offset 18, -12
126 ; CHECK-LE-NEXT:    .cfi_offset 17, -16
127 ; CHECK-LE-NEXT:    .cfi_offset 16, -20
128 ; CHECK-LE-NEXT:    move $16, $7
129 ; CHECK-LE-NEXT:    move $17, $6
130 ; CHECK-LE-NEXT:    move $18, $5
131 ; CHECK-LE-NEXT:    move $19, $4
132 ; CHECK-LE-NEXT:    lw $4, 56($sp)
133 ; CHECK-LE-NEXT:    lw $5, 60($sp)
134 ; CHECK-LE-NEXT:    addiu $6, $zero, 37
135 ; CHECK-LE-NEXT:    jal __umoddi3
136 ; CHECK-LE-NEXT:    addiu $7, $zero, 0
137 ; CHECK-LE-NEXT:    not $1, $2
138 ; CHECK-LE-NEXT:    andi $3, $2, 63
139 ; CHECK-LE-NEXT:    not $4, $3
140 ; CHECK-LE-NEXT:    srl $5, $19, 1
141 ; CHECK-LE-NEXT:    sllv $6, $18, $3
142 ; CHECK-LE-NEXT:    srlv $4, $5, $4
143 ; CHECK-LE-NEXT:    andi $5, $1, 63
144 ; CHECK-LE-NEXT:    srl $7, $17, 5
145 ; CHECK-LE-NEXT:    sll $8, $16, 27
146 ; CHECK-LE-NEXT:    or $7, $8, $7
147 ; CHECK-LE-NEXT:    srl $8, $7, 1
148 ; CHECK-LE-NEXT:    srlv $9, $8, $5
149 ; CHECK-LE-NEXT:    andi $1, $1, 32
150 ; CHECK-LE-NEXT:    move $10, $9
151 ; CHECK-LE-NEXT:    movn $10, $zero, $1
152 ; CHECK-LE-NEXT:    or $4, $6, $4
153 ; CHECK-LE-NEXT:    sllv $6, $19, $3
154 ; CHECK-LE-NEXT:    andi $2, $2, 32
155 ; CHECK-LE-NEXT:    movn $4, $6, $2
156 ; CHECK-LE-NEXT:    sll $7, $7, 31
157 ; CHECK-LE-NEXT:    sll $3, $17, 27
158 ; CHECK-LE-NEXT:    srl $11, $3, 1
159 ; CHECK-LE-NEXT:    or $3, $4, $10
160 ; CHECK-LE-NEXT:    movn $6, $zero, $2
161 ; CHECK-LE-NEXT:    or $2, $11, $7
162 ; CHECK-LE-NEXT:    srlv $2, $2, $5
163 ; CHECK-LE-NEXT:    not $4, $5
164 ; CHECK-LE-NEXT:    sll $5, $8, 1
165 ; CHECK-LE-NEXT:    sllv $4, $5, $4
166 ; CHECK-LE-NEXT:    or $2, $4, $2
167 ; CHECK-LE-NEXT:    movn $2, $9, $1
168 ; CHECK-LE-NEXT:    or $2, $6, $2
169 ; CHECK-LE-NEXT:    lw $16, 20($sp) # 4-byte Folded Reload
170 ; CHECK-LE-NEXT:    lw $17, 24($sp) # 4-byte Folded Reload
171 ; CHECK-LE-NEXT:    lw $18, 28($sp) # 4-byte Folded Reload
172 ; CHECK-LE-NEXT:    lw $19, 32($sp) # 4-byte Folded Reload
173 ; CHECK-LE-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
174 ; CHECK-LE-NEXT:    jr $ra
175 ; CHECK-LE-NEXT:    addiu $sp, $sp, 40
176   %f = call i37 @llvm.fshl.i37(i37 %x, i37 %y, i37 %z)
177   ret i37 %f
180 ; extract(concat(0b1110000, 0b1111111) << 2) = 0b1000011
182 declare i7 @llvm.fshl.i7(i7, i7, i7)
183 define i7 @fshl_i7_const_fold() {
184 ; CHECK-LABEL: fshl_i7_const_fold:
185 ; CHECK:       # %bb.0:
186 ; CHECK-NEXT:    jr $ra
187 ; CHECK-NEXT:    addiu $2, $zero, 67
188   %f = call i7 @llvm.fshl.i7(i7 112, i7 127, i7 2)
189   ret i7 %f
192 define i8 @fshl_i8_const_fold_overshift_1() {
193 ; CHECK-LABEL: fshl_i8_const_fold_overshift_1:
194 ; CHECK:       # %bb.0:
195 ; CHECK-NEXT:    jr $ra
196 ; CHECK-NEXT:    addiu $2, $zero, 128
197   %f = call i8 @llvm.fshl.i8(i8 255, i8 0, i8 15)
198   ret i8 %f
201 define i8 @fshl_i8_const_fold_overshift_2() {
202 ; CHECK-LABEL: fshl_i8_const_fold_overshift_2:
203 ; CHECK:       # %bb.0:
204 ; CHECK-NEXT:    jr $ra
205 ; CHECK-NEXT:    addiu $2, $zero, 120
206   %f = call i8 @llvm.fshl.i8(i8 15, i8 15, i8 11)
207   ret i8 %f
210 define i8 @fshl_i8_const_fold_overshift_3() {
211 ; CHECK-LABEL: fshl_i8_const_fold_overshift_3:
212 ; CHECK:       # %bb.0:
213 ; CHECK-NEXT:    jr $ra
214 ; CHECK-NEXT:    addiu $2, $zero, 0
215   %f = call i8 @llvm.fshl.i8(i8 0, i8 225, i8 8)
216   ret i8 %f
219 ; With constant shift amount, this is 'extr'.
221 define i32 @fshl_i32_const_shift(i32 %x, i32 %y) {
222 ; CHECK-LABEL: fshl_i32_const_shift:
223 ; CHECK:       # %bb.0:
224 ; CHECK-NEXT:    srl $1, $5, 23
225 ; CHECK-NEXT:    sll $2, $4, 9
226 ; CHECK-NEXT:    jr $ra
227 ; CHECK-NEXT:    or $2, $2, $1
228   %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 9)
229   ret i32 %f
232 ; Check modulo math on shift amount.
234 define i32 @fshl_i32_const_overshift(i32 %x, i32 %y) {
235 ; CHECK-LABEL: fshl_i32_const_overshift:
236 ; CHECK:       # %bb.0:
237 ; CHECK-NEXT:    srl $1, $5, 23
238 ; CHECK-NEXT:    sll $2, $4, 9
239 ; CHECK-NEXT:    jr $ra
240 ; CHECK-NEXT:    or $2, $2, $1
241   %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 41)
242   ret i32 %f
245 ; 64-bit should also work.
247 define i64 @fshl_i64_const_overshift(i64 %x, i64 %y) {
248 ; CHECK-BE-LABEL: fshl_i64_const_overshift:
249 ; CHECK-BE:       # %bb.0:
250 ; CHECK-BE-NEXT:    srl $1, $6, 23
251 ; CHECK-BE-NEXT:    sll $2, $5, 9
252 ; CHECK-BE-NEXT:    or $2, $2, $1
253 ; CHECK-BE-NEXT:    sll $1, $6, 9
254 ; CHECK-BE-NEXT:    srl $3, $7, 23
255 ; CHECK-BE-NEXT:    jr $ra
256 ; CHECK-BE-NEXT:    or $3, $3, $1
258 ; CHECK-LE-LABEL: fshl_i64_const_overshift:
259 ; CHECK-LE:       # %bb.0:
260 ; CHECK-LE-NEXT:    sll $1, $7, 9
261 ; CHECK-LE-NEXT:    srl $2, $6, 23
262 ; CHECK-LE-NEXT:    or $2, $2, $1
263 ; CHECK-LE-NEXT:    srl $1, $7, 23
264 ; CHECK-LE-NEXT:    sll $3, $4, 9
265 ; CHECK-LE-NEXT:    jr $ra
266 ; CHECK-LE-NEXT:    or $3, $3, $1
267   %f = call i64 @llvm.fshl.i64(i64 %x, i64 %y, i64 105)
268   ret i64 %f
271 ; This should work without any node-specific logic.
273 define i8 @fshl_i8_const_fold() {
274 ; CHECK-LABEL: fshl_i8_const_fold:
275 ; CHECK:       # %bb.0:
276 ; CHECK-NEXT:    jr $ra
277 ; CHECK-NEXT:    addiu $2, $zero, 128
278   %f = call i8 @llvm.fshl.i8(i8 255, i8 0, i8 7)
279   ret i8 %f
282 ; Repeat everything for funnel shift right.
284 ; General case - all operands can be variables.
286 define i16 @fshr_i16(i16 %x, i16 %y, i16 %z) {
287 ; CHECK-LABEL: fshr_i16:
288 ; CHECK:       # %bb.0:
289 ; CHECK-NEXT:    andi $1, $5, 65535
290 ; CHECK-NEXT:    sll $2, $4, 16
291 ; CHECK-NEXT:    or $1, $2, $1
292 ; CHECK-NEXT:    andi $2, $6, 15
293 ; CHECK-NEXT:    jr $ra
294 ; CHECK-NEXT:    srlv $2, $1, $2
295   %f = call i16 @llvm.fshr.i16(i16 %x, i16 %y, i16 %z)
296   ret i16 %f
299 define i32 @fshr_i32(i32 %x, i32 %y, i32 %z) {
300 ; CHECK-LABEL: fshr_i32:
301 ; CHECK:       # %bb.0:
302 ; CHECK-NEXT:    andi $1, $6, 31
303 ; CHECK-NEXT:    srlv $1, $5, $1
304 ; CHECK-NEXT:    sll $2, $4, 1
305 ; CHECK-NEXT:    not $3, $6
306 ; CHECK-NEXT:    andi $3, $3, 31
307 ; CHECK-NEXT:    sllv $2, $2, $3
308 ; CHECK-NEXT:    jr $ra
309 ; CHECK-NEXT:    or $2, $2, $1
310   %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %z)
311   ret i32 %f
314 ; Verify that weird types are minimally supported.
315 declare i37 @llvm.fshr.i37(i37, i37, i37)
316 define i37 @fshr_i37(i37 %x, i37 %y, i37 %z) {
317 ; CHECK-BE-LABEL: fshr_i37:
318 ; CHECK-BE:       # %bb.0:
319 ; CHECK-BE-NEXT:    addiu $sp, $sp, -40
320 ; CHECK-BE-NEXT:    .cfi_def_cfa_offset 40
321 ; CHECK-BE-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
322 ; CHECK-BE-NEXT:    sw $19, 32($sp) # 4-byte Folded Spill
323 ; CHECK-BE-NEXT:    sw $18, 28($sp) # 4-byte Folded Spill
324 ; CHECK-BE-NEXT:    sw $17, 24($sp) # 4-byte Folded Spill
325 ; CHECK-BE-NEXT:    sw $16, 20($sp) # 4-byte Folded Spill
326 ; CHECK-BE-NEXT:    .cfi_offset 31, -4
327 ; CHECK-BE-NEXT:    .cfi_offset 19, -8
328 ; CHECK-BE-NEXT:    .cfi_offset 18, -12
329 ; CHECK-BE-NEXT:    .cfi_offset 17, -16
330 ; CHECK-BE-NEXT:    .cfi_offset 16, -20
331 ; CHECK-BE-NEXT:    move $16, $7
332 ; CHECK-BE-NEXT:    move $17, $6
333 ; CHECK-BE-NEXT:    move $18, $5
334 ; CHECK-BE-NEXT:    move $19, $4
335 ; CHECK-BE-NEXT:    lw $4, 56($sp)
336 ; CHECK-BE-NEXT:    lw $5, 60($sp)
337 ; CHECK-BE-NEXT:    addiu $6, $zero, 0
338 ; CHECK-BE-NEXT:    jal __umoddi3
339 ; CHECK-BE-NEXT:    addiu $7, $zero, 37
340 ; CHECK-BE-NEXT:    addiu $1, $3, 27
341 ; CHECK-BE-NEXT:    andi $2, $1, 63
342 ; CHECK-BE-NEXT:    not $3, $2
343 ; CHECK-BE-NEXT:    srl $4, $16, 5
344 ; CHECK-BE-NEXT:    sll $5, $17, 27
345 ; CHECK-BE-NEXT:    or $4, $5, $4
346 ; CHECK-BE-NEXT:    sll $5, $4, 1
347 ; CHECK-BE-NEXT:    sll $6, $16, 27
348 ; CHECK-BE-NEXT:    srlv $6, $6, $2
349 ; CHECK-BE-NEXT:    sllv $3, $5, $3
350 ; CHECK-BE-NEXT:    not $5, $1
351 ; CHECK-BE-NEXT:    andi $7, $5, 63
352 ; CHECK-BE-NEXT:    sll $8, $18, 1
353 ; CHECK-BE-NEXT:    sllv $8, $8, $7
354 ; CHECK-BE-NEXT:    andi $5, $5, 32
355 ; CHECK-BE-NEXT:    move $9, $8
356 ; CHECK-BE-NEXT:    movn $9, $zero, $5
357 ; CHECK-BE-NEXT:    or $3, $3, $6
358 ; CHECK-BE-NEXT:    srlv $2, $4, $2
359 ; CHECK-BE-NEXT:    andi $1, $1, 32
360 ; CHECK-BE-NEXT:    movn $3, $2, $1
361 ; CHECK-BE-NEXT:    srl $4, $18, 31
362 ; CHECK-BE-NEXT:    sll $6, $19, 1
363 ; CHECK-BE-NEXT:    or $4, $6, $4
364 ; CHECK-BE-NEXT:    or $3, $9, $3
365 ; CHECK-BE-NEXT:    movn $2, $zero, $1
366 ; CHECK-BE-NEXT:    sllv $1, $4, $7
367 ; CHECK-BE-NEXT:    not $4, $7
368 ; CHECK-BE-NEXT:    lui $6, 32767
369 ; CHECK-BE-NEXT:    ori $6, $6, 65535
370 ; CHECK-BE-NEXT:    and $6, $18, $6
371 ; CHECK-BE-NEXT:    srlv $4, $6, $4
372 ; CHECK-BE-NEXT:    or $1, $1, $4
373 ; CHECK-BE-NEXT:    movn $1, $8, $5
374 ; CHECK-BE-NEXT:    or $2, $1, $2
375 ; CHECK-BE-NEXT:    lw $16, 20($sp) # 4-byte Folded Reload
376 ; CHECK-BE-NEXT:    lw $17, 24($sp) # 4-byte Folded Reload
377 ; CHECK-BE-NEXT:    lw $18, 28($sp) # 4-byte Folded Reload
378 ; CHECK-BE-NEXT:    lw $19, 32($sp) # 4-byte Folded Reload
379 ; CHECK-BE-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
380 ; CHECK-BE-NEXT:    jr $ra
381 ; CHECK-BE-NEXT:    addiu $sp, $sp, 40
383 ; CHECK-LE-LABEL: fshr_i37:
384 ; CHECK-LE:       # %bb.0:
385 ; CHECK-LE-NEXT:    addiu $sp, $sp, -40
386 ; CHECK-LE-NEXT:    .cfi_def_cfa_offset 40
387 ; CHECK-LE-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
388 ; CHECK-LE-NEXT:    sw $19, 32($sp) # 4-byte Folded Spill
389 ; CHECK-LE-NEXT:    sw $18, 28($sp) # 4-byte Folded Spill
390 ; CHECK-LE-NEXT:    sw $17, 24($sp) # 4-byte Folded Spill
391 ; CHECK-LE-NEXT:    sw $16, 20($sp) # 4-byte Folded Spill
392 ; CHECK-LE-NEXT:    .cfi_offset 31, -4
393 ; CHECK-LE-NEXT:    .cfi_offset 19, -8
394 ; CHECK-LE-NEXT:    .cfi_offset 18, -12
395 ; CHECK-LE-NEXT:    .cfi_offset 17, -16
396 ; CHECK-LE-NEXT:    .cfi_offset 16, -20
397 ; CHECK-LE-NEXT:    move $16, $7
398 ; CHECK-LE-NEXT:    move $17, $6
399 ; CHECK-LE-NEXT:    move $18, $5
400 ; CHECK-LE-NEXT:    move $19, $4
401 ; CHECK-LE-NEXT:    lw $4, 56($sp)
402 ; CHECK-LE-NEXT:    lw $5, 60($sp)
403 ; CHECK-LE-NEXT:    addiu $6, $zero, 37
404 ; CHECK-LE-NEXT:    jal __umoddi3
405 ; CHECK-LE-NEXT:    addiu $7, $zero, 0
406 ; CHECK-LE-NEXT:    addiu $1, $2, 27
407 ; CHECK-LE-NEXT:    andi $2, $1, 63
408 ; CHECK-LE-NEXT:    not $3, $2
409 ; CHECK-LE-NEXT:    srl $4, $17, 5
410 ; CHECK-LE-NEXT:    sll $5, $16, 27
411 ; CHECK-LE-NEXT:    or $4, $5, $4
412 ; CHECK-LE-NEXT:    sll $5, $4, 1
413 ; CHECK-LE-NEXT:    sll $6, $17, 27
414 ; CHECK-LE-NEXT:    srlv $6, $6, $2
415 ; CHECK-LE-NEXT:    sllv $3, $5, $3
416 ; CHECK-LE-NEXT:    not $5, $1
417 ; CHECK-LE-NEXT:    andi $7, $5, 63
418 ; CHECK-LE-NEXT:    sll $8, $19, 1
419 ; CHECK-LE-NEXT:    sllv $8, $8, $7
420 ; CHECK-LE-NEXT:    andi $5, $5, 32
421 ; CHECK-LE-NEXT:    move $9, $8
422 ; CHECK-LE-NEXT:    movn $9, $zero, $5
423 ; CHECK-LE-NEXT:    or $3, $3, $6
424 ; CHECK-LE-NEXT:    srlv $4, $4, $2
425 ; CHECK-LE-NEXT:    andi $1, $1, 32
426 ; CHECK-LE-NEXT:    movn $3, $4, $1
427 ; CHECK-LE-NEXT:    srl $2, $19, 31
428 ; CHECK-LE-NEXT:    sll $6, $18, 1
429 ; CHECK-LE-NEXT:    or $6, $6, $2
430 ; CHECK-LE-NEXT:    or $2, $9, $3
431 ; CHECK-LE-NEXT:    movn $4, $zero, $1
432 ; CHECK-LE-NEXT:    sllv $1, $6, $7
433 ; CHECK-LE-NEXT:    not $3, $7
434 ; CHECK-LE-NEXT:    lui $6, 32767
435 ; CHECK-LE-NEXT:    ori $6, $6, 65535
436 ; CHECK-LE-NEXT:    and $6, $19, $6
437 ; CHECK-LE-NEXT:    srlv $3, $6, $3
438 ; CHECK-LE-NEXT:    or $1, $1, $3
439 ; CHECK-LE-NEXT:    movn $1, $8, $5
440 ; CHECK-LE-NEXT:    or $3, $1, $4
441 ; CHECK-LE-NEXT:    lw $16, 20($sp) # 4-byte Folded Reload
442 ; CHECK-LE-NEXT:    lw $17, 24($sp) # 4-byte Folded Reload
443 ; CHECK-LE-NEXT:    lw $18, 28($sp) # 4-byte Folded Reload
444 ; CHECK-LE-NEXT:    lw $19, 32($sp) # 4-byte Folded Reload
445 ; CHECK-LE-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
446 ; CHECK-LE-NEXT:    jr $ra
447 ; CHECK-LE-NEXT:    addiu $sp, $sp, 40
448   %f = call i37 @llvm.fshr.i37(i37 %x, i37 %y, i37 %z)
449   ret i37 %f
452 ; extract(concat(0b1110000, 0b1111111) >> 2) = 0b0011111
454 declare i7 @llvm.fshr.i7(i7, i7, i7)
455 define i7 @fshr_i7_const_fold() {
456 ; CHECK-LABEL: fshr_i7_const_fold:
457 ; CHECK:       # %bb.0:
458 ; CHECK-NEXT:    jr $ra
459 ; CHECK-NEXT:    addiu $2, $zero, 31
460   %f = call i7 @llvm.fshr.i7(i7 112, i7 127, i7 2)
461   ret i7 %f
464 define i8 @fshr_i8_const_fold_overshift_1() {
465 ; CHECK-LABEL: fshr_i8_const_fold_overshift_1:
466 ; CHECK:       # %bb.0:
467 ; CHECK-NEXT:    jr $ra
468 ; CHECK-NEXT:    addiu $2, $zero, 254
469   %f = call i8 @llvm.fshr.i8(i8 255, i8 0, i8 15)
470   ret i8 %f
473 define i8 @fshr_i8_const_fold_overshift_2() {
474 ; CHECK-LABEL: fshr_i8_const_fold_overshift_2:
475 ; CHECK:       # %bb.0:
476 ; CHECK-NEXT:    jr $ra
477 ; CHECK-NEXT:    addiu $2, $zero, 225
478   %f = call i8 @llvm.fshr.i8(i8 15, i8 15, i8 11)
479   ret i8 %f
482 define i8 @fshr_i8_const_fold_overshift_3() {
483 ; CHECK-LABEL: fshr_i8_const_fold_overshift_3:
484 ; CHECK:       # %bb.0:
485 ; CHECK-NEXT:    jr $ra
486 ; CHECK-NEXT:    addiu $2, $zero, 255
487   %f = call i8 @llvm.fshr.i8(i8 0, i8 255, i8 8)
488   ret i8 %f
491 ; With constant shift amount, this is 'extr'.
493 define i32 @fshr_i32_const_shift(i32 %x, i32 %y) {
494 ; CHECK-LABEL: fshr_i32_const_shift:
495 ; CHECK:       # %bb.0:
496 ; CHECK-NEXT:    srl $1, $5, 9
497 ; CHECK-NEXT:    sll $2, $4, 23
498 ; CHECK-NEXT:    jr $ra
499 ; CHECK-NEXT:    or $2, $2, $1
500   %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 9)
501   ret i32 %f
504 ; Check modulo math on shift amount. 41-32=9.
506 define i32 @fshr_i32_const_overshift(i32 %x, i32 %y) {
507 ; CHECK-LABEL: fshr_i32_const_overshift:
508 ; CHECK:       # %bb.0:
509 ; CHECK-NEXT:    srl $1, $5, 9
510 ; CHECK-NEXT:    sll $2, $4, 23
511 ; CHECK-NEXT:    jr $ra
512 ; CHECK-NEXT:    or $2, $2, $1
513   %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 41)
514   ret i32 %f
517 ; 64-bit should also work. 105-64 = 41.
519 define i64 @fshr_i64_const_overshift(i64 %x, i64 %y) {
520 ; CHECK-BE-LABEL: fshr_i64_const_overshift:
521 ; CHECK-BE:       # %bb.0:
522 ; CHECK-BE-NEXT:    srl $1, $5, 9
523 ; CHECK-BE-NEXT:    sll $2, $4, 23
524 ; CHECK-BE-NEXT:    or $2, $2, $1
525 ; CHECK-BE-NEXT:    srl $1, $6, 9
526 ; CHECK-BE-NEXT:    sll $3, $5, 23
527 ; CHECK-BE-NEXT:    jr $ra
528 ; CHECK-BE-NEXT:    or $3, $3, $1
530 ; CHECK-LE-LABEL: fshr_i64_const_overshift:
531 ; CHECK-LE:       # %bb.0:
532 ; CHECK-LE-NEXT:    srl $1, $7, 9
533 ; CHECK-LE-NEXT:    sll $2, $4, 23
534 ; CHECK-LE-NEXT:    or $2, $2, $1
535 ; CHECK-LE-NEXT:    srl $1, $4, 9
536 ; CHECK-LE-NEXT:    sll $3, $5, 23
537 ; CHECK-LE-NEXT:    jr $ra
538 ; CHECK-LE-NEXT:    or $3, $3, $1
539   %f = call i64 @llvm.fshr.i64(i64 %x, i64 %y, i64 105)
540   ret i64 %f
543 ; This should work without any node-specific logic.
545 define i8 @fshr_i8_const_fold() {
546 ; CHECK-LABEL: fshr_i8_const_fold:
547 ; CHECK:       # %bb.0:
548 ; CHECK-NEXT:    jr $ra
549 ; CHECK-NEXT:    addiu $2, $zero, 254
550   %f = call i8 @llvm.fshr.i8(i8 255, i8 0, i8 7)
551   ret i8 %f
554 define i32 @fshl_i32_shift_by_bitwidth(i32 %x, i32 %y) {
555 ; CHECK-LABEL: fshl_i32_shift_by_bitwidth:
556 ; CHECK:       # %bb.0:
557 ; CHECK-NEXT:    jr $ra
558 ; CHECK-NEXT:    move $2, $4
559   %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 32)
560   ret i32 %f
563 define i32 @fshr_i32_shift_by_bitwidth(i32 %x, i32 %y) {
564 ; CHECK-LABEL: fshr_i32_shift_by_bitwidth:
565 ; CHECK:       # %bb.0:
566 ; CHECK-NEXT:    jr $ra
567 ; CHECK-NEXT:    move $2, $5
568   %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 32)
569   ret i32 %f
572 define <4 x i32> @fshl_v4i32_shift_by_bitwidth(<4 x i32> %x, <4 x i32> %y) {
573 ; CHECK-LABEL: fshl_v4i32_shift_by_bitwidth:
574 ; CHECK:       # %bb.0:
575 ; CHECK-NEXT:    move $2, $4
576 ; CHECK-NEXT:    move $3, $5
577 ; CHECK-NEXT:    move $4, $6
578 ; CHECK-NEXT:    jr $ra
579 ; CHECK-NEXT:    move $5, $7
580   %f = call <4 x i32> @llvm.fshl.v4i32(<4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 32, i32 32, i32 32, i32 32>)
581   ret <4 x i32> %f
584 define <4 x i32> @fshr_v4i32_shift_by_bitwidth(<4 x i32> %x, <4 x i32> %y) {
585 ; CHECK-LABEL: fshr_v4i32_shift_by_bitwidth:
586 ; CHECK:       # %bb.0:
587 ; CHECK-NEXT:    lw $5, 28($sp)
588 ; CHECK-NEXT:    lw $4, 24($sp)
589 ; CHECK-NEXT:    lw $3, 20($sp)
590 ; CHECK-NEXT:    lw $2, 16($sp)
591 ; CHECK-NEXT:    jr $ra
592 ; CHECK-NEXT:    nop
593   %f = call <4 x i32> @llvm.fshr.v4i32(<4 x i32> %x, <4 x i32> %y, <4 x i32> <i32 32, i32 32, i32 32, i32 32>)
594   ret <4 x i32> %f