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:
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
28 ; CHECK-NEXT: srl $2, $1, 16
29 %f = call i16 @llvm.fshl.i16(i16 %x, i16 %y, i16 %z)
33 define i32 @fshl_i32(i32 %x, i32 %y, i32 %z) {
34 ; CHECK-LABEL: fshl_i32:
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
43 ; CHECK-NEXT: or $2, $1, $2
44 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %z)
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:
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 $1, 56($sp)
70 ; CHECK-BE-NEXT: andi $4, $1, 31
71 ; CHECK-BE-NEXT: lw $5, 60($sp)
72 ; CHECK-BE-NEXT: addiu $6, $zero, 0
73 ; CHECK-BE-NEXT: jal __umoddi3
74 ; CHECK-BE-NEXT: addiu $7, $zero, 37
75 ; CHECK-BE-NEXT: not $1, $3
76 ; CHECK-BE-NEXT: srl $2, $3, 5
77 ; CHECK-BE-NEXT: andi $4, $2, 1
78 ; CHECK-BE-NEXT: movn $19, $18, $4
79 ; CHECK-BE-NEXT: andi $3, $3, 31
80 ; CHECK-BE-NEXT: sllv $2, $19, $3
81 ; CHECK-BE-NEXT: andi $1, $1, 31
82 ; CHECK-BE-NEXT: srl $5, $16, 5
83 ; CHECK-BE-NEXT: sll $6, $17, 27
84 ; CHECK-BE-NEXT: or $5, $6, $5
85 ; CHECK-BE-NEXT: movn $18, $5, $4
86 ; CHECK-BE-NEXT: srl $6, $18, 1
87 ; CHECK-BE-NEXT: srlv $6, $6, $1
88 ; CHECK-BE-NEXT: or $2, $2, $6
89 ; CHECK-BE-NEXT: sllv $3, $18, $3
90 ; CHECK-BE-NEXT: sll $6, $16, 27
91 ; CHECK-BE-NEXT: movn $5, $6, $4
92 ; CHECK-BE-NEXT: srl $4, $5, 1
93 ; CHECK-BE-NEXT: srlv $1, $4, $1
94 ; CHECK-BE-NEXT: or $3, $3, $1
95 ; CHECK-BE-NEXT: lw $16, 20($sp) # 4-byte Folded Reload
96 ; CHECK-BE-NEXT: lw $17, 24($sp) # 4-byte Folded Reload
97 ; CHECK-BE-NEXT: lw $18, 28($sp) # 4-byte Folded Reload
98 ; CHECK-BE-NEXT: lw $19, 32($sp) # 4-byte Folded Reload
99 ; CHECK-BE-NEXT: lw $ra, 36($sp) # 4-byte Folded Reload
100 ; CHECK-BE-NEXT: jr $ra
101 ; CHECK-BE-NEXT: addiu $sp, $sp, 40
103 ; CHECK-LE-LABEL: fshl_i37:
105 ; CHECK-LE-NEXT: addiu $sp, $sp, -40
106 ; CHECK-LE-NEXT: .cfi_def_cfa_offset 40
107 ; CHECK-LE-NEXT: sw $ra, 36($sp) # 4-byte Folded Spill
108 ; CHECK-LE-NEXT: sw $19, 32($sp) # 4-byte Folded Spill
109 ; CHECK-LE-NEXT: sw $18, 28($sp) # 4-byte Folded Spill
110 ; CHECK-LE-NEXT: sw $17, 24($sp) # 4-byte Folded Spill
111 ; CHECK-LE-NEXT: sw $16, 20($sp) # 4-byte Folded Spill
112 ; CHECK-LE-NEXT: .cfi_offset 31, -4
113 ; CHECK-LE-NEXT: .cfi_offset 19, -8
114 ; CHECK-LE-NEXT: .cfi_offset 18, -12
115 ; CHECK-LE-NEXT: .cfi_offset 17, -16
116 ; CHECK-LE-NEXT: .cfi_offset 16, -20
117 ; CHECK-LE-NEXT: move $16, $7
118 ; CHECK-LE-NEXT: move $17, $6
119 ; CHECK-LE-NEXT: move $18, $5
120 ; CHECK-LE-NEXT: move $19, $4
121 ; CHECK-LE-NEXT: lw $1, 60($sp)
122 ; CHECK-LE-NEXT: andi $5, $1, 31
123 ; CHECK-LE-NEXT: lw $4, 56($sp)
124 ; CHECK-LE-NEXT: addiu $6, $zero, 37
125 ; CHECK-LE-NEXT: jal __umoddi3
126 ; CHECK-LE-NEXT: addiu $7, $zero, 0
127 ; CHECK-LE-NEXT: srl $1, $2, 5
128 ; CHECK-LE-NEXT: andi $1, $1, 1
129 ; CHECK-LE-NEXT: srl $3, $17, 5
130 ; CHECK-LE-NEXT: sll $4, $16, 27
131 ; CHECK-LE-NEXT: or $3, $4, $3
132 ; CHECK-LE-NEXT: move $4, $19
133 ; CHECK-LE-NEXT: movn $4, $3, $1
134 ; CHECK-LE-NEXT: andi $5, $2, 31
135 ; CHECK-LE-NEXT: sllv $6, $4, $5
136 ; CHECK-LE-NEXT: not $2, $2
137 ; CHECK-LE-NEXT: andi $7, $2, 31
138 ; CHECK-LE-NEXT: sll $2, $17, 27
139 ; CHECK-LE-NEXT: movn $3, $2, $1
140 ; CHECK-LE-NEXT: srl $2, $3, 1
141 ; CHECK-LE-NEXT: srlv $2, $2, $7
142 ; CHECK-LE-NEXT: or $2, $6, $2
143 ; CHECK-LE-NEXT: movn $18, $19, $1
144 ; CHECK-LE-NEXT: sllv $1, $18, $5
145 ; CHECK-LE-NEXT: srl $3, $4, 1
146 ; CHECK-LE-NEXT: srlv $3, $3, $7
147 ; CHECK-LE-NEXT: or $3, $1, $3
148 ; CHECK-LE-NEXT: lw $16, 20($sp) # 4-byte Folded Reload
149 ; CHECK-LE-NEXT: lw $17, 24($sp) # 4-byte Folded Reload
150 ; CHECK-LE-NEXT: lw $18, 28($sp) # 4-byte Folded Reload
151 ; CHECK-LE-NEXT: lw $19, 32($sp) # 4-byte Folded Reload
152 ; CHECK-LE-NEXT: lw $ra, 36($sp) # 4-byte Folded Reload
153 ; CHECK-LE-NEXT: jr $ra
154 ; CHECK-LE-NEXT: addiu $sp, $sp, 40
155 %f = call i37 @llvm.fshl.i37(i37 %x, i37 %y, i37 %z)
159 ; extract(concat(0b1110000, 0b1111111) << 2) = 0b1000011
161 declare i7 @llvm.fshl.i7(i7, i7, i7)
162 define i7 @fshl_i7_const_fold() {
163 ; CHECK-LABEL: fshl_i7_const_fold:
166 ; CHECK-NEXT: addiu $2, $zero, 67
167 %f = call i7 @llvm.fshl.i7(i7 112, i7 127, i7 2)
171 define i8 @fshl_i8_const_fold_overshift_1() {
172 ; CHECK-LABEL: fshl_i8_const_fold_overshift_1:
175 ; CHECK-NEXT: addiu $2, $zero, 128
176 %f = call i8 @llvm.fshl.i8(i8 255, i8 0, i8 15)
180 define i8 @fshl_i8_const_fold_overshift_2() {
181 ; CHECK-LABEL: fshl_i8_const_fold_overshift_2:
184 ; CHECK-NEXT: addiu $2, $zero, 120
185 %f = call i8 @llvm.fshl.i8(i8 15, i8 15, i8 11)
189 define i8 @fshl_i8_const_fold_overshift_3() {
190 ; CHECK-LABEL: fshl_i8_const_fold_overshift_3:
193 ; CHECK-NEXT: addiu $2, $zero, 0
194 %f = call i8 @llvm.fshl.i8(i8 0, i8 225, i8 8)
198 ; With constant shift amount, this is 'extr'.
200 define i32 @fshl_i32_const_shift(i32 %x, i32 %y) {
201 ; CHECK-LABEL: fshl_i32_const_shift:
203 ; CHECK-NEXT: srl $1, $5, 23
204 ; CHECK-NEXT: sll $2, $4, 9
206 ; CHECK-NEXT: or $2, $2, $1
207 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 9)
211 ; Check modulo math on shift amount.
213 define i32 @fshl_i32_const_overshift(i32 %x, i32 %y) {
214 ; CHECK-LABEL: fshl_i32_const_overshift:
216 ; CHECK-NEXT: srl $1, $5, 23
217 ; CHECK-NEXT: sll $2, $4, 9
219 ; CHECK-NEXT: or $2, $2, $1
220 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 41)
224 ; 64-bit should also work.
226 define i64 @fshl_i64_const_overshift(i64 %x, i64 %y) {
227 ; CHECK-BE-LABEL: fshl_i64_const_overshift:
229 ; CHECK-BE-NEXT: srl $1, $6, 23
230 ; CHECK-BE-NEXT: sll $2, $5, 9
231 ; CHECK-BE-NEXT: or $2, $2, $1
232 ; CHECK-BE-NEXT: srl $1, $7, 23
233 ; CHECK-BE-NEXT: sll $3, $6, 9
234 ; CHECK-BE-NEXT: jr $ra
235 ; CHECK-BE-NEXT: or $3, $3, $1
237 ; CHECK-LE-LABEL: fshl_i64_const_overshift:
239 ; CHECK-LE-NEXT: srl $1, $6, 23
240 ; CHECK-LE-NEXT: sll $2, $7, 9
241 ; CHECK-LE-NEXT: or $2, $2, $1
242 ; CHECK-LE-NEXT: srl $1, $7, 23
243 ; CHECK-LE-NEXT: sll $3, $4, 9
244 ; CHECK-LE-NEXT: jr $ra
245 ; CHECK-LE-NEXT: or $3, $3, $1
246 %f = call i64 @llvm.fshl.i64(i64 %x, i64 %y, i64 105)
250 ; This should work without any node-specific logic.
252 define i8 @fshl_i8_const_fold() {
253 ; CHECK-LABEL: fshl_i8_const_fold:
256 ; CHECK-NEXT: addiu $2, $zero, 128
257 %f = call i8 @llvm.fshl.i8(i8 255, i8 0, i8 7)
261 ; Repeat everything for funnel shift right.
263 ; General case - all operands can be variables.
265 define i16 @fshr_i16(i16 %x, i16 %y, i16 %z) {
266 ; CHECK-LABEL: fshr_i16:
268 ; CHECK-NEXT: andi $1, $5, 65535
269 ; CHECK-NEXT: sll $2, $4, 16
270 ; CHECK-NEXT: or $1, $2, $1
271 ; CHECK-NEXT: andi $2, $6, 15
273 ; CHECK-NEXT: srlv $2, $1, $2
274 %f = call i16 @llvm.fshr.i16(i16 %x, i16 %y, i16 %z)
278 define i32 @fshr_i32(i32 %x, i32 %y, i32 %z) {
279 ; CHECK-LABEL: fshr_i32:
281 ; CHECK-NEXT: andi $1, $6, 31
282 ; CHECK-NEXT: srlv $1, $5, $1
283 ; CHECK-NEXT: sll $2, $4, 1
284 ; CHECK-NEXT: not $3, $6
285 ; CHECK-NEXT: andi $3, $3, 31
286 ; CHECK-NEXT: sllv $2, $2, $3
288 ; CHECK-NEXT: or $2, $2, $1
289 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %z)
293 ; Verify that weird types are minimally supported.
294 declare i37 @llvm.fshr.i37(i37, i37, i37)
295 define i37 @fshr_i37(i37 %x, i37 %y, i37 %z) {
296 ; CHECK-BE-LABEL: fshr_i37:
298 ; CHECK-BE-NEXT: addiu $sp, $sp, -40
299 ; CHECK-BE-NEXT: .cfi_def_cfa_offset 40
300 ; CHECK-BE-NEXT: sw $ra, 36($sp) # 4-byte Folded Spill
301 ; CHECK-BE-NEXT: sw $19, 32($sp) # 4-byte Folded Spill
302 ; CHECK-BE-NEXT: sw $18, 28($sp) # 4-byte Folded Spill
303 ; CHECK-BE-NEXT: sw $17, 24($sp) # 4-byte Folded Spill
304 ; CHECK-BE-NEXT: sw $16, 20($sp) # 4-byte Folded Spill
305 ; CHECK-BE-NEXT: .cfi_offset 31, -4
306 ; CHECK-BE-NEXT: .cfi_offset 19, -8
307 ; CHECK-BE-NEXT: .cfi_offset 18, -12
308 ; CHECK-BE-NEXT: .cfi_offset 17, -16
309 ; CHECK-BE-NEXT: .cfi_offset 16, -20
310 ; CHECK-BE-NEXT: move $16, $7
311 ; CHECK-BE-NEXT: move $17, $6
312 ; CHECK-BE-NEXT: move $18, $5
313 ; CHECK-BE-NEXT: move $19, $4
314 ; CHECK-BE-NEXT: lw $1, 56($sp)
315 ; CHECK-BE-NEXT: andi $4, $1, 31
316 ; CHECK-BE-NEXT: lw $5, 60($sp)
317 ; CHECK-BE-NEXT: addiu $6, $zero, 0
318 ; CHECK-BE-NEXT: jal __umoddi3
319 ; CHECK-BE-NEXT: addiu $7, $zero, 37
320 ; CHECK-BE-NEXT: addiu $1, $3, 27
321 ; CHECK-BE-NEXT: andi $3, $1, 32
322 ; CHECK-BE-NEXT: srl $2, $16, 5
323 ; CHECK-BE-NEXT: sll $4, $17, 27
324 ; CHECK-BE-NEXT: or $4, $4, $2
325 ; CHECK-BE-NEXT: movz $19, $18, $3
326 ; CHECK-BE-NEXT: movz $18, $4, $3
327 ; CHECK-BE-NEXT: andi $5, $1, 31
328 ; CHECK-BE-NEXT: srlv $2, $18, $5
329 ; CHECK-BE-NEXT: not $1, $1
330 ; CHECK-BE-NEXT: andi $1, $1, 31
331 ; CHECK-BE-NEXT: sll $6, $19, 1
332 ; CHECK-BE-NEXT: sllv $6, $6, $1
333 ; CHECK-BE-NEXT: sll $7, $16, 27
334 ; CHECK-BE-NEXT: or $2, $6, $2
335 ; CHECK-BE-NEXT: movz $4, $7, $3
336 ; CHECK-BE-NEXT: srlv $3, $4, $5
337 ; CHECK-BE-NEXT: sll $4, $18, 1
338 ; CHECK-BE-NEXT: sllv $1, $4, $1
339 ; CHECK-BE-NEXT: or $3, $1, $3
340 ; CHECK-BE-NEXT: lw $16, 20($sp) # 4-byte Folded Reload
341 ; CHECK-BE-NEXT: lw $17, 24($sp) # 4-byte Folded Reload
342 ; CHECK-BE-NEXT: lw $18, 28($sp) # 4-byte Folded Reload
343 ; CHECK-BE-NEXT: lw $19, 32($sp) # 4-byte Folded Reload
344 ; CHECK-BE-NEXT: lw $ra, 36($sp) # 4-byte Folded Reload
345 ; CHECK-BE-NEXT: jr $ra
346 ; CHECK-BE-NEXT: addiu $sp, $sp, 40
348 ; CHECK-LE-LABEL: fshr_i37:
350 ; CHECK-LE-NEXT: addiu $sp, $sp, -40
351 ; CHECK-LE-NEXT: .cfi_def_cfa_offset 40
352 ; CHECK-LE-NEXT: sw $ra, 36($sp) # 4-byte Folded Spill
353 ; CHECK-LE-NEXT: sw $19, 32($sp) # 4-byte Folded Spill
354 ; CHECK-LE-NEXT: sw $18, 28($sp) # 4-byte Folded Spill
355 ; CHECK-LE-NEXT: sw $17, 24($sp) # 4-byte Folded Spill
356 ; CHECK-LE-NEXT: sw $16, 20($sp) # 4-byte Folded Spill
357 ; CHECK-LE-NEXT: .cfi_offset 31, -4
358 ; CHECK-LE-NEXT: .cfi_offset 19, -8
359 ; CHECK-LE-NEXT: .cfi_offset 18, -12
360 ; CHECK-LE-NEXT: .cfi_offset 17, -16
361 ; CHECK-LE-NEXT: .cfi_offset 16, -20
362 ; CHECK-LE-NEXT: move $16, $7
363 ; CHECK-LE-NEXT: move $17, $6
364 ; CHECK-LE-NEXT: move $18, $5
365 ; CHECK-LE-NEXT: move $19, $4
366 ; CHECK-LE-NEXT: lw $1, 60($sp)
367 ; CHECK-LE-NEXT: andi $5, $1, 31
368 ; CHECK-LE-NEXT: lw $4, 56($sp)
369 ; CHECK-LE-NEXT: addiu $6, $zero, 37
370 ; CHECK-LE-NEXT: jal __umoddi3
371 ; CHECK-LE-NEXT: addiu $7, $zero, 0
372 ; CHECK-LE-NEXT: addiu $1, $2, 27
373 ; CHECK-LE-NEXT: andi $3, $1, 32
374 ; CHECK-LE-NEXT: srl $2, $17, 5
375 ; CHECK-LE-NEXT: sll $4, $16, 27
376 ; CHECK-LE-NEXT: or $2, $4, $2
377 ; CHECK-LE-NEXT: sll $4, $17, 27
378 ; CHECK-LE-NEXT: move $5, $19
379 ; CHECK-LE-NEXT: movz $5, $2, $3
380 ; CHECK-LE-NEXT: movz $2, $4, $3
381 ; CHECK-LE-NEXT: andi $4, $1, 31
382 ; CHECK-LE-NEXT: srlv $2, $2, $4
383 ; CHECK-LE-NEXT: not $1, $1
384 ; CHECK-LE-NEXT: andi $1, $1, 31
385 ; CHECK-LE-NEXT: sll $6, $5, 1
386 ; CHECK-LE-NEXT: sllv $6, $6, $1
387 ; CHECK-LE-NEXT: or $2, $6, $2
388 ; CHECK-LE-NEXT: srlv $4, $5, $4
389 ; CHECK-LE-NEXT: movz $18, $19, $3
390 ; CHECK-LE-NEXT: sll $3, $18, 1
391 ; CHECK-LE-NEXT: sllv $1, $3, $1
392 ; CHECK-LE-NEXT: or $3, $1, $4
393 ; CHECK-LE-NEXT: lw $16, 20($sp) # 4-byte Folded Reload
394 ; CHECK-LE-NEXT: lw $17, 24($sp) # 4-byte Folded Reload
395 ; CHECK-LE-NEXT: lw $18, 28($sp) # 4-byte Folded Reload
396 ; CHECK-LE-NEXT: lw $19, 32($sp) # 4-byte Folded Reload
397 ; CHECK-LE-NEXT: lw $ra, 36($sp) # 4-byte Folded Reload
398 ; CHECK-LE-NEXT: jr $ra
399 ; CHECK-LE-NEXT: addiu $sp, $sp, 40
400 %f = call i37 @llvm.fshr.i37(i37 %x, i37 %y, i37 %z)
404 ; extract(concat(0b1110000, 0b1111111) >> 2) = 0b0011111
406 declare i7 @llvm.fshr.i7(i7, i7, i7)
407 define i7 @fshr_i7_const_fold() {
408 ; CHECK-LABEL: fshr_i7_const_fold:
411 ; CHECK-NEXT: addiu $2, $zero, 31
412 %f = call i7 @llvm.fshr.i7(i7 112, i7 127, i7 2)
416 define i8 @fshr_i8_const_fold_overshift_1() {
417 ; CHECK-LABEL: fshr_i8_const_fold_overshift_1:
420 ; CHECK-NEXT: addiu $2, $zero, 254
421 %f = call i8 @llvm.fshr.i8(i8 255, i8 0, i8 15)
425 define i8 @fshr_i8_const_fold_overshift_2() {
426 ; CHECK-LABEL: fshr_i8_const_fold_overshift_2:
429 ; CHECK-NEXT: addiu $2, $zero, 225
430 %f = call i8 @llvm.fshr.i8(i8 15, i8 15, i8 11)
434 define i8 @fshr_i8_const_fold_overshift_3() {
435 ; CHECK-LABEL: fshr_i8_const_fold_overshift_3:
438 ; CHECK-NEXT: addiu $2, $zero, 255
439 %f = call i8 @llvm.fshr.i8(i8 0, i8 255, i8 8)
443 ; With constant shift amount, this is 'extr'.
445 define i32 @fshr_i32_const_shift(i32 %x, i32 %y) {
446 ; CHECK-LABEL: fshr_i32_const_shift:
448 ; CHECK-NEXT: srl $1, $5, 9
449 ; CHECK-NEXT: sll $2, $4, 23
451 ; CHECK-NEXT: or $2, $2, $1
452 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 9)
456 ; Check modulo math on shift amount. 41-32=9.
458 define i32 @fshr_i32_const_overshift(i32 %x, i32 %y) {
459 ; CHECK-LABEL: fshr_i32_const_overshift:
461 ; CHECK-NEXT: srl $1, $5, 9
462 ; CHECK-NEXT: sll $2, $4, 23
464 ; CHECK-NEXT: or $2, $2, $1
465 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 41)
469 ; 64-bit should also work. 105-64 = 41.
471 define i64 @fshr_i64_const_overshift(i64 %x, i64 %y) {
472 ; CHECK-BE-LABEL: fshr_i64_const_overshift:
474 ; CHECK-BE-NEXT: srl $1, $5, 9
475 ; CHECK-BE-NEXT: sll $2, $4, 23
476 ; CHECK-BE-NEXT: or $2, $2, $1
477 ; CHECK-BE-NEXT: srl $1, $6, 9
478 ; CHECK-BE-NEXT: sll $3, $5, 23
479 ; CHECK-BE-NEXT: jr $ra
480 ; CHECK-BE-NEXT: or $3, $3, $1
482 ; CHECK-LE-LABEL: fshr_i64_const_overshift:
484 ; CHECK-LE-NEXT: srl $1, $7, 9
485 ; CHECK-LE-NEXT: sll $2, $4, 23
486 ; CHECK-LE-NEXT: or $2, $2, $1
487 ; CHECK-LE-NEXT: srl $1, $4, 9
488 ; CHECK-LE-NEXT: sll $3, $5, 23
489 ; CHECK-LE-NEXT: jr $ra
490 ; CHECK-LE-NEXT: or $3, $3, $1
491 %f = call i64 @llvm.fshr.i64(i64 %x, i64 %y, i64 105)
495 ; This should work without any node-specific logic.
497 define i8 @fshr_i8_const_fold() {
498 ; CHECK-LABEL: fshr_i8_const_fold:
501 ; CHECK-NEXT: addiu $2, $zero, 254
502 %f = call i8 @llvm.fshr.i8(i8 255, i8 0, i8 7)
506 define i32 @fshl_i32_shift_by_bitwidth(i32 %x, i32 %y) {
507 ; CHECK-LABEL: fshl_i32_shift_by_bitwidth:
510 ; CHECK-NEXT: move $2, $4
511 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 32)
515 define i32 @fshr_i32_shift_by_bitwidth(i32 %x, i32 %y) {
516 ; CHECK-LABEL: fshr_i32_shift_by_bitwidth:
519 ; CHECK-NEXT: move $2, $5
520 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 32)
524 define <4 x i32> @fshl_v4i32_shift_by_bitwidth(<4 x i32> %x, <4 x i32> %y) {
525 ; CHECK-LABEL: fshl_v4i32_shift_by_bitwidth:
527 ; CHECK-NEXT: move $2, $4
528 ; CHECK-NEXT: move $3, $5
529 ; CHECK-NEXT: move $4, $6
531 ; CHECK-NEXT: move $5, $7
532 %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>)
536 define <4 x i32> @fshr_v4i32_shift_by_bitwidth(<4 x i32> %x, <4 x i32> %y) {
537 ; CHECK-LABEL: fshr_v4i32_shift_by_bitwidth:
539 ; CHECK-NEXT: lw $5, 28($sp)
540 ; CHECK-NEXT: lw $4, 24($sp)
541 ; CHECK-NEXT: lw $3, 20($sp)
542 ; CHECK-NEXT: lw $2, 16($sp)
545 %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>)