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 $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:
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)
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:
187 ; CHECK-NEXT: addiu $2, $zero, 67
188 %f = call i7 @llvm.fshl.i7(i7 112, i7 127, i7 2)
192 define i8 @fshl_i8_const_fold_overshift_1() {
193 ; CHECK-LABEL: fshl_i8_const_fold_overshift_1:
196 ; CHECK-NEXT: addiu $2, $zero, 128
197 %f = call i8 @llvm.fshl.i8(i8 255, i8 0, i8 15)
201 define i8 @fshl_i8_const_fold_overshift_2() {
202 ; CHECK-LABEL: fshl_i8_const_fold_overshift_2:
205 ; CHECK-NEXT: addiu $2, $zero, 120
206 %f = call i8 @llvm.fshl.i8(i8 15, i8 15, i8 11)
210 define i8 @fshl_i8_const_fold_overshift_3() {
211 ; CHECK-LABEL: fshl_i8_const_fold_overshift_3:
214 ; CHECK-NEXT: addiu $2, $zero, 0
215 %f = call i8 @llvm.fshl.i8(i8 0, i8 225, i8 8)
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:
224 ; CHECK-NEXT: srl $1, $5, 23
225 ; CHECK-NEXT: sll $2, $4, 9
227 ; CHECK-NEXT: or $2, $2, $1
228 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 9)
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:
237 ; CHECK-NEXT: srl $1, $5, 23
238 ; CHECK-NEXT: sll $2, $4, 9
240 ; CHECK-NEXT: or $2, $2, $1
241 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 41)
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:
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:
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)
271 ; This should work without any node-specific logic.
273 define i8 @fshl_i8_const_fold() {
274 ; CHECK-LABEL: fshl_i8_const_fold:
277 ; CHECK-NEXT: addiu $2, $zero, 128
278 %f = call i8 @llvm.fshl.i8(i8 255, i8 0, i8 7)
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:
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
294 ; CHECK-NEXT: srlv $2, $1, $2
295 %f = call i16 @llvm.fshr.i16(i16 %x, i16 %y, i16 %z)
299 define i32 @fshr_i32(i32 %x, i32 %y, i32 %z) {
300 ; CHECK-LABEL: fshr_i32:
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
309 ; CHECK-NEXT: or $2, $2, $1
310 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %z)
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:
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:
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)
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:
459 ; CHECK-NEXT: addiu $2, $zero, 31
460 %f = call i7 @llvm.fshr.i7(i7 112, i7 127, i7 2)
464 define i8 @fshr_i8_const_fold_overshift_1() {
465 ; CHECK-LABEL: fshr_i8_const_fold_overshift_1:
468 ; CHECK-NEXT: addiu $2, $zero, 254
469 %f = call i8 @llvm.fshr.i8(i8 255, i8 0, i8 15)
473 define i8 @fshr_i8_const_fold_overshift_2() {
474 ; CHECK-LABEL: fshr_i8_const_fold_overshift_2:
477 ; CHECK-NEXT: addiu $2, $zero, 225
478 %f = call i8 @llvm.fshr.i8(i8 15, i8 15, i8 11)
482 define i8 @fshr_i8_const_fold_overshift_3() {
483 ; CHECK-LABEL: fshr_i8_const_fold_overshift_3:
486 ; CHECK-NEXT: addiu $2, $zero, 255
487 %f = call i8 @llvm.fshr.i8(i8 0, i8 255, i8 8)
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:
496 ; CHECK-NEXT: srl $1, $5, 9
497 ; CHECK-NEXT: sll $2, $4, 23
499 ; CHECK-NEXT: or $2, $2, $1
500 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 9)
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:
509 ; CHECK-NEXT: srl $1, $5, 9
510 ; CHECK-NEXT: sll $2, $4, 23
512 ; CHECK-NEXT: or $2, $2, $1
513 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 41)
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:
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:
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)
543 ; This should work without any node-specific logic.
545 define i8 @fshr_i8_const_fold() {
546 ; CHECK-LABEL: fshr_i8_const_fold:
549 ; CHECK-NEXT: addiu $2, $zero, 254
550 %f = call i8 @llvm.fshr.i8(i8 255, i8 0, i8 7)
554 define i32 @fshl_i32_shift_by_bitwidth(i32 %x, i32 %y) {
555 ; CHECK-LABEL: fshl_i32_shift_by_bitwidth:
558 ; CHECK-NEXT: move $2, $4
559 %f = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 32)
563 define i32 @fshr_i32_shift_by_bitwidth(i32 %x, i32 %y) {
564 ; CHECK-LABEL: fshr_i32_shift_by_bitwidth:
567 ; CHECK-NEXT: move $2, $5
568 %f = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 32)
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:
575 ; CHECK-NEXT: move $2, $4
576 ; CHECK-NEXT: move $3, $5
577 ; CHECK-NEXT: move $4, $6
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>)
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:
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)
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>)