1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s \
3 ; RUN: | FileCheck %s -check-prefixes=CHECK,RV64I
4 ; RUN: llc -mtriple=riscv64 -mattr=+m,+zba -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s -check-prefixes=CHECK,RV64ZBA,RV64ZBANOZBB
6 ; RUN: llc -mtriple=riscv64 -mattr=+m,+zba,+zbb -verify-machineinstrs < %s \
7 ; RUN: | FileCheck %s -check-prefixes=CHECK,RV64ZBA,RV64ZBAZBB
9 define i64 @slliuw(i64 %a) nounwind {
10 ; RV64I-LABEL: slliuw:
12 ; RV64I-NEXT: slli a0, a0, 32
13 ; RV64I-NEXT: srli a0, a0, 31
16 ; RV64ZBA-LABEL: slliuw:
18 ; RV64ZBA-NEXT: slli.uw a0, a0, 1
20 %conv1 = shl i64 %a, 1
21 %shl = and i64 %conv1, 8589934590
25 define i128 @slliuw_2(i32 signext %0, ptr %1) {
26 ; RV64I-LABEL: slliuw_2:
28 ; RV64I-NEXT: slli a0, a0, 32
29 ; RV64I-NEXT: srli a0, a0, 28
30 ; RV64I-NEXT: add a1, a1, a0
31 ; RV64I-NEXT: ld a0, 0(a1)
32 ; RV64I-NEXT: ld a1, 8(a1)
35 ; RV64ZBA-LABEL: slliuw_2:
37 ; RV64ZBA-NEXT: slli.uw a0, a0, 4
38 ; RV64ZBA-NEXT: add a1, a1, a0
39 ; RV64ZBA-NEXT: ld a0, 0(a1)
40 ; RV64ZBA-NEXT: ld a1, 8(a1)
42 %3 = zext i32 %0 to i64
43 %4 = getelementptr inbounds i128, ptr %1, i64 %3
44 %5 = load i128, ptr %4
48 define i64 @adduw(i64 %a, i64 %b) nounwind {
51 ; RV64I-NEXT: slli a1, a1, 32
52 ; RV64I-NEXT: srli a1, a1, 32
53 ; RV64I-NEXT: add a0, a1, a0
56 ; RV64ZBA-LABEL: adduw:
58 ; RV64ZBA-NEXT: add.uw a0, a1, a0
60 %and = and i64 %b, 4294967295
61 %add = add i64 %and, %a
65 define signext i8 @adduw_2(i32 signext %0, ptr %1) {
66 ; RV64I-LABEL: adduw_2:
68 ; RV64I-NEXT: slli a0, a0, 32
69 ; RV64I-NEXT: srli a0, a0, 32
70 ; RV64I-NEXT: add a0, a1, a0
71 ; RV64I-NEXT: lb a0, 0(a0)
74 ; RV64ZBA-LABEL: adduw_2:
76 ; RV64ZBA-NEXT: add.uw a0, a0, a1
77 ; RV64ZBA-NEXT: lb a0, 0(a0)
79 %3 = zext i32 %0 to i64
80 %4 = getelementptr inbounds i8, ptr %1, i64 %3
85 define i64 @zextw_i64(i64 %a) nounwind {
86 ; RV64I-LABEL: zextw_i64:
88 ; RV64I-NEXT: slli a0, a0, 32
89 ; RV64I-NEXT: srli a0, a0, 32
92 ; RV64ZBA-LABEL: zextw_i64:
94 ; RV64ZBA-NEXT: zext.w a0, a0
96 %and = and i64 %a, 4294967295
100 ; This makes sure targetShrinkDemandedConstant changes the and immmediate to
101 ; allow zext.w or slli+srli.
102 define i64 @zextw_demandedbits_i64(i64 %0) {
103 ; RV64I-LABEL: zextw_demandedbits_i64:
105 ; RV64I-NEXT: ori a0, a0, 1
106 ; RV64I-NEXT: slli a0, a0, 32
107 ; RV64I-NEXT: srli a0, a0, 32
110 ; RV64ZBA-LABEL: zextw_demandedbits_i64:
112 ; RV64ZBA-NEXT: ori a0, a0, 1
113 ; RV64ZBA-NEXT: zext.w a0, a0
115 %2 = and i64 %0, 4294967294
120 define signext i16 @sh1add(i64 %0, ptr %1) {
121 ; RV64I-LABEL: sh1add:
123 ; RV64I-NEXT: slli a0, a0, 1
124 ; RV64I-NEXT: add a0, a1, a0
125 ; RV64I-NEXT: lh a0, 0(a0)
128 ; RV64ZBA-LABEL: sh1add:
130 ; RV64ZBA-NEXT: sh1add a0, a0, a1
131 ; RV64ZBA-NEXT: lh a0, 0(a0)
133 %3 = getelementptr inbounds i16, ptr %1, i64 %0
134 %4 = load i16, ptr %3
138 define signext i32 @sh2add(i64 %0, ptr %1) {
139 ; RV64I-LABEL: sh2add:
141 ; RV64I-NEXT: slli a0, a0, 2
142 ; RV64I-NEXT: add a0, a1, a0
143 ; RV64I-NEXT: lw a0, 0(a0)
146 ; RV64ZBA-LABEL: sh2add:
148 ; RV64ZBA-NEXT: sh2add a0, a0, a1
149 ; RV64ZBA-NEXT: lw a0, 0(a0)
151 %3 = getelementptr inbounds i32, ptr %1, i64 %0
152 %4 = load i32, ptr %3
156 define i64 @sh3add(i64 %0, ptr %1) {
157 ; RV64I-LABEL: sh3add:
159 ; RV64I-NEXT: slli a0, a0, 3
160 ; RV64I-NEXT: add a0, a1, a0
161 ; RV64I-NEXT: ld a0, 0(a0)
164 ; RV64ZBA-LABEL: sh3add:
166 ; RV64ZBA-NEXT: sh3add a0, a0, a1
167 ; RV64ZBA-NEXT: ld a0, 0(a0)
169 %3 = getelementptr inbounds i64, ptr %1, i64 %0
170 %4 = load i64, ptr %3
174 define signext i16 @sh1adduw(i32 signext %0, ptr %1) {
175 ; RV64I-LABEL: sh1adduw:
177 ; RV64I-NEXT: slli a0, a0, 32
178 ; RV64I-NEXT: srli a0, a0, 31
179 ; RV64I-NEXT: add a0, a1, a0
180 ; RV64I-NEXT: lh a0, 0(a0)
183 ; RV64ZBA-LABEL: sh1adduw:
185 ; RV64ZBA-NEXT: sh1add.uw a0, a0, a1
186 ; RV64ZBA-NEXT: lh a0, 0(a0)
188 %3 = zext i32 %0 to i64
189 %4 = getelementptr inbounds i16, ptr %1, i64 %3
190 %5 = load i16, ptr %4
194 define i64 @sh1adduw_2(i64 %0, i64 %1) {
195 ; RV64I-LABEL: sh1adduw_2:
197 ; RV64I-NEXT: slli a0, a0, 32
198 ; RV64I-NEXT: srli a0, a0, 31
199 ; RV64I-NEXT: add a0, a0, a1
202 ; RV64ZBA-LABEL: sh1adduw_2:
204 ; RV64ZBA-NEXT: sh1add.uw a0, a0, a1
207 %4 = and i64 %3, 8589934590
212 define signext i32 @sh2adduw(i32 signext %0, ptr %1) {
213 ; RV64I-LABEL: sh2adduw:
215 ; RV64I-NEXT: slli a0, a0, 32
216 ; RV64I-NEXT: srli a0, a0, 30
217 ; RV64I-NEXT: add a0, a1, a0
218 ; RV64I-NEXT: lw a0, 0(a0)
221 ; RV64ZBA-LABEL: sh2adduw:
223 ; RV64ZBA-NEXT: sh2add.uw a0, a0, a1
224 ; RV64ZBA-NEXT: lw a0, 0(a0)
226 %3 = zext i32 %0 to i64
227 %4 = getelementptr inbounds i32, ptr %1, i64 %3
228 %5 = load i32, ptr %4
232 define i64 @sh2adduw_2(i64 %0, i64 %1) {
233 ; RV64I-LABEL: sh2adduw_2:
235 ; RV64I-NEXT: slli a0, a0, 32
236 ; RV64I-NEXT: srli a0, a0, 30
237 ; RV64I-NEXT: add a0, a0, a1
240 ; RV64ZBA-LABEL: sh2adduw_2:
242 ; RV64ZBA-NEXT: sh2add.uw a0, a0, a1
245 %4 = and i64 %3, 17179869180
250 define i64 @sh3adduw(i32 signext %0, ptr %1) {
251 ; RV64I-LABEL: sh3adduw:
253 ; RV64I-NEXT: slli a0, a0, 32
254 ; RV64I-NEXT: srli a0, a0, 29
255 ; RV64I-NEXT: add a0, a1, a0
256 ; RV64I-NEXT: ld a0, 0(a0)
259 ; RV64ZBA-LABEL: sh3adduw:
261 ; RV64ZBA-NEXT: sh3add.uw a0, a0, a1
262 ; RV64ZBA-NEXT: ld a0, 0(a0)
264 %3 = zext i32 %0 to i64
265 %4 = getelementptr inbounds i64, ptr %1, i64 %3
266 %5 = load i64, ptr %4
270 define i64 @sh3adduw_2(i64 %0, i64 %1) {
271 ; RV64I-LABEL: sh3adduw_2:
273 ; RV64I-NEXT: slli a0, a0, 32
274 ; RV64I-NEXT: srli a0, a0, 29
275 ; RV64I-NEXT: add a0, a0, a1
278 ; RV64ZBA-LABEL: sh3adduw_2:
280 ; RV64ZBA-NEXT: sh3add.uw a0, a0, a1
283 %4 = and i64 %3, 34359738360
288 ; Type legalization inserts a sext_inreg after the first add. That add will be
289 ; selected as sh2add which does not sign extend. SimplifyDemandedBits is unable
290 ; to remove the sext_inreg because it has multiple uses. The ashr will use the
291 ; sext_inreg to become sraiw. This leaves the sext_inreg only used by the shl.
292 ; If the shl is selected as sllw, we don't need the sext_inreg.
293 define i64 @sh2add_extra_sext(i32 %x, i32 %y, i32 %z) {
294 ; RV64I-LABEL: sh2add_extra_sext:
296 ; RV64I-NEXT: slli a0, a0, 2
297 ; RV64I-NEXT: add a0, a0, a1
298 ; RV64I-NEXT: sllw a1, a2, a0
299 ; RV64I-NEXT: sraiw a0, a0, 2
300 ; RV64I-NEXT: mul a0, a1, a0
303 ; RV64ZBA-LABEL: sh2add_extra_sext:
305 ; RV64ZBA-NEXT: sh2add a0, a0, a1
306 ; RV64ZBA-NEXT: sllw a1, a2, a0
307 ; RV64ZBA-NEXT: sraiw a0, a0, 2
308 ; RV64ZBA-NEXT: mul a0, a1, a0
314 %e = sext i32 %c to i64
315 %f = sext i32 %d to i64
320 define i64 @addmul6(i64 %a, i64 %b) {
321 ; RV64I-LABEL: addmul6:
323 ; RV64I-NEXT: li a2, 6
324 ; RV64I-NEXT: mul a0, a0, a2
325 ; RV64I-NEXT: add a0, a0, a1
328 ; RV64ZBA-LABEL: addmul6:
330 ; RV64ZBA-NEXT: sh1add a0, a0, a0
331 ; RV64ZBA-NEXT: sh1add a0, a0, a1
338 define i64 @addmul10(i64 %a, i64 %b) {
339 ; RV64I-LABEL: addmul10:
341 ; RV64I-NEXT: li a2, 10
342 ; RV64I-NEXT: mul a0, a0, a2
343 ; RV64I-NEXT: add a0, a0, a1
346 ; RV64ZBA-LABEL: addmul10:
348 ; RV64ZBA-NEXT: sh2add a0, a0, a0
349 ; RV64ZBA-NEXT: sh1add a0, a0, a1
356 define i64 @addmul12(i64 %a, i64 %b) {
357 ; RV64I-LABEL: addmul12:
359 ; RV64I-NEXT: li a2, 12
360 ; RV64I-NEXT: mul a0, a0, a2
361 ; RV64I-NEXT: add a0, a0, a1
364 ; RV64ZBA-LABEL: addmul12:
366 ; RV64ZBA-NEXT: sh1add a0, a0, a0
367 ; RV64ZBA-NEXT: sh2add a0, a0, a1
374 define i64 @addmul18(i64 %a, i64 %b) {
375 ; RV64I-LABEL: addmul18:
377 ; RV64I-NEXT: li a2, 18
378 ; RV64I-NEXT: mul a0, a0, a2
379 ; RV64I-NEXT: add a0, a0, a1
382 ; RV64ZBA-LABEL: addmul18:
384 ; RV64ZBA-NEXT: sh3add a0, a0, a0
385 ; RV64ZBA-NEXT: sh1add a0, a0, a1
392 define i64 @addmul20(i64 %a, i64 %b) {
393 ; RV64I-LABEL: addmul20:
395 ; RV64I-NEXT: li a2, 20
396 ; RV64I-NEXT: mul a0, a0, a2
397 ; RV64I-NEXT: add a0, a0, a1
400 ; RV64ZBA-LABEL: addmul20:
402 ; RV64ZBA-NEXT: sh2add a0, a0, a0
403 ; RV64ZBA-NEXT: sh2add a0, a0, a1
410 define i64 @addmul24(i64 %a, i64 %b) {
411 ; RV64I-LABEL: addmul24:
413 ; RV64I-NEXT: li a2, 24
414 ; RV64I-NEXT: mul a0, a0, a2
415 ; RV64I-NEXT: add a0, a0, a1
418 ; RV64ZBA-LABEL: addmul24:
420 ; RV64ZBA-NEXT: sh1add a0, a0, a0
421 ; RV64ZBA-NEXT: sh3add a0, a0, a1
428 define i64 @addmul36(i64 %a, i64 %b) {
429 ; RV64I-LABEL: addmul36:
431 ; RV64I-NEXT: li a2, 36
432 ; RV64I-NEXT: mul a0, a0, a2
433 ; RV64I-NEXT: add a0, a0, a1
436 ; RV64ZBA-LABEL: addmul36:
438 ; RV64ZBA-NEXT: sh3add a0, a0, a0
439 ; RV64ZBA-NEXT: sh2add a0, a0, a1
446 define i64 @addmul40(i64 %a, i64 %b) {
447 ; RV64I-LABEL: addmul40:
449 ; RV64I-NEXT: li a2, 40
450 ; RV64I-NEXT: mul a0, a0, a2
451 ; RV64I-NEXT: add a0, a0, a1
454 ; RV64ZBA-LABEL: addmul40:
456 ; RV64ZBA-NEXT: sh2add a0, a0, a0
457 ; RV64ZBA-NEXT: sh3add a0, a0, a1
464 define i64 @addmul72(i64 %a, i64 %b) {
465 ; RV64I-LABEL: addmul72:
467 ; RV64I-NEXT: li a2, 72
468 ; RV64I-NEXT: mul a0, a0, a2
469 ; RV64I-NEXT: add a0, a0, a1
472 ; RV64ZBA-LABEL: addmul72:
474 ; RV64ZBA-NEXT: sh3add a0, a0, a0
475 ; RV64ZBA-NEXT: sh3add a0, a0, a1
482 define i64 @mul96(i64 %a) {
483 ; RV64I-LABEL: mul96:
485 ; RV64I-NEXT: li a1, 96
486 ; RV64I-NEXT: mul a0, a0, a1
489 ; RV64ZBA-LABEL: mul96:
491 ; RV64ZBA-NEXT: sh1add a0, a0, a0
492 ; RV64ZBA-NEXT: slli a0, a0, 5
498 define i64 @mul160(i64 %a) {
499 ; RV64I-LABEL: mul160:
501 ; RV64I-NEXT: li a1, 160
502 ; RV64I-NEXT: mul a0, a0, a1
505 ; RV64ZBA-LABEL: mul160:
507 ; RV64ZBA-NEXT: sh2add a0, a0, a0
508 ; RV64ZBA-NEXT: slli a0, a0, 5
514 define i64 @mul288(i64 %a) {
515 ; RV64I-LABEL: mul288:
517 ; RV64I-NEXT: li a1, 288
518 ; RV64I-NEXT: mul a0, a0, a1
521 ; RV64ZBA-LABEL: mul288:
523 ; RV64ZBA-NEXT: sh3add a0, a0, a0
524 ; RV64ZBA-NEXT: slli a0, a0, 5
530 define i64 @zext_mul96(i32 signext %a) {
531 ; RV64I-LABEL: zext_mul96:
533 ; RV64I-NEXT: li a1, 3
534 ; RV64I-NEXT: slli a1, a1, 37
535 ; RV64I-NEXT: slli a0, a0, 32
536 ; RV64I-NEXT: mulhu a0, a0, a1
539 ; RV64ZBA-LABEL: zext_mul96:
541 ; RV64ZBA-NEXT: slli.uw a0, a0, 5
542 ; RV64ZBA-NEXT: sh1add a0, a0, a0
544 %b = zext i32 %a to i64
549 define i64 @zext_mul160(i32 signext %a) {
550 ; RV64I-LABEL: zext_mul160:
552 ; RV64I-NEXT: li a1, 5
553 ; RV64I-NEXT: slli a1, a1, 37
554 ; RV64I-NEXT: slli a0, a0, 32
555 ; RV64I-NEXT: mulhu a0, a0, a1
558 ; RV64ZBA-LABEL: zext_mul160:
560 ; RV64ZBA-NEXT: slli.uw a0, a0, 5
561 ; RV64ZBA-NEXT: sh2add a0, a0, a0
563 %b = zext i32 %a to i64
568 define i64 @zext_mul288(i32 signext %a) {
569 ; RV64I-LABEL: zext_mul288:
571 ; RV64I-NEXT: li a1, 9
572 ; RV64I-NEXT: slli a1, a1, 37
573 ; RV64I-NEXT: slli a0, a0, 32
574 ; RV64I-NEXT: mulhu a0, a0, a1
577 ; RV64ZBA-LABEL: zext_mul288:
579 ; RV64ZBA-NEXT: slli.uw a0, a0, 5
580 ; RV64ZBA-NEXT: sh3add a0, a0, a0
582 %b = zext i32 %a to i64
587 ; We can't use slli.uw becaues the shift amount is more than 31.
588 ; FIXME: The zext.w is unneeded.
589 define i64 @zext_mul12884901888(i32 signext %a) {
590 ; RV64I-LABEL: zext_mul12884901888:
592 ; RV64I-NEXT: slli a0, a0, 32
593 ; RV64I-NEXT: srli a0, a0, 32
594 ; RV64I-NEXT: li a1, 3
595 ; RV64I-NEXT: slli a1, a1, 32
596 ; RV64I-NEXT: mul a0, a0, a1
599 ; RV64ZBA-LABEL: zext_mul12884901888:
601 ; RV64ZBA-NEXT: andi a0, a0, -1
602 ; RV64ZBA-NEXT: sh1add a0, a0, a0
603 ; RV64ZBA-NEXT: slli a0, a0, 32
605 %b = zext i32 %a to i64
606 %c = mul i64 %b, 12884901888
610 ; We can't use slli.uw becaues the shift amount is more than 31.
611 ; FIXME: The zext.w is unneeded.
612 define i64 @zext_mul21474836480(i32 signext %a) {
613 ; RV64I-LABEL: zext_mul21474836480:
615 ; RV64I-NEXT: slli a0, a0, 32
616 ; RV64I-NEXT: srli a0, a0, 32
617 ; RV64I-NEXT: li a1, 5
618 ; RV64I-NEXT: slli a1, a1, 32
619 ; RV64I-NEXT: mul a0, a0, a1
622 ; RV64ZBA-LABEL: zext_mul21474836480:
624 ; RV64ZBA-NEXT: andi a0, a0, -1
625 ; RV64ZBA-NEXT: sh2add a0, a0, a0
626 ; RV64ZBA-NEXT: slli a0, a0, 32
628 %b = zext i32 %a to i64
629 %c = mul i64 %b, 21474836480
633 ; We can't use slli.uw becaues the shift amount is more than 31.
634 ; FIXME: The zext.w is unneeded.
635 define i64 @zext_mul38654705664(i32 signext %a) {
636 ; RV64I-LABEL: zext_mul38654705664:
638 ; RV64I-NEXT: slli a0, a0, 32
639 ; RV64I-NEXT: srli a0, a0, 32
640 ; RV64I-NEXT: li a1, 9
641 ; RV64I-NEXT: slli a1, a1, 32
642 ; RV64I-NEXT: mul a0, a0, a1
645 ; RV64ZBA-LABEL: zext_mul38654705664:
647 ; RV64ZBA-NEXT: andi a0, a0, -1
648 ; RV64ZBA-NEXT: sh3add a0, a0, a0
649 ; RV64ZBA-NEXT: slli a0, a0, 32
651 %b = zext i32 %a to i64
652 %c = mul i64 %b, 38654705664
656 define i64 @sh1add_imm(i64 %0) {
657 ; CHECK-LABEL: sh1add_imm:
659 ; CHECK-NEXT: slli a0, a0, 1
660 ; CHECK-NEXT: addi a0, a0, 5
667 define i64 @sh2add_imm(i64 %0) {
668 ; CHECK-LABEL: sh2add_imm:
670 ; CHECK-NEXT: slli a0, a0, 2
671 ; CHECK-NEXT: addi a0, a0, -6
678 define i64 @sh3add_imm(i64 %0) {
679 ; CHECK-LABEL: sh3add_imm:
681 ; CHECK-NEXT: slli a0, a0, 3
682 ; CHECK-NEXT: addi a0, a0, 7
689 define i64 @sh1adduw_imm(i32 signext %0) {
690 ; RV64I-LABEL: sh1adduw_imm:
692 ; RV64I-NEXT: slli a0, a0, 32
693 ; RV64I-NEXT: srli a0, a0, 31
694 ; RV64I-NEXT: addi a0, a0, 11
697 ; RV64ZBA-LABEL: sh1adduw_imm:
699 ; RV64ZBA-NEXT: slli.uw a0, a0, 1
700 ; RV64ZBA-NEXT: addi a0, a0, 11
702 %a = zext i32 %0 to i64
708 define i64 @sh2adduw_imm(i32 signext %0) {
709 ; RV64I-LABEL: sh2adduw_imm:
711 ; RV64I-NEXT: slli a0, a0, 32
712 ; RV64I-NEXT: srli a0, a0, 30
713 ; RV64I-NEXT: addi a0, a0, -12
716 ; RV64ZBA-LABEL: sh2adduw_imm:
718 ; RV64ZBA-NEXT: slli.uw a0, a0, 2
719 ; RV64ZBA-NEXT: addi a0, a0, -12
721 %a = zext i32 %0 to i64
727 define i64 @sh3adduw_imm(i32 signext %0) {
728 ; RV64I-LABEL: sh3adduw_imm:
730 ; RV64I-NEXT: slli a0, a0, 32
731 ; RV64I-NEXT: srli a0, a0, 29
732 ; RV64I-NEXT: addi a0, a0, 13
735 ; RV64ZBA-LABEL: sh3adduw_imm:
737 ; RV64ZBA-NEXT: slli.uw a0, a0, 3
738 ; RV64ZBA-NEXT: addi a0, a0, 13
740 %a = zext i32 %0 to i64
746 define i64 @adduw_imm(i32 signext %0) nounwind {
747 ; RV64I-LABEL: adduw_imm:
749 ; RV64I-NEXT: slli a0, a0, 32
750 ; RV64I-NEXT: srli a0, a0, 32
751 ; RV64I-NEXT: addi a0, a0, 5
754 ; RV64ZBA-LABEL: adduw_imm:
756 ; RV64ZBA-NEXT: zext.w a0, a0
757 ; RV64ZBA-NEXT: addi a0, a0, 5
759 %a = zext i32 %0 to i64
764 define i64 @mul258(i64 %a) {
765 ; CHECK-LABEL: mul258:
767 ; CHECK-NEXT: li a1, 258
768 ; CHECK-NEXT: mul a0, a0, a1
774 define i64 @mul260(i64 %a) {
775 ; CHECK-LABEL: mul260:
777 ; CHECK-NEXT: li a1, 260
778 ; CHECK-NEXT: mul a0, a0, a1
784 define i64 @mul264(i64 %a) {
785 ; CHECK-LABEL: mul264:
787 ; CHECK-NEXT: li a1, 264
788 ; CHECK-NEXT: mul a0, a0, a1
794 define i64 @imm_zextw() nounwind {
795 ; RV64I-LABEL: imm_zextw:
797 ; RV64I-NEXT: li a0, 1
798 ; RV64I-NEXT: slli a0, a0, 32
799 ; RV64I-NEXT: addi a0, a0, -2
802 ; RV64ZBA-LABEL: imm_zextw:
804 ; RV64ZBA-NEXT: li a0, -2
805 ; RV64ZBA-NEXT: zext.w a0, a0
807 ret i64 4294967294 ; -2 in 32 bits.
810 define i64 @mul11(i64 %a) {
811 ; RV64I-LABEL: mul11:
813 ; RV64I-NEXT: li a1, 11
814 ; RV64I-NEXT: mul a0, a0, a1
817 ; RV64ZBA-LABEL: mul11:
819 ; RV64ZBA-NEXT: sh2add a1, a0, a0
820 ; RV64ZBA-NEXT: sh1add a0, a1, a0
826 define i64 @mul19(i64 %a) {
827 ; RV64I-LABEL: mul19:
829 ; RV64I-NEXT: li a1, 19
830 ; RV64I-NEXT: mul a0, a0, a1
833 ; RV64ZBA-LABEL: mul19:
835 ; RV64ZBA-NEXT: sh3add a1, a0, a0
836 ; RV64ZBA-NEXT: sh1add a0, a1, a0
842 define i64 @mul13(i64 %a) {
843 ; RV64I-LABEL: mul13:
845 ; RV64I-NEXT: li a1, 13
846 ; RV64I-NEXT: mul a0, a0, a1
849 ; RV64ZBA-LABEL: mul13:
851 ; RV64ZBA-NEXT: sh1add a1, a0, a0
852 ; RV64ZBA-NEXT: sh2add a0, a1, a0
858 define i64 @mul21(i64 %a) {
859 ; RV64I-LABEL: mul21:
861 ; RV64I-NEXT: li a1, 21
862 ; RV64I-NEXT: mul a0, a0, a1
865 ; RV64ZBA-LABEL: mul21:
867 ; RV64ZBA-NEXT: sh2add a1, a0, a0
868 ; RV64ZBA-NEXT: sh2add a0, a1, a0
874 define i64 @mul37(i64 %a) {
875 ; RV64I-LABEL: mul37:
877 ; RV64I-NEXT: li a1, 37
878 ; RV64I-NEXT: mul a0, a0, a1
881 ; RV64ZBA-LABEL: mul37:
883 ; RV64ZBA-NEXT: sh3add a1, a0, a0
884 ; RV64ZBA-NEXT: sh2add a0, a1, a0
890 define i64 @mul25(i64 %a) {
891 ; RV64I-LABEL: mul25:
893 ; RV64I-NEXT: li a1, 25
894 ; RV64I-NEXT: mul a0, a0, a1
897 ; RV64ZBA-LABEL: mul25:
899 ; RV64ZBA-NEXT: sh1add a1, a0, a0
900 ; RV64ZBA-NEXT: sh3add a0, a1, a0
906 define i64 @mul41(i64 %a) {
907 ; RV64I-LABEL: mul41:
909 ; RV64I-NEXT: li a1, 41
910 ; RV64I-NEXT: mul a0, a0, a1
913 ; RV64ZBA-LABEL: mul41:
915 ; RV64ZBA-NEXT: sh2add a1, a0, a0
916 ; RV64ZBA-NEXT: sh3add a0, a1, a0
922 define i64 @mul73(i64 %a) {
923 ; RV64I-LABEL: mul73:
925 ; RV64I-NEXT: li a1, 73
926 ; RV64I-NEXT: mul a0, a0, a1
929 ; RV64ZBA-LABEL: mul73:
931 ; RV64ZBA-NEXT: sh3add a1, a0, a0
932 ; RV64ZBA-NEXT: sh3add a0, a1, a0
938 define i64 @mul27(i64 %a) {
939 ; RV64I-LABEL: mul27:
941 ; RV64I-NEXT: li a1, 27
942 ; RV64I-NEXT: mul a0, a0, a1
945 ; RV64ZBA-LABEL: mul27:
947 ; RV64ZBA-NEXT: sh3add a0, a0, a0
948 ; RV64ZBA-NEXT: sh1add a0, a0, a0
954 define i64 @mul45(i64 %a) {
955 ; RV64I-LABEL: mul45:
957 ; RV64I-NEXT: li a1, 45
958 ; RV64I-NEXT: mul a0, a0, a1
961 ; RV64ZBA-LABEL: mul45:
963 ; RV64ZBA-NEXT: sh3add a0, a0, a0
964 ; RV64ZBA-NEXT: sh2add a0, a0, a0
970 define i64 @mul81(i64 %a) {
971 ; RV64I-LABEL: mul81:
973 ; RV64I-NEXT: li a1, 81
974 ; RV64I-NEXT: mul a0, a0, a1
977 ; RV64ZBA-LABEL: mul81:
979 ; RV64ZBA-NEXT: sh3add a0, a0, a0
980 ; RV64ZBA-NEXT: sh3add a0, a0, a0
986 define i64 @mul4098(i64 %a) {
987 ; RV64I-LABEL: mul4098:
989 ; RV64I-NEXT: slli a1, a0, 1
990 ; RV64I-NEXT: slli a0, a0, 12
991 ; RV64I-NEXT: add a0, a0, a1
994 ; RV64ZBA-LABEL: mul4098:
996 ; RV64ZBA-NEXT: slli a1, a0, 12
997 ; RV64ZBA-NEXT: sh1add a0, a0, a1
999 %c = mul i64 %a, 4098
1003 define i64 @mul4100(i64 %a) {
1004 ; RV64I-LABEL: mul4100:
1006 ; RV64I-NEXT: slli a1, a0, 2
1007 ; RV64I-NEXT: slli a0, a0, 12
1008 ; RV64I-NEXT: add a0, a0, a1
1011 ; RV64ZBA-LABEL: mul4100:
1013 ; RV64ZBA-NEXT: slli a1, a0, 12
1014 ; RV64ZBA-NEXT: sh2add a0, a0, a1
1016 %c = mul i64 %a, 4100
1020 define i64 @mul4104(i64 %a) {
1021 ; RV64I-LABEL: mul4104:
1023 ; RV64I-NEXT: slli a1, a0, 3
1024 ; RV64I-NEXT: slli a0, a0, 12
1025 ; RV64I-NEXT: add a0, a0, a1
1028 ; RV64ZBA-LABEL: mul4104:
1030 ; RV64ZBA-NEXT: slli a1, a0, 12
1031 ; RV64ZBA-NEXT: sh3add a0, a0, a1
1033 %c = mul i64 %a, 4104
1037 define signext i32 @mulw192(i32 signext %a) {
1038 ; RV64I-LABEL: mulw192:
1040 ; RV64I-NEXT: li a1, 192
1041 ; RV64I-NEXT: mulw a0, a0, a1
1044 ; RV64ZBA-LABEL: mulw192:
1046 ; RV64ZBA-NEXT: sh1add a0, a0, a0
1047 ; RV64ZBA-NEXT: slliw a0, a0, 6
1049 %c = mul i32 %a, 192
1053 define signext i32 @mulw320(i32 signext %a) {
1054 ; RV64I-LABEL: mulw320:
1056 ; RV64I-NEXT: li a1, 320
1057 ; RV64I-NEXT: mulw a0, a0, a1
1060 ; RV64ZBA-LABEL: mulw320:
1062 ; RV64ZBA-NEXT: sh2add a0, a0, a0
1063 ; RV64ZBA-NEXT: slliw a0, a0, 6
1065 %c = mul i32 %a, 320
1069 define signext i32 @mulw576(i32 signext %a) {
1070 ; RV64I-LABEL: mulw576:
1072 ; RV64I-NEXT: li a1, 576
1073 ; RV64I-NEXT: mulw a0, a0, a1
1076 ; RV64ZBA-LABEL: mulw576:
1078 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1079 ; RV64ZBA-NEXT: slliw a0, a0, 6
1081 %c = mul i32 %a, 576
1085 define i64 @add4104(i64 %a) {
1086 ; RV64I-LABEL: add4104:
1088 ; RV64I-NEXT: lui a1, 1
1089 ; RV64I-NEXT: addiw a1, a1, 8
1090 ; RV64I-NEXT: add a0, a0, a1
1093 ; RV64ZBA-LABEL: add4104:
1095 ; RV64ZBA-NEXT: li a1, 1026
1096 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1098 %c = add i64 %a, 4104
1102 define i64 @add8208(i64 %a) {
1103 ; RV64I-LABEL: add8208:
1105 ; RV64I-NEXT: lui a1, 2
1106 ; RV64I-NEXT: addiw a1, a1, 16
1107 ; RV64I-NEXT: add a0, a0, a1
1110 ; RV64ZBA-LABEL: add8208:
1112 ; RV64ZBA-NEXT: li a1, 1026
1113 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1115 %c = add i64 %a, 8208
1119 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1120 define signext i32 @add8192_i32(i32 signext %a) {
1121 ; CHECK-LABEL: add8192_i32:
1123 ; CHECK-NEXT: lui a1, 2
1124 ; CHECK-NEXT: addw a0, a0, a1
1126 %c = add i32 %a, 8192
1130 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1131 define i64 @add8192(i64 %a) {
1132 ; CHECK-LABEL: add8192:
1134 ; CHECK-NEXT: lui a1, 2
1135 ; CHECK-NEXT: add a0, a0, a1
1137 %c = add i64 %a, 8192
1141 define signext i32 @addshl32_5_6(i32 signext %a, i32 signext %b) {
1142 ; RV64I-LABEL: addshl32_5_6:
1144 ; RV64I-NEXT: slli a0, a0, 5
1145 ; RV64I-NEXT: slli a1, a1, 6
1146 ; RV64I-NEXT: addw a0, a0, a1
1149 ; RV64ZBA-LABEL: addshl32_5_6:
1151 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1152 ; RV64ZBA-NEXT: slliw a0, a0, 5
1160 define i64 @addshl64_5_6(i64 %a, i64 %b) {
1161 ; RV64I-LABEL: addshl64_5_6:
1163 ; RV64I-NEXT: slli a0, a0, 5
1164 ; RV64I-NEXT: slli a1, a1, 6
1165 ; RV64I-NEXT: add a0, a0, a1
1168 ; RV64ZBA-LABEL: addshl64_5_6:
1170 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1171 ; RV64ZBA-NEXT: slli a0, a0, 5
1179 define signext i32 @addshl32_5_7(i32 signext %a, i32 signext %b) {
1180 ; RV64I-LABEL: addshl32_5_7:
1182 ; RV64I-NEXT: slli a0, a0, 5
1183 ; RV64I-NEXT: slli a1, a1, 7
1184 ; RV64I-NEXT: addw a0, a0, a1
1187 ; RV64ZBA-LABEL: addshl32_5_7:
1189 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1190 ; RV64ZBA-NEXT: slliw a0, a0, 5
1198 define i64 @addshl64_5_7(i64 %a, i64 %b) {
1199 ; RV64I-LABEL: addshl64_5_7:
1201 ; RV64I-NEXT: slli a0, a0, 5
1202 ; RV64I-NEXT: slli a1, a1, 7
1203 ; RV64I-NEXT: add a0, a0, a1
1206 ; RV64ZBA-LABEL: addshl64_5_7:
1208 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1209 ; RV64ZBA-NEXT: slli a0, a0, 5
1217 define signext i32 @addshl32_5_8(i32 signext %a, i32 signext %b) {
1218 ; RV64I-LABEL: addshl32_5_8:
1220 ; RV64I-NEXT: slli a0, a0, 5
1221 ; RV64I-NEXT: slli a1, a1, 8
1222 ; RV64I-NEXT: addw a0, a0, a1
1225 ; RV64ZBA-LABEL: addshl32_5_8:
1227 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1228 ; RV64ZBA-NEXT: slliw a0, a0, 5
1236 define i64 @addshl64_5_8(i64 %a, i64 %b) {
1237 ; RV64I-LABEL: addshl64_5_8:
1239 ; RV64I-NEXT: slli a0, a0, 5
1240 ; RV64I-NEXT: slli a1, a1, 8
1241 ; RV64I-NEXT: add a0, a0, a1
1244 ; RV64ZBA-LABEL: addshl64_5_8:
1246 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1247 ; RV64ZBA-NEXT: slli a0, a0, 5
1255 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1256 ; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
1257 define zeroext i32 @sext_ashr_zext_i8(i8 %a) nounwind {
1258 ; RV64I-LABEL: sext_ashr_zext_i8:
1260 ; RV64I-NEXT: slli a0, a0, 56
1261 ; RV64I-NEXT: srai a0, a0, 56
1262 ; RV64I-NEXT: slli a0, a0, 23
1263 ; RV64I-NEXT: srli a0, a0, 32
1266 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i8:
1267 ; RV64ZBANOZBB: # %bb.0:
1268 ; RV64ZBANOZBB-NEXT: slli a0, a0, 56
1269 ; RV64ZBANOZBB-NEXT: srai a0, a0, 56
1270 ; RV64ZBANOZBB-NEXT: slli a0, a0, 23
1271 ; RV64ZBANOZBB-NEXT: srli a0, a0, 32
1272 ; RV64ZBANOZBB-NEXT: ret
1274 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i8:
1275 ; RV64ZBAZBB: # %bb.0:
1276 ; RV64ZBAZBB-NEXT: sext.b a0, a0
1277 ; RV64ZBAZBB-NEXT: slli a0, a0, 23
1278 ; RV64ZBAZBB-NEXT: srli a0, a0, 32
1279 ; RV64ZBAZBB-NEXT: ret
1280 %ext = sext i8 %a to i32
1281 %1 = ashr i32 %ext, 9
1285 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1286 ; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
1287 define zeroext i32 @sext_ashr_zext_i16(i16 %a) nounwind {
1288 ; RV64I-LABEL: sext_ashr_zext_i16:
1290 ; RV64I-NEXT: slli a0, a0, 48
1291 ; RV64I-NEXT: srai a0, a0, 48
1292 ; RV64I-NEXT: slli a0, a0, 23
1293 ; RV64I-NEXT: srli a0, a0, 32
1296 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i16:
1297 ; RV64ZBANOZBB: # %bb.0:
1298 ; RV64ZBANOZBB-NEXT: slli a0, a0, 48
1299 ; RV64ZBANOZBB-NEXT: srai a0, a0, 48
1300 ; RV64ZBANOZBB-NEXT: slli a0, a0, 23
1301 ; RV64ZBANOZBB-NEXT: srli a0, a0, 32
1302 ; RV64ZBANOZBB-NEXT: ret
1304 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i16:
1305 ; RV64ZBAZBB: # %bb.0:
1306 ; RV64ZBAZBB-NEXT: sext.h a0, a0
1307 ; RV64ZBAZBB-NEXT: slli a0, a0, 23
1308 ; RV64ZBAZBB-NEXT: srli a0, a0, 32
1309 ; RV64ZBAZBB-NEXT: ret
1310 %ext = sext i16 %a to i32
1311 %1 = ashr i32 %ext, 9
1315 ; This the IR you get from InstCombine if take the difference of 2 pointers and
1316 ; cast is to unsigned before using as an index.
1317 define signext i16 @sh1adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1318 ; RV64I-LABEL: sh1adduw_ptrdiff:
1320 ; RV64I-NEXT: li a2, 1
1321 ; RV64I-NEXT: slli a2, a2, 33
1322 ; RV64I-NEXT: addi a2, a2, -2
1323 ; RV64I-NEXT: and a0, a0, a2
1324 ; RV64I-NEXT: add a0, a1, a0
1325 ; RV64I-NEXT: lh a0, 0(a0)
1328 ; RV64ZBA-LABEL: sh1adduw_ptrdiff:
1330 ; RV64ZBA-NEXT: srli a0, a0, 1
1331 ; RV64ZBA-NEXT: sh1add.uw a0, a0, a1
1332 ; RV64ZBA-NEXT: lh a0, 0(a0)
1334 %ptrdiff = lshr exact i64 %diff, 1
1335 %cast = and i64 %ptrdiff, 4294967295
1336 %ptr = getelementptr inbounds i16, ptr %baseptr, i64 %cast
1337 %res = load i16, ptr %ptr
1341 define signext i32 @sh2adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1342 ; RV64I-LABEL: sh2adduw_ptrdiff:
1344 ; RV64I-NEXT: li a2, 1
1345 ; RV64I-NEXT: slli a2, a2, 34
1346 ; RV64I-NEXT: addi a2, a2, -4
1347 ; RV64I-NEXT: and a0, a0, a2
1348 ; RV64I-NEXT: add a0, a1, a0
1349 ; RV64I-NEXT: lw a0, 0(a0)
1352 ; RV64ZBA-LABEL: sh2adduw_ptrdiff:
1354 ; RV64ZBA-NEXT: srli a0, a0, 2
1355 ; RV64ZBA-NEXT: sh2add.uw a0, a0, a1
1356 ; RV64ZBA-NEXT: lw a0, 0(a0)
1358 %ptrdiff = lshr exact i64 %diff, 2
1359 %cast = and i64 %ptrdiff, 4294967295
1360 %ptr = getelementptr inbounds i32, ptr %baseptr, i64 %cast
1361 %res = load i32, ptr %ptr
1365 define i64 @sh3adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1366 ; RV64I-LABEL: sh3adduw_ptrdiff:
1368 ; RV64I-NEXT: li a2, 1
1369 ; RV64I-NEXT: slli a2, a2, 35
1370 ; RV64I-NEXT: addi a2, a2, -8
1371 ; RV64I-NEXT: and a0, a0, a2
1372 ; RV64I-NEXT: add a0, a1, a0
1373 ; RV64I-NEXT: ld a0, 0(a0)
1376 ; RV64ZBA-LABEL: sh3adduw_ptrdiff:
1378 ; RV64ZBA-NEXT: srli a0, a0, 3
1379 ; RV64ZBA-NEXT: sh3add.uw a0, a0, a1
1380 ; RV64ZBA-NEXT: ld a0, 0(a0)
1382 %ptrdiff = lshr exact i64 %diff, 3
1383 %cast = and i64 %ptrdiff, 4294967295
1384 %ptr = getelementptr inbounds i64, ptr %baseptr, i64 %cast
1385 %res = load i64, ptr %ptr
1389 define signext i16 @srliw_1_sh1add(ptr %0, i32 signext %1) {
1390 ; RV64I-LABEL: srliw_1_sh1add:
1392 ; RV64I-NEXT: srliw a1, a1, 1
1393 ; RV64I-NEXT: slli a1, a1, 1
1394 ; RV64I-NEXT: add a0, a0, a1
1395 ; RV64I-NEXT: lh a0, 0(a0)
1398 ; RV64ZBA-LABEL: srliw_1_sh1add:
1400 ; RV64ZBA-NEXT: srliw a1, a1, 1
1401 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1402 ; RV64ZBA-NEXT: lh a0, 0(a0)
1405 %4 = zext i32 %3 to i64
1406 %5 = getelementptr inbounds i16, ptr %0, i64 %4
1407 %6 = load i16, ptr %5, align 2
1411 define i128 @slliuw_ptrdiff(i64 %diff, ptr %baseptr) {
1412 ; RV64I-LABEL: slliuw_ptrdiff:
1414 ; RV64I-NEXT: li a2, 1
1415 ; RV64I-NEXT: slli a2, a2, 36
1416 ; RV64I-NEXT: addi a2, a2, -16
1417 ; RV64I-NEXT: and a0, a0, a2
1418 ; RV64I-NEXT: add a1, a1, a0
1419 ; RV64I-NEXT: ld a0, 0(a1)
1420 ; RV64I-NEXT: ld a1, 8(a1)
1423 ; RV64ZBA-LABEL: slliuw_ptrdiff:
1425 ; RV64ZBA-NEXT: srli a0, a0, 4
1426 ; RV64ZBA-NEXT: slli.uw a0, a0, 4
1427 ; RV64ZBA-NEXT: add a1, a1, a0
1428 ; RV64ZBA-NEXT: ld a0, 0(a1)
1429 ; RV64ZBA-NEXT: ld a1, 8(a1)
1431 %ptrdiff = lshr exact i64 %diff, 4
1432 %cast = and i64 %ptrdiff, 4294967295
1433 %ptr = getelementptr inbounds i128, ptr %baseptr, i64 %cast
1434 %res = load i128, ptr %ptr
1438 define signext i32 @srliw_2_sh2add(ptr %0, i32 signext %1) {
1439 ; RV64I-LABEL: srliw_2_sh2add:
1441 ; RV64I-NEXT: srliw a1, a1, 2
1442 ; RV64I-NEXT: slli a1, a1, 2
1443 ; RV64I-NEXT: add a0, a0, a1
1444 ; RV64I-NEXT: lw a0, 0(a0)
1447 ; RV64ZBA-LABEL: srliw_2_sh2add:
1449 ; RV64ZBA-NEXT: srliw a1, a1, 2
1450 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1451 ; RV64ZBA-NEXT: lw a0, 0(a0)
1454 %4 = zext i32 %3 to i64
1455 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1456 %6 = load i32, ptr %5, align 4
1460 define i64 @srliw_3_sh3add(ptr %0, i32 signext %1) {
1461 ; RV64I-LABEL: srliw_3_sh3add:
1463 ; RV64I-NEXT: srliw a1, a1, 3
1464 ; RV64I-NEXT: slli a1, a1, 3
1465 ; RV64I-NEXT: add a0, a0, a1
1466 ; RV64I-NEXT: ld a0, 0(a0)
1469 ; RV64ZBA-LABEL: srliw_3_sh3add:
1471 ; RV64ZBA-NEXT: srliw a1, a1, 3
1472 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1473 ; RV64ZBA-NEXT: ld a0, 0(a0)
1476 %4 = zext i32 %3 to i64
1477 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1478 %6 = load i64, ptr %5, align 8
1482 define signext i32 @srliw_1_sh2add(ptr %0, i32 signext %1) {
1483 ; RV64I-LABEL: srliw_1_sh2add:
1485 ; RV64I-NEXT: srliw a1, a1, 1
1486 ; RV64I-NEXT: slli a1, a1, 2
1487 ; RV64I-NEXT: add a0, a0, a1
1488 ; RV64I-NEXT: lw a0, 0(a0)
1491 ; RV64ZBA-LABEL: srliw_1_sh2add:
1493 ; RV64ZBA-NEXT: srliw a1, a1, 1
1494 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1495 ; RV64ZBA-NEXT: lw a0, 0(a0)
1498 %4 = zext i32 %3 to i64
1499 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1500 %6 = load i32, ptr %5, align 4
1504 define i64 @srliw_1_sh3add(ptr %0, i32 signext %1) {
1505 ; RV64I-LABEL: srliw_1_sh3add:
1507 ; RV64I-NEXT: srliw a1, a1, 1
1508 ; RV64I-NEXT: slli a1, a1, 3
1509 ; RV64I-NEXT: add a0, a0, a1
1510 ; RV64I-NEXT: ld a0, 0(a0)
1513 ; RV64ZBA-LABEL: srliw_1_sh3add:
1515 ; RV64ZBA-NEXT: srliw a1, a1, 1
1516 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1517 ; RV64ZBA-NEXT: ld a0, 0(a0)
1520 %4 = zext i32 %3 to i64
1521 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1522 %6 = load i64, ptr %5, align 8
1526 define i64 @srliw_2_sh3add(ptr %0, i32 signext %1) {
1527 ; RV64I-LABEL: srliw_2_sh3add:
1529 ; RV64I-NEXT: srliw a1, a1, 2
1530 ; RV64I-NEXT: slli a1, a1, 3
1531 ; RV64I-NEXT: add a0, a0, a1
1532 ; RV64I-NEXT: ld a0, 0(a0)
1535 ; RV64ZBA-LABEL: srliw_2_sh3add:
1537 ; RV64ZBA-NEXT: srliw a1, a1, 2
1538 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1539 ; RV64ZBA-NEXT: ld a0, 0(a0)
1542 %4 = zext i32 %3 to i64
1543 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1544 %6 = load i64, ptr %5, align 8
1548 define signext i16 @srliw_2_sh1add(ptr %0, i32 signext %1) {
1549 ; RV64I-LABEL: srliw_2_sh1add:
1551 ; RV64I-NEXT: srliw a1, a1, 2
1552 ; RV64I-NEXT: slli a1, a1, 1
1553 ; RV64I-NEXT: add a0, a0, a1
1554 ; RV64I-NEXT: lh a0, 0(a0)
1557 ; RV64ZBA-LABEL: srliw_2_sh1add:
1559 ; RV64ZBA-NEXT: srliw a1, a1, 2
1560 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1561 ; RV64ZBA-NEXT: lh a0, 0(a0)
1564 %4 = zext i32 %3 to i64
1565 %5 = getelementptr inbounds i16, ptr %0, i64 %4
1566 %6 = load i16, ptr %5, align 2
1571 define signext i32 @srliw_3_sh2add(ptr %0, i32 signext %1) {
1572 ; RV64I-LABEL: srliw_3_sh2add:
1574 ; RV64I-NEXT: srliw a1, a1, 3
1575 ; RV64I-NEXT: slli a1, a1, 2
1576 ; RV64I-NEXT: add a0, a0, a1
1577 ; RV64I-NEXT: lw a0, 0(a0)
1580 ; RV64ZBA-LABEL: srliw_3_sh2add:
1582 ; RV64ZBA-NEXT: srliw a1, a1, 3
1583 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1584 ; RV64ZBA-NEXT: lw a0, 0(a0)
1587 %4 = zext i32 %3 to i64
1588 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1589 %6 = load i32, ptr %5, align 4
1593 define i64 @srliw_4_sh3add(ptr %0, i32 signext %1) {
1594 ; RV64I-LABEL: srliw_4_sh3add:
1596 ; RV64I-NEXT: srliw a1, a1, 4
1597 ; RV64I-NEXT: slli a1, a1, 3
1598 ; RV64I-NEXT: add a0, a0, a1
1599 ; RV64I-NEXT: ld a0, 0(a0)
1602 ; RV64ZBA-LABEL: srliw_4_sh3add:
1604 ; RV64ZBA-NEXT: srliw a1, a1, 4
1605 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1606 ; RV64ZBA-NEXT: ld a0, 0(a0)
1609 %4 = zext i32 %3 to i64
1610 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1611 %6 = load i64, ptr %5, align 8
1615 define signext i32 @srli_1_sh2add(ptr %0, i64 %1) {
1616 ; RV64I-LABEL: srli_1_sh2add:
1618 ; RV64I-NEXT: slli a1, a1, 1
1619 ; RV64I-NEXT: andi a1, a1, -4
1620 ; RV64I-NEXT: add a0, a0, a1
1621 ; RV64I-NEXT: lw a0, 0(a0)
1624 ; RV64ZBA-LABEL: srli_1_sh2add:
1626 ; RV64ZBA-NEXT: srli a1, a1, 1
1627 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1628 ; RV64ZBA-NEXT: lw a0, 0(a0)
1631 %4 = getelementptr inbounds i32, ptr %0, i64 %3
1632 %5 = load i32, ptr %4, align 4
1636 define i64 @srli_2_sh3add(ptr %0, i64 %1) {
1637 ; RV64I-LABEL: srli_2_sh3add:
1639 ; RV64I-NEXT: slli a1, a1, 1
1640 ; RV64I-NEXT: andi a1, a1, -8
1641 ; RV64I-NEXT: add a0, a0, a1
1642 ; RV64I-NEXT: ld a0, 0(a0)
1645 ; RV64ZBA-LABEL: srli_2_sh3add:
1647 ; RV64ZBA-NEXT: srli a1, a1, 2
1648 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1649 ; RV64ZBA-NEXT: ld a0, 0(a0)
1652 %4 = getelementptr inbounds i64, ptr %0, i64 %3
1653 %5 = load i64, ptr %4, align 8
1657 define signext i16 @srli_2_sh1add(ptr %0, i64 %1) {
1658 ; RV64I-LABEL: srli_2_sh1add:
1660 ; RV64I-NEXT: srli a1, a1, 1
1661 ; RV64I-NEXT: andi a1, a1, -2
1662 ; RV64I-NEXT: add a0, a0, a1
1663 ; RV64I-NEXT: lh a0, 0(a0)
1666 ; RV64ZBA-LABEL: srli_2_sh1add:
1668 ; RV64ZBA-NEXT: srli a1, a1, 2
1669 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1670 ; RV64ZBA-NEXT: lh a0, 0(a0)
1673 %4 = getelementptr inbounds i16, ptr %0, i64 %3
1674 %5 = load i16, ptr %4, align 2
1678 define signext i32 @srli_3_sh2add(ptr %0, i64 %1) {
1679 ; RV64I-LABEL: srli_3_sh2add:
1681 ; RV64I-NEXT: srli a1, a1, 1
1682 ; RV64I-NEXT: andi a1, a1, -4
1683 ; RV64I-NEXT: add a0, a0, a1
1684 ; RV64I-NEXT: lw a0, 0(a0)
1687 ; RV64ZBA-LABEL: srli_3_sh2add:
1689 ; RV64ZBA-NEXT: srli a1, a1, 3
1690 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1691 ; RV64ZBA-NEXT: lw a0, 0(a0)
1694 %4 = getelementptr inbounds i32, ptr %0, i64 %3
1695 %5 = load i32, ptr %4, align 4
1699 define i64 @srli_4_sh3add(ptr %0, i64 %1) {
1700 ; RV64I-LABEL: srli_4_sh3add:
1702 ; RV64I-NEXT: srli a1, a1, 1
1703 ; RV64I-NEXT: andi a1, a1, -8
1704 ; RV64I-NEXT: add a0, a0, a1
1705 ; RV64I-NEXT: ld a0, 0(a0)
1708 ; RV64ZBA-LABEL: srli_4_sh3add:
1710 ; RV64ZBA-NEXT: srli a1, a1, 4
1711 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1712 ; RV64ZBA-NEXT: ld a0, 0(a0)
1715 %4 = getelementptr inbounds i64, ptr %0, i64 %3
1716 %5 = load i64, ptr %4, align 8
1720 define signext i16 @shl_2_sh1add(ptr %0, i32 signext %1) {
1721 ; RV64I-LABEL: shl_2_sh1add:
1723 ; RV64I-NEXT: slli a1, a1, 34
1724 ; RV64I-NEXT: srli a1, a1, 31
1725 ; RV64I-NEXT: add a0, a0, a1
1726 ; RV64I-NEXT: lh a0, 0(a0)
1729 ; RV64ZBA-LABEL: shl_2_sh1add:
1731 ; RV64ZBA-NEXT: slli a1, a1, 2
1732 ; RV64ZBA-NEXT: sh1add.uw a0, a1, a0
1733 ; RV64ZBA-NEXT: lh a0, 0(a0)
1736 %4 = zext i32 %3 to i64
1737 %5 = getelementptr inbounds i16, ptr %0, i64 %4
1738 %6 = load i16, ptr %5, align 2
1742 define signext i32 @shl_16_sh2add(ptr %0, i32 signext %1) {
1743 ; RV64I-LABEL: shl_16_sh2add:
1745 ; RV64I-NEXT: slli a1, a1, 48
1746 ; RV64I-NEXT: srli a1, a1, 30
1747 ; RV64I-NEXT: add a0, a0, a1
1748 ; RV64I-NEXT: lw a0, 0(a0)
1751 ; RV64ZBA-LABEL: shl_16_sh2add:
1753 ; RV64ZBA-NEXT: slli a1, a1, 16
1754 ; RV64ZBA-NEXT: sh2add.uw a0, a1, a0
1755 ; RV64ZBA-NEXT: lw a0, 0(a0)
1758 %4 = zext i32 %3 to i64
1759 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1760 %6 = load i32, ptr %5, align 4
1764 define i64 @shl_31_sh3add(ptr %0, i32 signext %1) {
1765 ; RV64I-LABEL: shl_31_sh3add:
1767 ; RV64I-NEXT: slli a1, a1, 63
1768 ; RV64I-NEXT: srli a1, a1, 29
1769 ; RV64I-NEXT: add a0, a0, a1
1770 ; RV64I-NEXT: ld a0, 0(a0)
1773 ; RV64ZBA-LABEL: shl_31_sh3add:
1775 ; RV64ZBA-NEXT: slli a1, a1, 31
1776 ; RV64ZBA-NEXT: sh3add.uw a0, a1, a0
1777 ; RV64ZBA-NEXT: ld a0, 0(a0)
1780 %4 = zext i32 %3 to i64
1781 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1782 %6 = load i64, ptr %5, align 8
1786 define i64 @pack_i64(i64 %a, i64 %b) nounwind {
1787 ; RV64I-LABEL: pack_i64:
1789 ; RV64I-NEXT: slli a0, a0, 32
1790 ; RV64I-NEXT: srli a0, a0, 32
1791 ; RV64I-NEXT: slli a1, a1, 32
1792 ; RV64I-NEXT: or a0, a1, a0
1795 ; RV64ZBA-LABEL: pack_i64:
1797 ; RV64ZBA-NEXT: slli a1, a1, 32
1798 ; RV64ZBA-NEXT: add.uw a0, a0, a1
1800 %shl = and i64 %a, 4294967295
1801 %shl1 = shl i64 %b, 32
1802 %or = or i64 %shl1, %shl
1806 define i64 @pack_i64_2(i32 signext %a, i32 signext %b) nounwind {
1807 ; RV64I-LABEL: pack_i64_2:
1809 ; RV64I-NEXT: slli a0, a0, 32
1810 ; RV64I-NEXT: srli a0, a0, 32
1811 ; RV64I-NEXT: slli a1, a1, 32
1812 ; RV64I-NEXT: or a0, a1, a0
1815 ; RV64ZBA-LABEL: pack_i64_2:
1817 ; RV64ZBA-NEXT: slli a1, a1, 32
1818 ; RV64ZBA-NEXT: add.uw a0, a0, a1
1820 %zexta = zext i32 %a to i64
1821 %zextb = zext i32 %b to i64
1822 %shl1 = shl i64 %zextb, 32
1823 %or = or i64 %shl1, %zexta