1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
3 ; RUN: | FileCheck %s -check-prefixes=CHECK,RV64I
4 ; RUN: llc -mtriple=riscv64 -mattr=+zbs -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s -check-prefixes=CHECK,RV64ZBS
6 ; RUN: llc -mtriple=riscv64 -mattr=+zbs,+zbb -verify-machineinstrs < %s \
7 ; RUN: | FileCheck %s -check-prefixes=CHECK,RV64ZBS
9 define signext i32 @bclr_i32(i32 signext %a, i32 signext %b) nounwind {
10 ; RV64I-LABEL: bclr_i32:
12 ; RV64I-NEXT: li a2, 1
13 ; RV64I-NEXT: sllw a1, a2, a1
14 ; RV64I-NEXT: not a1, a1
15 ; RV64I-NEXT: and a0, a1, a0
18 ; RV64ZBS-LABEL: bclr_i32:
20 ; RV64ZBS-NEXT: andi a1, a1, 31
21 ; RV64ZBS-NEXT: bclr a0, a0, a1
22 ; RV64ZBS-NEXT: sext.w a0, a0
25 %shl = shl nuw i32 1, %and
26 %neg = xor i32 %shl, -1
27 %and1 = and i32 %neg, %a
31 define signext i32 @bclr_i32_no_mask(i32 signext %a, i32 signext %b) nounwind {
32 ; RV64I-LABEL: bclr_i32_no_mask:
34 ; RV64I-NEXT: li a2, 1
35 ; RV64I-NEXT: sllw a1, a2, a1
36 ; RV64I-NEXT: not a1, a1
37 ; RV64I-NEXT: and a0, a1, a0
40 ; RV64ZBS-LABEL: bclr_i32_no_mask:
42 ; RV64ZBS-NEXT: bclr a0, a0, a1
43 ; RV64ZBS-NEXT: sext.w a0, a0
46 %neg = xor i32 %shl, -1
47 %and1 = and i32 %neg, %a
51 define signext i32 @bclr_i32_load(ptr %p, i32 signext %b) nounwind {
52 ; RV64I-LABEL: bclr_i32_load:
54 ; RV64I-NEXT: lw a0, 0(a0)
55 ; RV64I-NEXT: li a2, 1
56 ; RV64I-NEXT: sllw a1, a2, a1
57 ; RV64I-NEXT: not a1, a1
58 ; RV64I-NEXT: and a0, a1, a0
61 ; RV64ZBS-LABEL: bclr_i32_load:
63 ; RV64ZBS-NEXT: lw a0, 0(a0)
64 ; RV64ZBS-NEXT: bclr a0, a0, a1
65 ; RV64ZBS-NEXT: sext.w a0, a0
69 %neg = xor i32 %shl, -1
70 %and1 = and i32 %neg, %a
74 define i64 @bclr_i64(i64 %a, i64 %b) nounwind {
75 ; RV64I-LABEL: bclr_i64:
77 ; RV64I-NEXT: li a2, 1
78 ; RV64I-NEXT: sll a1, a2, a1
79 ; RV64I-NEXT: not a1, a1
80 ; RV64I-NEXT: and a0, a1, a0
83 ; RV64ZBS-LABEL: bclr_i64:
85 ; RV64ZBS-NEXT: bclr a0, a0, a1
88 %shl = shl nuw i64 1, %and
89 %neg = xor i64 %shl, -1
90 %and1 = and i64 %neg, %a
94 define i64 @bclr_i64_no_mask(i64 %a, i64 %b) nounwind {
95 ; RV64I-LABEL: bclr_i64_no_mask:
97 ; RV64I-NEXT: li a2, 1
98 ; RV64I-NEXT: sll a1, a2, a1
99 ; RV64I-NEXT: not a1, a1
100 ; RV64I-NEXT: and a0, a1, a0
103 ; RV64ZBS-LABEL: bclr_i64_no_mask:
105 ; RV64ZBS-NEXT: bclr a0, a0, a1
108 %neg = xor i64 %shl, -1
109 %and1 = and i64 %neg, %a
113 define signext i32 @bset_i32(i32 signext %a, i32 signext %b) nounwind {
114 ; RV64I-LABEL: bset_i32:
116 ; RV64I-NEXT: li a2, 1
117 ; RV64I-NEXT: sllw a1, a2, a1
118 ; RV64I-NEXT: or a0, a1, a0
121 ; RV64ZBS-LABEL: bset_i32:
123 ; RV64ZBS-NEXT: andi a1, a1, 31
124 ; RV64ZBS-NEXT: bset a0, a0, a1
125 ; RV64ZBS-NEXT: sext.w a0, a0
127 %and = and i32 %b, 31
128 %shl = shl nuw i32 1, %and
129 %or = or i32 %shl, %a
133 define signext i32 @bset_i32_no_mask(i32 signext %a, i32 signext %b) nounwind {
134 ; RV64I-LABEL: bset_i32_no_mask:
136 ; RV64I-NEXT: li a2, 1
137 ; RV64I-NEXT: sllw a1, a2, a1
138 ; RV64I-NEXT: or a0, a1, a0
141 ; RV64ZBS-LABEL: bset_i32_no_mask:
143 ; RV64ZBS-NEXT: bset a0, a0, a1
144 ; RV64ZBS-NEXT: sext.w a0, a0
147 %or = or i32 %shl, %a
151 define signext i32 @bset_i32_load(ptr %p, i32 signext %b) nounwind {
152 ; RV64I-LABEL: bset_i32_load:
154 ; RV64I-NEXT: lw a0, 0(a0)
155 ; RV64I-NEXT: li a2, 1
156 ; RV64I-NEXT: sllw a1, a2, a1
157 ; RV64I-NEXT: or a0, a1, a0
160 ; RV64ZBS-LABEL: bset_i32_load:
162 ; RV64ZBS-NEXT: lw a0, 0(a0)
163 ; RV64ZBS-NEXT: bset a0, a0, a1
164 ; RV64ZBS-NEXT: sext.w a0, a0
166 %a = load i32, ptr %p
168 %or = or i32 %shl, %a
172 ; We can use bsetw for 1 << x by setting the first source to zero.
173 define signext i32 @bset_i32_zero(i32 signext %a) nounwind {
174 ; RV64I-LABEL: bset_i32_zero:
176 ; RV64I-NEXT: li a1, 1
177 ; RV64I-NEXT: sllw a0, a1, a0
180 ; RV64ZBS-LABEL: bset_i32_zero:
182 ; RV64ZBS-NEXT: bset a0, zero, a0
183 ; RV64ZBS-NEXT: sext.w a0, a0
189 define i64 @bset_i64(i64 %a, i64 %b) nounwind {
190 ; RV64I-LABEL: bset_i64:
192 ; RV64I-NEXT: li a2, 1
193 ; RV64I-NEXT: sll a1, a2, a1
194 ; RV64I-NEXT: or a0, a1, a0
197 ; RV64ZBS-LABEL: bset_i64:
199 ; RV64ZBS-NEXT: bset a0, a0, a1
201 %conv = and i64 %b, 63
202 %shl = shl nuw i64 1, %conv
203 %or = or i64 %shl, %a
207 define i64 @bset_i64_no_mask(i64 %a, i64 %b) nounwind {
208 ; RV64I-LABEL: bset_i64_no_mask:
210 ; RV64I-NEXT: li a2, 1
211 ; RV64I-NEXT: sll a1, a2, a1
212 ; RV64I-NEXT: or a0, a1, a0
215 ; RV64ZBS-LABEL: bset_i64_no_mask:
217 ; RV64ZBS-NEXT: bset a0, a0, a1
220 %or = or i64 %shl, %a
224 ; We can use bsetw for 1 << x by setting the first source to zero.
225 define signext i64 @bset_i64_zero(i64 signext %a) nounwind {
226 ; RV64I-LABEL: bset_i64_zero:
228 ; RV64I-NEXT: li a1, 1
229 ; RV64I-NEXT: sll a0, a1, a0
232 ; RV64ZBS-LABEL: bset_i64_zero:
234 ; RV64ZBS-NEXT: bset a0, zero, a0
240 define signext i32 @binv_i32(i32 signext %a, i32 signext %b) nounwind {
241 ; RV64I-LABEL: binv_i32:
243 ; RV64I-NEXT: li a2, 1
244 ; RV64I-NEXT: sllw a1, a2, a1
245 ; RV64I-NEXT: xor a0, a1, a0
248 ; RV64ZBS-LABEL: binv_i32:
250 ; RV64ZBS-NEXT: andi a1, a1, 31
251 ; RV64ZBS-NEXT: binv a0, a0, a1
252 ; RV64ZBS-NEXT: sext.w a0, a0
254 %and = and i32 %b, 31
255 %shl = shl nuw i32 1, %and
256 %xor = xor i32 %shl, %a
260 define signext i32 @binv_i32_no_mask(i32 signext %a, i32 signext %b) nounwind {
261 ; RV64I-LABEL: binv_i32_no_mask:
263 ; RV64I-NEXT: li a2, 1
264 ; RV64I-NEXT: sllw a1, a2, a1
265 ; RV64I-NEXT: xor a0, a1, a0
268 ; RV64ZBS-LABEL: binv_i32_no_mask:
270 ; RV64ZBS-NEXT: binv a0, a0, a1
271 ; RV64ZBS-NEXT: sext.w a0, a0
274 %xor = xor i32 %shl, %a
278 define signext i32 @binv_i32_load(ptr %p, i32 signext %b) nounwind {
279 ; RV64I-LABEL: binv_i32_load:
281 ; RV64I-NEXT: lw a0, 0(a0)
282 ; RV64I-NEXT: li a2, 1
283 ; RV64I-NEXT: sllw a1, a2, a1
284 ; RV64I-NEXT: xor a0, a1, a0
287 ; RV64ZBS-LABEL: binv_i32_load:
289 ; RV64ZBS-NEXT: lw a0, 0(a0)
290 ; RV64ZBS-NEXT: binv a0, a0, a1
291 ; RV64ZBS-NEXT: sext.w a0, a0
293 %a = load i32, ptr %p
295 %xor = xor i32 %shl, %a
299 define i64 @binv_i64(i64 %a, i64 %b) nounwind {
300 ; RV64I-LABEL: binv_i64:
302 ; RV64I-NEXT: li a2, 1
303 ; RV64I-NEXT: sll a1, a2, a1
304 ; RV64I-NEXT: xor a0, a1, a0
307 ; RV64ZBS-LABEL: binv_i64:
309 ; RV64ZBS-NEXT: binv a0, a0, a1
311 %conv = and i64 %b, 63
312 %shl = shl nuw i64 1, %conv
313 %xor = xor i64 %shl, %a
317 define i64 @binv_i64_no_mask(i64 %a, i64 %b) nounwind {
318 ; RV64I-LABEL: binv_i64_no_mask:
320 ; RV64I-NEXT: li a2, 1
321 ; RV64I-NEXT: sll a1, a2, a1
322 ; RV64I-NEXT: xor a0, a1, a0
325 ; RV64ZBS-LABEL: binv_i64_no_mask:
327 ; RV64ZBS-NEXT: binv a0, a0, a1
329 %shl = shl nuw i64 1, %b
330 %xor = xor i64 %shl, %a
334 define signext i32 @bext_i32(i32 signext %a, i32 signext %b) nounwind {
335 ; RV64I-LABEL: bext_i32:
337 ; RV64I-NEXT: srlw a0, a0, a1
338 ; RV64I-NEXT: andi a0, a0, 1
341 ; RV64ZBS-LABEL: bext_i32:
343 ; RV64ZBS-NEXT: andi a1, a1, 31
344 ; RV64ZBS-NEXT: bext a0, a0, a1
346 %and = and i32 %b, 31
347 %shr = lshr i32 %a, %and
348 %and1 = and i32 %shr, 1
352 define signext i32 @bext_i32_no_mask(i32 signext %a, i32 signext %b) nounwind {
353 ; RV64I-LABEL: bext_i32_no_mask:
355 ; RV64I-NEXT: srlw a0, a0, a1
356 ; RV64I-NEXT: andi a0, a0, 1
359 ; RV64ZBS-LABEL: bext_i32_no_mask:
361 ; RV64ZBS-NEXT: bext a0, a0, a1
363 %shr = lshr i32 %a, %b
364 %and1 = and i32 %shr, 1
368 ; This gets previous converted to (i1 (truncate (srl X, Y)). Make sure we are
370 define void @bext_i32_trunc(i32 signext %0, i32 signext %1) {
371 ; RV64I-LABEL: bext_i32_trunc:
373 ; RV64I-NEXT: srlw a0, a0, a1
374 ; RV64I-NEXT: andi a0, a0, 1
375 ; RV64I-NEXT: beqz a0, .LBB19_2
376 ; RV64I-NEXT: # %bb.1:
378 ; RV64I-NEXT: .LBB19_2:
379 ; RV64I-NEXT: tail bar
381 ; RV64ZBS-LABEL: bext_i32_trunc:
383 ; RV64ZBS-NEXT: bext a0, a0, a1
384 ; RV64ZBS-NEXT: beqz a0, .LBB19_2
385 ; RV64ZBS-NEXT: # %bb.1:
387 ; RV64ZBS-NEXT: .LBB19_2:
388 ; RV64ZBS-NEXT: tail bar
391 %5 = icmp eq i32 %4, 0
392 br i1 %5, label %6, label %7
395 tail call void @bar()
404 define i64 @bext_i64(i64 %a, i64 %b) nounwind {
405 ; RV64I-LABEL: bext_i64:
407 ; RV64I-NEXT: srl a0, a0, a1
408 ; RV64I-NEXT: andi a0, a0, 1
411 ; RV64ZBS-LABEL: bext_i64:
413 ; RV64ZBS-NEXT: bext a0, a0, a1
415 %conv = and i64 %b, 63
416 %shr = lshr i64 %a, %conv
417 %and1 = and i64 %shr, 1
421 define i64 @bext_i64_no_mask(i64 %a, i64 %b) nounwind {
422 ; RV64I-LABEL: bext_i64_no_mask:
424 ; RV64I-NEXT: srl a0, a0, a1
425 ; RV64I-NEXT: andi a0, a0, 1
428 ; RV64ZBS-LABEL: bext_i64_no_mask:
430 ; RV64ZBS-NEXT: bext a0, a0, a1
432 %shr = lshr i64 %a, %b
433 %and1 = and i64 %shr, 1
437 define signext i32 @bexti_i32(i32 signext %a) nounwind {
438 ; RV64I-LABEL: bexti_i32:
440 ; RV64I-NEXT: slli a0, a0, 58
441 ; RV64I-NEXT: srli a0, a0, 63
444 ; RV64ZBS-LABEL: bexti_i32:
446 ; RV64ZBS-NEXT: bexti a0, a0, 5
448 %shr = lshr i32 %a, 5
449 %and = and i32 %shr, 1
453 define i64 @bexti_i64(i64 %a) nounwind {
454 ; RV64I-LABEL: bexti_i64:
456 ; RV64I-NEXT: slli a0, a0, 58
457 ; RV64I-NEXT: srli a0, a0, 63
460 ; RV64ZBS-LABEL: bexti_i64:
462 ; RV64ZBS-NEXT: bexti a0, a0, 5
464 %shr = lshr i64 %a, 5
465 %and = and i64 %shr, 1
469 define signext i32 @bexti_i32_cmp(i32 signext %a) nounwind {
470 ; RV64I-LABEL: bexti_i32_cmp:
472 ; RV64I-NEXT: slli a0, a0, 58
473 ; RV64I-NEXT: srli a0, a0, 63
476 ; RV64ZBS-LABEL: bexti_i32_cmp:
478 ; RV64ZBS-NEXT: bexti a0, a0, 5
480 %and = and i32 %a, 32
481 %cmp = icmp ne i32 %and, 0
482 %zext = zext i1 %cmp to i32
486 define i64 @bexti_i64_cmp(i64 %a) nounwind {
487 ; RV64I-LABEL: bexti_i64_cmp:
489 ; RV64I-NEXT: slli a0, a0, 58
490 ; RV64I-NEXT: srli a0, a0, 63
493 ; RV64ZBS-LABEL: bexti_i64_cmp:
495 ; RV64ZBS-NEXT: bexti a0, a0, 5
497 %and = and i64 %a, 32
498 %cmp = icmp ne i64 %and, 0
499 %zext = zext i1 %cmp to i64
503 define signext i32 @bclri_i32_10(i32 signext %a) nounwind {
504 ; CHECK-LABEL: bclri_i32_10:
506 ; CHECK-NEXT: andi a0, a0, -1025
508 %and = and i32 %a, -1025
512 define signext i32 @bclri_i32_11(i32 signext %a) nounwind {
513 ; RV64I-LABEL: bclri_i32_11:
515 ; RV64I-NEXT: lui a1, 1048575
516 ; RV64I-NEXT: addiw a1, a1, 2047
517 ; RV64I-NEXT: and a0, a0, a1
520 ; RV64ZBS-LABEL: bclri_i32_11:
522 ; RV64ZBS-NEXT: bclri a0, a0, 11
524 %and = and i32 %a, -2049
528 define signext i32 @bclri_i32_30(i32 signext %a) nounwind {
529 ; RV64I-LABEL: bclri_i32_30:
531 ; RV64I-NEXT: lui a1, 786432
532 ; RV64I-NEXT: addiw a1, a1, -1
533 ; RV64I-NEXT: and a0, a0, a1
536 ; RV64ZBS-LABEL: bclri_i32_30:
538 ; RV64ZBS-NEXT: bclri a0, a0, 30
540 %and = and i32 %a, -1073741825
544 define signext i32 @bclri_i32_31(i32 signext %a) nounwind {
545 ; CHECK-LABEL: bclri_i32_31:
547 ; CHECK-NEXT: slli a0, a0, 33
548 ; CHECK-NEXT: srli a0, a0, 33
550 %and = and i32 %a, -2147483649
554 define i64 @bclri_i64_10(i64 %a) nounwind {
555 ; CHECK-LABEL: bclri_i64_10:
557 ; CHECK-NEXT: andi a0, a0, -1025
559 %and = and i64 %a, -1025
563 define i64 @bclri_i64_11(i64 %a) nounwind {
564 ; RV64I-LABEL: bclri_i64_11:
566 ; RV64I-NEXT: lui a1, 1048575
567 ; RV64I-NEXT: addiw a1, a1, 2047
568 ; RV64I-NEXT: and a0, a0, a1
571 ; RV64ZBS-LABEL: bclri_i64_11:
573 ; RV64ZBS-NEXT: bclri a0, a0, 11
575 %and = and i64 %a, -2049
579 define i64 @bclri_i64_30(i64 %a) nounwind {
580 ; RV64I-LABEL: bclri_i64_30:
582 ; RV64I-NEXT: lui a1, 786432
583 ; RV64I-NEXT: addiw a1, a1, -1
584 ; RV64I-NEXT: and a0, a0, a1
587 ; RV64ZBS-LABEL: bclri_i64_30:
589 ; RV64ZBS-NEXT: bclri a0, a0, 30
591 %and = and i64 %a, -1073741825
595 define i64 @bclri_i64_31(i64 %a) nounwind {
596 ; RV64I-LABEL: bclri_i64_31:
598 ; RV64I-NEXT: lui a1, 524288
599 ; RV64I-NEXT: addi a1, a1, -1
600 ; RV64I-NEXT: and a0, a0, a1
603 ; RV64ZBS-LABEL: bclri_i64_31:
605 ; RV64ZBS-NEXT: bclri a0, a0, 31
607 %and = and i64 %a, -2147483649
611 define i64 @bclri_i64_62(i64 %a) nounwind {
612 ; RV64I-LABEL: bclri_i64_62:
614 ; RV64I-NEXT: li a1, -1
615 ; RV64I-NEXT: slli a1, a1, 62
616 ; RV64I-NEXT: addi a1, a1, -1
617 ; RV64I-NEXT: and a0, a0, a1
620 ; RV64ZBS-LABEL: bclri_i64_62:
622 ; RV64ZBS-NEXT: bclri a0, a0, 62
624 %and = and i64 %a, -4611686018427387905
628 define i64 @bclri_i64_63(i64 %a) nounwind {
629 ; RV64I-LABEL: bclri_i64_63:
631 ; RV64I-NEXT: slli a0, a0, 1
632 ; RV64I-NEXT: srli a0, a0, 1
635 ; RV64ZBS-LABEL: bclri_i64_63:
637 ; RV64ZBS-NEXT: bclri a0, a0, 63
639 %and = and i64 %a, -9223372036854775809
643 define i64 @bclri_i64_large0(i64 %a) nounwind {
644 ; RV64I-LABEL: bclri_i64_large0:
646 ; RV64I-NEXT: lui a1, 1044480
647 ; RV64I-NEXT: addiw a1, a1, -256
648 ; RV64I-NEXT: and a0, a0, a1
651 ; RV64ZBS-LABEL: bclri_i64_large0:
653 ; RV64ZBS-NEXT: andi a0, a0, -256
654 ; RV64ZBS-NEXT: bclri a0, a0, 24
656 %and = and i64 %a, -16777472
660 define i64 @bclri_i64_large1(i64 %a) nounwind {
661 ; RV64I-LABEL: bclri_i64_large1:
663 ; RV64I-NEXT: lui a1, 1044464
664 ; RV64I-NEXT: addiw a1, a1, -1
665 ; RV64I-NEXT: and a0, a0, a1
668 ; RV64ZBS-LABEL: bclri_i64_large1:
670 ; RV64ZBS-NEXT: bclri a0, a0, 16
671 ; RV64ZBS-NEXT: bclri a0, a0, 24
673 %and = and i64 %a, -16842753
677 define signext i32 @bseti_i32_10(i32 signext %a) nounwind {
678 ; CHECK-LABEL: bseti_i32_10:
680 ; CHECK-NEXT: ori a0, a0, 1024
682 %or = or i32 %a, 1024
686 define signext i32 @bseti_i32_11(i32 signext %a) nounwind {
687 ; RV64I-LABEL: bseti_i32_11:
689 ; RV64I-NEXT: li a1, 1
690 ; RV64I-NEXT: slli a1, a1, 11
691 ; RV64I-NEXT: or a0, a0, a1
694 ; RV64ZBS-LABEL: bseti_i32_11:
696 ; RV64ZBS-NEXT: bseti a0, a0, 11
698 %or = or i32 %a, 2048
702 define signext i32 @bseti_i32_30(i32 signext %a) nounwind {
703 ; RV64I-LABEL: bseti_i32_30:
705 ; RV64I-NEXT: lui a1, 262144
706 ; RV64I-NEXT: or a0, a0, a1
709 ; RV64ZBS-LABEL: bseti_i32_30:
711 ; RV64ZBS-NEXT: bseti a0, a0, 30
713 %or = or i32 %a, 1073741824
717 define signext i32 @bseti_i32_31(i32 signext %a) nounwind {
718 ; CHECK-LABEL: bseti_i32_31:
720 ; CHECK-NEXT: lui a1, 524288
721 ; CHECK-NEXT: or a0, a0, a1
723 %or = or i32 %a, 2147483648
727 define i64 @bseti_i64_10(i64 %a) nounwind {
728 ; CHECK-LABEL: bseti_i64_10:
730 ; CHECK-NEXT: ori a0, a0, 1024
732 %or = or i64 %a, 1024
736 define i64 @bseti_i64_11(i64 %a) nounwind {
737 ; RV64I-LABEL: bseti_i64_11:
739 ; RV64I-NEXT: li a1, 1
740 ; RV64I-NEXT: slli a1, a1, 11
741 ; RV64I-NEXT: or a0, a0, a1
744 ; RV64ZBS-LABEL: bseti_i64_11:
746 ; RV64ZBS-NEXT: bseti a0, a0, 11
748 %or = or i64 %a, 2048
752 define i64 @bseti_i64_30(i64 %a) nounwind {
753 ; RV64I-LABEL: bseti_i64_30:
755 ; RV64I-NEXT: lui a1, 262144
756 ; RV64I-NEXT: or a0, a0, a1
759 ; RV64ZBS-LABEL: bseti_i64_30:
761 ; RV64ZBS-NEXT: bseti a0, a0, 30
763 %or = or i64 %a, 1073741824
767 define i64 @bseti_i64_31(i64 %a) nounwind {
768 ; RV64I-LABEL: bseti_i64_31:
770 ; RV64I-NEXT: li a1, 1
771 ; RV64I-NEXT: slli a1, a1, 31
772 ; RV64I-NEXT: or a0, a0, a1
775 ; RV64ZBS-LABEL: bseti_i64_31:
777 ; RV64ZBS-NEXT: bseti a0, a0, 31
779 %or = or i64 %a, 2147483648
783 define i64 @bseti_i64_62(i64 %a) nounwind {
784 ; RV64I-LABEL: bseti_i64_62:
786 ; RV64I-NEXT: li a1, 1
787 ; RV64I-NEXT: slli a1, a1, 62
788 ; RV64I-NEXT: or a0, a0, a1
791 ; RV64ZBS-LABEL: bseti_i64_62:
793 ; RV64ZBS-NEXT: bseti a0, a0, 62
795 %or = or i64 %a, 4611686018427387904
799 define i64 @bseti_i64_63(i64 %a) nounwind {
800 ; RV64I-LABEL: bseti_i64_63:
802 ; RV64I-NEXT: li a1, -1
803 ; RV64I-NEXT: slli a1, a1, 63
804 ; RV64I-NEXT: or a0, a0, a1
807 ; RV64ZBS-LABEL: bseti_i64_63:
809 ; RV64ZBS-NEXT: bseti a0, a0, 63
811 %or = or i64 %a, 9223372036854775808
815 define signext i32 @binvi_i32_10(i32 signext %a) nounwind {
816 ; CHECK-LABEL: binvi_i32_10:
818 ; CHECK-NEXT: xori a0, a0, 1024
820 %xor = xor i32 %a, 1024
824 define signext i32 @binvi_i32_11(i32 signext %a) nounwind {
825 ; RV64I-LABEL: binvi_i32_11:
827 ; RV64I-NEXT: li a1, 1
828 ; RV64I-NEXT: slli a1, a1, 11
829 ; RV64I-NEXT: xor a0, a0, a1
832 ; RV64ZBS-LABEL: binvi_i32_11:
834 ; RV64ZBS-NEXT: binvi a0, a0, 11
836 %xor = xor i32 %a, 2048
840 define signext i32 @binvi_i32_30(i32 signext %a) nounwind {
841 ; RV64I-LABEL: binvi_i32_30:
843 ; RV64I-NEXT: lui a1, 262144
844 ; RV64I-NEXT: xor a0, a0, a1
847 ; RV64ZBS-LABEL: binvi_i32_30:
849 ; RV64ZBS-NEXT: binvi a0, a0, 30
851 %xor = xor i32 %a, 1073741824
855 define signext i32 @binvi_i32_31(i32 signext %a) nounwind {
856 ; CHECK-LABEL: binvi_i32_31:
858 ; CHECK-NEXT: lui a1, 524288
859 ; CHECK-NEXT: xor a0, a0, a1
861 %xor = xor i32 %a, 2147483648
865 define i64 @binvi_i64_10(i64 %a) nounwind {
866 ; CHECK-LABEL: binvi_i64_10:
868 ; CHECK-NEXT: xori a0, a0, 1024
870 %xor = xor i64 %a, 1024
874 define i64 @binvi_i64_11(i64 %a) nounwind {
875 ; RV64I-LABEL: binvi_i64_11:
877 ; RV64I-NEXT: li a1, 1
878 ; RV64I-NEXT: slli a1, a1, 11
879 ; RV64I-NEXT: xor a0, a0, a1
882 ; RV64ZBS-LABEL: binvi_i64_11:
884 ; RV64ZBS-NEXT: binvi a0, a0, 11
886 %xor = xor i64 %a, 2048
890 define i64 @binvi_i64_30(i64 %a) nounwind {
891 ; RV64I-LABEL: binvi_i64_30:
893 ; RV64I-NEXT: lui a1, 262144
894 ; RV64I-NEXT: xor a0, a0, a1
897 ; RV64ZBS-LABEL: binvi_i64_30:
899 ; RV64ZBS-NEXT: binvi a0, a0, 30
901 %xor = xor i64 %a, 1073741824
905 define i64 @binvi_i64_31(i64 %a) nounwind {
906 ; RV64I-LABEL: binvi_i64_31:
908 ; RV64I-NEXT: li a1, 1
909 ; RV64I-NEXT: slli a1, a1, 31
910 ; RV64I-NEXT: xor a0, a0, a1
913 ; RV64ZBS-LABEL: binvi_i64_31:
915 ; RV64ZBS-NEXT: binvi a0, a0, 31
917 %xor = xor i64 %a, 2147483648
921 define i64 @binvi_i64_62(i64 %a) nounwind {
922 ; RV64I-LABEL: binvi_i64_62:
924 ; RV64I-NEXT: li a1, 1
925 ; RV64I-NEXT: slli a1, a1, 62
926 ; RV64I-NEXT: xor a0, a0, a1
929 ; RV64ZBS-LABEL: binvi_i64_62:
931 ; RV64ZBS-NEXT: binvi a0, a0, 62
933 %xor = xor i64 %a, 4611686018427387904
937 define i64 @binvi_i64_63(i64 %a) nounwind {
938 ; RV64I-LABEL: binvi_i64_63:
940 ; RV64I-NEXT: li a1, -1
941 ; RV64I-NEXT: slli a1, a1, 63
942 ; RV64I-NEXT: xor a0, a0, a1
945 ; RV64ZBS-LABEL: binvi_i64_63:
947 ; RV64ZBS-NEXT: binvi a0, a0, 63
949 %xor = xor i64 %a, 9223372036854775808
953 define i64 @xor_i64_large(i64 %a) nounwind {
954 ; RV64I-LABEL: xor_i64_large:
956 ; RV64I-NEXT: li a1, 1
957 ; RV64I-NEXT: slli a1, a1, 32
958 ; RV64I-NEXT: addi a1, a1, 1
959 ; RV64I-NEXT: xor a0, a0, a1
962 ; RV64ZBS-LABEL: xor_i64_large:
964 ; RV64ZBS-NEXT: binvi a0, a0, 0
965 ; RV64ZBS-NEXT: binvi a0, a0, 32
967 %xor = xor i64 %a, 4294967297
971 define i64 @xor_i64_4099(i64 %a) nounwind {
972 ; RV64I-LABEL: xor_i64_4099:
974 ; RV64I-NEXT: lui a1, 1
975 ; RV64I-NEXT: addiw a1, a1, 3
976 ; RV64I-NEXT: xor a0, a0, a1
979 ; RV64ZBS-LABEL: xor_i64_4099:
981 ; RV64ZBS-NEXT: xori a0, a0, 3
982 ; RV64ZBS-NEXT: binvi a0, a0, 12
984 %xor = xor i64 %a, 4099
988 define i64 @xor_i64_96(i64 %a) nounwind {
989 ; CHECK-LABEL: xor_i64_96:
991 ; CHECK-NEXT: xori a0, a0, 96
993 %xor = xor i64 %a, 96
997 define i64 @or_i64_large(i64 %a) nounwind {
998 ; RV64I-LABEL: or_i64_large:
1000 ; RV64I-NEXT: li a1, 1
1001 ; RV64I-NEXT: slli a1, a1, 32
1002 ; RV64I-NEXT: addi a1, a1, 1
1003 ; RV64I-NEXT: or a0, a0, a1
1006 ; RV64ZBS-LABEL: or_i64_large:
1008 ; RV64ZBS-NEXT: bseti a0, a0, 0
1009 ; RV64ZBS-NEXT: bseti a0, a0, 32
1011 %or = or i64 %a, 4294967297
1015 define i64 @xor_i64_66901(i64 %a) nounwind {
1016 ; RV64I-LABEL: xor_i64_66901:
1018 ; RV64I-NEXT: lui a1, 16
1019 ; RV64I-NEXT: addiw a1, a1, 1365
1020 ; RV64I-NEXT: xor a0, a0, a1
1023 ; RV64ZBS-LABEL: xor_i64_66901:
1025 ; RV64ZBS-NEXT: xori a0, a0, 1365
1026 ; RV64ZBS-NEXT: binvi a0, a0, 16
1028 %xor = xor i64 %a, 66901
1032 define i64 @or_i64_4099(i64 %a) nounwind {
1033 ; RV64I-LABEL: or_i64_4099:
1035 ; RV64I-NEXT: lui a1, 1
1036 ; RV64I-NEXT: addiw a1, a1, 3
1037 ; RV64I-NEXT: or a0, a0, a1
1040 ; RV64ZBS-LABEL: or_i64_4099:
1042 ; RV64ZBS-NEXT: ori a0, a0, 3
1043 ; RV64ZBS-NEXT: bseti a0, a0, 12
1045 %or = or i64 %a, 4099
1049 define i64 @or_i64_96(i64 %a) nounwind {
1050 ; CHECK-LABEL: or_i64_96:
1052 ; CHECK-NEXT: ori a0, a0, 96
1058 define i64 @or_i64_66901(i64 %a) nounwind {
1059 ; RV64I-LABEL: or_i64_66901:
1061 ; RV64I-NEXT: lui a1, 16
1062 ; RV64I-NEXT: addiw a1, a1, 1365
1063 ; RV64I-NEXT: or a0, a0, a1
1066 ; RV64ZBS-LABEL: or_i64_66901:
1068 ; RV64ZBS-NEXT: ori a0, a0, 1365
1069 ; RV64ZBS-NEXT: bseti a0, a0, 16
1071 %or = or i64 %a, 66901
1075 define signext i32 @bset_trailing_ones_i32_mask(i32 signext %a) nounwind {
1076 ; RV64I-LABEL: bset_trailing_ones_i32_mask:
1078 ; RV64I-NEXT: li a1, -1
1079 ; RV64I-NEXT: sllw a0, a1, a0
1080 ; RV64I-NEXT: not a0, a0
1083 ; RV64ZBS-LABEL: bset_trailing_ones_i32_mask:
1085 ; RV64ZBS-NEXT: andi a0, a0, 31
1086 ; RV64ZBS-NEXT: bset a0, zero, a0
1087 ; RV64ZBS-NEXT: addi a0, a0, -1
1089 %and = and i32 %a, 31
1090 %shift = shl nsw i32 -1, %and
1091 %not = xor i32 %shift, -1
1095 define signext i32 @bset_trailing_ones_i32_no_mask(i32 signext %a) nounwind {
1096 ; RV64I-LABEL: bset_trailing_ones_i32_no_mask:
1098 ; RV64I-NEXT: li a1, -1
1099 ; RV64I-NEXT: sllw a0, a1, a0
1100 ; RV64I-NEXT: not a0, a0
1103 ; RV64ZBS-LABEL: bset_trailing_ones_i32_no_mask:
1105 ; RV64ZBS-NEXT: bset a0, zero, a0
1106 ; RV64ZBS-NEXT: addiw a0, a0, -1
1108 %shift = shl nsw i32 -1, %a
1109 %not = xor i32 %shift, -1
1113 define signext i64 @bset_trailing_ones_i64_mask(i64 signext %a) nounwind {
1114 ; RV64I-LABEL: bset_trailing_ones_i64_mask:
1116 ; RV64I-NEXT: li a1, -1
1117 ; RV64I-NEXT: sll a0, a1, a0
1118 ; RV64I-NEXT: not a0, a0
1121 ; RV64ZBS-LABEL: bset_trailing_ones_i64_mask:
1123 ; RV64ZBS-NEXT: bset a0, zero, a0
1124 ; RV64ZBS-NEXT: addi a0, a0, -1
1126 %and = and i64 %a, 63
1127 %shift = shl nsw i64 -1, %and
1128 %not = xor i64 %shift, -1
1132 define signext i64 @bset_trailing_ones_i64_no_mask(i64 signext %a) nounwind {
1133 ; RV64I-LABEL: bset_trailing_ones_i64_no_mask:
1135 ; RV64I-NEXT: li a1, -1
1136 ; RV64I-NEXT: sll a0, a1, a0
1137 ; RV64I-NEXT: not a0, a0
1140 ; RV64ZBS-LABEL: bset_trailing_ones_i64_no_mask:
1142 ; RV64ZBS-NEXT: bset a0, zero, a0
1143 ; RV64ZBS-NEXT: addi a0, a0, -1
1145 %shift = shl nsw i64 -1, %a
1146 %not = xor i64 %shift, -1
1150 define i1 @icmp_eq_pow2(i32 signext %x) nounwind {
1151 ; RV64I-LABEL: icmp_eq_pow2:
1153 ; RV64I-NEXT: lui a1, 8
1154 ; RV64I-NEXT: xor a0, a0, a1
1155 ; RV64I-NEXT: seqz a0, a0
1158 ; RV64ZBS-LABEL: icmp_eq_pow2:
1160 ; RV64ZBS-NEXT: binvi a0, a0, 15
1161 ; RV64ZBS-NEXT: seqz a0, a0
1163 %cmp = icmp eq i32 %x, 32768
1167 define i1 @icmp_eq_pow2_64(i64 %x) nounwind {
1168 ; RV64I-LABEL: icmp_eq_pow2_64:
1170 ; RV64I-NEXT: li a1, 1
1171 ; RV64I-NEXT: slli a1, a1, 40
1172 ; RV64I-NEXT: xor a0, a0, a1
1173 ; RV64I-NEXT: seqz a0, a0
1176 ; RV64ZBS-LABEL: icmp_eq_pow2_64:
1178 ; RV64ZBS-NEXT: binvi a0, a0, 40
1179 ; RV64ZBS-NEXT: seqz a0, a0
1181 %cmp = icmp eq i64 %x, 1099511627776
1185 define i1 @icmp_ne_pow2(i32 signext %x) nounwind {
1186 ; RV64I-LABEL: icmp_ne_pow2:
1188 ; RV64I-NEXT: lui a1, 8
1189 ; RV64I-NEXT: xor a0, a0, a1
1190 ; RV64I-NEXT: seqz a0, a0
1193 ; RV64ZBS-LABEL: icmp_ne_pow2:
1195 ; RV64ZBS-NEXT: binvi a0, a0, 15
1196 ; RV64ZBS-NEXT: seqz a0, a0
1198 %cmp = icmp eq i32 %x, 32768
1202 define i1 @icmp_eq_nonpow2(i32 signext %x) nounwind {
1203 ; CHECK-LABEL: icmp_eq_nonpow2:
1205 ; CHECK-NEXT: lui a1, 8
1206 ; CHECK-NEXT: addiw a1, a1, -1
1207 ; CHECK-NEXT: xor a0, a0, a1
1208 ; CHECK-NEXT: seqz a0, a0
1210 %cmp = icmp eq i32 %x, 32767
1214 define signext i32 @fold_sextinreg_shl_to_sllw(i64 %x) nounwind {
1215 ; CHECK-LABEL: fold_sextinreg_shl_to_sllw:
1216 ; CHECK: # %bb.0: # %entry
1217 ; CHECK-NEXT: li a1, 1
1218 ; CHECK-NEXT: sllw a0, a1, a0
1221 %mask = and i64 %x, 31
1222 %shl = shl i64 1, %mask
1223 %trunc = trunc i64 %shl to i32
1227 define signext i32 @fold_sextinreg_shl_to_sllw_large_shamt(i64 %x) nounwind {
1228 ; RV64I-LABEL: fold_sextinreg_shl_to_sllw_large_shamt:
1229 ; RV64I: # %bb.0: # %entry
1230 ; RV64I-NEXT: li a1, 1
1231 ; RV64I-NEXT: sll a0, a1, a0
1232 ; RV64I-NEXT: sext.w a0, a0
1235 ; RV64ZBS-LABEL: fold_sextinreg_shl_to_sllw_large_shamt:
1236 ; RV64ZBS: # %bb.0: # %entry
1237 ; RV64ZBS-NEXT: bset a0, zero, a0
1238 ; RV64ZBS-NEXT: sext.w a0, a0
1241 %mask = and i64 %x, 63
1242 %shl = shl i64 1, %mask
1243 %trunc = trunc i64 %shl to i32