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-prefixes=CHECK,RV32I
4 ; RUN: llc -mtriple=riscv32 -mattr=+zbs -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s -check-prefixes=CHECK,RV32ZBS
7 define i32 @bclr_i32(i32 %a, i32 %b) nounwind {
8 ; RV32I-LABEL: bclr_i32:
10 ; RV32I-NEXT: li a2, 1
11 ; RV32I-NEXT: sll a1, a2, a1
12 ; RV32I-NEXT: not a1, a1
13 ; RV32I-NEXT: and a0, a1, a0
16 ; RV32ZBS-LABEL: bclr_i32:
18 ; RV32ZBS-NEXT: bclr a0, a0, a1
21 %shl = shl nuw i32 1, %and
22 %neg = xor i32 %shl, -1
23 %and1 = and i32 %neg, %a
27 define i32 @bclr_i32_no_mask(i32 %a, i32 %b) nounwind {
28 ; RV32I-LABEL: bclr_i32_no_mask:
30 ; RV32I-NEXT: li a2, 1
31 ; RV32I-NEXT: sll a1, a2, a1
32 ; RV32I-NEXT: not a1, a1
33 ; RV32I-NEXT: and a0, a1, a0
36 ; RV32ZBS-LABEL: bclr_i32_no_mask:
38 ; RV32ZBS-NEXT: bclr a0, a0, a1
40 %shl = shl nuw i32 1, %b
41 %neg = xor i32 %shl, -1
42 %and1 = and i32 %neg, %a
46 define i64 @bclr_i64(i64 %a, i64 %b) nounwind {
47 ; RV32I-LABEL: bclr_i64:
49 ; RV32I-NEXT: li a3, 1
50 ; RV32I-NEXT: sll a4, a3, a2
51 ; RV32I-NEXT: andi a2, a2, 63
52 ; RV32I-NEXT: addi a5, a2, -32
53 ; RV32I-NEXT: slti a5, a5, 0
54 ; RV32I-NEXT: neg a6, a5
55 ; RV32I-NEXT: and a4, a6, a4
56 ; RV32I-NEXT: sll a2, a3, a2
57 ; RV32I-NEXT: addi a5, a5, -1
58 ; RV32I-NEXT: and a2, a5, a2
59 ; RV32I-NEXT: not a3, a4
60 ; RV32I-NEXT: not a2, a2
61 ; RV32I-NEXT: and a0, a3, a0
62 ; RV32I-NEXT: and a1, a2, a1
65 ; RV32ZBS-LABEL: bclr_i64:
67 ; RV32ZBS-NEXT: andi a3, a2, 63
68 ; RV32ZBS-NEXT: addi a4, a3, -32
69 ; RV32ZBS-NEXT: slti a4, a4, 0
70 ; RV32ZBS-NEXT: neg a5, a4
71 ; RV32ZBS-NEXT: bset a2, zero, a2
72 ; RV32ZBS-NEXT: and a2, a5, a2
73 ; RV32ZBS-NEXT: bset a3, zero, a3
74 ; RV32ZBS-NEXT: addi a4, a4, -1
75 ; RV32ZBS-NEXT: and a3, a4, a3
76 ; RV32ZBS-NEXT: not a3, a3
77 ; RV32ZBS-NEXT: not a2, a2
78 ; RV32ZBS-NEXT: and a0, a2, a0
79 ; RV32ZBS-NEXT: and a1, a3, a1
82 %shl = shl nuw i64 1, %and
83 %neg = xor i64 %shl, -1
84 %and1 = and i64 %neg, %a
88 define i32 @bset_i32(i32 %a, i32 %b) nounwind {
89 ; RV32I-LABEL: bset_i32:
91 ; RV32I-NEXT: li a2, 1
92 ; RV32I-NEXT: sll a1, a2, a1
93 ; RV32I-NEXT: or a0, a1, a0
96 ; RV32ZBS-LABEL: bset_i32:
98 ; RV32ZBS-NEXT: bset a0, a0, a1
100 %and = and i32 %b, 31
101 %shl = shl nuw i32 1, %and
102 %or = or i32 %shl, %a
106 define i32 @bset_i32_no_mask(i32 %a, i32 %b) nounwind {
107 ; RV32I-LABEL: bset_i32_no_mask:
109 ; RV32I-NEXT: li a2, 1
110 ; RV32I-NEXT: sll a1, a2, a1
111 ; RV32I-NEXT: or a0, a1, a0
114 ; RV32ZBS-LABEL: bset_i32_no_mask:
116 ; RV32ZBS-NEXT: bset a0, a0, a1
118 %shl = shl nuw i32 1, %b
119 %or = or i32 %shl, %a
123 ; We can use bsetw for 1 << x by setting the first source to zero.
124 define signext i32 @bset_i32_zero(i32 signext %a) nounwind {
125 ; RV32I-LABEL: bset_i32_zero:
127 ; RV32I-NEXT: li a1, 1
128 ; RV32I-NEXT: sll a0, a1, a0
131 ; RV32ZBS-LABEL: bset_i32_zero:
133 ; RV32ZBS-NEXT: bset a0, zero, a0
139 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
140 ; don't have yet any matching bit manipulation instructions on RV32.
141 ; This test is presented here in case future expansions of the Bitmanip
142 ; extensions introduce instructions suitable for this pattern.
144 define i64 @bset_i64(i64 %a, i64 %b) nounwind {
145 ; RV32I-LABEL: bset_i64:
147 ; RV32I-NEXT: li a3, 1
148 ; RV32I-NEXT: sll a2, a3, a2
149 ; RV32I-NEXT: srai a3, a2, 31
150 ; RV32I-NEXT: or a0, a2, a0
151 ; RV32I-NEXT: or a1, a3, a1
154 ; RV32ZBS-LABEL: bset_i64:
156 ; RV32ZBS-NEXT: bset a3, zero, a2
157 ; RV32ZBS-NEXT: srai a3, a3, 31
158 ; RV32ZBS-NEXT: bset a0, a0, a2
159 ; RV32ZBS-NEXT: or a1, a3, a1
161 %1 = trunc i64 %b to i32
162 %conv = and i32 %1, 63
163 %shl = shl nuw i32 1, %conv
164 %conv1 = sext i32 %shl to i64
165 %or = or i64 %conv1, %a
169 define signext i64 @bset_i64_zero(i64 signext %a) nounwind {
170 ; RV32I-LABEL: bset_i64_zero:
172 ; RV32I-NEXT: li a1, 1
173 ; RV32I-NEXT: sll a1, a1, a0
174 ; RV32I-NEXT: addi a0, a0, -32
175 ; RV32I-NEXT: slti a2, a0, 0
176 ; RV32I-NEXT: neg a0, a2
177 ; RV32I-NEXT: and a0, a0, a1
178 ; RV32I-NEXT: addi a2, a2, -1
179 ; RV32I-NEXT: and a1, a2, a1
182 ; RV32ZBS-LABEL: bset_i64_zero:
184 ; RV32ZBS-NEXT: addi a1, a0, -32
185 ; RV32ZBS-NEXT: slti a1, a1, 0
186 ; RV32ZBS-NEXT: neg a2, a1
187 ; RV32ZBS-NEXT: bset a3, zero, a0
188 ; RV32ZBS-NEXT: and a0, a2, a3
189 ; RV32ZBS-NEXT: addi a1, a1, -1
190 ; RV32ZBS-NEXT: and a1, a1, a3
196 define i32 @binv_i32(i32 %a, i32 %b) nounwind {
197 ; RV32I-LABEL: binv_i32:
199 ; RV32I-NEXT: li a2, 1
200 ; RV32I-NEXT: sll a1, a2, a1
201 ; RV32I-NEXT: xor a0, a1, a0
204 ; RV32ZBS-LABEL: binv_i32:
206 ; RV32ZBS-NEXT: binv a0, a0, a1
208 %and = and i32 %b, 31
209 %shl = shl nuw i32 1, %and
210 %xor = xor i32 %shl, %a
214 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
215 ; don't have yet any matching bit manipulation instructions on RV32.
216 ; This test is presented here in case future expansions of the Bitmanip
217 ; extensions introduce instructions suitable for this pattern.
219 define i64 @binv_i64(i64 %a, i64 %b) nounwind {
220 ; RV32I-LABEL: binv_i64:
222 ; RV32I-NEXT: li a3, 1
223 ; RV32I-NEXT: sll a2, a3, a2
224 ; RV32I-NEXT: srai a3, a2, 31
225 ; RV32I-NEXT: xor a0, a2, a0
226 ; RV32I-NEXT: xor a1, a3, a1
229 ; RV32ZBS-LABEL: binv_i64:
231 ; RV32ZBS-NEXT: bset a3, zero, a2
232 ; RV32ZBS-NEXT: srai a3, a3, 31
233 ; RV32ZBS-NEXT: binv a0, a0, a2
234 ; RV32ZBS-NEXT: xor a1, a3, a1
236 %1 = trunc i64 %b to i32
237 %conv = and i32 %1, 63
238 %shl = shl nuw i32 1, %conv
239 %conv1 = sext i32 %shl to i64
240 %xor = xor i64 %conv1, %a
244 define i32 @bext_i32(i32 %a, i32 %b) nounwind {
245 ; RV32I-LABEL: bext_i32:
247 ; RV32I-NEXT: srl a0, a0, a1
248 ; RV32I-NEXT: andi a0, a0, 1
251 ; RV32ZBS-LABEL: bext_i32:
253 ; RV32ZBS-NEXT: bext a0, a0, a1
255 %and = and i32 %b, 31
256 %shr = lshr i32 %a, %and
257 %and1 = and i32 %shr, 1
261 define i32 @bext_i32_no_mask(i32 %a, i32 %b) nounwind {
262 ; RV32I-LABEL: bext_i32_no_mask:
264 ; RV32I-NEXT: srl a0, a0, a1
265 ; RV32I-NEXT: andi a0, a0, 1
268 ; RV32ZBS-LABEL: bext_i32_no_mask:
270 ; RV32ZBS-NEXT: bext a0, a0, a1
272 %shr = lshr i32 %a, %b
273 %and1 = and i32 %shr, 1
277 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
278 ; don't have yet any matching bit manipulation instructions on RV32.
279 ; This test is presented here in case future expansions of the Bitmanip
280 ; extensions introduce instructions suitable for this pattern.
282 define i64 @bext_i64(i64 %a, i64 %b) nounwind {
283 ; CHECK-LABEL: bext_i64:
285 ; CHECK-NEXT: andi a3, a2, 63
286 ; CHECK-NEXT: addi a4, a3, -32
287 ; CHECK-NEXT: bltz a4, .LBB12_2
288 ; CHECK-NEXT: # %bb.1:
289 ; CHECK-NEXT: srl a0, a1, a3
290 ; CHECK-NEXT: j .LBB12_3
291 ; CHECK-NEXT: .LBB12_2:
292 ; CHECK-NEXT: srl a0, a0, a2
293 ; CHECK-NEXT: slli a1, a1, 1
294 ; CHECK-NEXT: not a2, a3
295 ; CHECK-NEXT: sll a1, a1, a2
296 ; CHECK-NEXT: or a0, a0, a1
297 ; CHECK-NEXT: .LBB12_3:
298 ; CHECK-NEXT: andi a0, a0, 1
299 ; CHECK-NEXT: li a1, 0
301 %conv = and i64 %b, 63
302 %shr = lshr i64 %a, %conv
303 %and1 = and i64 %shr, 1
307 define i32 @bexti_i32(i32 %a) nounwind {
308 ; RV32I-LABEL: bexti_i32:
310 ; RV32I-NEXT: slli a0, a0, 26
311 ; RV32I-NEXT: srli a0, a0, 31
314 ; RV32ZBS-LABEL: bexti_i32:
316 ; RV32ZBS-NEXT: bexti a0, a0, 5
318 %shr = lshr i32 %a, 5
319 %and = and i32 %shr, 1
323 define i64 @bexti_i64(i64 %a) nounwind {
324 ; RV32I-LABEL: bexti_i64:
326 ; RV32I-NEXT: slli a0, a0, 26
327 ; RV32I-NEXT: srli a0, a0, 31
328 ; RV32I-NEXT: li a1, 0
331 ; RV32ZBS-LABEL: bexti_i64:
333 ; RV32ZBS-NEXT: bexti a0, a0, 5
334 ; RV32ZBS-NEXT: li a1, 0
336 %shr = lshr i64 %a, 5
337 %and = and i64 %shr, 1
341 define signext i32 @bexti_i32_cmp(i32 signext %a) nounwind {
342 ; RV32I-LABEL: bexti_i32_cmp:
344 ; RV32I-NEXT: slli a0, a0, 26
345 ; RV32I-NEXT: srli a0, a0, 31
348 ; RV32ZBS-LABEL: bexti_i32_cmp:
350 ; RV32ZBS-NEXT: bexti a0, a0, 5
352 %and = and i32 %a, 32
353 %cmp = icmp ne i32 %and, 0
354 %zext = zext i1 %cmp to i32
358 define i64 @bexti_i64_cmp(i64 %a) nounwind {
359 ; RV32I-LABEL: bexti_i64_cmp:
361 ; RV32I-NEXT: slli a0, a0, 26
362 ; RV32I-NEXT: srli a0, a0, 31
363 ; RV32I-NEXT: li a1, 0
366 ; RV32ZBS-LABEL: bexti_i64_cmp:
368 ; RV32ZBS-NEXT: bexti a0, a0, 5
369 ; RV32ZBS-NEXT: li a1, 0
371 %and = and i64 %a, 32
372 %cmp = icmp ne i64 %and, 0
373 %zext = zext i1 %cmp to i64
377 define i32 @bclri_i32_10(i32 %a) nounwind {
378 ; CHECK-LABEL: bclri_i32_10:
380 ; CHECK-NEXT: andi a0, a0, -1025
382 %and = and i32 %a, -1025
386 define i32 @bclri_i32_11(i32 %a) nounwind {
387 ; RV32I-LABEL: bclri_i32_11:
389 ; RV32I-NEXT: lui a1, 1048575
390 ; RV32I-NEXT: addi a1, a1, 2047
391 ; RV32I-NEXT: and a0, a0, a1
394 ; RV32ZBS-LABEL: bclri_i32_11:
396 ; RV32ZBS-NEXT: bclri a0, a0, 11
398 %and = and i32 %a, -2049
402 define i32 @bclri_i32_30(i32 %a) nounwind {
403 ; RV32I-LABEL: bclri_i32_30:
405 ; RV32I-NEXT: lui a1, 786432
406 ; RV32I-NEXT: addi a1, a1, -1
407 ; RV32I-NEXT: and a0, a0, a1
410 ; RV32ZBS-LABEL: bclri_i32_30:
412 ; RV32ZBS-NEXT: bclri a0, a0, 30
414 %and = and i32 %a, -1073741825
418 define i32 @bclri_i32_31(i32 %a) nounwind {
419 ; RV32I-LABEL: bclri_i32_31:
421 ; RV32I-NEXT: slli a0, a0, 1
422 ; RV32I-NEXT: srli a0, a0, 1
425 ; RV32ZBS-LABEL: bclri_i32_31:
427 ; RV32ZBS-NEXT: bclri a0, a0, 31
429 %and = and i32 %a, -2147483649
433 define i32 @bclri_i32_large0(i32 %a) nounwind {
434 ; RV32I-LABEL: bclri_i32_large0:
436 ; RV32I-NEXT: lui a1, 1044480
437 ; RV32I-NEXT: addi a1, a1, -256
438 ; RV32I-NEXT: and a0, a0, a1
441 ; RV32ZBS-LABEL: bclri_i32_large0:
443 ; RV32ZBS-NEXT: andi a0, a0, -256
444 ; RV32ZBS-NEXT: bclri a0, a0, 24
446 %and = and i32 %a, -16777472
450 define i32 @bclri_i32_large1(i32 %a) nounwind {
451 ; RV32I-LABEL: bclri_i32_large1:
453 ; RV32I-NEXT: lui a1, 1044464
454 ; RV32I-NEXT: addi a1, a1, -1
455 ; RV32I-NEXT: and a0, a0, a1
458 ; RV32ZBS-LABEL: bclri_i32_large1:
460 ; RV32ZBS-NEXT: bclri a0, a0, 16
461 ; RV32ZBS-NEXT: bclri a0, a0, 24
463 %and = and i32 %a, -16842753
467 define i32 @bclri_i32_large2(i32 %0) {
468 ; RV32I-LABEL: bclri_i32_large2:
470 ; RV32I-NEXT: lui a1, 524288
471 ; RV32I-NEXT: addi a1, a1, -5
472 ; RV32I-NEXT: and a0, a0, a1
475 ; RV32ZBS-LABEL: bclri_i32_large2:
477 ; RV32ZBS-NEXT: bclri a0, a0, 2
478 ; RV32ZBS-NEXT: bclri a0, a0, 31
480 %2 = and i32 %0, 2147483643
484 define i32 @bclri_i32_large3(i32 %0) {
485 ; RV32I-LABEL: bclri_i32_large3:
487 ; RV32I-NEXT: lui a1, 524288
488 ; RV32I-NEXT: addi a1, a1, -6
489 ; RV32I-NEXT: and a0, a0, a1
492 ; RV32ZBS-LABEL: bclri_i32_large3:
494 ; RV32ZBS-NEXT: andi a0, a0, -6
495 ; RV32ZBS-NEXT: bclri a0, a0, 31
497 %2 = and i32 %0, 2147483642
501 define i32 @bseti_i32_10(i32 %a) nounwind {
502 ; CHECK-LABEL: bseti_i32_10:
504 ; CHECK-NEXT: ori a0, a0, 1024
506 %or = or i32 %a, 1024
510 define i32 @bseti_i32_11(i32 %a) nounwind {
511 ; RV32I-LABEL: bseti_i32_11:
513 ; RV32I-NEXT: li a1, 1
514 ; RV32I-NEXT: slli a1, a1, 11
515 ; RV32I-NEXT: or a0, a0, a1
518 ; RV32ZBS-LABEL: bseti_i32_11:
520 ; RV32ZBS-NEXT: bseti a0, a0, 11
522 %or = or i32 %a, 2048
526 define i32 @bseti_i32_30(i32 %a) nounwind {
527 ; RV32I-LABEL: bseti_i32_30:
529 ; RV32I-NEXT: lui a1, 262144
530 ; RV32I-NEXT: or a0, a0, a1
533 ; RV32ZBS-LABEL: bseti_i32_30:
535 ; RV32ZBS-NEXT: bseti a0, a0, 30
537 %or = or i32 %a, 1073741824
541 define i32 @bseti_i32_31(i32 %a) nounwind {
542 ; RV32I-LABEL: bseti_i32_31:
544 ; RV32I-NEXT: lui a1, 524288
545 ; RV32I-NEXT: or a0, a0, a1
548 ; RV32ZBS-LABEL: bseti_i32_31:
550 ; RV32ZBS-NEXT: bseti a0, a0, 31
552 %or = or i32 %a, 2147483648
556 define i32 @binvi_i32_10(i32 %a) nounwind {
557 ; CHECK-LABEL: binvi_i32_10:
559 ; CHECK-NEXT: xori a0, a0, 1024
561 %xor = xor i32 %a, 1024
565 define i32 @binvi_i32_11(i32 %a) nounwind {
566 ; RV32I-LABEL: binvi_i32_11:
568 ; RV32I-NEXT: li a1, 1
569 ; RV32I-NEXT: slli a1, a1, 11
570 ; RV32I-NEXT: xor a0, a0, a1
573 ; RV32ZBS-LABEL: binvi_i32_11:
575 ; RV32ZBS-NEXT: binvi a0, a0, 11
577 %xor = xor i32 %a, 2048
581 define i32 @binvi_i32_30(i32 %a) nounwind {
582 ; RV32I-LABEL: binvi_i32_30:
584 ; RV32I-NEXT: lui a1, 262144
585 ; RV32I-NEXT: xor a0, a0, a1
588 ; RV32ZBS-LABEL: binvi_i32_30:
590 ; RV32ZBS-NEXT: binvi a0, a0, 30
592 %xor = xor i32 %a, 1073741824
596 define i32 @binvi_i32_31(i32 %a) nounwind {
597 ; RV32I-LABEL: binvi_i32_31:
599 ; RV32I-NEXT: lui a1, 524288
600 ; RV32I-NEXT: xor a0, a0, a1
603 ; RV32ZBS-LABEL: binvi_i32_31:
605 ; RV32ZBS-NEXT: binvi a0, a0, 31
607 %xor = xor i32 %a, 2147483648
611 define i32 @xor_i32_4098(i32 %a) nounwind {
612 ; RV32I-LABEL: xor_i32_4098:
614 ; RV32I-NEXT: lui a1, 1
615 ; RV32I-NEXT: addi a1, a1, 2
616 ; RV32I-NEXT: xor a0, a0, a1
619 ; RV32ZBS-LABEL: xor_i32_4098:
621 ; RV32ZBS-NEXT: binvi a0, a0, 1
622 ; RV32ZBS-NEXT: binvi a0, a0, 12
624 %xor = xor i32 %a, 4098
628 define i32 @xor_i32_4099(i32 %a) nounwind {
629 ; RV32I-LABEL: xor_i32_4099:
631 ; RV32I-NEXT: lui a1, 1
632 ; RV32I-NEXT: addi a1, a1, 3
633 ; RV32I-NEXT: xor a0, a0, a1
636 ; RV32ZBS-LABEL: xor_i32_4099:
638 ; RV32ZBS-NEXT: xori a0, a0, 3
639 ; RV32ZBS-NEXT: binvi a0, a0, 12
641 %xor = xor i32 %a, 4099
645 define i32 @xor_i32_96(i32 %a) nounwind {
646 ; CHECK-LABEL: xor_i32_96:
648 ; CHECK-NEXT: xori a0, a0, 96
650 %xor = xor i32 %a, 96
654 define i32 @xor_i32_66901(i32 %a) nounwind {
655 ; RV32I-LABEL: xor_i32_66901:
657 ; RV32I-NEXT: lui a1, 16
658 ; RV32I-NEXT: addi a1, a1, 1365
659 ; RV32I-NEXT: xor a0, a0, a1
662 ; RV32ZBS-LABEL: xor_i32_66901:
664 ; RV32ZBS-NEXT: xori a0, a0, 1365
665 ; RV32ZBS-NEXT: binvi a0, a0, 16
667 %xor = xor i32 %a, 66901
671 define i32 @or_i32_4098(i32 %a) nounwind {
672 ; RV32I-LABEL: or_i32_4098:
674 ; RV32I-NEXT: lui a1, 1
675 ; RV32I-NEXT: addi a1, a1, 2
676 ; RV32I-NEXT: or a0, a0, a1
679 ; RV32ZBS-LABEL: or_i32_4098:
681 ; RV32ZBS-NEXT: bseti a0, a0, 1
682 ; RV32ZBS-NEXT: bseti a0, a0, 12
684 %or = or i32 %a, 4098
688 define i32 @or_i32_4099(i32 %a) nounwind {
689 ; RV32I-LABEL: or_i32_4099:
691 ; RV32I-NEXT: lui a1, 1
692 ; RV32I-NEXT: addi a1, a1, 3
693 ; RV32I-NEXT: or a0, a0, a1
696 ; RV32ZBS-LABEL: or_i32_4099:
698 ; RV32ZBS-NEXT: ori a0, a0, 3
699 ; RV32ZBS-NEXT: bseti a0, a0, 12
701 %or = or i32 %a, 4099
705 define i32 @or_i32_96(i32 %a) nounwind {
706 ; CHECK-LABEL: or_i32_96:
708 ; CHECK-NEXT: ori a0, a0, 96
714 define i32 @or_i32_66901(i32 %a) nounwind {
715 ; RV32I-LABEL: or_i32_66901:
717 ; RV32I-NEXT: lui a1, 16
718 ; RV32I-NEXT: addi a1, a1, 1365
719 ; RV32I-NEXT: or a0, a0, a1
722 ; RV32ZBS-LABEL: or_i32_66901:
724 ; RV32ZBS-NEXT: ori a0, a0, 1365
725 ; RV32ZBS-NEXT: bseti a0, a0, 16
727 %or = or i32 %a, 66901