1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3 ; RUN: | FileCheck %s -check-prefix=RV32I
4 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs -enable-legalize-types-checking < %s \
5 ; RUN: | FileCheck %s -check-prefix=RV64I
6 ; RUN: llc -mtriple=riscv32 -mattr=+zbb -verify-machineinstrs < %s \
7 ; RUN: | FileCheck %s -check-prefix=RV32ZBB
8 ; RUN: llc -mtriple=riscv64 -mattr=+zbb -verify-machineinstrs < %s \
9 ; RUN: | FileCheck %s -check-prefix=RV64ZBB
11 ; NOTE: -enable-legalize-types-checking is on one command line due to a previous
12 ; assertion failure on an expensive checks build for @rotr_32_mask_multiple.
14 ; These IR sequences are idioms for rotates. If rotate instructions are
15 ; supported, they will be turned into ISD::ROTL or ISD::ROTR.
17 define i32 @rotl_32(i32 %x, i32 %y) nounwind {
18 ; RV32I-LABEL: rotl_32:
20 ; RV32I-NEXT: neg a2, a1
21 ; RV32I-NEXT: sll a1, a0, a1
22 ; RV32I-NEXT: srl a0, a0, a2
23 ; RV32I-NEXT: or a0, a1, a0
26 ; RV64I-LABEL: rotl_32:
28 ; RV64I-NEXT: negw a2, a1
29 ; RV64I-NEXT: sllw a1, a0, a1
30 ; RV64I-NEXT: srlw a0, a0, a2
31 ; RV64I-NEXT: or a0, a1, a0
34 ; RV32ZBB-LABEL: rotl_32:
36 ; RV32ZBB-NEXT: rol a0, a0, a1
39 ; RV64ZBB-LABEL: rotl_32:
41 ; RV64ZBB-NEXT: rolw a0, a0, a1
50 define i32 @rotr_32(i32 %x, i32 %y) nounwind {
51 ; RV32I-LABEL: rotr_32:
53 ; RV32I-NEXT: neg a2, a1
54 ; RV32I-NEXT: srl a1, a0, a1
55 ; RV32I-NEXT: sll a0, a0, a2
56 ; RV32I-NEXT: or a0, a1, a0
59 ; RV64I-LABEL: rotr_32:
61 ; RV64I-NEXT: negw a2, a1
62 ; RV64I-NEXT: srlw a1, a0, a1
63 ; RV64I-NEXT: sllw a0, a0, a2
64 ; RV64I-NEXT: or a0, a1, a0
67 ; RV32ZBB-LABEL: rotr_32:
69 ; RV32ZBB-NEXT: ror a0, a0, a1
72 ; RV64ZBB-LABEL: rotr_32:
74 ; RV64ZBB-NEXT: rorw a0, a0, a1
83 define i64 @rotl_64(i64 %x, i64 %y) nounwind {
84 ; RV32I-LABEL: rotl_64:
86 ; RV32I-NEXT: addi a5, a2, -32
87 ; RV32I-NEXT: mv a4, a1
88 ; RV32I-NEXT: bltz a5, .LBB2_2
89 ; RV32I-NEXT: # %bb.1:
90 ; RV32I-NEXT: sll a1, a0, a5
91 ; RV32I-NEXT: j .LBB2_3
92 ; RV32I-NEXT: .LBB2_2:
93 ; RV32I-NEXT: sll a1, a4, a2
94 ; RV32I-NEXT: xori a3, a2, 31
95 ; RV32I-NEXT: srli a6, a0, 1
96 ; RV32I-NEXT: srl a3, a6, a3
97 ; RV32I-NEXT: or a1, a1, a3
98 ; RV32I-NEXT: .LBB2_3:
99 ; RV32I-NEXT: neg a6, a2
100 ; RV32I-NEXT: li a3, 32
101 ; RV32I-NEXT: sub a7, a3, a2
102 ; RV32I-NEXT: srl a3, a4, a6
103 ; RV32I-NEXT: bltz a7, .LBB2_6
104 ; RV32I-NEXT: # %bb.4:
105 ; RV32I-NEXT: bltz a5, .LBB2_7
106 ; RV32I-NEXT: .LBB2_5:
107 ; RV32I-NEXT: mv a0, a3
109 ; RV32I-NEXT: .LBB2_6:
110 ; RV32I-NEXT: srl a6, a0, a6
111 ; RV32I-NEXT: li a7, 64
112 ; RV32I-NEXT: sub a7, a7, a2
113 ; RV32I-NEXT: xori a7, a7, 31
114 ; RV32I-NEXT: slli a4, a4, 1
115 ; RV32I-NEXT: sll a4, a4, a7
116 ; RV32I-NEXT: or a4, a6, a4
117 ; RV32I-NEXT: or a1, a1, a3
118 ; RV32I-NEXT: mv a3, a4
119 ; RV32I-NEXT: bgez a5, .LBB2_5
120 ; RV32I-NEXT: .LBB2_7:
121 ; RV32I-NEXT: sll a0, a0, a2
122 ; RV32I-NEXT: or a3, a3, a0
123 ; RV32I-NEXT: mv a0, a3
126 ; RV64I-LABEL: rotl_64:
128 ; RV64I-NEXT: negw a2, a1
129 ; RV64I-NEXT: sll a1, a0, a1
130 ; RV64I-NEXT: srl a0, a0, a2
131 ; RV64I-NEXT: or a0, a1, a0
134 ; RV32ZBB-LABEL: rotl_64:
136 ; RV32ZBB-NEXT: addi a5, a2, -32
137 ; RV32ZBB-NEXT: mv a4, a1
138 ; RV32ZBB-NEXT: bltz a5, .LBB2_2
139 ; RV32ZBB-NEXT: # %bb.1:
140 ; RV32ZBB-NEXT: sll a1, a0, a5
141 ; RV32ZBB-NEXT: j .LBB2_3
142 ; RV32ZBB-NEXT: .LBB2_2:
143 ; RV32ZBB-NEXT: sll a1, a4, a2
144 ; RV32ZBB-NEXT: xori a3, a2, 31
145 ; RV32ZBB-NEXT: srli a6, a0, 1
146 ; RV32ZBB-NEXT: srl a3, a6, a3
147 ; RV32ZBB-NEXT: or a1, a1, a3
148 ; RV32ZBB-NEXT: .LBB2_3:
149 ; RV32ZBB-NEXT: neg a6, a2
150 ; RV32ZBB-NEXT: li a3, 32
151 ; RV32ZBB-NEXT: sub a7, a3, a2
152 ; RV32ZBB-NEXT: srl a3, a4, a6
153 ; RV32ZBB-NEXT: bltz a7, .LBB2_6
154 ; RV32ZBB-NEXT: # %bb.4:
155 ; RV32ZBB-NEXT: bltz a5, .LBB2_7
156 ; RV32ZBB-NEXT: .LBB2_5:
157 ; RV32ZBB-NEXT: mv a0, a3
159 ; RV32ZBB-NEXT: .LBB2_6:
160 ; RV32ZBB-NEXT: srl a6, a0, a6
161 ; RV32ZBB-NEXT: li a7, 64
162 ; RV32ZBB-NEXT: sub a7, a7, a2
163 ; RV32ZBB-NEXT: xori a7, a7, 31
164 ; RV32ZBB-NEXT: slli a4, a4, 1
165 ; RV32ZBB-NEXT: sll a4, a4, a7
166 ; RV32ZBB-NEXT: or a4, a6, a4
167 ; RV32ZBB-NEXT: or a1, a1, a3
168 ; RV32ZBB-NEXT: mv a3, a4
169 ; RV32ZBB-NEXT: bgez a5, .LBB2_5
170 ; RV32ZBB-NEXT: .LBB2_7:
171 ; RV32ZBB-NEXT: sll a0, a0, a2
172 ; RV32ZBB-NEXT: or a3, a3, a0
173 ; RV32ZBB-NEXT: mv a0, a3
176 ; RV64ZBB-LABEL: rotl_64:
178 ; RV64ZBB-NEXT: rol a0, a0, a1
187 define i64 @rotr_64(i64 %x, i64 %y) nounwind {
188 ; RV32I-LABEL: rotr_64:
190 ; RV32I-NEXT: addi a5, a2, -32
191 ; RV32I-NEXT: mv a4, a0
192 ; RV32I-NEXT: bltz a5, .LBB3_2
193 ; RV32I-NEXT: # %bb.1:
194 ; RV32I-NEXT: srl a0, a1, a5
195 ; RV32I-NEXT: j .LBB3_3
196 ; RV32I-NEXT: .LBB3_2:
197 ; RV32I-NEXT: srl a0, a4, a2
198 ; RV32I-NEXT: xori a3, a2, 31
199 ; RV32I-NEXT: slli a6, a1, 1
200 ; RV32I-NEXT: sll a3, a6, a3
201 ; RV32I-NEXT: or a0, a0, a3
202 ; RV32I-NEXT: .LBB3_3:
203 ; RV32I-NEXT: neg a6, a2
204 ; RV32I-NEXT: li a3, 32
205 ; RV32I-NEXT: sub a7, a3, a2
206 ; RV32I-NEXT: sll a3, a4, a6
207 ; RV32I-NEXT: bltz a7, .LBB3_6
208 ; RV32I-NEXT: # %bb.4:
209 ; RV32I-NEXT: bltz a5, .LBB3_7
210 ; RV32I-NEXT: .LBB3_5:
211 ; RV32I-NEXT: mv a1, a3
213 ; RV32I-NEXT: .LBB3_6:
214 ; RV32I-NEXT: sll a6, a1, a6
215 ; RV32I-NEXT: li a7, 64
216 ; RV32I-NEXT: sub a7, a7, a2
217 ; RV32I-NEXT: xori a7, a7, 31
218 ; RV32I-NEXT: srli a4, a4, 1
219 ; RV32I-NEXT: srl a4, a4, a7
220 ; RV32I-NEXT: or a4, a6, a4
221 ; RV32I-NEXT: or a0, a0, a3
222 ; RV32I-NEXT: mv a3, a4
223 ; RV32I-NEXT: bgez a5, .LBB3_5
224 ; RV32I-NEXT: .LBB3_7:
225 ; RV32I-NEXT: srl a1, a1, a2
226 ; RV32I-NEXT: or a3, a3, a1
227 ; RV32I-NEXT: mv a1, a3
230 ; RV64I-LABEL: rotr_64:
232 ; RV64I-NEXT: negw a2, a1
233 ; RV64I-NEXT: srl a1, a0, a1
234 ; RV64I-NEXT: sll a0, a0, a2
235 ; RV64I-NEXT: or a0, a1, a0
238 ; RV32ZBB-LABEL: rotr_64:
240 ; RV32ZBB-NEXT: addi a5, a2, -32
241 ; RV32ZBB-NEXT: mv a4, a0
242 ; RV32ZBB-NEXT: bltz a5, .LBB3_2
243 ; RV32ZBB-NEXT: # %bb.1:
244 ; RV32ZBB-NEXT: srl a0, a1, a5
245 ; RV32ZBB-NEXT: j .LBB3_3
246 ; RV32ZBB-NEXT: .LBB3_2:
247 ; RV32ZBB-NEXT: srl a0, a4, a2
248 ; RV32ZBB-NEXT: xori a3, a2, 31
249 ; RV32ZBB-NEXT: slli a6, a1, 1
250 ; RV32ZBB-NEXT: sll a3, a6, a3
251 ; RV32ZBB-NEXT: or a0, a0, a3
252 ; RV32ZBB-NEXT: .LBB3_3:
253 ; RV32ZBB-NEXT: neg a6, a2
254 ; RV32ZBB-NEXT: li a3, 32
255 ; RV32ZBB-NEXT: sub a7, a3, a2
256 ; RV32ZBB-NEXT: sll a3, a4, a6
257 ; RV32ZBB-NEXT: bltz a7, .LBB3_6
258 ; RV32ZBB-NEXT: # %bb.4:
259 ; RV32ZBB-NEXT: bltz a5, .LBB3_7
260 ; RV32ZBB-NEXT: .LBB3_5:
261 ; RV32ZBB-NEXT: mv a1, a3
263 ; RV32ZBB-NEXT: .LBB3_6:
264 ; RV32ZBB-NEXT: sll a6, a1, a6
265 ; RV32ZBB-NEXT: li a7, 64
266 ; RV32ZBB-NEXT: sub a7, a7, a2
267 ; RV32ZBB-NEXT: xori a7, a7, 31
268 ; RV32ZBB-NEXT: srli a4, a4, 1
269 ; RV32ZBB-NEXT: srl a4, a4, a7
270 ; RV32ZBB-NEXT: or a4, a6, a4
271 ; RV32ZBB-NEXT: or a0, a0, a3
272 ; RV32ZBB-NEXT: mv a3, a4
273 ; RV32ZBB-NEXT: bgez a5, .LBB3_5
274 ; RV32ZBB-NEXT: .LBB3_7:
275 ; RV32ZBB-NEXT: srl a1, a1, a2
276 ; RV32ZBB-NEXT: or a3, a3, a1
277 ; RV32ZBB-NEXT: mv a1, a3
280 ; RV64ZBB-LABEL: rotr_64:
282 ; RV64ZBB-NEXT: ror a0, a0, a1
291 define i32 @rotl_32_mask(i32 %x, i32 %y) nounwind {
292 ; RV32I-LABEL: rotl_32_mask:
294 ; RV32I-NEXT: neg a2, a1
295 ; RV32I-NEXT: sll a1, a0, a1
296 ; RV32I-NEXT: srl a0, a0, a2
297 ; RV32I-NEXT: or a0, a1, a0
300 ; RV64I-LABEL: rotl_32_mask:
302 ; RV64I-NEXT: negw a2, a1
303 ; RV64I-NEXT: sllw a1, a0, a1
304 ; RV64I-NEXT: srlw a0, a0, a2
305 ; RV64I-NEXT: or a0, a1, a0
308 ; RV32ZBB-LABEL: rotl_32_mask:
310 ; RV32ZBB-NEXT: rol a0, a0, a1
313 ; RV64ZBB-LABEL: rotl_32_mask:
315 ; RV64ZBB-NEXT: rolw a0, a0, a1
318 %and = and i32 %z, 31
320 %c = lshr i32 %x, %and
325 define i32 @rotr_32_mask(i32 %x, i32 %y) nounwind {
326 ; RV32I-LABEL: rotr_32_mask:
328 ; RV32I-NEXT: neg a2, a1
329 ; RV32I-NEXT: srl a1, a0, a1
330 ; RV32I-NEXT: sll a0, a0, a2
331 ; RV32I-NEXT: or a0, a1, a0
334 ; RV64I-LABEL: rotr_32_mask:
336 ; RV64I-NEXT: negw a2, a1
337 ; RV64I-NEXT: srlw a1, a0, a1
338 ; RV64I-NEXT: sllw a0, a0, a2
339 ; RV64I-NEXT: or a0, a1, a0
342 ; RV32ZBB-LABEL: rotr_32_mask:
344 ; RV32ZBB-NEXT: ror a0, a0, a1
347 ; RV64ZBB-LABEL: rotr_32_mask:
349 ; RV64ZBB-NEXT: rorw a0, a0, a1
352 %and = and i32 %z, 31
354 %c = shl i32 %x, %and
359 define i64 @rotl_64_mask(i64 %x, i64 %y) nounwind {
360 ; RV32I-LABEL: rotl_64_mask:
362 ; RV32I-NEXT: addi a5, a2, -32
363 ; RV32I-NEXT: mv a3, a1
364 ; RV32I-NEXT: bltz a5, .LBB6_2
365 ; RV32I-NEXT: # %bb.1:
366 ; RV32I-NEXT: sll a1, a0, a5
367 ; RV32I-NEXT: j .LBB6_3
368 ; RV32I-NEXT: .LBB6_2:
369 ; RV32I-NEXT: sll a1, a3, a2
370 ; RV32I-NEXT: xori a4, a2, 31
371 ; RV32I-NEXT: srli a6, a0, 1
372 ; RV32I-NEXT: srl a4, a6, a4
373 ; RV32I-NEXT: or a1, a1, a4
374 ; RV32I-NEXT: .LBB6_3:
375 ; RV32I-NEXT: neg a6, a2
376 ; RV32I-NEXT: andi a4, a6, 63
377 ; RV32I-NEXT: addi a7, a4, -32
378 ; RV32I-NEXT: bltz a7, .LBB6_5
379 ; RV32I-NEXT: # %bb.4:
380 ; RV32I-NEXT: srl a4, a3, a7
381 ; RV32I-NEXT: bltz a5, .LBB6_6
382 ; RV32I-NEXT: j .LBB6_7
383 ; RV32I-NEXT: .LBB6_5:
384 ; RV32I-NEXT: srl a7, a0, a6
385 ; RV32I-NEXT: xori a4, a4, 31
386 ; RV32I-NEXT: slli t0, a3, 1
387 ; RV32I-NEXT: sll a4, t0, a4
388 ; RV32I-NEXT: or a4, a7, a4
389 ; RV32I-NEXT: srl a3, a3, a6
390 ; RV32I-NEXT: or a1, a1, a3
391 ; RV32I-NEXT: bgez a5, .LBB6_7
392 ; RV32I-NEXT: .LBB6_6:
393 ; RV32I-NEXT: sll a0, a0, a2
394 ; RV32I-NEXT: or a4, a4, a0
395 ; RV32I-NEXT: .LBB6_7:
396 ; RV32I-NEXT: mv a0, a4
399 ; RV64I-LABEL: rotl_64_mask:
401 ; RV64I-NEXT: neg a2, a1
402 ; RV64I-NEXT: sll a1, a0, a1
403 ; RV64I-NEXT: srl a0, a0, a2
404 ; RV64I-NEXT: or a0, a1, a0
407 ; RV32ZBB-LABEL: rotl_64_mask:
409 ; RV32ZBB-NEXT: addi a5, a2, -32
410 ; RV32ZBB-NEXT: mv a3, a1
411 ; RV32ZBB-NEXT: bltz a5, .LBB6_2
412 ; RV32ZBB-NEXT: # %bb.1:
413 ; RV32ZBB-NEXT: sll a1, a0, a5
414 ; RV32ZBB-NEXT: j .LBB6_3
415 ; RV32ZBB-NEXT: .LBB6_2:
416 ; RV32ZBB-NEXT: sll a1, a3, a2
417 ; RV32ZBB-NEXT: xori a4, a2, 31
418 ; RV32ZBB-NEXT: srli a6, a0, 1
419 ; RV32ZBB-NEXT: srl a4, a6, a4
420 ; RV32ZBB-NEXT: or a1, a1, a4
421 ; RV32ZBB-NEXT: .LBB6_3:
422 ; RV32ZBB-NEXT: neg a6, a2
423 ; RV32ZBB-NEXT: andi a4, a6, 63
424 ; RV32ZBB-NEXT: addi a7, a4, -32
425 ; RV32ZBB-NEXT: bltz a7, .LBB6_5
426 ; RV32ZBB-NEXT: # %bb.4:
427 ; RV32ZBB-NEXT: srl a4, a3, a7
428 ; RV32ZBB-NEXT: bltz a5, .LBB6_6
429 ; RV32ZBB-NEXT: j .LBB6_7
430 ; RV32ZBB-NEXT: .LBB6_5:
431 ; RV32ZBB-NEXT: srl a7, a0, a6
432 ; RV32ZBB-NEXT: xori a4, a4, 31
433 ; RV32ZBB-NEXT: slli t0, a3, 1
434 ; RV32ZBB-NEXT: sll a4, t0, a4
435 ; RV32ZBB-NEXT: or a4, a7, a4
436 ; RV32ZBB-NEXT: srl a3, a3, a6
437 ; RV32ZBB-NEXT: or a1, a1, a3
438 ; RV32ZBB-NEXT: bgez a5, .LBB6_7
439 ; RV32ZBB-NEXT: .LBB6_6:
440 ; RV32ZBB-NEXT: sll a0, a0, a2
441 ; RV32ZBB-NEXT: or a4, a4, a0
442 ; RV32ZBB-NEXT: .LBB6_7:
443 ; RV32ZBB-NEXT: mv a0, a4
446 ; RV64ZBB-LABEL: rotl_64_mask:
448 ; RV64ZBB-NEXT: rol a0, a0, a1
451 %and = and i64 %z, 63
453 %c = lshr i64 %x, %and
458 define i64 @rotr_64_mask(i64 %x, i64 %y) nounwind {
459 ; RV32I-LABEL: rotr_64_mask:
461 ; RV32I-NEXT: addi a5, a2, -32
462 ; RV32I-NEXT: mv a3, a0
463 ; RV32I-NEXT: bltz a5, .LBB7_2
464 ; RV32I-NEXT: # %bb.1:
465 ; RV32I-NEXT: srl a0, a1, a5
466 ; RV32I-NEXT: j .LBB7_3
467 ; RV32I-NEXT: .LBB7_2:
468 ; RV32I-NEXT: srl a0, a3, a2
469 ; RV32I-NEXT: xori a4, a2, 31
470 ; RV32I-NEXT: slli a6, a1, 1
471 ; RV32I-NEXT: sll a4, a6, a4
472 ; RV32I-NEXT: or a0, a0, a4
473 ; RV32I-NEXT: .LBB7_3:
474 ; RV32I-NEXT: neg a6, a2
475 ; RV32I-NEXT: andi a4, a6, 63
476 ; RV32I-NEXT: addi a7, a4, -32
477 ; RV32I-NEXT: bltz a7, .LBB7_5
478 ; RV32I-NEXT: # %bb.4:
479 ; RV32I-NEXT: sll a4, a3, a7
480 ; RV32I-NEXT: bltz a5, .LBB7_6
481 ; RV32I-NEXT: j .LBB7_7
482 ; RV32I-NEXT: .LBB7_5:
483 ; RV32I-NEXT: sll a7, a1, a6
484 ; RV32I-NEXT: xori a4, a4, 31
485 ; RV32I-NEXT: srli t0, a3, 1
486 ; RV32I-NEXT: srl a4, t0, a4
487 ; RV32I-NEXT: or a4, a7, a4
488 ; RV32I-NEXT: sll a3, a3, a6
489 ; RV32I-NEXT: or a0, a0, a3
490 ; RV32I-NEXT: bgez a5, .LBB7_7
491 ; RV32I-NEXT: .LBB7_6:
492 ; RV32I-NEXT: srl a1, a1, a2
493 ; RV32I-NEXT: or a4, a4, a1
494 ; RV32I-NEXT: .LBB7_7:
495 ; RV32I-NEXT: mv a1, a4
498 ; RV64I-LABEL: rotr_64_mask:
500 ; RV64I-NEXT: neg a2, a1
501 ; RV64I-NEXT: srl a1, a0, a1
502 ; RV64I-NEXT: sll a0, a0, a2
503 ; RV64I-NEXT: or a0, a1, a0
506 ; RV32ZBB-LABEL: rotr_64_mask:
508 ; RV32ZBB-NEXT: addi a5, a2, -32
509 ; RV32ZBB-NEXT: mv a3, a0
510 ; RV32ZBB-NEXT: bltz a5, .LBB7_2
511 ; RV32ZBB-NEXT: # %bb.1:
512 ; RV32ZBB-NEXT: srl a0, a1, a5
513 ; RV32ZBB-NEXT: j .LBB7_3
514 ; RV32ZBB-NEXT: .LBB7_2:
515 ; RV32ZBB-NEXT: srl a0, a3, a2
516 ; RV32ZBB-NEXT: xori a4, a2, 31
517 ; RV32ZBB-NEXT: slli a6, a1, 1
518 ; RV32ZBB-NEXT: sll a4, a6, a4
519 ; RV32ZBB-NEXT: or a0, a0, a4
520 ; RV32ZBB-NEXT: .LBB7_3:
521 ; RV32ZBB-NEXT: neg a6, a2
522 ; RV32ZBB-NEXT: andi a4, a6, 63
523 ; RV32ZBB-NEXT: addi a7, a4, -32
524 ; RV32ZBB-NEXT: bltz a7, .LBB7_5
525 ; RV32ZBB-NEXT: # %bb.4:
526 ; RV32ZBB-NEXT: sll a4, a3, a7
527 ; RV32ZBB-NEXT: bltz a5, .LBB7_6
528 ; RV32ZBB-NEXT: j .LBB7_7
529 ; RV32ZBB-NEXT: .LBB7_5:
530 ; RV32ZBB-NEXT: sll a7, a1, a6
531 ; RV32ZBB-NEXT: xori a4, a4, 31
532 ; RV32ZBB-NEXT: srli t0, a3, 1
533 ; RV32ZBB-NEXT: srl a4, t0, a4
534 ; RV32ZBB-NEXT: or a4, a7, a4
535 ; RV32ZBB-NEXT: sll a3, a3, a6
536 ; RV32ZBB-NEXT: or a0, a0, a3
537 ; RV32ZBB-NEXT: bgez a5, .LBB7_7
538 ; RV32ZBB-NEXT: .LBB7_6:
539 ; RV32ZBB-NEXT: srl a1, a1, a2
540 ; RV32ZBB-NEXT: or a4, a4, a1
541 ; RV32ZBB-NEXT: .LBB7_7:
542 ; RV32ZBB-NEXT: mv a1, a4
545 ; RV64ZBB-LABEL: rotr_64_mask:
547 ; RV64ZBB-NEXT: ror a0, a0, a1
550 %and = and i64 %z, 63
552 %c = shl i64 %x, %and
557 ; Test that we're able to remove a mask on the rotate amount that has more than
559 define signext i32 @rotl_32_mask_shared(i32 signext %a, i32 signext %b, i32 signext %amt) nounwind {
560 ; RV32I-LABEL: rotl_32_mask_shared:
562 ; RV32I-NEXT: sll a3, a0, a2
563 ; RV32I-NEXT: neg a4, a2
564 ; RV32I-NEXT: srl a0, a0, a4
565 ; RV32I-NEXT: or a0, a3, a0
566 ; RV32I-NEXT: sll a1, a1, a2
567 ; RV32I-NEXT: add a0, a0, a1
570 ; RV64I-LABEL: rotl_32_mask_shared:
572 ; RV64I-NEXT: sllw a3, a0, a2
573 ; RV64I-NEXT: negw a4, a2
574 ; RV64I-NEXT: srlw a0, a0, a4
575 ; RV64I-NEXT: or a0, a3, a0
576 ; RV64I-NEXT: sllw a1, a1, a2
577 ; RV64I-NEXT: addw a0, a0, a1
580 ; RV32ZBB-LABEL: rotl_32_mask_shared:
582 ; RV32ZBB-NEXT: rol a0, a0, a2
583 ; RV32ZBB-NEXT: sll a1, a1, a2
584 ; RV32ZBB-NEXT: add a0, a0, a1
587 ; RV64ZBB-LABEL: rotl_32_mask_shared:
589 ; RV64ZBB-NEXT: rolw a0, a0, a2
590 ; RV64ZBB-NEXT: sllw a1, a1, a2
591 ; RV64ZBB-NEXT: addw a0, a0, a1
593 %maskedamt = and i32 %amt, 31
594 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %maskedamt)
595 %2 = shl i32 %b, %maskedamt
599 declare i32 @llvm.fshl.i32(i32, i32, i32)
601 define signext i64 @rotl_64_mask_shared(i64 signext %a, i64 signext %b, i64 signext %amt) nounwind {
602 ; RV32I-LABEL: rotl_64_mask_shared:
604 ; RV32I-NEXT: slli a5, a4, 26
605 ; RV32I-NEXT: srli a5, a5, 31
606 ; RV32I-NEXT: mv a7, a0
607 ; RV32I-NEXT: bnez a5, .LBB9_2
608 ; RV32I-NEXT: # %bb.1:
609 ; RV32I-NEXT: mv a7, a1
610 ; RV32I-NEXT: .LBB9_2:
611 ; RV32I-NEXT: andi a6, a4, 63
612 ; RV32I-NEXT: sll t0, a7, a4
613 ; RV32I-NEXT: bnez a5, .LBB9_4
614 ; RV32I-NEXT: # %bb.3:
615 ; RV32I-NEXT: mv a1, a0
616 ; RV32I-NEXT: .LBB9_4:
617 ; RV32I-NEXT: srli a0, a1, 1
618 ; RV32I-NEXT: not t1, a4
619 ; RV32I-NEXT: srl a0, a0, t1
620 ; RV32I-NEXT: or a5, t0, a0
621 ; RV32I-NEXT: sll a1, a1, a4
622 ; RV32I-NEXT: srli a0, a7, 1
623 ; RV32I-NEXT: srl a7, a0, t1
624 ; RV32I-NEXT: addi a0, a6, -32
625 ; RV32I-NEXT: or a1, a1, a7
626 ; RV32I-NEXT: bltz a0, .LBB9_6
627 ; RV32I-NEXT: # %bb.5:
628 ; RV32I-NEXT: sll a3, a2, a0
629 ; RV32I-NEXT: mv a0, a1
630 ; RV32I-NEXT: j .LBB9_7
631 ; RV32I-NEXT: .LBB9_6:
632 ; RV32I-NEXT: sll a0, a3, a4
633 ; RV32I-NEXT: srli a3, a2, 1
634 ; RV32I-NEXT: xori a6, a6, 31
635 ; RV32I-NEXT: srl a3, a3, a6
636 ; RV32I-NEXT: or a3, a0, a3
637 ; RV32I-NEXT: sll a0, a2, a4
638 ; RV32I-NEXT: add a0, a1, a0
639 ; RV32I-NEXT: .LBB9_7:
640 ; RV32I-NEXT: sltu a1, a0, a1
641 ; RV32I-NEXT: add a2, a5, a3
642 ; RV32I-NEXT: add a1, a2, a1
645 ; RV64I-LABEL: rotl_64_mask_shared:
647 ; RV64I-NEXT: sll a3, a0, a2
648 ; RV64I-NEXT: neg a4, a2
649 ; RV64I-NEXT: srl a0, a0, a4
650 ; RV64I-NEXT: or a0, a3, a0
651 ; RV64I-NEXT: sll a1, a1, a2
652 ; RV64I-NEXT: add a0, a0, a1
655 ; RV32ZBB-LABEL: rotl_64_mask_shared:
657 ; RV32ZBB-NEXT: slli a5, a4, 26
658 ; RV32ZBB-NEXT: srli a5, a5, 31
659 ; RV32ZBB-NEXT: mv a7, a0
660 ; RV32ZBB-NEXT: bnez a5, .LBB9_2
661 ; RV32ZBB-NEXT: # %bb.1:
662 ; RV32ZBB-NEXT: mv a7, a1
663 ; RV32ZBB-NEXT: .LBB9_2:
664 ; RV32ZBB-NEXT: andi a6, a4, 63
665 ; RV32ZBB-NEXT: sll t0, a7, a4
666 ; RV32ZBB-NEXT: bnez a5, .LBB9_4
667 ; RV32ZBB-NEXT: # %bb.3:
668 ; RV32ZBB-NEXT: mv a1, a0
669 ; RV32ZBB-NEXT: .LBB9_4:
670 ; RV32ZBB-NEXT: srli a0, a1, 1
671 ; RV32ZBB-NEXT: not t1, a4
672 ; RV32ZBB-NEXT: srl a0, a0, t1
673 ; RV32ZBB-NEXT: or a5, t0, a0
674 ; RV32ZBB-NEXT: sll a1, a1, a4
675 ; RV32ZBB-NEXT: srli a0, a7, 1
676 ; RV32ZBB-NEXT: srl a7, a0, t1
677 ; RV32ZBB-NEXT: addi a0, a6, -32
678 ; RV32ZBB-NEXT: or a1, a1, a7
679 ; RV32ZBB-NEXT: bltz a0, .LBB9_6
680 ; RV32ZBB-NEXT: # %bb.5:
681 ; RV32ZBB-NEXT: sll a3, a2, a0
682 ; RV32ZBB-NEXT: mv a0, a1
683 ; RV32ZBB-NEXT: j .LBB9_7
684 ; RV32ZBB-NEXT: .LBB9_6:
685 ; RV32ZBB-NEXT: sll a0, a3, a4
686 ; RV32ZBB-NEXT: srli a3, a2, 1
687 ; RV32ZBB-NEXT: xori a6, a6, 31
688 ; RV32ZBB-NEXT: srl a3, a3, a6
689 ; RV32ZBB-NEXT: or a3, a0, a3
690 ; RV32ZBB-NEXT: sll a0, a2, a4
691 ; RV32ZBB-NEXT: add a0, a1, a0
692 ; RV32ZBB-NEXT: .LBB9_7:
693 ; RV32ZBB-NEXT: sltu a1, a0, a1
694 ; RV32ZBB-NEXT: add a2, a5, a3
695 ; RV32ZBB-NEXT: add a1, a2, a1
698 ; RV64ZBB-LABEL: rotl_64_mask_shared:
700 ; RV64ZBB-NEXT: rol a0, a0, a2
701 ; RV64ZBB-NEXT: sll a1, a1, a2
702 ; RV64ZBB-NEXT: add a0, a0, a1
704 %maskedamt = and i64 %amt, 63
705 %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %maskedamt)
706 %2 = shl i64 %b, %maskedamt
710 declare i64 @llvm.fshl.i64(i64, i64, i64)
712 define signext i32 @rotr_32_mask_shared(i32 signext %a, i32 signext %b, i32 signext %amt) nounwind {
713 ; RV32I-LABEL: rotr_32_mask_shared:
715 ; RV32I-NEXT: srl a3, a0, a2
716 ; RV32I-NEXT: neg a4, a2
717 ; RV32I-NEXT: sll a0, a0, a4
718 ; RV32I-NEXT: or a0, a3, a0
719 ; RV32I-NEXT: sll a1, a1, a2
720 ; RV32I-NEXT: add a0, a0, a1
723 ; RV64I-LABEL: rotr_32_mask_shared:
725 ; RV64I-NEXT: srlw a3, a0, a2
726 ; RV64I-NEXT: negw a4, a2
727 ; RV64I-NEXT: sllw a0, a0, a4
728 ; RV64I-NEXT: or a0, a3, a0
729 ; RV64I-NEXT: sllw a1, a1, a2
730 ; RV64I-NEXT: addw a0, a0, a1
733 ; RV32ZBB-LABEL: rotr_32_mask_shared:
735 ; RV32ZBB-NEXT: ror a0, a0, a2
736 ; RV32ZBB-NEXT: sll a1, a1, a2
737 ; RV32ZBB-NEXT: add a0, a0, a1
740 ; RV64ZBB-LABEL: rotr_32_mask_shared:
742 ; RV64ZBB-NEXT: rorw a0, a0, a2
743 ; RV64ZBB-NEXT: sllw a1, a1, a2
744 ; RV64ZBB-NEXT: addw a0, a0, a1
746 %maskedamt = and i32 %amt, 31
747 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %maskedamt)
748 %2 = shl i32 %b, %maskedamt
752 declare i32 @llvm.fshr.i32(i32, i32, i32)
754 define signext i64 @rotr_64_mask_shared(i64 signext %a, i64 signext %b, i64 signext %amt) nounwind {
755 ; RV32I-LABEL: rotr_64_mask_shared:
757 ; RV32I-NEXT: andi a7, a4, 32
758 ; RV32I-NEXT: mv a6, a1
759 ; RV32I-NEXT: beqz a7, .LBB11_2
760 ; RV32I-NEXT: # %bb.1:
761 ; RV32I-NEXT: mv a6, a0
762 ; RV32I-NEXT: .LBB11_2:
763 ; RV32I-NEXT: andi a5, a4, 63
764 ; RV32I-NEXT: srl t0, a6, a4
765 ; RV32I-NEXT: beqz a7, .LBB11_4
766 ; RV32I-NEXT: # %bb.3:
767 ; RV32I-NEXT: mv a0, a1
768 ; RV32I-NEXT: .LBB11_4:
769 ; RV32I-NEXT: slli a1, a0, 1
770 ; RV32I-NEXT: not a7, a4
771 ; RV32I-NEXT: sll a1, a1, a7
772 ; RV32I-NEXT: or a1, a1, t0
773 ; RV32I-NEXT: srl t0, a0, a4
774 ; RV32I-NEXT: slli a0, a6, 1
775 ; RV32I-NEXT: sll a6, a0, a7
776 ; RV32I-NEXT: addi a0, a5, -32
777 ; RV32I-NEXT: or a6, a6, t0
778 ; RV32I-NEXT: bltz a0, .LBB11_6
779 ; RV32I-NEXT: # %bb.5:
780 ; RV32I-NEXT: sll a3, a2, a0
781 ; RV32I-NEXT: mv a0, a6
782 ; RV32I-NEXT: j .LBB11_7
783 ; RV32I-NEXT: .LBB11_6:
784 ; RV32I-NEXT: sll a0, a3, a4
785 ; RV32I-NEXT: srli a3, a2, 1
786 ; RV32I-NEXT: xori a5, a5, 31
787 ; RV32I-NEXT: srl a3, a3, a5
788 ; RV32I-NEXT: or a3, a0, a3
789 ; RV32I-NEXT: sll a0, a2, a4
790 ; RV32I-NEXT: add a0, a6, a0
791 ; RV32I-NEXT: .LBB11_7:
792 ; RV32I-NEXT: sltu a2, a0, a6
793 ; RV32I-NEXT: add a1, a1, a3
794 ; RV32I-NEXT: add a1, a1, a2
797 ; RV64I-LABEL: rotr_64_mask_shared:
799 ; RV64I-NEXT: srl a3, a0, a2
800 ; RV64I-NEXT: neg a4, a2
801 ; RV64I-NEXT: sll a0, a0, a4
802 ; RV64I-NEXT: or a0, a3, a0
803 ; RV64I-NEXT: sll a1, a1, a2
804 ; RV64I-NEXT: add a0, a0, a1
807 ; RV32ZBB-LABEL: rotr_64_mask_shared:
809 ; RV32ZBB-NEXT: andi a7, a4, 32
810 ; RV32ZBB-NEXT: mv a6, a1
811 ; RV32ZBB-NEXT: beqz a7, .LBB11_2
812 ; RV32ZBB-NEXT: # %bb.1:
813 ; RV32ZBB-NEXT: mv a6, a0
814 ; RV32ZBB-NEXT: .LBB11_2:
815 ; RV32ZBB-NEXT: andi a5, a4, 63
816 ; RV32ZBB-NEXT: srl t0, a6, a4
817 ; RV32ZBB-NEXT: beqz a7, .LBB11_4
818 ; RV32ZBB-NEXT: # %bb.3:
819 ; RV32ZBB-NEXT: mv a0, a1
820 ; RV32ZBB-NEXT: .LBB11_4:
821 ; RV32ZBB-NEXT: slli a1, a0, 1
822 ; RV32ZBB-NEXT: not a7, a4
823 ; RV32ZBB-NEXT: sll a1, a1, a7
824 ; RV32ZBB-NEXT: or a1, a1, t0
825 ; RV32ZBB-NEXT: srl t0, a0, a4
826 ; RV32ZBB-NEXT: slli a0, a6, 1
827 ; RV32ZBB-NEXT: sll a6, a0, a7
828 ; RV32ZBB-NEXT: addi a0, a5, -32
829 ; RV32ZBB-NEXT: or a6, a6, t0
830 ; RV32ZBB-NEXT: bltz a0, .LBB11_6
831 ; RV32ZBB-NEXT: # %bb.5:
832 ; RV32ZBB-NEXT: sll a3, a2, a0
833 ; RV32ZBB-NEXT: mv a0, a6
834 ; RV32ZBB-NEXT: j .LBB11_7
835 ; RV32ZBB-NEXT: .LBB11_6:
836 ; RV32ZBB-NEXT: sll a0, a3, a4
837 ; RV32ZBB-NEXT: srli a3, a2, 1
838 ; RV32ZBB-NEXT: xori a5, a5, 31
839 ; RV32ZBB-NEXT: srl a3, a3, a5
840 ; RV32ZBB-NEXT: or a3, a0, a3
841 ; RV32ZBB-NEXT: sll a0, a2, a4
842 ; RV32ZBB-NEXT: add a0, a6, a0
843 ; RV32ZBB-NEXT: .LBB11_7:
844 ; RV32ZBB-NEXT: sltu a2, a0, a6
845 ; RV32ZBB-NEXT: add a1, a1, a3
846 ; RV32ZBB-NEXT: add a1, a1, a2
849 ; RV64ZBB-LABEL: rotr_64_mask_shared:
851 ; RV64ZBB-NEXT: ror a0, a0, a2
852 ; RV64ZBB-NEXT: sll a1, a1, a2
853 ; RV64ZBB-NEXT: add a0, a0, a1
855 %maskedamt = and i64 %amt, 63
856 %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %maskedamt)
857 %2 = shl i64 %b, %maskedamt
861 declare i64 @llvm.fshr.i64(i64, i64, i64)
863 define signext i32 @rotl_32_mask_multiple(i32 signext %a, i32 signext %b, i32 signext %amt) nounwind {
864 ; RV32I-LABEL: rotl_32_mask_multiple:
866 ; RV32I-NEXT: sll a3, a0, a2
867 ; RV32I-NEXT: neg a4, a2
868 ; RV32I-NEXT: srl a0, a0, a4
869 ; RV32I-NEXT: or a0, a3, a0
870 ; RV32I-NEXT: sll a2, a1, a2
871 ; RV32I-NEXT: srl a1, a1, a4
872 ; RV32I-NEXT: or a1, a2, a1
873 ; RV32I-NEXT: add a0, a0, a1
876 ; RV64I-LABEL: rotl_32_mask_multiple:
878 ; RV64I-NEXT: sllw a3, a0, a2
879 ; RV64I-NEXT: negw a4, a2
880 ; RV64I-NEXT: srlw a0, a0, a4
881 ; RV64I-NEXT: or a0, a3, a0
882 ; RV64I-NEXT: sllw a2, a1, a2
883 ; RV64I-NEXT: srlw a1, a1, a4
884 ; RV64I-NEXT: or a1, a2, a1
885 ; RV64I-NEXT: addw a0, a0, a1
888 ; RV32ZBB-LABEL: rotl_32_mask_multiple:
890 ; RV32ZBB-NEXT: rol a0, a0, a2
891 ; RV32ZBB-NEXT: rol a1, a1, a2
892 ; RV32ZBB-NEXT: add a0, a0, a1
895 ; RV64ZBB-LABEL: rotl_32_mask_multiple:
897 ; RV64ZBB-NEXT: rolw a0, a0, a2
898 ; RV64ZBB-NEXT: rolw a1, a1, a2
899 ; RV64ZBB-NEXT: addw a0, a0, a1
901 %maskedamt = and i32 %amt, 31
902 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %maskedamt)
903 %2 = tail call i32 @llvm.fshl.i32(i32 %b, i32 %b, i32 %maskedamt)
908 define i64 @rotl_64_mask_multiple(i64 %a, i64 %b, i64 %amt) nounwind {
909 ; RV32I-LABEL: rotl_64_mask_multiple:
911 ; RV32I-NEXT: slli a5, a4, 26
912 ; RV32I-NEXT: srli a5, a5, 31
913 ; RV32I-NEXT: mv a6, a1
914 ; RV32I-NEXT: bnez a5, .LBB13_2
915 ; RV32I-NEXT: # %bb.1:
916 ; RV32I-NEXT: mv a6, a0
917 ; RV32I-NEXT: .LBB13_2:
918 ; RV32I-NEXT: bnez a5, .LBB13_4
919 ; RV32I-NEXT: # %bb.3:
920 ; RV32I-NEXT: mv a0, a1
921 ; RV32I-NEXT: .LBB13_4:
922 ; RV32I-NEXT: sll a7, a6, a4
923 ; RV32I-NEXT: srli t0, a0, 1
924 ; RV32I-NEXT: not a1, a4
925 ; RV32I-NEXT: srl t0, t0, a1
926 ; RV32I-NEXT: sll t1, a0, a4
927 ; RV32I-NEXT: srli a0, a6, 1
928 ; RV32I-NEXT: srl t2, a0, a1
929 ; RV32I-NEXT: mv a0, a3
930 ; RV32I-NEXT: bnez a5, .LBB13_6
931 ; RV32I-NEXT: # %bb.5:
932 ; RV32I-NEXT: mv a0, a2
933 ; RV32I-NEXT: .LBB13_6:
934 ; RV32I-NEXT: or a6, a7, t0
935 ; RV32I-NEXT: or a7, t1, t2
936 ; RV32I-NEXT: sll t0, a0, a4
937 ; RV32I-NEXT: bnez a5, .LBB13_8
938 ; RV32I-NEXT: # %bb.7:
939 ; RV32I-NEXT: mv a2, a3
940 ; RV32I-NEXT: .LBB13_8:
941 ; RV32I-NEXT: srli a3, a2, 1
942 ; RV32I-NEXT: srl a3, a3, a1
943 ; RV32I-NEXT: or a3, t0, a3
944 ; RV32I-NEXT: sll a2, a2, a4
945 ; RV32I-NEXT: srli a0, a0, 1
946 ; RV32I-NEXT: srl a0, a0, a1
947 ; RV32I-NEXT: or a0, a2, a0
948 ; RV32I-NEXT: add a1, a7, a0
949 ; RV32I-NEXT: add a0, a6, a3
950 ; RV32I-NEXT: sltu a2, a0, a6
951 ; RV32I-NEXT: add a1, a1, a2
954 ; RV64I-LABEL: rotl_64_mask_multiple:
956 ; RV64I-NEXT: sll a3, a0, a2
957 ; RV64I-NEXT: neg a4, a2
958 ; RV64I-NEXT: srl a0, a0, a4
959 ; RV64I-NEXT: or a0, a3, a0
960 ; RV64I-NEXT: sll a2, a1, a2
961 ; RV64I-NEXT: srl a1, a1, a4
962 ; RV64I-NEXT: or a1, a2, a1
963 ; RV64I-NEXT: add a0, a0, a1
966 ; RV32ZBB-LABEL: rotl_64_mask_multiple:
968 ; RV32ZBB-NEXT: slli a5, a4, 26
969 ; RV32ZBB-NEXT: srli a5, a5, 31
970 ; RV32ZBB-NEXT: mv a6, a1
971 ; RV32ZBB-NEXT: bnez a5, .LBB13_2
972 ; RV32ZBB-NEXT: # %bb.1:
973 ; RV32ZBB-NEXT: mv a6, a0
974 ; RV32ZBB-NEXT: .LBB13_2:
975 ; RV32ZBB-NEXT: bnez a5, .LBB13_4
976 ; RV32ZBB-NEXT: # %bb.3:
977 ; RV32ZBB-NEXT: mv a0, a1
978 ; RV32ZBB-NEXT: .LBB13_4:
979 ; RV32ZBB-NEXT: sll a7, a6, a4
980 ; RV32ZBB-NEXT: srli t0, a0, 1
981 ; RV32ZBB-NEXT: not a1, a4
982 ; RV32ZBB-NEXT: srl t0, t0, a1
983 ; RV32ZBB-NEXT: sll t1, a0, a4
984 ; RV32ZBB-NEXT: srli a0, a6, 1
985 ; RV32ZBB-NEXT: srl t2, a0, a1
986 ; RV32ZBB-NEXT: mv a0, a3
987 ; RV32ZBB-NEXT: bnez a5, .LBB13_6
988 ; RV32ZBB-NEXT: # %bb.5:
989 ; RV32ZBB-NEXT: mv a0, a2
990 ; RV32ZBB-NEXT: .LBB13_6:
991 ; RV32ZBB-NEXT: or a6, a7, t0
992 ; RV32ZBB-NEXT: or a7, t1, t2
993 ; RV32ZBB-NEXT: sll t0, a0, a4
994 ; RV32ZBB-NEXT: bnez a5, .LBB13_8
995 ; RV32ZBB-NEXT: # %bb.7:
996 ; RV32ZBB-NEXT: mv a2, a3
997 ; RV32ZBB-NEXT: .LBB13_8:
998 ; RV32ZBB-NEXT: srli a3, a2, 1
999 ; RV32ZBB-NEXT: srl a3, a3, a1
1000 ; RV32ZBB-NEXT: or a3, t0, a3
1001 ; RV32ZBB-NEXT: sll a2, a2, a4
1002 ; RV32ZBB-NEXT: srli a0, a0, 1
1003 ; RV32ZBB-NEXT: srl a0, a0, a1
1004 ; RV32ZBB-NEXT: or a0, a2, a0
1005 ; RV32ZBB-NEXT: add a1, a7, a0
1006 ; RV32ZBB-NEXT: add a0, a6, a3
1007 ; RV32ZBB-NEXT: sltu a2, a0, a6
1008 ; RV32ZBB-NEXT: add a1, a1, a2
1011 ; RV64ZBB-LABEL: rotl_64_mask_multiple:
1013 ; RV64ZBB-NEXT: rol a0, a0, a2
1014 ; RV64ZBB-NEXT: rol a1, a1, a2
1015 ; RV64ZBB-NEXT: add a0, a0, a1
1017 %maskedamt = and i64 %amt, 63
1018 %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %maskedamt)
1019 %2 = tail call i64 @llvm.fshl.i64(i64 %b, i64 %b, i64 %maskedamt)
1024 define signext i32 @rotr_32_mask_multiple(i32 signext %a, i32 signext %b, i32 signext %amt) nounwind {
1025 ; RV32I-LABEL: rotr_32_mask_multiple:
1027 ; RV32I-NEXT: srl a3, a0, a2
1028 ; RV32I-NEXT: neg a4, a2
1029 ; RV32I-NEXT: sll a0, a0, a4
1030 ; RV32I-NEXT: or a0, a3, a0
1031 ; RV32I-NEXT: srl a2, a1, a2
1032 ; RV32I-NEXT: sll a1, a1, a4
1033 ; RV32I-NEXT: or a1, a2, a1
1034 ; RV32I-NEXT: add a0, a0, a1
1037 ; RV64I-LABEL: rotr_32_mask_multiple:
1039 ; RV64I-NEXT: srlw a3, a0, a2
1040 ; RV64I-NEXT: negw a4, a2
1041 ; RV64I-NEXT: sllw a0, a0, a4
1042 ; RV64I-NEXT: or a0, a3, a0
1043 ; RV64I-NEXT: srlw a2, a1, a2
1044 ; RV64I-NEXT: sllw a1, a1, a4
1045 ; RV64I-NEXT: or a1, a2, a1
1046 ; RV64I-NEXT: addw a0, a0, a1
1049 ; RV32ZBB-LABEL: rotr_32_mask_multiple:
1051 ; RV32ZBB-NEXT: ror a0, a0, a2
1052 ; RV32ZBB-NEXT: ror a1, a1, a2
1053 ; RV32ZBB-NEXT: add a0, a0, a1
1056 ; RV64ZBB-LABEL: rotr_32_mask_multiple:
1058 ; RV64ZBB-NEXT: rorw a0, a0, a2
1059 ; RV64ZBB-NEXT: rorw a1, a1, a2
1060 ; RV64ZBB-NEXT: addw a0, a0, a1
1062 %maskedamt = and i32 %amt, 31
1063 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %maskedamt)
1064 %2 = tail call i32 @llvm.fshr.i32(i32 %b, i32 %b, i32 %maskedamt)
1069 define i64 @rotr_64_mask_multiple(i64 %a, i64 %b, i64 %amt) nounwind {
1070 ; RV32I-LABEL: rotr_64_mask_multiple:
1072 ; RV32I-NEXT: andi a5, a4, 32
1073 ; RV32I-NEXT: mv a6, a0
1074 ; RV32I-NEXT: beqz a5, .LBB15_2
1075 ; RV32I-NEXT: # %bb.1:
1076 ; RV32I-NEXT: mv a6, a1
1077 ; RV32I-NEXT: .LBB15_2:
1078 ; RV32I-NEXT: beqz a5, .LBB15_4
1079 ; RV32I-NEXT: # %bb.3:
1080 ; RV32I-NEXT: mv a1, a0
1081 ; RV32I-NEXT: .LBB15_4:
1082 ; RV32I-NEXT: srl a7, a6, a4
1083 ; RV32I-NEXT: slli t0, a1, 1
1084 ; RV32I-NEXT: not a0, a4
1085 ; RV32I-NEXT: sll t0, t0, a0
1086 ; RV32I-NEXT: srl t1, a1, a4
1087 ; RV32I-NEXT: slli a1, a6, 1
1088 ; RV32I-NEXT: sll t2, a1, a0
1089 ; RV32I-NEXT: mv a6, a2
1090 ; RV32I-NEXT: beqz a5, .LBB15_6
1091 ; RV32I-NEXT: # %bb.5:
1092 ; RV32I-NEXT: mv a6, a3
1093 ; RV32I-NEXT: .LBB15_6:
1094 ; RV32I-NEXT: or a1, t0, a7
1095 ; RV32I-NEXT: or a7, t2, t1
1096 ; RV32I-NEXT: srl t0, a6, a4
1097 ; RV32I-NEXT: beqz a5, .LBB15_8
1098 ; RV32I-NEXT: # %bb.7:
1099 ; RV32I-NEXT: mv a3, a2
1100 ; RV32I-NEXT: .LBB15_8:
1101 ; RV32I-NEXT: slli a2, a3, 1
1102 ; RV32I-NEXT: sll a2, a2, a0
1103 ; RV32I-NEXT: or a2, a2, t0
1104 ; RV32I-NEXT: srl a3, a3, a4
1105 ; RV32I-NEXT: slli a4, a6, 1
1106 ; RV32I-NEXT: sll a0, a4, a0
1107 ; RV32I-NEXT: or a0, a0, a3
1108 ; RV32I-NEXT: add a3, a7, a0
1109 ; RV32I-NEXT: add a0, a1, a2
1110 ; RV32I-NEXT: sltu a1, a0, a1
1111 ; RV32I-NEXT: add a1, a3, a1
1114 ; RV64I-LABEL: rotr_64_mask_multiple:
1116 ; RV64I-NEXT: srl a3, a0, a2
1117 ; RV64I-NEXT: neg a4, a2
1118 ; RV64I-NEXT: sll a0, a0, a4
1119 ; RV64I-NEXT: or a0, a3, a0
1120 ; RV64I-NEXT: srl a2, a1, a2
1121 ; RV64I-NEXT: sll a1, a1, a4
1122 ; RV64I-NEXT: or a1, a2, a1
1123 ; RV64I-NEXT: add a0, a0, a1
1126 ; RV32ZBB-LABEL: rotr_64_mask_multiple:
1128 ; RV32ZBB-NEXT: andi a5, a4, 32
1129 ; RV32ZBB-NEXT: mv a6, a0
1130 ; RV32ZBB-NEXT: beqz a5, .LBB15_2
1131 ; RV32ZBB-NEXT: # %bb.1:
1132 ; RV32ZBB-NEXT: mv a6, a1
1133 ; RV32ZBB-NEXT: .LBB15_2:
1134 ; RV32ZBB-NEXT: beqz a5, .LBB15_4
1135 ; RV32ZBB-NEXT: # %bb.3:
1136 ; RV32ZBB-NEXT: mv a1, a0
1137 ; RV32ZBB-NEXT: .LBB15_4:
1138 ; RV32ZBB-NEXT: srl a7, a6, a4
1139 ; RV32ZBB-NEXT: slli t0, a1, 1
1140 ; RV32ZBB-NEXT: not a0, a4
1141 ; RV32ZBB-NEXT: sll t0, t0, a0
1142 ; RV32ZBB-NEXT: srl t1, a1, a4
1143 ; RV32ZBB-NEXT: slli a1, a6, 1
1144 ; RV32ZBB-NEXT: sll t2, a1, a0
1145 ; RV32ZBB-NEXT: mv a6, a2
1146 ; RV32ZBB-NEXT: beqz a5, .LBB15_6
1147 ; RV32ZBB-NEXT: # %bb.5:
1148 ; RV32ZBB-NEXT: mv a6, a3
1149 ; RV32ZBB-NEXT: .LBB15_6:
1150 ; RV32ZBB-NEXT: or a1, t0, a7
1151 ; RV32ZBB-NEXT: or a7, t2, t1
1152 ; RV32ZBB-NEXT: srl t0, a6, a4
1153 ; RV32ZBB-NEXT: beqz a5, .LBB15_8
1154 ; RV32ZBB-NEXT: # %bb.7:
1155 ; RV32ZBB-NEXT: mv a3, a2
1156 ; RV32ZBB-NEXT: .LBB15_8:
1157 ; RV32ZBB-NEXT: slli a2, a3, 1
1158 ; RV32ZBB-NEXT: sll a2, a2, a0
1159 ; RV32ZBB-NEXT: or a2, a2, t0
1160 ; RV32ZBB-NEXT: srl a3, a3, a4
1161 ; RV32ZBB-NEXT: slli a4, a6, 1
1162 ; RV32ZBB-NEXT: sll a0, a4, a0
1163 ; RV32ZBB-NEXT: or a0, a0, a3
1164 ; RV32ZBB-NEXT: add a3, a7, a0
1165 ; RV32ZBB-NEXT: add a0, a1, a2
1166 ; RV32ZBB-NEXT: sltu a1, a0, a1
1167 ; RV32ZBB-NEXT: add a1, a3, a1
1170 ; RV64ZBB-LABEL: rotr_64_mask_multiple:
1172 ; RV64ZBB-NEXT: ror a0, a0, a2
1173 ; RV64ZBB-NEXT: ror a1, a1, a2
1174 ; RV64ZBB-NEXT: add a0, a0, a1
1176 %maskedamt = and i64 %amt, 63
1177 %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %maskedamt)
1178 %2 = tail call i64 @llvm.fshr.i64(i64 %b, i64 %b, i64 %maskedamt)