Revert rGe6ccb57bb3f6b761f2310e97fd6ca99eff42f73e "[SLP] Add cost model for `llvm...
[llvm-project.git] / llvm / test / CodeGen / RISCV / rotl-rotr.ll
blob6e8b73fc987982d6a65f4c1d7ff58ba91cd82567
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:
19 ; RV32I:       # %bb.0:
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
24 ; RV32I-NEXT:    ret
26 ; RV64I-LABEL: rotl_32:
27 ; RV64I:       # %bb.0:
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
32 ; RV64I-NEXT:    ret
34 ; RV32ZBB-LABEL: rotl_32:
35 ; RV32ZBB:       # %bb.0:
36 ; RV32ZBB-NEXT:    rol a0, a0, a1
37 ; RV32ZBB-NEXT:    ret
39 ; RV64ZBB-LABEL: rotl_32:
40 ; RV64ZBB:       # %bb.0:
41 ; RV64ZBB-NEXT:    rolw a0, a0, a1
42 ; RV64ZBB-NEXT:    ret
43   %z = sub i32 32, %y
44   %b = shl i32 %x, %y
45   %c = lshr i32 %x, %z
46   %d = or i32 %b, %c
47   ret i32 %d
50 define i32 @rotr_32(i32 %x, i32 %y) nounwind {
51 ; RV32I-LABEL: rotr_32:
52 ; RV32I:       # %bb.0:
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
57 ; RV32I-NEXT:    ret
59 ; RV64I-LABEL: rotr_32:
60 ; RV64I:       # %bb.0:
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
65 ; RV64I-NEXT:    ret
67 ; RV32ZBB-LABEL: rotr_32:
68 ; RV32ZBB:       # %bb.0:
69 ; RV32ZBB-NEXT:    ror a0, a0, a1
70 ; RV32ZBB-NEXT:    ret
72 ; RV64ZBB-LABEL: rotr_32:
73 ; RV64ZBB:       # %bb.0:
74 ; RV64ZBB-NEXT:    rorw a0, a0, a1
75 ; RV64ZBB-NEXT:    ret
76   %z = sub i32 32, %y
77   %b = lshr i32 %x, %y
78   %c = shl i32 %x, %z
79   %d = or i32 %b, %c
80   ret i32 %d
83 define i64 @rotl_64(i64 %x, i64 %y) nounwind {
84 ; RV32I-LABEL: rotl_64:
85 ; RV32I:       # %bb.0:
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
108 ; RV32I-NEXT:    ret
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
124 ; RV32I-NEXT:    ret
126 ; RV64I-LABEL: rotl_64:
127 ; RV64I:       # %bb.0:
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
132 ; RV64I-NEXT:    ret
134 ; RV32ZBB-LABEL: rotl_64:
135 ; RV32ZBB:       # %bb.0:
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
158 ; RV32ZBB-NEXT:    ret
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
174 ; RV32ZBB-NEXT:    ret
176 ; RV64ZBB-LABEL: rotl_64:
177 ; RV64ZBB:       # %bb.0:
178 ; RV64ZBB-NEXT:    rol a0, a0, a1
179 ; RV64ZBB-NEXT:    ret
180   %z = sub i64 64, %y
181   %b = shl i64 %x, %y
182   %c = lshr i64 %x, %z
183   %d = or i64 %b, %c
184   ret i64 %d
187 define i64 @rotr_64(i64 %x, i64 %y) nounwind {
188 ; RV32I-LABEL: rotr_64:
189 ; RV32I:       # %bb.0:
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
212 ; RV32I-NEXT:    ret
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
228 ; RV32I-NEXT:    ret
230 ; RV64I-LABEL: rotr_64:
231 ; RV64I:       # %bb.0:
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
236 ; RV64I-NEXT:    ret
238 ; RV32ZBB-LABEL: rotr_64:
239 ; RV32ZBB:       # %bb.0:
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
262 ; RV32ZBB-NEXT:    ret
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
278 ; RV32ZBB-NEXT:    ret
280 ; RV64ZBB-LABEL: rotr_64:
281 ; RV64ZBB:       # %bb.0:
282 ; RV64ZBB-NEXT:    ror a0, a0, a1
283 ; RV64ZBB-NEXT:    ret
284   %z = sub i64 64, %y
285   %b = lshr i64 %x, %y
286   %c = shl i64 %x, %z
287   %d = or i64 %b, %c
288   ret i64 %d
291 define i32 @rotl_32_mask(i32 %x, i32 %y) nounwind {
292 ; RV32I-LABEL: rotl_32_mask:
293 ; RV32I:       # %bb.0:
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
298 ; RV32I-NEXT:    ret
300 ; RV64I-LABEL: rotl_32_mask:
301 ; RV64I:       # %bb.0:
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
306 ; RV64I-NEXT:    ret
308 ; RV32ZBB-LABEL: rotl_32_mask:
309 ; RV32ZBB:       # %bb.0:
310 ; RV32ZBB-NEXT:    rol a0, a0, a1
311 ; RV32ZBB-NEXT:    ret
313 ; RV64ZBB-LABEL: rotl_32_mask:
314 ; RV64ZBB:       # %bb.0:
315 ; RV64ZBB-NEXT:    rolw a0, a0, a1
316 ; RV64ZBB-NEXT:    ret
317   %z = sub i32 0, %y
318   %and = and i32 %z, 31
319   %b = shl i32 %x, %y
320   %c = lshr i32 %x, %and
321   %d = or i32 %b, %c
322   ret i32 %d
325 define i32 @rotr_32_mask(i32 %x, i32 %y) nounwind {
326 ; RV32I-LABEL: rotr_32_mask:
327 ; RV32I:       # %bb.0:
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
332 ; RV32I-NEXT:    ret
334 ; RV64I-LABEL: rotr_32_mask:
335 ; RV64I:       # %bb.0:
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
340 ; RV64I-NEXT:    ret
342 ; RV32ZBB-LABEL: rotr_32_mask:
343 ; RV32ZBB:       # %bb.0:
344 ; RV32ZBB-NEXT:    ror a0, a0, a1
345 ; RV32ZBB-NEXT:    ret
347 ; RV64ZBB-LABEL: rotr_32_mask:
348 ; RV64ZBB:       # %bb.0:
349 ; RV64ZBB-NEXT:    rorw a0, a0, a1
350 ; RV64ZBB-NEXT:    ret
351   %z = sub i32 0, %y
352   %and = and i32 %z, 31
353   %b = lshr i32 %x, %y
354   %c = shl i32 %x, %and
355   %d = or i32 %b, %c
356   ret i32 %d
359 define i64 @rotl_64_mask(i64 %x, i64 %y) nounwind {
360 ; RV32I-LABEL: rotl_64_mask:
361 ; RV32I:       # %bb.0:
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
397 ; RV32I-NEXT:    ret
399 ; RV64I-LABEL: rotl_64_mask:
400 ; RV64I:       # %bb.0:
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
405 ; RV64I-NEXT:    ret
407 ; RV32ZBB-LABEL: rotl_64_mask:
408 ; RV32ZBB:       # %bb.0:
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
444 ; RV32ZBB-NEXT:    ret
446 ; RV64ZBB-LABEL: rotl_64_mask:
447 ; RV64ZBB:       # %bb.0:
448 ; RV64ZBB-NEXT:    rol a0, a0, a1
449 ; RV64ZBB-NEXT:    ret
450   %z = sub i64 0, %y
451   %and = and i64 %z, 63
452   %b = shl i64 %x, %y
453   %c = lshr i64 %x, %and
454   %d = or i64 %b, %c
455   ret i64 %d
458 define i64 @rotr_64_mask(i64 %x, i64 %y) nounwind {
459 ; RV32I-LABEL: rotr_64_mask:
460 ; RV32I:       # %bb.0:
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
496 ; RV32I-NEXT:    ret
498 ; RV64I-LABEL: rotr_64_mask:
499 ; RV64I:       # %bb.0:
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
504 ; RV64I-NEXT:    ret
506 ; RV32ZBB-LABEL: rotr_64_mask:
507 ; RV32ZBB:       # %bb.0:
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
543 ; RV32ZBB-NEXT:    ret
545 ; RV64ZBB-LABEL: rotr_64_mask:
546 ; RV64ZBB:       # %bb.0:
547 ; RV64ZBB-NEXT:    ror a0, a0, a1
548 ; RV64ZBB-NEXT:    ret
549   %z = sub i64 0, %y
550   %and = and i64 %z, 63
551   %b = lshr i64 %x, %y
552   %c = shl i64 %x, %and
553   %d = or i64 %b, %c
554   ret i64 %d
557 ; Test that we're able to remove a mask on the rotate amount that has more than
558 ; one use.
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:
561 ; RV32I:       # %bb.0:
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
568 ; RV32I-NEXT:    ret
570 ; RV64I-LABEL: rotl_32_mask_shared:
571 ; RV64I:       # %bb.0:
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
578 ; RV64I-NEXT:    ret
580 ; RV32ZBB-LABEL: rotl_32_mask_shared:
581 ; RV32ZBB:       # %bb.0:
582 ; RV32ZBB-NEXT:    rol a0, a0, a2
583 ; RV32ZBB-NEXT:    sll a1, a1, a2
584 ; RV32ZBB-NEXT:    add a0, a0, a1
585 ; RV32ZBB-NEXT:    ret
587 ; RV64ZBB-LABEL: rotl_32_mask_shared:
588 ; RV64ZBB:       # %bb.0:
589 ; RV64ZBB-NEXT:    rolw a0, a0, a2
590 ; RV64ZBB-NEXT:    sllw a1, a1, a2
591 ; RV64ZBB-NEXT:    addw a0, a0, a1
592 ; RV64ZBB-NEXT:    ret
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
596   %3 = add i32 %1, %2
597   ret i32 %3
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:
603 ; RV32I:       # %bb.0:
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
643 ; RV32I-NEXT:    ret
645 ; RV64I-LABEL: rotl_64_mask_shared:
646 ; RV64I:       # %bb.0:
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
653 ; RV64I-NEXT:    ret
655 ; RV32ZBB-LABEL: rotl_64_mask_shared:
656 ; RV32ZBB:       # %bb.0:
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
696 ; RV32ZBB-NEXT:    ret
698 ; RV64ZBB-LABEL: rotl_64_mask_shared:
699 ; RV64ZBB:       # %bb.0:
700 ; RV64ZBB-NEXT:    rol a0, a0, a2
701 ; RV64ZBB-NEXT:    sll a1, a1, a2
702 ; RV64ZBB-NEXT:    add a0, a0, a1
703 ; RV64ZBB-NEXT:    ret
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
707   %3 = add i64 %1, %2
708   ret i64 %3
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:
714 ; RV32I:       # %bb.0:
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
721 ; RV32I-NEXT:    ret
723 ; RV64I-LABEL: rotr_32_mask_shared:
724 ; RV64I:       # %bb.0:
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
731 ; RV64I-NEXT:    ret
733 ; RV32ZBB-LABEL: rotr_32_mask_shared:
734 ; RV32ZBB:       # %bb.0:
735 ; RV32ZBB-NEXT:    ror a0, a0, a2
736 ; RV32ZBB-NEXT:    sll a1, a1, a2
737 ; RV32ZBB-NEXT:    add a0, a0, a1
738 ; RV32ZBB-NEXT:    ret
740 ; RV64ZBB-LABEL: rotr_32_mask_shared:
741 ; RV64ZBB:       # %bb.0:
742 ; RV64ZBB-NEXT:    rorw a0, a0, a2
743 ; RV64ZBB-NEXT:    sllw a1, a1, a2
744 ; RV64ZBB-NEXT:    addw a0, a0, a1
745 ; RV64ZBB-NEXT:    ret
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
749   %3 = add i32 %1, %2
750   ret i32 %3
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:
756 ; RV32I:       # %bb.0:
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
795 ; RV32I-NEXT:    ret
797 ; RV64I-LABEL: rotr_64_mask_shared:
798 ; RV64I:       # %bb.0:
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
805 ; RV64I-NEXT:    ret
807 ; RV32ZBB-LABEL: rotr_64_mask_shared:
808 ; RV32ZBB:       # %bb.0:
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
847 ; RV32ZBB-NEXT:    ret
849 ; RV64ZBB-LABEL: rotr_64_mask_shared:
850 ; RV64ZBB:       # %bb.0:
851 ; RV64ZBB-NEXT:    ror a0, a0, a2
852 ; RV64ZBB-NEXT:    sll a1, a1, a2
853 ; RV64ZBB-NEXT:    add a0, a0, a1
854 ; RV64ZBB-NEXT:    ret
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
858   %3 = add i64 %1, %2
859   ret i64 %3
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:
865 ; RV32I:       # %bb.0:
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
874 ; RV32I-NEXT:    ret
876 ; RV64I-LABEL: rotl_32_mask_multiple:
877 ; RV64I:       # %bb.0:
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
886 ; RV64I-NEXT:    ret
888 ; RV32ZBB-LABEL: rotl_32_mask_multiple:
889 ; RV32ZBB:       # %bb.0:
890 ; RV32ZBB-NEXT:    rol a0, a0, a2
891 ; RV32ZBB-NEXT:    rol a1, a1, a2
892 ; RV32ZBB-NEXT:    add a0, a0, a1
893 ; RV32ZBB-NEXT:    ret
895 ; RV64ZBB-LABEL: rotl_32_mask_multiple:
896 ; RV64ZBB:       # %bb.0:
897 ; RV64ZBB-NEXT:    rolw a0, a0, a2
898 ; RV64ZBB-NEXT:    rolw a1, a1, a2
899 ; RV64ZBB-NEXT:    addw a0, a0, a1
900 ; RV64ZBB-NEXT:    ret
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)
904   %3 = add i32 %1, %2
905   ret i32 %3
908 define i64 @rotl_64_mask_multiple(i64 %a, i64 %b, i64 %amt) nounwind {
909 ; RV32I-LABEL: rotl_64_mask_multiple:
910 ; RV32I:       # %bb.0:
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
952 ; RV32I-NEXT:    ret
954 ; RV64I-LABEL: rotl_64_mask_multiple:
955 ; RV64I:       # %bb.0:
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
964 ; RV64I-NEXT:    ret
966 ; RV32ZBB-LABEL: rotl_64_mask_multiple:
967 ; RV32ZBB:       # %bb.0:
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
1009 ; RV32ZBB-NEXT:    ret
1011 ; RV64ZBB-LABEL: rotl_64_mask_multiple:
1012 ; RV64ZBB:       # %bb.0:
1013 ; RV64ZBB-NEXT:    rol a0, a0, a2
1014 ; RV64ZBB-NEXT:    rol a1, a1, a2
1015 ; RV64ZBB-NEXT:    add a0, a0, a1
1016 ; RV64ZBB-NEXT:    ret
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)
1020   %3 = add i64 %1, %2
1021   ret i64 %3
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:
1026 ; RV32I:       # %bb.0:
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
1035 ; RV32I-NEXT:    ret
1037 ; RV64I-LABEL: rotr_32_mask_multiple:
1038 ; RV64I:       # %bb.0:
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
1047 ; RV64I-NEXT:    ret
1049 ; RV32ZBB-LABEL: rotr_32_mask_multiple:
1050 ; RV32ZBB:       # %bb.0:
1051 ; RV32ZBB-NEXT:    ror a0, a0, a2
1052 ; RV32ZBB-NEXT:    ror a1, a1, a2
1053 ; RV32ZBB-NEXT:    add a0, a0, a1
1054 ; RV32ZBB-NEXT:    ret
1056 ; RV64ZBB-LABEL: rotr_32_mask_multiple:
1057 ; RV64ZBB:       # %bb.0:
1058 ; RV64ZBB-NEXT:    rorw a0, a0, a2
1059 ; RV64ZBB-NEXT:    rorw a1, a1, a2
1060 ; RV64ZBB-NEXT:    addw a0, a0, a1
1061 ; RV64ZBB-NEXT:    ret
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)
1065   %3 = add i32 %1, %2
1066   ret i32 %3
1069 define i64 @rotr_64_mask_multiple(i64 %a, i64 %b, i64 %amt) nounwind {
1070 ; RV32I-LABEL: rotr_64_mask_multiple:
1071 ; RV32I:       # %bb.0:
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
1112 ; RV32I-NEXT:    ret
1114 ; RV64I-LABEL: rotr_64_mask_multiple:
1115 ; RV64I:       # %bb.0:
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
1124 ; RV64I-NEXT:    ret
1126 ; RV32ZBB-LABEL: rotr_64_mask_multiple:
1127 ; RV32ZBB:       # %bb.0:
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
1168 ; RV32ZBB-NEXT:    ret
1170 ; RV64ZBB-LABEL: rotr_64_mask_multiple:
1171 ; RV64ZBB:       # %bb.0:
1172 ; RV64ZBB-NEXT:    ror a0, a0, a2
1173 ; RV64ZBB-NEXT:    ror a1, a1, a2
1174 ; RV64ZBB-NEXT:    add a0, a0, a1
1175 ; RV64ZBB-NEXT:    ret
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)
1179   %3 = add i64 %1, %2
1180   ret i64 %3