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=riscv32 -mattr=+experimental-b -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s -check-prefix=RV32B
6 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbt -verify-machineinstrs < %s \
7 ; RUN: | FileCheck %s -check-prefix=RV32ZBT
9 define i32 @cmix_i32(i32 %a, i32 %b, i32 %c) nounwind {
10 ; RV32I-LABEL: cmix_i32:
12 ; RV32I-NEXT: and a0, a1, a0
13 ; RV32I-NEXT: not a1, a1
14 ; RV32I-NEXT: and a1, a1, a2
15 ; RV32I-NEXT: or a0, a1, a0
18 ; RV32B-LABEL: cmix_i32:
20 ; RV32B-NEXT: cmix a0, a1, a0, a2
23 ; RV32ZBT-LABEL: cmix_i32:
25 ; RV32ZBT-NEXT: cmix a0, a1, a0, a2
29 %and1 = and i32 %neg, %c
30 %or = or i32 %and1, %and
34 define i64 @cmix_i64(i64 %a, i64 %b, i64 %c) nounwind {
35 ; RV32I-LABEL: cmix_i64:
37 ; RV32I-NEXT: and a1, a3, a1
38 ; RV32I-NEXT: and a0, a2, a0
39 ; RV32I-NEXT: not a2, a2
40 ; RV32I-NEXT: not a3, a3
41 ; RV32I-NEXT: and a3, a3, a5
42 ; RV32I-NEXT: and a2, a2, a4
43 ; RV32I-NEXT: or a0, a2, a0
44 ; RV32I-NEXT: or a1, a3, a1
47 ; RV32B-LABEL: cmix_i64:
49 ; RV32B-NEXT: cmix a0, a2, a0, a4
50 ; RV32B-NEXT: cmix a1, a3, a1, a5
53 ; RV32ZBT-LABEL: cmix_i64:
55 ; RV32ZBT-NEXT: cmix a0, a2, a0, a4
56 ; RV32ZBT-NEXT: cmix a1, a3, a1, a5
60 %and1 = and i64 %neg, %c
61 %or = or i64 %and1, %and
65 define i32 @cmov_i32(i32 %a, i32 %b, i32 %c) nounwind {
66 ; RV32I-LABEL: cmov_i32:
68 ; RV32I-NEXT: beqz a1, .LBB2_2
69 ; RV32I-NEXT: # %bb.1:
70 ; RV32I-NEXT: mv a2, a0
71 ; RV32I-NEXT: .LBB2_2:
72 ; RV32I-NEXT: mv a0, a2
75 ; RV32B-LABEL: cmov_i32:
77 ; RV32B-NEXT: cmov a0, a1, a0, a2
80 ; RV32ZBT-LABEL: cmov_i32:
82 ; RV32ZBT-NEXT: cmov a0, a1, a0, a2
84 %tobool.not = icmp eq i32 %b, 0
85 %cond = select i1 %tobool.not, i32 %c, i32 %a
89 define i32 @cmov_sle_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
90 ; RV32I-LABEL: cmov_sle_i32:
92 ; RV32I-NEXT: bge a2, a1, .LBB3_2
93 ; RV32I-NEXT: # %bb.1:
94 ; RV32I-NEXT: mv a0, a3
95 ; RV32I-NEXT: .LBB3_2:
98 ; RV32B-LABEL: cmov_sle_i32:
100 ; RV32B-NEXT: slt a1, a2, a1
101 ; RV32B-NEXT: cmov a0, a1, a3, a0
104 ; RV32ZBT-LABEL: cmov_sle_i32:
106 ; RV32ZBT-NEXT: slt a1, a2, a1
107 ; RV32ZBT-NEXT: cmov a0, a1, a3, a0
109 %tobool = icmp sle i32 %b, %c
110 %cond = select i1 %tobool, i32 %a, i32 %d
114 define i32 @cmov_sge_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
115 ; RV32I-LABEL: cmov_sge_i32:
117 ; RV32I-NEXT: bge a1, a2, .LBB4_2
118 ; RV32I-NEXT: # %bb.1:
119 ; RV32I-NEXT: mv a0, a3
120 ; RV32I-NEXT: .LBB4_2:
123 ; RV32B-LABEL: cmov_sge_i32:
125 ; RV32B-NEXT: slt a1, a1, a2
126 ; RV32B-NEXT: cmov a0, a1, a3, a0
129 ; RV32ZBT-LABEL: cmov_sge_i32:
131 ; RV32ZBT-NEXT: slt a1, a1, a2
132 ; RV32ZBT-NEXT: cmov a0, a1, a3, a0
134 %tobool = icmp sge i32 %b, %c
135 %cond = select i1 %tobool, i32 %a, i32 %d
139 define i32 @cmov_ule_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
140 ; RV32I-LABEL: cmov_ule_i32:
142 ; RV32I-NEXT: bgeu a2, a1, .LBB5_2
143 ; RV32I-NEXT: # %bb.1:
144 ; RV32I-NEXT: mv a0, a3
145 ; RV32I-NEXT: .LBB5_2:
148 ; RV32B-LABEL: cmov_ule_i32:
150 ; RV32B-NEXT: sltu a1, a2, a1
151 ; RV32B-NEXT: cmov a0, a1, a3, a0
154 ; RV32ZBT-LABEL: cmov_ule_i32:
156 ; RV32ZBT-NEXT: sltu a1, a2, a1
157 ; RV32ZBT-NEXT: cmov a0, a1, a3, a0
159 %tobool = icmp ule i32 %b, %c
160 %cond = select i1 %tobool, i32 %a, i32 %d
164 define i32 @cmov_uge_i32(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
165 ; RV32I-LABEL: cmov_uge_i32:
167 ; RV32I-NEXT: bgeu a1, a2, .LBB6_2
168 ; RV32I-NEXT: # %bb.1:
169 ; RV32I-NEXT: mv a0, a3
170 ; RV32I-NEXT: .LBB6_2:
173 ; RV32B-LABEL: cmov_uge_i32:
175 ; RV32B-NEXT: sltu a1, a1, a2
176 ; RV32B-NEXT: cmov a0, a1, a3, a0
179 ; RV32ZBT-LABEL: cmov_uge_i32:
181 ; RV32ZBT-NEXT: sltu a1, a1, a2
182 ; RV32ZBT-NEXT: cmov a0, a1, a3, a0
184 %tobool = icmp uge i32 %b, %c
185 %cond = select i1 %tobool, i32 %a, i32 %d
189 define i64 @cmov_i64(i64 %a, i64 %b, i64 %c) nounwind {
190 ; RV32I-LABEL: cmov_i64:
192 ; RV32I-NEXT: or a2, a2, a3
193 ; RV32I-NEXT: beqz a2, .LBB7_2
194 ; RV32I-NEXT: # %bb.1:
195 ; RV32I-NEXT: mv a4, a0
196 ; RV32I-NEXT: mv a5, a1
197 ; RV32I-NEXT: .LBB7_2:
198 ; RV32I-NEXT: mv a0, a4
199 ; RV32I-NEXT: mv a1, a5
202 ; RV32B-LABEL: cmov_i64:
204 ; RV32B-NEXT: or a2, a2, a3
205 ; RV32B-NEXT: cmov a0, a2, a0, a4
206 ; RV32B-NEXT: cmov a1, a2, a1, a5
209 ; RV32ZBT-LABEL: cmov_i64:
211 ; RV32ZBT-NEXT: or a2, a2, a3
212 ; RV32ZBT-NEXT: cmov a0, a2, a0, a4
213 ; RV32ZBT-NEXT: cmov a1, a2, a1, a5
215 %tobool.not = icmp eq i64 %b, 0
216 %cond = select i1 %tobool.not, i64 %c, i64 %a
220 define i64 @cmov_sle_i64(i64 %a, i64 %b, i64 %c, i64 %d) nounwind {
221 ; RV32I-LABEL: cmov_sle_i64:
223 ; RV32I-NEXT: beq a3, a5, .LBB8_2
224 ; RV32I-NEXT: # %bb.1:
225 ; RV32I-NEXT: slt a2, a5, a3
226 ; RV32I-NEXT: xori a2, a2, 1
227 ; RV32I-NEXT: beqz a2, .LBB8_3
228 ; RV32I-NEXT: j .LBB8_4
229 ; RV32I-NEXT: .LBB8_2:
230 ; RV32I-NEXT: sltu a2, a4, a2
231 ; RV32I-NEXT: xori a2, a2, 1
232 ; RV32I-NEXT: bnez a2, .LBB8_4
233 ; RV32I-NEXT: .LBB8_3:
234 ; RV32I-NEXT: mv a0, a6
235 ; RV32I-NEXT: mv a1, a7
236 ; RV32I-NEXT: .LBB8_4:
239 ; RV32B-LABEL: cmov_sle_i64:
241 ; RV32B-NEXT: xor t0, a3, a5
242 ; RV32B-NEXT: sltu a2, a4, a2
243 ; RV32B-NEXT: xori a2, a2, 1
244 ; RV32B-NEXT: slt a3, a5, a3
245 ; RV32B-NEXT: xori a3, a3, 1
246 ; RV32B-NEXT: cmov a2, t0, a3, a2
247 ; RV32B-NEXT: cmov a0, a2, a0, a6
248 ; RV32B-NEXT: cmov a1, a2, a1, a7
251 ; RV32ZBT-LABEL: cmov_sle_i64:
253 ; RV32ZBT-NEXT: xor t0, a3, a5
254 ; RV32ZBT-NEXT: sltu a2, a4, a2
255 ; RV32ZBT-NEXT: xori a2, a2, 1
256 ; RV32ZBT-NEXT: slt a3, a5, a3
257 ; RV32ZBT-NEXT: xori a3, a3, 1
258 ; RV32ZBT-NEXT: cmov a2, t0, a3, a2
259 ; RV32ZBT-NEXT: cmov a0, a2, a0, a6
260 ; RV32ZBT-NEXT: cmov a1, a2, a1, a7
262 %tobool = icmp sle i64 %b, %c
263 %cond = select i1 %tobool, i64 %a, i64 %d
267 define i64 @cmov_sge_i64(i64 %a, i64 %b, i64 %c, i64 %d) nounwind {
268 ; RV32I-LABEL: cmov_sge_i64:
270 ; RV32I-NEXT: beq a3, a5, .LBB9_2
271 ; RV32I-NEXT: # %bb.1:
272 ; RV32I-NEXT: slt a2, a3, a5
273 ; RV32I-NEXT: xori a2, a2, 1
274 ; RV32I-NEXT: beqz a2, .LBB9_3
275 ; RV32I-NEXT: j .LBB9_4
276 ; RV32I-NEXT: .LBB9_2:
277 ; RV32I-NEXT: sltu a2, a2, a4
278 ; RV32I-NEXT: xori a2, a2, 1
279 ; RV32I-NEXT: bnez a2, .LBB9_4
280 ; RV32I-NEXT: .LBB9_3:
281 ; RV32I-NEXT: mv a0, a6
282 ; RV32I-NEXT: mv a1, a7
283 ; RV32I-NEXT: .LBB9_4:
286 ; RV32B-LABEL: cmov_sge_i64:
288 ; RV32B-NEXT: xor t0, a3, a5
289 ; RV32B-NEXT: sltu a2, a2, a4
290 ; RV32B-NEXT: xori a2, a2, 1
291 ; RV32B-NEXT: slt a3, a3, a5
292 ; RV32B-NEXT: xori a3, a3, 1
293 ; RV32B-NEXT: cmov a2, t0, a3, a2
294 ; RV32B-NEXT: cmov a0, a2, a0, a6
295 ; RV32B-NEXT: cmov a1, a2, a1, a7
298 ; RV32ZBT-LABEL: cmov_sge_i64:
300 ; RV32ZBT-NEXT: xor t0, a3, a5
301 ; RV32ZBT-NEXT: sltu a2, a2, a4
302 ; RV32ZBT-NEXT: xori a2, a2, 1
303 ; RV32ZBT-NEXT: slt a3, a3, a5
304 ; RV32ZBT-NEXT: xori a3, a3, 1
305 ; RV32ZBT-NEXT: cmov a2, t0, a3, a2
306 ; RV32ZBT-NEXT: cmov a0, a2, a0, a6
307 ; RV32ZBT-NEXT: cmov a1, a2, a1, a7
309 %tobool = icmp sge i64 %b, %c
310 %cond = select i1 %tobool, i64 %a, i64 %d
314 define i64 @cmov_ule_i64(i64 %a, i64 %b, i64 %c, i64 %d) nounwind {
315 ; RV32I-LABEL: cmov_ule_i64:
317 ; RV32I-NEXT: beq a3, a5, .LBB10_2
318 ; RV32I-NEXT: # %bb.1:
319 ; RV32I-NEXT: sltu a2, a5, a3
320 ; RV32I-NEXT: xori a2, a2, 1
321 ; RV32I-NEXT: beqz a2, .LBB10_3
322 ; RV32I-NEXT: j .LBB10_4
323 ; RV32I-NEXT: .LBB10_2:
324 ; RV32I-NEXT: sltu a2, a4, a2
325 ; RV32I-NEXT: xori a2, a2, 1
326 ; RV32I-NEXT: bnez a2, .LBB10_4
327 ; RV32I-NEXT: .LBB10_3:
328 ; RV32I-NEXT: mv a0, a6
329 ; RV32I-NEXT: mv a1, a7
330 ; RV32I-NEXT: .LBB10_4:
333 ; RV32B-LABEL: cmov_ule_i64:
335 ; RV32B-NEXT: xor t0, a3, a5
336 ; RV32B-NEXT: sltu a2, a4, a2
337 ; RV32B-NEXT: xori a2, a2, 1
338 ; RV32B-NEXT: sltu a3, a5, a3
339 ; RV32B-NEXT: xori a3, a3, 1
340 ; RV32B-NEXT: cmov a2, t0, a3, a2
341 ; RV32B-NEXT: cmov a0, a2, a0, a6
342 ; RV32B-NEXT: cmov a1, a2, a1, a7
345 ; RV32ZBT-LABEL: cmov_ule_i64:
347 ; RV32ZBT-NEXT: xor t0, a3, a5
348 ; RV32ZBT-NEXT: sltu a2, a4, a2
349 ; RV32ZBT-NEXT: xori a2, a2, 1
350 ; RV32ZBT-NEXT: sltu a3, a5, a3
351 ; RV32ZBT-NEXT: xori a3, a3, 1
352 ; RV32ZBT-NEXT: cmov a2, t0, a3, a2
353 ; RV32ZBT-NEXT: cmov a0, a2, a0, a6
354 ; RV32ZBT-NEXT: cmov a1, a2, a1, a7
356 %tobool = icmp ule i64 %b, %c
357 %cond = select i1 %tobool, i64 %a, i64 %d
361 define i64 @cmov_uge_i64(i64 %a, i64 %b, i64 %c, i64 %d) nounwind {
362 ; RV32I-LABEL: cmov_uge_i64:
364 ; RV32I-NEXT: beq a3, a5, .LBB11_2
365 ; RV32I-NEXT: # %bb.1:
366 ; RV32I-NEXT: sltu a2, a3, a5
367 ; RV32I-NEXT: xori a2, a2, 1
368 ; RV32I-NEXT: beqz a2, .LBB11_3
369 ; RV32I-NEXT: j .LBB11_4
370 ; RV32I-NEXT: .LBB11_2:
371 ; RV32I-NEXT: sltu a2, a2, a4
372 ; RV32I-NEXT: xori a2, a2, 1
373 ; RV32I-NEXT: bnez a2, .LBB11_4
374 ; RV32I-NEXT: .LBB11_3:
375 ; RV32I-NEXT: mv a0, a6
376 ; RV32I-NEXT: mv a1, a7
377 ; RV32I-NEXT: .LBB11_4:
380 ; RV32B-LABEL: cmov_uge_i64:
382 ; RV32B-NEXT: xor t0, a3, a5
383 ; RV32B-NEXT: sltu a2, a2, a4
384 ; RV32B-NEXT: xori a2, a2, 1
385 ; RV32B-NEXT: sltu a3, a3, a5
386 ; RV32B-NEXT: xori a3, a3, 1
387 ; RV32B-NEXT: cmov a2, t0, a3, a2
388 ; RV32B-NEXT: cmov a0, a2, a0, a6
389 ; RV32B-NEXT: cmov a1, a2, a1, a7
392 ; RV32ZBT-LABEL: cmov_uge_i64:
394 ; RV32ZBT-NEXT: xor t0, a3, a5
395 ; RV32ZBT-NEXT: sltu a2, a2, a4
396 ; RV32ZBT-NEXT: xori a2, a2, 1
397 ; RV32ZBT-NEXT: sltu a3, a3, a5
398 ; RV32ZBT-NEXT: xori a3, a3, 1
399 ; RV32ZBT-NEXT: cmov a2, t0, a3, a2
400 ; RV32ZBT-NEXT: cmov a0, a2, a0, a6
401 ; RV32ZBT-NEXT: cmov a1, a2, a1, a7
403 %tobool = icmp uge i64 %b, %c
404 %cond = select i1 %tobool, i64 %a, i64 %d
408 declare i32 @llvm.fshl.i32(i32, i32, i32)
410 define i32 @fshl_i32(i32 %a, i32 %b, i32 %c) nounwind {
411 ; RV32I-LABEL: fshl_i32:
413 ; RV32I-NEXT: sll a0, a0, a2
414 ; RV32I-NEXT: not a2, a2
415 ; RV32I-NEXT: srli a1, a1, 1
416 ; RV32I-NEXT: srl a1, a1, a2
417 ; RV32I-NEXT: or a0, a0, a1
420 ; RV32B-LABEL: fshl_i32:
422 ; RV32B-NEXT: andi a2, a2, 31
423 ; RV32B-NEXT: fsl a0, a0, a1, a2
426 ; RV32ZBT-LABEL: fshl_i32:
428 ; RV32ZBT-NEXT: andi a2, a2, 31
429 ; RV32ZBT-NEXT: fsl a0, a0, a1, a2
431 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %c)
435 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
436 ; don't have yet an efficient pattern-matching with bit manipulation
437 ; instructions on RV32.
438 ; This test is presented here in case future expansions of the experimental-b
439 ; extension introduce instructions that can match more efficiently this pattern.
441 declare i64 @llvm.fshl.i64(i64, i64, i64)
443 define i64 @fshl_i64(i64 %a, i64 %b, i64 %c) nounwind {
444 ; RV32I-LABEL: fshl_i64:
446 ; RV32I-NEXT: andi a5, a4, 63
447 ; RV32I-NEXT: addi a7, a5, -32
448 ; RV32I-NEXT: addi a6, zero, 31
449 ; RV32I-NEXT: bltz a7, .LBB13_2
450 ; RV32I-NEXT: # %bb.1:
451 ; RV32I-NEXT: sll a1, a0, a7
452 ; RV32I-NEXT: j .LBB13_3
453 ; RV32I-NEXT: .LBB13_2:
454 ; RV32I-NEXT: sll t0, a1, a4
455 ; RV32I-NEXT: sub a5, a6, a5
456 ; RV32I-NEXT: srli a1, a0, 1
457 ; RV32I-NEXT: srl a1, a1, a5
458 ; RV32I-NEXT: or a1, t0, a1
459 ; RV32I-NEXT: .LBB13_3:
460 ; RV32I-NEXT: not t2, a4
461 ; RV32I-NEXT: andi t1, t2, 63
462 ; RV32I-NEXT: addi a5, t1, -32
463 ; RV32I-NEXT: srli t0, a3, 1
464 ; RV32I-NEXT: bltz a5, .LBB13_5
465 ; RV32I-NEXT: # %bb.4:
466 ; RV32I-NEXT: srl a2, t0, a5
467 ; RV32I-NEXT: bltz a7, .LBB13_6
468 ; RV32I-NEXT: j .LBB13_7
469 ; RV32I-NEXT: .LBB13_5:
470 ; RV32I-NEXT: srl a5, t0, t2
471 ; RV32I-NEXT: or a1, a1, a5
472 ; RV32I-NEXT: slli a3, a3, 31
473 ; RV32I-NEXT: srli a2, a2, 1
474 ; RV32I-NEXT: or a2, a2, a3
475 ; RV32I-NEXT: srl a2, a2, t2
476 ; RV32I-NEXT: sub a3, a6, t1
477 ; RV32I-NEXT: slli a5, t0, 1
478 ; RV32I-NEXT: sll a3, a5, a3
479 ; RV32I-NEXT: or a2, a2, a3
480 ; RV32I-NEXT: bgez a7, .LBB13_7
481 ; RV32I-NEXT: .LBB13_6:
482 ; RV32I-NEXT: sll a0, a0, a4
483 ; RV32I-NEXT: or a2, a2, a0
484 ; RV32I-NEXT: .LBB13_7:
485 ; RV32I-NEXT: mv a0, a2
488 ; RV32B-LABEL: fshl_i64:
490 ; RV32B-NEXT: sll a7, a1, a4
491 ; RV32B-NEXT: andi a5, a4, 63
492 ; RV32B-NEXT: addi a6, zero, 31
493 ; RV32B-NEXT: sub t0, a6, a5
494 ; RV32B-NEXT: srli a1, a0, 1
495 ; RV32B-NEXT: srl a1, a1, t0
496 ; RV32B-NEXT: or a7, a7, a1
497 ; RV32B-NEXT: addi t1, a5, -32
498 ; RV32B-NEXT: sll t0, a0, t1
499 ; RV32B-NEXT: slti a1, t1, 0
500 ; RV32B-NEXT: cmov t0, a1, a7, t0
501 ; RV32B-NEXT: not a7, a4
502 ; RV32B-NEXT: srli t4, a3, 1
503 ; RV32B-NEXT: srl t2, t4, a7
504 ; RV32B-NEXT: addi a1, zero, 63
505 ; RV32B-NEXT: andn t3, a1, a4
506 ; RV32B-NEXT: addi a5, t3, -32
507 ; RV32B-NEXT: srai a1, a5, 31
508 ; RV32B-NEXT: and a1, a1, t2
509 ; RV32B-NEXT: or a1, t0, a1
510 ; RV32B-NEXT: fsri a2, a2, a3, 1
511 ; RV32B-NEXT: srl a7, a2, a7
512 ; RV32B-NEXT: sub a3, a6, t3
513 ; RV32B-NEXT: slli a2, t4, 1
514 ; RV32B-NEXT: sll a2, a2, a3
515 ; RV32B-NEXT: or a2, a7, a2
516 ; RV32B-NEXT: srl a3, t4, a5
517 ; RV32B-NEXT: slti a5, a5, 0
518 ; RV32B-NEXT: cmov a2, a5, a2, a3
519 ; RV32B-NEXT: sll a0, a0, a4
520 ; RV32B-NEXT: srai a3, t1, 31
521 ; RV32B-NEXT: and a0, a3, a0
522 ; RV32B-NEXT: or a0, a0, a2
525 ; RV32ZBT-LABEL: fshl_i64:
527 ; RV32ZBT-NEXT: sll a7, a1, a4
528 ; RV32ZBT-NEXT: andi a5, a4, 63
529 ; RV32ZBT-NEXT: addi a6, zero, 31
530 ; RV32ZBT-NEXT: sub t0, a6, a5
531 ; RV32ZBT-NEXT: srli a1, a0, 1
532 ; RV32ZBT-NEXT: srl a1, a1, t0
533 ; RV32ZBT-NEXT: or a7, a7, a1
534 ; RV32ZBT-NEXT: addi t1, a5, -32
535 ; RV32ZBT-NEXT: sll t0, a0, t1
536 ; RV32ZBT-NEXT: slti a1, t1, 0
537 ; RV32ZBT-NEXT: cmov t0, a1, a7, t0
538 ; RV32ZBT-NEXT: not a5, a4
539 ; RV32ZBT-NEXT: srli a7, a3, 1
540 ; RV32ZBT-NEXT: srl t4, a7, a5
541 ; RV32ZBT-NEXT: andi t2, a5, 63
542 ; RV32ZBT-NEXT: addi t3, t2, -32
543 ; RV32ZBT-NEXT: srai a1, t3, 31
544 ; RV32ZBT-NEXT: and a1, a1, t4
545 ; RV32ZBT-NEXT: or a1, t0, a1
546 ; RV32ZBT-NEXT: fsri a2, a2, a3, 1
547 ; RV32ZBT-NEXT: srl a2, a2, a5
548 ; RV32ZBT-NEXT: sub a3, a6, t2
549 ; RV32ZBT-NEXT: slli a5, a7, 1
550 ; RV32ZBT-NEXT: sll a3, a5, a3
551 ; RV32ZBT-NEXT: or a2, a2, a3
552 ; RV32ZBT-NEXT: srl a3, a7, t3
553 ; RV32ZBT-NEXT: slti a5, t3, 0
554 ; RV32ZBT-NEXT: cmov a2, a5, a2, a3
555 ; RV32ZBT-NEXT: sll a0, a0, a4
556 ; RV32ZBT-NEXT: srai a3, t1, 31
557 ; RV32ZBT-NEXT: and a0, a3, a0
558 ; RV32ZBT-NEXT: or a0, a0, a2
560 %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %b, i64 %c)
564 declare i32 @llvm.fshr.i32(i32, i32, i32)
566 define i32 @fshr_i32(i32 %a, i32 %b, i32 %c) nounwind {
567 ; RV32I-LABEL: fshr_i32:
569 ; RV32I-NEXT: srl a1, a1, a2
570 ; RV32I-NEXT: not a2, a2
571 ; RV32I-NEXT: slli a0, a0, 1
572 ; RV32I-NEXT: sll a0, a0, a2
573 ; RV32I-NEXT: or a0, a0, a1
576 ; RV32B-LABEL: fshr_i32:
578 ; RV32B-NEXT: andi a2, a2, 31
579 ; RV32B-NEXT: fsr a0, a1, a0, a2
582 ; RV32ZBT-LABEL: fshr_i32:
584 ; RV32ZBT-NEXT: andi a2, a2, 31
585 ; RV32ZBT-NEXT: fsr a0, a1, a0, a2
587 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %b, i32 %c)
591 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
592 ; don't have yet an efficient pattern-matching with bit manipulation
593 ; instructions on RV32.
594 ; This test is presented here in case future expansions of the experimental-b
595 ; extension introduce instructions that can match more efficiently this pattern.
597 declare i64 @llvm.fshr.i64(i64, i64, i64)
599 define i64 @fshr_i64(i64 %a, i64 %b, i64 %c) nounwind {
600 ; RV32I-LABEL: fshr_i64:
602 ; RV32I-NEXT: mv t0, a0
603 ; RV32I-NEXT: andi a0, a4, 63
604 ; RV32I-NEXT: addi a6, a0, -32
605 ; RV32I-NEXT: addi a7, zero, 31
606 ; RV32I-NEXT: bltz a6, .LBB15_2
607 ; RV32I-NEXT: # %bb.1:
608 ; RV32I-NEXT: srl a0, a3, a6
609 ; RV32I-NEXT: j .LBB15_3
610 ; RV32I-NEXT: .LBB15_2:
611 ; RV32I-NEXT: srl a2, a2, a4
612 ; RV32I-NEXT: sub a0, a7, a0
613 ; RV32I-NEXT: slli a5, a3, 1
614 ; RV32I-NEXT: sll a0, a5, a0
615 ; RV32I-NEXT: or a0, a2, a0
616 ; RV32I-NEXT: .LBB15_3:
617 ; RV32I-NEXT: not t2, a4
618 ; RV32I-NEXT: andi a5, t2, 63
619 ; RV32I-NEXT: addi a2, a5, -32
620 ; RV32I-NEXT: slli t1, t0, 1
621 ; RV32I-NEXT: bltz a2, .LBB15_5
622 ; RV32I-NEXT: # %bb.4:
623 ; RV32I-NEXT: sll a1, t1, a2
624 ; RV32I-NEXT: bltz a6, .LBB15_6
625 ; RV32I-NEXT: j .LBB15_7
626 ; RV32I-NEXT: .LBB15_5:
627 ; RV32I-NEXT: sll a2, t1, t2
628 ; RV32I-NEXT: or a0, a0, a2
629 ; RV32I-NEXT: lui a2, 524288
630 ; RV32I-NEXT: addi a2, a2, -1
631 ; RV32I-NEXT: and a2, t0, a2
632 ; RV32I-NEXT: sub a5, a7, a5
633 ; RV32I-NEXT: srl a2, a2, a5
634 ; RV32I-NEXT: srli a5, t0, 31
635 ; RV32I-NEXT: slli a1, a1, 1
636 ; RV32I-NEXT: or a1, a1, a5
637 ; RV32I-NEXT: sll a1, a1, t2
638 ; RV32I-NEXT: or a1, a1, a2
639 ; RV32I-NEXT: bgez a6, .LBB15_7
640 ; RV32I-NEXT: .LBB15_6:
641 ; RV32I-NEXT: srl a2, a3, a4
642 ; RV32I-NEXT: or a1, a1, a2
643 ; RV32I-NEXT: .LBB15_7:
646 ; RV32B-LABEL: fshr_i64:
648 ; RV32B-NEXT: srl a7, a2, a4
649 ; RV32B-NEXT: andi a5, a4, 63
650 ; RV32B-NEXT: addi a6, zero, 31
651 ; RV32B-NEXT: sub t0, a6, a5
652 ; RV32B-NEXT: slli a2, a3, 1
653 ; RV32B-NEXT: sll a2, a2, t0
654 ; RV32B-NEXT: or a7, a7, a2
655 ; RV32B-NEXT: addi t2, a5, -32
656 ; RV32B-NEXT: srl t0, a3, t2
657 ; RV32B-NEXT: slti a2, t2, 0
658 ; RV32B-NEXT: cmov a7, a2, a7, t0
659 ; RV32B-NEXT: not t3, a4
660 ; RV32B-NEXT: slli t0, a0, 1
661 ; RV32B-NEXT: sll t1, t0, t3
662 ; RV32B-NEXT: addi a5, zero, 63
663 ; RV32B-NEXT: andn t4, a5, a4
664 ; RV32B-NEXT: addi a2, t4, -32
665 ; RV32B-NEXT: srai a5, a2, 31
666 ; RV32B-NEXT: and a5, a5, t1
667 ; RV32B-NEXT: or a7, a5, a7
668 ; RV32B-NEXT: fsri a1, a0, a1, 31
669 ; RV32B-NEXT: sll a1, a1, t3
670 ; RV32B-NEXT: sub a5, a6, t4
671 ; RV32B-NEXT: bclri a0, a0, 31
672 ; RV32B-NEXT: srl a0, a0, a5
673 ; RV32B-NEXT: or a0, a1, a0
674 ; RV32B-NEXT: sll a1, t0, a2
675 ; RV32B-NEXT: slti a2, a2, 0
676 ; RV32B-NEXT: cmov a0, a2, a0, a1
677 ; RV32B-NEXT: srl a1, a3, a4
678 ; RV32B-NEXT: srai a2, t2, 31
679 ; RV32B-NEXT: and a1, a2, a1
680 ; RV32B-NEXT: or a1, a0, a1
681 ; RV32B-NEXT: mv a0, a7
684 ; RV32ZBT-LABEL: fshr_i64:
686 ; RV32ZBT-NEXT: srl a7, a2, a4
687 ; RV32ZBT-NEXT: andi a5, a4, 63
688 ; RV32ZBT-NEXT: addi a6, zero, 31
689 ; RV32ZBT-NEXT: sub t0, a6, a5
690 ; RV32ZBT-NEXT: slli a2, a3, 1
691 ; RV32ZBT-NEXT: sll a2, a2, t0
692 ; RV32ZBT-NEXT: or a7, a7, a2
693 ; RV32ZBT-NEXT: addi t2, a5, -32
694 ; RV32ZBT-NEXT: srl t0, a3, t2
695 ; RV32ZBT-NEXT: slti a2, t2, 0
696 ; RV32ZBT-NEXT: cmov a7, a2, a7, t0
697 ; RV32ZBT-NEXT: not t4, a4
698 ; RV32ZBT-NEXT: slli t0, a0, 1
699 ; RV32ZBT-NEXT: sll t1, t0, t4
700 ; RV32ZBT-NEXT: andi t3, t4, 63
701 ; RV32ZBT-NEXT: addi a5, t3, -32
702 ; RV32ZBT-NEXT: srai a2, a5, 31
703 ; RV32ZBT-NEXT: and a2, a2, t1
704 ; RV32ZBT-NEXT: or a7, a2, a7
705 ; RV32ZBT-NEXT: lui a2, 524288
706 ; RV32ZBT-NEXT: addi a2, a2, -1
707 ; RV32ZBT-NEXT: and t1, a0, a2
708 ; RV32ZBT-NEXT: sub a2, a6, t3
709 ; RV32ZBT-NEXT: srl a2, t1, a2
710 ; RV32ZBT-NEXT: fsri a0, a0, a1, 31
711 ; RV32ZBT-NEXT: sll a0, a0, t4
712 ; RV32ZBT-NEXT: or a0, a0, a2
713 ; RV32ZBT-NEXT: sll a1, t0, a5
714 ; RV32ZBT-NEXT: slti a2, a5, 0
715 ; RV32ZBT-NEXT: cmov a0, a2, a0, a1
716 ; RV32ZBT-NEXT: srl a1, a3, a4
717 ; RV32ZBT-NEXT: srai a2, t2, 31
718 ; RV32ZBT-NEXT: and a1, a2, a1
719 ; RV32ZBT-NEXT: or a1, a0, a1
720 ; RV32ZBT-NEXT: mv a0, a7
722 %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %b, i64 %c)
726 define i32 @fshri_i32(i32 %a, i32 %b) nounwind {
727 ; RV32I-LABEL: fshri_i32:
729 ; RV32I-NEXT: srli a1, a1, 5
730 ; RV32I-NEXT: slli a0, a0, 27
731 ; RV32I-NEXT: or a0, a0, a1
734 ; RV32B-LABEL: fshri_i32:
736 ; RV32B-NEXT: fsri a0, a1, a0, 5
739 ; RV32ZBT-LABEL: fshri_i32:
741 ; RV32ZBT-NEXT: fsri a0, a1, a0, 5
743 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %b, i32 5)
747 define i64 @fshri_i64(i64 %a, i64 %b) nounwind {
748 ; RV32I-LABEL: fshri_i64:
750 ; RV32I-NEXT: slli a1, a3, 27
751 ; RV32I-NEXT: srli a2, a2, 5
752 ; RV32I-NEXT: or a2, a2, a1
753 ; RV32I-NEXT: srli a1, a3, 5
754 ; RV32I-NEXT: slli a0, a0, 27
755 ; RV32I-NEXT: or a1, a0, a1
756 ; RV32I-NEXT: mv a0, a2
759 ; RV32B-LABEL: fshri_i64:
761 ; RV32B-NEXT: fsri a2, a2, a3, 5
762 ; RV32B-NEXT: fsri a1, a3, a0, 5
763 ; RV32B-NEXT: mv a0, a2
766 ; RV32ZBT-LABEL: fshri_i64:
768 ; RV32ZBT-NEXT: fsri a2, a2, a3, 5
769 ; RV32ZBT-NEXT: fsri a1, a3, a0, 5
770 ; RV32ZBT-NEXT: mv a0, a2
772 %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %b, i64 5)
776 define i32 @fshli_i32(i32 %a, i32 %b) nounwind {
777 ; RV32I-LABEL: fshli_i32:
779 ; RV32I-NEXT: srli a1, a1, 27
780 ; RV32I-NEXT: slli a0, a0, 5
781 ; RV32I-NEXT: or a0, a0, a1
784 ; RV32B-LABEL: fshli_i32:
786 ; RV32B-NEXT: fsri a0, a1, a0, 27
789 ; RV32ZBT-LABEL: fshli_i32:
791 ; RV32ZBT-NEXT: fsri a0, a1, a0, 27
793 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 5)
797 define i64 @fshli_i64(i64 %a, i64 %b) nounwind {
798 ; RV32I-LABEL: fshli_i64:
800 ; RV32I-NEXT: srli a2, a3, 27
801 ; RV32I-NEXT: slli a3, a0, 5
802 ; RV32I-NEXT: or a2, a3, a2
803 ; RV32I-NEXT: srli a0, a0, 27
804 ; RV32I-NEXT: slli a1, a1, 5
805 ; RV32I-NEXT: or a1, a1, a0
806 ; RV32I-NEXT: mv a0, a2
809 ; RV32B-LABEL: fshli_i64:
811 ; RV32B-NEXT: fsri a2, a3, a0, 27
812 ; RV32B-NEXT: fsri a1, a0, a1, 27
813 ; RV32B-NEXT: mv a0, a2
816 ; RV32ZBT-LABEL: fshli_i64:
818 ; RV32ZBT-NEXT: fsri a2, a3, a0, 27
819 ; RV32ZBT-NEXT: fsri a1, a0, a1, 27
820 ; RV32ZBT-NEXT: mv a0, a2
822 %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %b, i64 5)