[LoongArch] Eliminate the redundant sign extension of division (#107971)
[llvm-project.git] / llvm / test / CodeGen / LoongArch / rotl-rotr.ll
blob75461f5820984b1f6b24dc238c9cccfa7c59454c
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc --mtriple=loongarch32 -mattr=+d < %s | FileCheck %s --check-prefix=LA32
3 ; RUN: llc --mtriple=loongarch64 -mattr=+d < %s | FileCheck %s --check-prefix=LA64
5 define signext i32 @rotl_32(i32 signext %x, i32 signext %y) nounwind {
6 ; LA32-LABEL: rotl_32:
7 ; LA32:       # %bb.0:
8 ; LA32-NEXT:    ori $a2, $zero, 32
9 ; LA32-NEXT:    sub.w $a1, $a2, $a1
10 ; LA32-NEXT:    rotr.w $a0, $a0, $a1
11 ; LA32-NEXT:    ret
13 ; LA64-LABEL: rotl_32:
14 ; LA64:       # %bb.0:
15 ; LA64-NEXT:    ori $a2, $zero, 32
16 ; LA64-NEXT:    sub.d $a1, $a2, $a1
17 ; LA64-NEXT:    rotr.w $a0, $a0, $a1
18 ; LA64-NEXT:    ret
19   %z = sub i32 32, %y
20   %b = shl i32 %x, %y
21   %c = lshr i32 %x, %z
22   %d = or i32 %b, %c
23   ret i32 %d
26 define signext i32 @rotr_32(i32 signext %x, i32 signext %y) nounwind {
27 ; LA32-LABEL: rotr_32:
28 ; LA32:       # %bb.0:
29 ; LA32-NEXT:    rotr.w $a0, $a0, $a1
30 ; LA32-NEXT:    ret
32 ; LA64-LABEL: rotr_32:
33 ; LA64:       # %bb.0:
34 ; LA64-NEXT:    rotr.w $a0, $a0, $a1
35 ; LA64-NEXT:    ret
36   %z = sub i32 32, %y
37   %b = lshr i32 %x, %y
38   %c = shl i32 %x, %z
39   %d = or i32 %b, %c
40   ret i32 %d
43 define i64 @rotl_64(i64 %x, i64 %y) nounwind {
44 ; LA32-LABEL: rotl_64:
45 ; LA32:       # %bb.0:
46 ; LA32-NEXT:    sll.w $a3, $a1, $a2
47 ; LA32-NEXT:    xori $a4, $a2, 31
48 ; LA32-NEXT:    srli.w $a5, $a0, 1
49 ; LA32-NEXT:    srl.w $a4, $a5, $a4
50 ; LA32-NEXT:    or $a3, $a3, $a4
51 ; LA32-NEXT:    addi.w $a4, $a2, -32
52 ; LA32-NEXT:    slti $a5, $a4, 0
53 ; LA32-NEXT:    maskeqz $a3, $a3, $a5
54 ; LA32-NEXT:    sll.w $a6, $a0, $a4
55 ; LA32-NEXT:    masknez $a5, $a6, $a5
56 ; LA32-NEXT:    or $a3, $a3, $a5
57 ; LA32-NEXT:    sll.w $a5, $a0, $a2
58 ; LA32-NEXT:    srai.w $a4, $a4, 31
59 ; LA32-NEXT:    and $a4, $a4, $a5
60 ; LA32-NEXT:    sub.w $a5, $zero, $a2
61 ; LA32-NEXT:    srl.w $a6, $a1, $a5
62 ; LA32-NEXT:    ori $a7, $zero, 32
63 ; LA32-NEXT:    sub.w $a7, $a7, $a2
64 ; LA32-NEXT:    slti $t0, $a7, 0
65 ; LA32-NEXT:    masknez $t1, $a6, $t0
66 ; LA32-NEXT:    srl.w $a0, $a0, $a5
67 ; LA32-NEXT:    ori $a5, $zero, 64
68 ; LA32-NEXT:    sub.w $a2, $a5, $a2
69 ; LA32-NEXT:    xori $a2, $a2, 31
70 ; LA32-NEXT:    slli.w $a1, $a1, 1
71 ; LA32-NEXT:    sll.w $a1, $a1, $a2
72 ; LA32-NEXT:    or $a0, $a0, $a1
73 ; LA32-NEXT:    maskeqz $a0, $a0, $t0
74 ; LA32-NEXT:    or $a0, $a0, $t1
75 ; LA32-NEXT:    srai.w $a1, $a7, 31
76 ; LA32-NEXT:    and $a1, $a1, $a6
77 ; LA32-NEXT:    or $a1, $a3, $a1
78 ; LA32-NEXT:    or $a0, $a4, $a0
79 ; LA32-NEXT:    ret
81 ; LA64-LABEL: rotl_64:
82 ; LA64:       # %bb.0:
83 ; LA64-NEXT:    ori $a2, $zero, 64
84 ; LA64-NEXT:    sub.d $a1, $a2, $a1
85 ; LA64-NEXT:    rotr.d $a0, $a0, $a1
86 ; LA64-NEXT:    ret
87   %z = sub i64 64, %y
88   %b = shl i64 %x, %y
89   %c = lshr i64 %x, %z
90   %d = or i64 %b, %c
91   ret i64 %d
94 define i64 @rotr_64(i64 %x, i64 %y) nounwind {
95 ; LA32-LABEL: rotr_64:
96 ; LA32:       # %bb.0:
97 ; LA32-NEXT:    srl.w $a3, $a0, $a2
98 ; LA32-NEXT:    xori $a4, $a2, 31
99 ; LA32-NEXT:    slli.w $a5, $a1, 1
100 ; LA32-NEXT:    sll.w $a4, $a5, $a4
101 ; LA32-NEXT:    or $a3, $a3, $a4
102 ; LA32-NEXT:    addi.w $a4, $a2, -32
103 ; LA32-NEXT:    slti $a5, $a4, 0
104 ; LA32-NEXT:    maskeqz $a3, $a3, $a5
105 ; LA32-NEXT:    srl.w $a6, $a1, $a4
106 ; LA32-NEXT:    masknez $a5, $a6, $a5
107 ; LA32-NEXT:    or $a3, $a3, $a5
108 ; LA32-NEXT:    srl.w $a5, $a1, $a2
109 ; LA32-NEXT:    srai.w $a4, $a4, 31
110 ; LA32-NEXT:    and $a4, $a4, $a5
111 ; LA32-NEXT:    sub.w $a5, $zero, $a2
112 ; LA32-NEXT:    sll.w $a6, $a0, $a5
113 ; LA32-NEXT:    ori $a7, $zero, 32
114 ; LA32-NEXT:    sub.w $a7, $a7, $a2
115 ; LA32-NEXT:    slti $t0, $a7, 0
116 ; LA32-NEXT:    masknez $t1, $a6, $t0
117 ; LA32-NEXT:    sll.w $a1, $a1, $a5
118 ; LA32-NEXT:    ori $a5, $zero, 64
119 ; LA32-NEXT:    sub.w $a2, $a5, $a2
120 ; LA32-NEXT:    xori $a2, $a2, 31
121 ; LA32-NEXT:    srli.w $a0, $a0, 1
122 ; LA32-NEXT:    srl.w $a0, $a0, $a2
123 ; LA32-NEXT:    or $a0, $a1, $a0
124 ; LA32-NEXT:    maskeqz $a0, $a0, $t0
125 ; LA32-NEXT:    or $a1, $a0, $t1
126 ; LA32-NEXT:    srai.w $a0, $a7, 31
127 ; LA32-NEXT:    and $a0, $a0, $a6
128 ; LA32-NEXT:    or $a0, $a3, $a0
129 ; LA32-NEXT:    or $a1, $a4, $a1
130 ; LA32-NEXT:    ret
132 ; LA64-LABEL: rotr_64:
133 ; LA64:       # %bb.0:
134 ; LA64-NEXT:    rotr.d $a0, $a0, $a1
135 ; LA64-NEXT:    ret
136   %z = sub i64 64, %y
137   %b = lshr i64 %x, %y
138   %c = shl i64 %x, %z
139   %d = or i64 %b, %c
140   ret i64 %d
143 define signext i32 @rotl_32_mask(i32 signext %x, i32 signext %y) nounwind {
144 ; LA32-LABEL: rotl_32_mask:
145 ; LA32:       # %bb.0:
146 ; LA32-NEXT:    sub.w $a1, $zero, $a1
147 ; LA32-NEXT:    rotr.w $a0, $a0, $a1
148 ; LA32-NEXT:    ret
150 ; LA64-LABEL: rotl_32_mask:
151 ; LA64:       # %bb.0:
152 ; LA64-NEXT:    ori $a2, $zero, 32
153 ; LA64-NEXT:    sub.d $a1, $a2, $a1
154 ; LA64-NEXT:    rotr.w $a0, $a0, $a1
155 ; LA64-NEXT:    ret
156   %z = sub i32 0, %y
157   %and = and i32 %z, 31
158   %b = shl i32 %x, %y
159   %c = lshr i32 %x, %and
160   %d = or i32 %b, %c
161   ret i32 %d
164 define signext i32 @rotl_32_mask_and_63_and_31(i32 signext %x, i32 signext %y) nounwind {
165 ; LA32-LABEL: rotl_32_mask_and_63_and_31:
166 ; LA32:       # %bb.0:
167 ; LA32-NEXT:    sub.w $a1, $zero, $a1
168 ; LA32-NEXT:    rotr.w $a0, $a0, $a1
169 ; LA32-NEXT:    ret
171 ; LA64-LABEL: rotl_32_mask_and_63_and_31:
172 ; LA64:       # %bb.0:
173 ; LA64-NEXT:    ori $a2, $zero, 32
174 ; LA64-NEXT:    sub.d $a1, $a2, $a1
175 ; LA64-NEXT:    rotr.w $a0, $a0, $a1
176 ; LA64-NEXT:    ret
177   %a = and i32 %y, 63
178   %b = shl i32 %x, %a
179   %c = sub i32 0, %y
180   %d = and i32 %c, 31
181   %e = lshr i32 %x, %d
182   %f = or i32 %b, %e
183   ret i32 %f
186 define signext i32 @rotl_32_mask_or_64_or_32(i32 signext %x, i32 signext %y) nounwind {
187 ; LA32-LABEL: rotl_32_mask_or_64_or_32:
188 ; LA32:       # %bb.0:
189 ; LA32-NEXT:    sub.w $a1, $zero, $a1
190 ; LA32-NEXT:    rotr.w $a0, $a0, $a1
191 ; LA32-NEXT:    ret
193 ; LA64-LABEL: rotl_32_mask_or_64_or_32:
194 ; LA64:       # %bb.0:
195 ; LA64-NEXT:    ori $a2, $zero, 32
196 ; LA64-NEXT:    sub.d $a1, $a2, $a1
197 ; LA64-NEXT:    rotr.w $a0, $a0, $a1
198 ; LA64-NEXT:    ret
199   %a = or i32 %y, 64
200   %b = shl i32 %x, %a
201   %c = sub i32 0, %y
202   %d = or i32 %c, 32
203   %e = lshr i32 %x, %d
204   %f = or i32 %b, %e
205   ret i32 %f
208 define signext i32 @rotr_32_mask(i32 signext %x, i32 signext %y) nounwind {
209 ; LA32-LABEL: rotr_32_mask:
210 ; LA32:       # %bb.0:
211 ; LA32-NEXT:    rotr.w $a0, $a0, $a1
212 ; LA32-NEXT:    ret
214 ; LA64-LABEL: rotr_32_mask:
215 ; LA64:       # %bb.0:
216 ; LA64-NEXT:    rotr.w $a0, $a0, $a1
217 ; LA64-NEXT:    ret
218   %z = sub i32 0, %y
219   %and = and i32 %z, 31
220   %b = lshr i32 %x, %y
221   %c = shl i32 %x, %and
222   %d = or i32 %b, %c
223   ret i32 %d
226 define signext i32 @rotr_32_mask_and_63_and_31(i32 signext %x, i32 signext %y) nounwind {
227 ; LA32-LABEL: rotr_32_mask_and_63_and_31:
228 ; LA32:       # %bb.0:
229 ; LA32-NEXT:    rotr.w $a0, $a0, $a1
230 ; LA32-NEXT:    ret
232 ; LA64-LABEL: rotr_32_mask_and_63_and_31:
233 ; LA64:       # %bb.0:
234 ; LA64-NEXT:    rotr.w $a0, $a0, $a1
235 ; LA64-NEXT:    ret
236   %a = and i32 %y, 63
237   %b = lshr i32 %x, %a
238   %c = sub i32 0, %y
239   %d = and i32 %c, 31
240   %e = shl i32 %x, %d
241   %f = or i32 %b, %e
242   ret i32 %f
245 define signext i32 @rotr_32_mask_or_64_or_32(i32 signext %x, i32 signext %y) nounwind {
246 ; LA32-LABEL: rotr_32_mask_or_64_or_32:
247 ; LA32:       # %bb.0:
248 ; LA32-NEXT:    rotr.w $a0, $a0, $a1
249 ; LA32-NEXT:    ret
251 ; LA64-LABEL: rotr_32_mask_or_64_or_32:
252 ; LA64:       # %bb.0:
253 ; LA64-NEXT:    rotr.w $a0, $a0, $a1
254 ; LA64-NEXT:    ret
255   %a = or i32 %y, 64
256   %b = lshr i32 %x, %a
257   %c = sub i32 0, %y
258   %d = or i32 %c, 32
259   %e = shl i32 %x, %d
260   %f = or i32 %b, %e
261   ret i32 %f
264 define i64 @rotl_64_mask(i64 %x, i64 %y) nounwind {
265 ; LA32-LABEL: rotl_64_mask:
266 ; LA32:       # %bb.0:
267 ; LA32-NEXT:    sll.w $a3, $a1, $a2
268 ; LA32-NEXT:    xori $a4, $a2, 31
269 ; LA32-NEXT:    srli.w $a5, $a0, 1
270 ; LA32-NEXT:    srl.w $a4, $a5, $a4
271 ; LA32-NEXT:    or $a3, $a3, $a4
272 ; LA32-NEXT:    addi.w $a4, $a2, -32
273 ; LA32-NEXT:    slti $a5, $a4, 0
274 ; LA32-NEXT:    maskeqz $a3, $a3, $a5
275 ; LA32-NEXT:    sll.w $a6, $a0, $a4
276 ; LA32-NEXT:    masknez $a5, $a6, $a5
277 ; LA32-NEXT:    or $a3, $a3, $a5
278 ; LA32-NEXT:    sll.w $a5, $a0, $a2
279 ; LA32-NEXT:    srai.w $a4, $a4, 31
280 ; LA32-NEXT:    and $a4, $a4, $a5
281 ; LA32-NEXT:    sub.w $a2, $zero, $a2
282 ; LA32-NEXT:    andi $a5, $a2, 63
283 ; LA32-NEXT:    addi.w $a6, $a5, -32
284 ; LA32-NEXT:    srl.w $a7, $a1, $a6
285 ; LA32-NEXT:    slti $t0, $a6, 0
286 ; LA32-NEXT:    masknez $a7, $a7, $t0
287 ; LA32-NEXT:    srl.w $a0, $a0, $a2
288 ; LA32-NEXT:    xori $a5, $a5, 31
289 ; LA32-NEXT:    slli.w $t1, $a1, 1
290 ; LA32-NEXT:    sll.w $a5, $t1, $a5
291 ; LA32-NEXT:    or $a0, $a0, $a5
292 ; LA32-NEXT:    maskeqz $a0, $a0, $t0
293 ; LA32-NEXT:    or $a0, $a0, $a7
294 ; LA32-NEXT:    srl.w $a1, $a1, $a2
295 ; LA32-NEXT:    srai.w $a2, $a6, 31
296 ; LA32-NEXT:    and $a1, $a2, $a1
297 ; LA32-NEXT:    or $a1, $a3, $a1
298 ; LA32-NEXT:    or $a0, $a4, $a0
299 ; LA32-NEXT:    ret
301 ; LA64-LABEL: rotl_64_mask:
302 ; LA64:       # %bb.0:
303 ; LA64-NEXT:    sub.d $a1, $zero, $a1
304 ; LA64-NEXT:    rotr.d $a0, $a0, $a1
305 ; LA64-NEXT:    ret
306   %z = sub i64 0, %y
307   %and = and i64 %z, 63
308   %b = shl i64 %x, %y
309   %c = lshr i64 %x, %and
310   %d = or i64 %b, %c
311   ret i64 %d
314 define i64 @rotl_64_mask_and_127_and_63(i64 %x, i64 %y) nounwind {
315 ; LA32-LABEL: rotl_64_mask_and_127_and_63:
316 ; LA32:       # %bb.0:
317 ; LA32-NEXT:    sll.w $a3, $a1, $a2
318 ; LA32-NEXT:    srli.w $a4, $a0, 1
319 ; LA32-NEXT:    andi $a5, $a2, 127
320 ; LA32-NEXT:    xori $a6, $a5, 31
321 ; LA32-NEXT:    srl.w $a4, $a4, $a6
322 ; LA32-NEXT:    or $a3, $a3, $a4
323 ; LA32-NEXT:    addi.w $a4, $a5, -32
324 ; LA32-NEXT:    slti $a5, $a4, 0
325 ; LA32-NEXT:    maskeqz $a3, $a3, $a5
326 ; LA32-NEXT:    sll.w $a6, $a0, $a4
327 ; LA32-NEXT:    masknez $a5, $a6, $a5
328 ; LA32-NEXT:    or $a3, $a3, $a5
329 ; LA32-NEXT:    sll.w $a5, $a0, $a2
330 ; LA32-NEXT:    srai.w $a4, $a4, 31
331 ; LA32-NEXT:    and $a4, $a4, $a5
332 ; LA32-NEXT:    sub.w $a2, $zero, $a2
333 ; LA32-NEXT:    andi $a5, $a2, 63
334 ; LA32-NEXT:    addi.w $a6, $a5, -32
335 ; LA32-NEXT:    srl.w $a7, $a1, $a6
336 ; LA32-NEXT:    slti $t0, $a6, 0
337 ; LA32-NEXT:    masknez $a7, $a7, $t0
338 ; LA32-NEXT:    srl.w $a0, $a0, $a2
339 ; LA32-NEXT:    xori $a5, $a5, 31
340 ; LA32-NEXT:    slli.w $t1, $a1, 1
341 ; LA32-NEXT:    sll.w $a5, $t1, $a5
342 ; LA32-NEXT:    or $a0, $a0, $a5
343 ; LA32-NEXT:    maskeqz $a0, $a0, $t0
344 ; LA32-NEXT:    or $a0, $a0, $a7
345 ; LA32-NEXT:    srl.w $a1, $a1, $a2
346 ; LA32-NEXT:    srai.w $a2, $a6, 31
347 ; LA32-NEXT:    and $a1, $a2, $a1
348 ; LA32-NEXT:    or $a1, $a3, $a1
349 ; LA32-NEXT:    or $a0, $a4, $a0
350 ; LA32-NEXT:    ret
352 ; LA64-LABEL: rotl_64_mask_and_127_and_63:
353 ; LA64:       # %bb.0:
354 ; LA64-NEXT:    sub.d $a1, $zero, $a1
355 ; LA64-NEXT:    rotr.d $a0, $a0, $a1
356 ; LA64-NEXT:    ret
357   %a = and i64 %y, 127
358   %b = shl i64 %x, %a
359   %c = sub i64 0, %y
360   %d = and i64 %c, 63
361   %e = lshr i64 %x, %d
362   %f = or i64 %b, %e
363   ret i64 %f
366 define i64 @rotl_64_mask_or_128_or_64(i64 %x, i64 %y) nounwind {
367 ; LA32-LABEL: rotl_64_mask_or_128_or_64:
368 ; LA32:       # %bb.0:
369 ; LA32-NEXT:    move $a0, $zero
370 ; LA32-NEXT:    move $a1, $zero
371 ; LA32-NEXT:    ret
373 ; LA64-LABEL: rotl_64_mask_or_128_or_64:
374 ; LA64:       # %bb.0:
375 ; LA64-NEXT:    sub.d $a1, $zero, $a1
376 ; LA64-NEXT:    rotr.d $a0, $a0, $a1
377 ; LA64-NEXT:    ret
378   %a = or i64 %y, 128
379   %b = shl i64 %x, %a
380   %c = sub i64 0, %y
381   %d = or i64 %c, 64
382   %e = lshr i64 %x, %d
383   %f = or i64 %b, %e
384   ret i64 %f
387 define i64 @rotr_64_mask(i64 %x, i64 %y) nounwind {
388 ; LA32-LABEL: rotr_64_mask:
389 ; LA32:       # %bb.0:
390 ; LA32-NEXT:    srl.w $a3, $a0, $a2
391 ; LA32-NEXT:    xori $a4, $a2, 31
392 ; LA32-NEXT:    slli.w $a5, $a1, 1
393 ; LA32-NEXT:    sll.w $a4, $a5, $a4
394 ; LA32-NEXT:    or $a3, $a3, $a4
395 ; LA32-NEXT:    addi.w $a4, $a2, -32
396 ; LA32-NEXT:    slti $a5, $a4, 0
397 ; LA32-NEXT:    maskeqz $a3, $a3, $a5
398 ; LA32-NEXT:    srl.w $a6, $a1, $a4
399 ; LA32-NEXT:    masknez $a5, $a6, $a5
400 ; LA32-NEXT:    or $a3, $a3, $a5
401 ; LA32-NEXT:    srl.w $a5, $a1, $a2
402 ; LA32-NEXT:    srai.w $a4, $a4, 31
403 ; LA32-NEXT:    and $a4, $a4, $a5
404 ; LA32-NEXT:    sub.w $a2, $zero, $a2
405 ; LA32-NEXT:    andi $a5, $a2, 63
406 ; LA32-NEXT:    addi.w $a6, $a5, -32
407 ; LA32-NEXT:    sll.w $a7, $a0, $a6
408 ; LA32-NEXT:    slti $t0, $a6, 0
409 ; LA32-NEXT:    masknez $a7, $a7, $t0
410 ; LA32-NEXT:    sll.w $a1, $a1, $a2
411 ; LA32-NEXT:    xori $a5, $a5, 31
412 ; LA32-NEXT:    srli.w $t1, $a0, 1
413 ; LA32-NEXT:    srl.w $a5, $t1, $a5
414 ; LA32-NEXT:    or $a1, $a1, $a5
415 ; LA32-NEXT:    maskeqz $a1, $a1, $t0
416 ; LA32-NEXT:    or $a1, $a1, $a7
417 ; LA32-NEXT:    sll.w $a0, $a0, $a2
418 ; LA32-NEXT:    srai.w $a2, $a6, 31
419 ; LA32-NEXT:    and $a0, $a2, $a0
420 ; LA32-NEXT:    or $a0, $a3, $a0
421 ; LA32-NEXT:    or $a1, $a4, $a1
422 ; LA32-NEXT:    ret
424 ; LA64-LABEL: rotr_64_mask:
425 ; LA64:       # %bb.0:
426 ; LA64-NEXT:    rotr.d $a0, $a0, $a1
427 ; LA64-NEXT:    ret
428   %z = sub i64 0, %y
429   %and = and i64 %z, 63
430   %b = lshr i64 %x, %y
431   %c = shl i64 %x, %and
432   %d = or i64 %b, %c
433   ret i64 %d
436 define i64 @rotr_64_mask_and_127_and_63(i64 %x, i64 %y) nounwind {
437 ; LA32-LABEL: rotr_64_mask_and_127_and_63:
438 ; LA32:       # %bb.0:
439 ; LA32-NEXT:    srl.w $a3, $a0, $a2
440 ; LA32-NEXT:    slli.w $a4, $a1, 1
441 ; LA32-NEXT:    andi $a5, $a2, 127
442 ; LA32-NEXT:    xori $a6, $a5, 31
443 ; LA32-NEXT:    sll.w $a4, $a4, $a6
444 ; LA32-NEXT:    or $a3, $a3, $a4
445 ; LA32-NEXT:    addi.w $a4, $a5, -32
446 ; LA32-NEXT:    slti $a5, $a4, 0
447 ; LA32-NEXT:    maskeqz $a3, $a3, $a5
448 ; LA32-NEXT:    srl.w $a6, $a1, $a4
449 ; LA32-NEXT:    masknez $a5, $a6, $a5
450 ; LA32-NEXT:    or $a3, $a3, $a5
451 ; LA32-NEXT:    srl.w $a5, $a1, $a2
452 ; LA32-NEXT:    srai.w $a4, $a4, 31
453 ; LA32-NEXT:    and $a4, $a4, $a5
454 ; LA32-NEXT:    sub.w $a2, $zero, $a2
455 ; LA32-NEXT:    andi $a5, $a2, 63
456 ; LA32-NEXT:    addi.w $a6, $a5, -32
457 ; LA32-NEXT:    sll.w $a7, $a0, $a6
458 ; LA32-NEXT:    slti $t0, $a6, 0
459 ; LA32-NEXT:    masknez $a7, $a7, $t0
460 ; LA32-NEXT:    sll.w $a1, $a1, $a2
461 ; LA32-NEXT:    xori $a5, $a5, 31
462 ; LA32-NEXT:    srli.w $t1, $a0, 1
463 ; LA32-NEXT:    srl.w $a5, $t1, $a5
464 ; LA32-NEXT:    or $a1, $a1, $a5
465 ; LA32-NEXT:    maskeqz $a1, $a1, $t0
466 ; LA32-NEXT:    or $a1, $a1, $a7
467 ; LA32-NEXT:    sll.w $a0, $a0, $a2
468 ; LA32-NEXT:    srai.w $a2, $a6, 31
469 ; LA32-NEXT:    and $a0, $a2, $a0
470 ; LA32-NEXT:    or $a0, $a3, $a0
471 ; LA32-NEXT:    or $a1, $a4, $a1
472 ; LA32-NEXT:    ret
474 ; LA64-LABEL: rotr_64_mask_and_127_and_63:
475 ; LA64:       # %bb.0:
476 ; LA64-NEXT:    rotr.d $a0, $a0, $a1
477 ; LA64-NEXT:    ret
478   %a = and i64 %y, 127
479   %b = lshr i64 %x, %a
480   %c = sub i64 0, %y
481   %d = and i64 %c, 63
482   %e = shl i64 %x, %d
483   %f = or i64 %b, %e
484   ret i64 %f
487 define i64 @rotr_64_mask_or_128_or_64(i64 %x, i64 %y) nounwind {
488 ; LA32-LABEL: rotr_64_mask_or_128_or_64:
489 ; LA32:       # %bb.0:
490 ; LA32-NEXT:    move $a0, $zero
491 ; LA32-NEXT:    move $a1, $zero
492 ; LA32-NEXT:    ret
494 ; LA64-LABEL: rotr_64_mask_or_128_or_64:
495 ; LA64:       # %bb.0:
496 ; LA64-NEXT:    rotr.d $a0, $a0, $a1
497 ; LA64-NEXT:    ret
498   %a = or i64 %y, 128
499   %b = lshr i64 %x, %a
500   %c = sub i64 0, %y
501   %d = or i64 %c, 64
502   %e = shl i64 %x, %d
503   %f = or i64 %b, %e
504   ret i64 %f
507 define signext i32 @rotr_64_trunc_32(i64 %x, i64 %y) nounwind {
508 ; LA32-LABEL: rotr_64_trunc_32:
509 ; LA32:       # %bb.0:
510 ; LA32-NEXT:    srl.w $a3, $a0, $a2
511 ; LA32-NEXT:    xori $a4, $a2, 31
512 ; LA32-NEXT:    slli.w $a5, $a1, 1
513 ; LA32-NEXT:    sll.w $a4, $a5, $a4
514 ; LA32-NEXT:    or $a3, $a3, $a4
515 ; LA32-NEXT:    addi.w $a4, $a2, -32
516 ; LA32-NEXT:    slti $a5, $a4, 0
517 ; LA32-NEXT:    maskeqz $a3, $a3, $a5
518 ; LA32-NEXT:    srl.w $a1, $a1, $a4
519 ; LA32-NEXT:    masknez $a1, $a1, $a5
520 ; LA32-NEXT:    or $a1, $a3, $a1
521 ; LA32-NEXT:    sub.w $a3, $zero, $a2
522 ; LA32-NEXT:    sll.w $a0, $a0, $a3
523 ; LA32-NEXT:    ori $a3, $zero, 32
524 ; LA32-NEXT:    sub.w $a2, $a3, $a2
525 ; LA32-NEXT:    srai.w $a2, $a2, 31
526 ; LA32-NEXT:    and $a0, $a2, $a0
527 ; LA32-NEXT:    or $a0, $a1, $a0
528 ; LA32-NEXT:    ret
530 ; LA64-LABEL: rotr_64_trunc_32:
531 ; LA64:       # %bb.0:
532 ; LA64-NEXT:    rotr.d $a0, $a0, $a1
533 ; LA64-NEXT:    addi.w $a0, $a0, 0
534 ; LA64-NEXT:    ret
535   %z = sub i64 64, %y
536   %b = lshr i64 %x, %y
537   %c = shl i64 %x, %z
538   %d = or i64 %b, %c
539   %e = trunc i64 %d to i32
540   ret i32 %e
543 define signext i32 @rotri_i32(i32 signext %a) nounwind {
544 ; LA32-LABEL: rotri_i32:
545 ; LA32:       # %bb.0:
546 ; LA32-NEXT:    rotri.w $a0, $a0, 16
547 ; LA32-NEXT:    ret
549 ; LA64-LABEL: rotri_i32:
550 ; LA64:       # %bb.0:
551 ; LA64-NEXT:    rotri.w $a0, $a0, 16
552 ; LA64-NEXT:    ret
553   %shl = shl i32 %a, 16
554   %shr = lshr i32 %a, 16
555   %or = or i32 %shl, %shr
556   ret i32 %or
559 define i64 @rotri_i64(i64 %a) nounwind {
560 ; LA32-LABEL: rotri_i64:
561 ; LA32:       # %bb.0:
562 ; LA32-NEXT:    move $a2, $a0
563 ; LA32-NEXT:    move $a0, $a1
564 ; LA32-NEXT:    move $a1, $a2
565 ; LA32-NEXT:    ret
567 ; LA64-LABEL: rotri_i64:
568 ; LA64:       # %bb.0:
569 ; LA64-NEXT:    rotri.d $a0, $a0, 32
570 ; LA64-NEXT:    ret
571   %shl = shl i64 %a, 32
572   %shr = lshr i64 %a, 32
573   %or = or i64 %shl, %shr
574   ret i64 %or
577 declare i32 @llvm.fshl.i32(i32, i32, i32)
578 declare i64 @llvm.fshl.i64(i64, i64, i64)
579 declare i32 @llvm.fshr.i32(i32, i32, i32)
580 declare i64 @llvm.fshr.i64(i64, i64, i64)
582 define signext i32 @rotl_i32_fshl(i32 signext %a) nounwind {
583 ; LA32-LABEL: rotl_i32_fshl:
584 ; LA32:       # %bb.0:
585 ; LA32-NEXT:    rotri.w $a0, $a0, 20
586 ; LA32-NEXT:    ret
588 ; LA64-LABEL: rotl_i32_fshl:
589 ; LA64:       # %bb.0:
590 ; LA64-NEXT:    rotri.w $a0, $a0, 20
591 ; LA64-NEXT:    ret
592   %or = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 12)
593   ret i32 %or
596 define i64 @rotl_i64_fshl(i64 %a) nounwind {
597 ; LA32-LABEL: rotl_i64_fshl:
598 ; LA32:       # %bb.0:
599 ; LA32-NEXT:    srli.w $a2, $a1, 20
600 ; LA32-NEXT:    slli.w $a3, $a0, 12
601 ; LA32-NEXT:    or $a2, $a3, $a2
602 ; LA32-NEXT:    srli.w $a0, $a0, 20
603 ; LA32-NEXT:    slli.w $a1, $a1, 12
604 ; LA32-NEXT:    or $a1, $a1, $a0
605 ; LA32-NEXT:    move $a0, $a2
606 ; LA32-NEXT:    ret
608 ; LA64-LABEL: rotl_i64_fshl:
609 ; LA64:       # %bb.0:
610 ; LA64-NEXT:    rotri.d $a0, $a0, 52
611 ; LA64-NEXT:    ret
612   %or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 12)
613   ret i64 %or
616 define signext i32 @rotr_i32_fshr(i32 signext %a) nounwind {
617 ; LA32-LABEL: rotr_i32_fshr:
618 ; LA32:       # %bb.0:
619 ; LA32-NEXT:    rotri.w $a0, $a0, 12
620 ; LA32-NEXT:    ret
622 ; LA64-LABEL: rotr_i32_fshr:
623 ; LA64:       # %bb.0:
624 ; LA64-NEXT:    rotri.w $a0, $a0, 12
625 ; LA64-NEXT:    ret
626   %or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 12)
627   ret i32 %or
630 define i64 @rotr_i64_fshr(i64 %a) nounwind {
631 ; LA32-LABEL: rotr_i64_fshr:
632 ; LA32:       # %bb.0:
633 ; LA32-NEXT:    srli.w $a2, $a0, 12
634 ; LA32-NEXT:    slli.w $a3, $a1, 20
635 ; LA32-NEXT:    or $a2, $a3, $a2
636 ; LA32-NEXT:    srli.w $a1, $a1, 12
637 ; LA32-NEXT:    slli.w $a0, $a0, 20
638 ; LA32-NEXT:    or $a1, $a0, $a1
639 ; LA32-NEXT:    move $a0, $a2
640 ; LA32-NEXT:    ret
642 ; LA64-LABEL: rotr_i64_fshr:
643 ; LA64:       # %bb.0:
644 ; LA64-NEXT:    rotri.d $a0, $a0, 12
645 ; LA64-NEXT:    ret
646   %or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 12)
647   ret i64 %or