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: -riscv-experimental-rv64-legal-i32 | FileCheck %s -check-prefixes=CHECK,RV64I
4 ; RUN: llc -mtriple=riscv64 -mattr=+m,+zba -verify-machineinstrs < %s \
5 ; RUN: -riscv-experimental-rv64-legal-i32 | FileCheck %s -check-prefixes=CHECK,RV64ZBA,RV64ZBANOZBB
6 ; RUN: llc -mtriple=riscv64 -mattr=+m,+zba,+zbb -verify-machineinstrs < %s \
7 ; RUN: -riscv-experimental-rv64-legal-i32 | 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: slli a1, a0, 32
299 ; RV64I-NEXT: srli a1, a1, 32
300 ; RV64I-NEXT: sllw a1, a2, a1
301 ; RV64I-NEXT: sraiw a0, a0, 2
302 ; RV64I-NEXT: mul a0, a1, a0
305 ; RV64ZBA-LABEL: sh2add_extra_sext:
307 ; RV64ZBA-NEXT: slli a0, a0, 2
308 ; RV64ZBA-NEXT: add a0, a0, a1
309 ; RV64ZBA-NEXT: zext.w a1, a0
310 ; RV64ZBA-NEXT: sllw a1, a2, a1
311 ; RV64ZBA-NEXT: sraiw a0, a0, 2
312 ; RV64ZBA-NEXT: mul a0, a1, a0
318 %e = sext i32 %c to i64
319 %f = sext i32 %d to i64
324 define i64 @addmul6(i64 %a, i64 %b) {
325 ; RV64I-LABEL: addmul6:
327 ; RV64I-NEXT: li a2, 6
328 ; RV64I-NEXT: mul a0, a0, a2
329 ; RV64I-NEXT: add a0, a0, a1
332 ; RV64ZBA-LABEL: addmul6:
334 ; RV64ZBA-NEXT: sh1add a0, a0, a0
335 ; RV64ZBA-NEXT: sh1add a0, a0, a1
342 define i64 @addmul10(i64 %a, i64 %b) {
343 ; RV64I-LABEL: addmul10:
345 ; RV64I-NEXT: li a2, 10
346 ; RV64I-NEXT: mul a0, a0, a2
347 ; RV64I-NEXT: add a0, a0, a1
350 ; RV64ZBA-LABEL: addmul10:
352 ; RV64ZBA-NEXT: sh2add a0, a0, a0
353 ; RV64ZBA-NEXT: sh1add a0, a0, a1
360 define i64 @addmul12(i64 %a, i64 %b) {
361 ; RV64I-LABEL: addmul12:
363 ; RV64I-NEXT: li a2, 12
364 ; RV64I-NEXT: mul a0, a0, a2
365 ; RV64I-NEXT: add a0, a0, a1
368 ; RV64ZBA-LABEL: addmul12:
370 ; RV64ZBA-NEXT: sh1add a0, a0, a0
371 ; RV64ZBA-NEXT: sh2add a0, a0, a1
378 define i64 @addmul18(i64 %a, i64 %b) {
379 ; RV64I-LABEL: addmul18:
381 ; RV64I-NEXT: li a2, 18
382 ; RV64I-NEXT: mul a0, a0, a2
383 ; RV64I-NEXT: add a0, a0, a1
386 ; RV64ZBA-LABEL: addmul18:
388 ; RV64ZBA-NEXT: sh3add a0, a0, a0
389 ; RV64ZBA-NEXT: sh1add a0, a0, a1
396 define i64 @addmul20(i64 %a, i64 %b) {
397 ; RV64I-LABEL: addmul20:
399 ; RV64I-NEXT: li a2, 20
400 ; RV64I-NEXT: mul a0, a0, a2
401 ; RV64I-NEXT: add a0, a0, a1
404 ; RV64ZBA-LABEL: addmul20:
406 ; RV64ZBA-NEXT: sh2add a0, a0, a0
407 ; RV64ZBA-NEXT: sh2add a0, a0, a1
414 define i64 @addmul24(i64 %a, i64 %b) {
415 ; RV64I-LABEL: addmul24:
417 ; RV64I-NEXT: li a2, 24
418 ; RV64I-NEXT: mul a0, a0, a2
419 ; RV64I-NEXT: add a0, a0, a1
422 ; RV64ZBA-LABEL: addmul24:
424 ; RV64ZBA-NEXT: sh1add a0, a0, a0
425 ; RV64ZBA-NEXT: sh3add a0, a0, a1
432 define i64 @addmul36(i64 %a, i64 %b) {
433 ; RV64I-LABEL: addmul36:
435 ; RV64I-NEXT: li a2, 36
436 ; RV64I-NEXT: mul a0, a0, a2
437 ; RV64I-NEXT: add a0, a0, a1
440 ; RV64ZBA-LABEL: addmul36:
442 ; RV64ZBA-NEXT: sh3add a0, a0, a0
443 ; RV64ZBA-NEXT: sh2add a0, a0, a1
450 define i64 @addmul40(i64 %a, i64 %b) {
451 ; RV64I-LABEL: addmul40:
453 ; RV64I-NEXT: li a2, 40
454 ; RV64I-NEXT: mul a0, a0, a2
455 ; RV64I-NEXT: add a0, a0, a1
458 ; RV64ZBA-LABEL: addmul40:
460 ; RV64ZBA-NEXT: sh2add a0, a0, a0
461 ; RV64ZBA-NEXT: sh3add a0, a0, a1
468 define i64 @addmul72(i64 %a, i64 %b) {
469 ; RV64I-LABEL: addmul72:
471 ; RV64I-NEXT: li a2, 72
472 ; RV64I-NEXT: mul a0, a0, a2
473 ; RV64I-NEXT: add a0, a0, a1
476 ; RV64ZBA-LABEL: addmul72:
478 ; RV64ZBA-NEXT: sh3add a0, a0, a0
479 ; RV64ZBA-NEXT: sh3add a0, a0, a1
486 define i64 @mul96(i64 %a) {
487 ; RV64I-LABEL: mul96:
489 ; RV64I-NEXT: li a1, 96
490 ; RV64I-NEXT: mul a0, a0, a1
493 ; RV64ZBA-LABEL: mul96:
495 ; RV64ZBA-NEXT: sh1add a0, a0, a0
496 ; RV64ZBA-NEXT: slli a0, a0, 5
502 define i64 @mul160(i64 %a) {
503 ; RV64I-LABEL: mul160:
505 ; RV64I-NEXT: li a1, 160
506 ; RV64I-NEXT: mul a0, a0, a1
509 ; RV64ZBA-LABEL: mul160:
511 ; RV64ZBA-NEXT: sh2add a0, a0, a0
512 ; RV64ZBA-NEXT: slli a0, a0, 5
518 define i64 @mul288(i64 %a) {
519 ; RV64I-LABEL: mul288:
521 ; RV64I-NEXT: li a1, 288
522 ; RV64I-NEXT: mul a0, a0, a1
525 ; RV64ZBA-LABEL: mul288:
527 ; RV64ZBA-NEXT: sh3add a0, a0, a0
528 ; RV64ZBA-NEXT: slli a0, a0, 5
534 define i64 @zext_mul96(i32 signext %a) {
535 ; RV64I-LABEL: zext_mul96:
537 ; RV64I-NEXT: li a1, 3
538 ; RV64I-NEXT: slli a1, a1, 37
539 ; RV64I-NEXT: slli a0, a0, 32
540 ; RV64I-NEXT: mulhu a0, a0, a1
543 ; RV64ZBA-LABEL: zext_mul96:
545 ; RV64ZBA-NEXT: slli.uw a0, a0, 5
546 ; RV64ZBA-NEXT: sh1add a0, a0, a0
548 %b = zext i32 %a to i64
553 define i64 @zext_mul160(i32 signext %a) {
554 ; RV64I-LABEL: zext_mul160:
556 ; RV64I-NEXT: li a1, 5
557 ; RV64I-NEXT: slli a1, a1, 37
558 ; RV64I-NEXT: slli a0, a0, 32
559 ; RV64I-NEXT: mulhu a0, a0, a1
562 ; RV64ZBA-LABEL: zext_mul160:
564 ; RV64ZBA-NEXT: slli.uw a0, a0, 5
565 ; RV64ZBA-NEXT: sh2add a0, a0, a0
567 %b = zext i32 %a to i64
572 define i64 @zext_mul288(i32 signext %a) {
573 ; RV64I-LABEL: zext_mul288:
575 ; RV64I-NEXT: li a1, 9
576 ; RV64I-NEXT: slli a1, a1, 37
577 ; RV64I-NEXT: slli a0, a0, 32
578 ; RV64I-NEXT: mulhu a0, a0, a1
581 ; RV64ZBA-LABEL: zext_mul288:
583 ; RV64ZBA-NEXT: slli.uw a0, a0, 5
584 ; RV64ZBA-NEXT: sh3add a0, a0, a0
586 %b = zext i32 %a to i64
591 ; We can't use slli.uw becaues the shift amount is more than 31.
592 ; FIXME: The zext.w is unneeded.
593 define i64 @zext_mul12884901888(i32 signext %a) {
594 ; RV64I-LABEL: zext_mul12884901888:
596 ; RV64I-NEXT: slli a0, a0, 32
597 ; RV64I-NEXT: srli a0, a0, 32
598 ; RV64I-NEXT: li a1, 3
599 ; RV64I-NEXT: slli a1, a1, 32
600 ; RV64I-NEXT: mul a0, a0, a1
603 ; RV64ZBA-LABEL: zext_mul12884901888:
605 ; RV64ZBA-NEXT: andi a0, a0, -1
606 ; RV64ZBA-NEXT: sh1add a0, a0, a0
607 ; RV64ZBA-NEXT: slli a0, a0, 32
609 %b = zext i32 %a to i64
610 %c = mul i64 %b, 12884901888
614 ; We can't use slli.uw becaues the shift amount is more than 31.
615 ; FIXME: The zext.w is unneeded.
616 define i64 @zext_mul21474836480(i32 signext %a) {
617 ; RV64I-LABEL: zext_mul21474836480:
619 ; RV64I-NEXT: slli a0, a0, 32
620 ; RV64I-NEXT: srli a0, a0, 32
621 ; RV64I-NEXT: li a1, 5
622 ; RV64I-NEXT: slli a1, a1, 32
623 ; RV64I-NEXT: mul a0, a0, a1
626 ; RV64ZBA-LABEL: zext_mul21474836480:
628 ; RV64ZBA-NEXT: andi a0, a0, -1
629 ; RV64ZBA-NEXT: sh2add a0, a0, a0
630 ; RV64ZBA-NEXT: slli a0, a0, 32
632 %b = zext i32 %a to i64
633 %c = mul i64 %b, 21474836480
637 ; We can't use slli.uw becaues the shift amount is more than 31.
638 ; FIXME: The zext.w is unneeded.
639 define i64 @zext_mul38654705664(i32 signext %a) {
640 ; RV64I-LABEL: zext_mul38654705664:
642 ; RV64I-NEXT: slli a0, a0, 32
643 ; RV64I-NEXT: srli a0, a0, 32
644 ; RV64I-NEXT: li a1, 9
645 ; RV64I-NEXT: slli a1, a1, 32
646 ; RV64I-NEXT: mul a0, a0, a1
649 ; RV64ZBA-LABEL: zext_mul38654705664:
651 ; RV64ZBA-NEXT: andi a0, a0, -1
652 ; RV64ZBA-NEXT: sh3add a0, a0, a0
653 ; RV64ZBA-NEXT: slli a0, a0, 32
655 %b = zext i32 %a to i64
656 %c = mul i64 %b, 38654705664
660 define i64 @sh1add_imm(i64 %0) {
661 ; CHECK-LABEL: sh1add_imm:
663 ; CHECK-NEXT: slli a0, a0, 1
664 ; CHECK-NEXT: addi a0, a0, 5
671 define i64 @sh2add_imm(i64 %0) {
672 ; CHECK-LABEL: sh2add_imm:
674 ; CHECK-NEXT: slli a0, a0, 2
675 ; CHECK-NEXT: addi a0, a0, -6
682 define i64 @sh3add_imm(i64 %0) {
683 ; CHECK-LABEL: sh3add_imm:
685 ; CHECK-NEXT: slli a0, a0, 3
686 ; CHECK-NEXT: addi a0, a0, 7
693 define i64 @sh1adduw_imm(i32 signext %0) {
694 ; RV64I-LABEL: sh1adduw_imm:
696 ; RV64I-NEXT: slli a0, a0, 32
697 ; RV64I-NEXT: srli a0, a0, 31
698 ; RV64I-NEXT: addi a0, a0, 11
701 ; RV64ZBA-LABEL: sh1adduw_imm:
703 ; RV64ZBA-NEXT: slli.uw a0, a0, 1
704 ; RV64ZBA-NEXT: addi a0, a0, 11
706 %a = zext i32 %0 to i64
712 define i64 @sh2adduw_imm(i32 signext %0) {
713 ; RV64I-LABEL: sh2adduw_imm:
715 ; RV64I-NEXT: slli a0, a0, 32
716 ; RV64I-NEXT: srli a0, a0, 30
717 ; RV64I-NEXT: addi a0, a0, -12
720 ; RV64ZBA-LABEL: sh2adduw_imm:
722 ; RV64ZBA-NEXT: slli.uw a0, a0, 2
723 ; RV64ZBA-NEXT: addi a0, a0, -12
725 %a = zext i32 %0 to i64
731 define i64 @sh3adduw_imm(i32 signext %0) {
732 ; RV64I-LABEL: sh3adduw_imm:
734 ; RV64I-NEXT: slli a0, a0, 32
735 ; RV64I-NEXT: srli a0, a0, 29
736 ; RV64I-NEXT: addi a0, a0, 13
739 ; RV64ZBA-LABEL: sh3adduw_imm:
741 ; RV64ZBA-NEXT: slli.uw a0, a0, 3
742 ; RV64ZBA-NEXT: addi a0, a0, 13
744 %a = zext i32 %0 to i64
750 define i64 @adduw_imm(i32 signext %0) nounwind {
751 ; RV64I-LABEL: adduw_imm:
753 ; RV64I-NEXT: slli a0, a0, 32
754 ; RV64I-NEXT: srli a0, a0, 32
755 ; RV64I-NEXT: addi a0, a0, 5
758 ; RV64ZBA-LABEL: adduw_imm:
760 ; RV64ZBA-NEXT: zext.w a0, a0
761 ; RV64ZBA-NEXT: addi a0, a0, 5
763 %a = zext i32 %0 to i64
768 define i64 @mul258(i64 %a) {
769 ; CHECK-LABEL: mul258:
771 ; CHECK-NEXT: li a1, 258
772 ; CHECK-NEXT: mul a0, a0, a1
778 define i64 @mul260(i64 %a) {
779 ; CHECK-LABEL: mul260:
781 ; CHECK-NEXT: li a1, 260
782 ; CHECK-NEXT: mul a0, a0, a1
788 define i64 @mul264(i64 %a) {
789 ; CHECK-LABEL: mul264:
791 ; CHECK-NEXT: li a1, 264
792 ; CHECK-NEXT: mul a0, a0, a1
798 define i64 @imm_zextw() nounwind {
799 ; RV64I-LABEL: imm_zextw:
801 ; RV64I-NEXT: li a0, 1
802 ; RV64I-NEXT: slli a0, a0, 32
803 ; RV64I-NEXT: addi a0, a0, -2
806 ; RV64ZBA-LABEL: imm_zextw:
808 ; RV64ZBA-NEXT: li a0, -2
809 ; RV64ZBA-NEXT: zext.w a0, a0
811 ret i64 4294967294 ; -2 in 32 bits.
814 define i64 @mul11(i64 %a) {
815 ; RV64I-LABEL: mul11:
817 ; RV64I-NEXT: li a1, 11
818 ; RV64I-NEXT: mul a0, a0, a1
821 ; RV64ZBA-LABEL: mul11:
823 ; RV64ZBA-NEXT: sh2add a1, a0, a0
824 ; RV64ZBA-NEXT: sh1add a0, a1, a0
830 define i64 @mul19(i64 %a) {
831 ; RV64I-LABEL: mul19:
833 ; RV64I-NEXT: li a1, 19
834 ; RV64I-NEXT: mul a0, a0, a1
837 ; RV64ZBA-LABEL: mul19:
839 ; RV64ZBA-NEXT: sh3add a1, a0, a0
840 ; RV64ZBA-NEXT: sh1add a0, a1, a0
846 define i64 @mul13(i64 %a) {
847 ; RV64I-LABEL: mul13:
849 ; RV64I-NEXT: li a1, 13
850 ; RV64I-NEXT: mul a0, a0, a1
853 ; RV64ZBA-LABEL: mul13:
855 ; RV64ZBA-NEXT: sh1add a1, a0, a0
856 ; RV64ZBA-NEXT: sh2add a0, a1, a0
862 define i64 @mul21(i64 %a) {
863 ; RV64I-LABEL: mul21:
865 ; RV64I-NEXT: li a1, 21
866 ; RV64I-NEXT: mul a0, a0, a1
869 ; RV64ZBA-LABEL: mul21:
871 ; RV64ZBA-NEXT: sh2add a1, a0, a0
872 ; RV64ZBA-NEXT: sh2add a0, a1, a0
878 define i64 @mul37(i64 %a) {
879 ; RV64I-LABEL: mul37:
881 ; RV64I-NEXT: li a1, 37
882 ; RV64I-NEXT: mul a0, a0, a1
885 ; RV64ZBA-LABEL: mul37:
887 ; RV64ZBA-NEXT: sh3add a1, a0, a0
888 ; RV64ZBA-NEXT: sh2add a0, a1, a0
894 define i64 @mul25(i64 %a) {
895 ; RV64I-LABEL: mul25:
897 ; RV64I-NEXT: li a1, 25
898 ; RV64I-NEXT: mul a0, a0, a1
901 ; RV64ZBA-LABEL: mul25:
903 ; RV64ZBA-NEXT: sh1add a1, a0, a0
904 ; RV64ZBA-NEXT: sh3add a0, a1, a0
910 define i64 @mul41(i64 %a) {
911 ; RV64I-LABEL: mul41:
913 ; RV64I-NEXT: li a1, 41
914 ; RV64I-NEXT: mul a0, a0, a1
917 ; RV64ZBA-LABEL: mul41:
919 ; RV64ZBA-NEXT: sh2add a1, a0, a0
920 ; RV64ZBA-NEXT: sh3add a0, a1, a0
926 define i64 @mul73(i64 %a) {
927 ; RV64I-LABEL: mul73:
929 ; RV64I-NEXT: li a1, 73
930 ; RV64I-NEXT: mul a0, a0, a1
933 ; RV64ZBA-LABEL: mul73:
935 ; RV64ZBA-NEXT: sh3add a1, a0, a0
936 ; RV64ZBA-NEXT: sh3add a0, a1, a0
942 define i64 @mul27(i64 %a) {
943 ; RV64I-LABEL: mul27:
945 ; RV64I-NEXT: li a1, 27
946 ; RV64I-NEXT: mul a0, a0, a1
949 ; RV64ZBA-LABEL: mul27:
951 ; RV64ZBA-NEXT: sh3add a0, a0, a0
952 ; RV64ZBA-NEXT: sh1add a0, a0, a0
958 define i64 @mul45(i64 %a) {
959 ; RV64I-LABEL: mul45:
961 ; RV64I-NEXT: li a1, 45
962 ; RV64I-NEXT: mul a0, a0, a1
965 ; RV64ZBA-LABEL: mul45:
967 ; RV64ZBA-NEXT: sh3add a0, a0, a0
968 ; RV64ZBA-NEXT: sh2add a0, a0, a0
974 define i64 @mul81(i64 %a) {
975 ; RV64I-LABEL: mul81:
977 ; RV64I-NEXT: li a1, 81
978 ; RV64I-NEXT: mul a0, a0, a1
981 ; RV64ZBA-LABEL: mul81:
983 ; RV64ZBA-NEXT: sh3add a0, a0, a0
984 ; RV64ZBA-NEXT: sh3add a0, a0, a0
990 define i64 @mul4098(i64 %a) {
991 ; RV64I-LABEL: mul4098:
993 ; RV64I-NEXT: slli a1, a0, 1
994 ; RV64I-NEXT: slli a0, a0, 12
995 ; RV64I-NEXT: add a0, a0, a1
998 ; RV64ZBA-LABEL: mul4098:
1000 ; RV64ZBA-NEXT: slli a1, a0, 12
1001 ; RV64ZBA-NEXT: sh1add a0, a0, a1
1003 %c = mul i64 %a, 4098
1007 define i64 @mul4100(i64 %a) {
1008 ; RV64I-LABEL: mul4100:
1010 ; RV64I-NEXT: slli a1, a0, 2
1011 ; RV64I-NEXT: slli a0, a0, 12
1012 ; RV64I-NEXT: add a0, a0, a1
1015 ; RV64ZBA-LABEL: mul4100:
1017 ; RV64ZBA-NEXT: slli a1, a0, 12
1018 ; RV64ZBA-NEXT: sh2add a0, a0, a1
1020 %c = mul i64 %a, 4100
1024 define i64 @mul4104(i64 %a) {
1025 ; RV64I-LABEL: mul4104:
1027 ; RV64I-NEXT: slli a1, a0, 3
1028 ; RV64I-NEXT: slli a0, a0, 12
1029 ; RV64I-NEXT: add a0, a0, a1
1032 ; RV64ZBA-LABEL: mul4104:
1034 ; RV64ZBA-NEXT: slli a1, a0, 12
1035 ; RV64ZBA-NEXT: sh3add a0, a0, a1
1037 %c = mul i64 %a, 4104
1041 define signext i32 @mulw192(i32 signext %a) {
1042 ; CHECK-LABEL: mulw192:
1044 ; CHECK-NEXT: li a1, 192
1045 ; CHECK-NEXT: mulw a0, a0, a1
1047 %c = mul i32 %a, 192
1051 define signext i32 @mulw320(i32 signext %a) {
1052 ; CHECK-LABEL: mulw320:
1054 ; CHECK-NEXT: li a1, 320
1055 ; CHECK-NEXT: mulw a0, a0, a1
1057 %c = mul i32 %a, 320
1061 define signext i32 @mulw576(i32 signext %a) {
1062 ; CHECK-LABEL: mulw576:
1064 ; CHECK-NEXT: li a1, 576
1065 ; CHECK-NEXT: mulw a0, a0, a1
1067 %c = mul i32 %a, 576
1071 define i64 @add4104(i64 %a) {
1072 ; RV64I-LABEL: add4104:
1074 ; RV64I-NEXT: lui a1, 1
1075 ; RV64I-NEXT: addiw a1, a1, 8
1076 ; RV64I-NEXT: add a0, a0, a1
1079 ; RV64ZBA-LABEL: add4104:
1081 ; RV64ZBA-NEXT: li a1, 1026
1082 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1084 %c = add i64 %a, 4104
1088 define i64 @add8208(i64 %a) {
1089 ; RV64I-LABEL: add8208:
1091 ; RV64I-NEXT: lui a1, 2
1092 ; RV64I-NEXT: addiw a1, a1, 16
1093 ; RV64I-NEXT: add a0, a0, a1
1096 ; RV64ZBA-LABEL: add8208:
1098 ; RV64ZBA-NEXT: li a1, 1026
1099 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1101 %c = add i64 %a, 8208
1105 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1106 define signext i32 @add8192_i32(i32 signext %a) {
1107 ; CHECK-LABEL: add8192_i32:
1109 ; CHECK-NEXT: lui a1, 2
1110 ; CHECK-NEXT: addw a0, a0, a1
1112 %c = add i32 %a, 8192
1116 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1117 define i64 @add8192(i64 %a) {
1118 ; CHECK-LABEL: add8192:
1120 ; CHECK-NEXT: lui a1, 2
1121 ; CHECK-NEXT: add a0, a0, a1
1123 %c = add i64 %a, 8192
1127 define signext i32 @addshl32_5_6(i32 signext %a, i32 signext %b) {
1128 ; RV64I-LABEL: addshl32_5_6:
1130 ; RV64I-NEXT: slli a0, a0, 5
1131 ; RV64I-NEXT: slli a1, a1, 6
1132 ; RV64I-NEXT: addw a0, a0, a1
1135 ; RV64ZBA-LABEL: addshl32_5_6:
1137 ; RV64ZBA-NEXT: slli a1, a1, 1
1138 ; RV64ZBA-NEXT: add a0, a1, a0
1139 ; RV64ZBA-NEXT: slliw a0, a0, 5
1147 define i64 @addshl64_5_6(i64 %a, i64 %b) {
1148 ; RV64I-LABEL: addshl64_5_6:
1150 ; RV64I-NEXT: slli a0, a0, 5
1151 ; RV64I-NEXT: slli a1, a1, 6
1152 ; RV64I-NEXT: add a0, a0, a1
1155 ; RV64ZBA-LABEL: addshl64_5_6:
1157 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1158 ; RV64ZBA-NEXT: slli a0, a0, 5
1166 define signext i32 @addshl32_5_7(i32 signext %a, i32 signext %b) {
1167 ; RV64I-LABEL: addshl32_5_7:
1169 ; RV64I-NEXT: slli a0, a0, 5
1170 ; RV64I-NEXT: slli a1, a1, 7
1171 ; RV64I-NEXT: addw a0, a0, a1
1174 ; RV64ZBA-LABEL: addshl32_5_7:
1176 ; RV64ZBA-NEXT: slli a1, a1, 2
1177 ; RV64ZBA-NEXT: add a0, a1, a0
1178 ; RV64ZBA-NEXT: slliw a0, a0, 5
1186 define i64 @addshl64_5_7(i64 %a, i64 %b) {
1187 ; RV64I-LABEL: addshl64_5_7:
1189 ; RV64I-NEXT: slli a0, a0, 5
1190 ; RV64I-NEXT: slli a1, a1, 7
1191 ; RV64I-NEXT: add a0, a0, a1
1194 ; RV64ZBA-LABEL: addshl64_5_7:
1196 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1197 ; RV64ZBA-NEXT: slli a0, a0, 5
1205 define signext i32 @addshl32_5_8(i32 signext %a, i32 signext %b) {
1206 ; RV64I-LABEL: addshl32_5_8:
1208 ; RV64I-NEXT: slli a0, a0, 5
1209 ; RV64I-NEXT: slli a1, a1, 8
1210 ; RV64I-NEXT: addw a0, a0, a1
1213 ; RV64ZBA-LABEL: addshl32_5_8:
1215 ; RV64ZBA-NEXT: slli a1, a1, 3
1216 ; RV64ZBA-NEXT: add a0, a1, a0
1217 ; RV64ZBA-NEXT: slliw a0, a0, 5
1225 define i64 @addshl64_5_8(i64 %a, i64 %b) {
1226 ; RV64I-LABEL: addshl64_5_8:
1228 ; RV64I-NEXT: slli a0, a0, 5
1229 ; RV64I-NEXT: slli a1, a1, 8
1230 ; RV64I-NEXT: add a0, a0, a1
1233 ; RV64ZBA-LABEL: addshl64_5_8:
1235 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1236 ; RV64ZBA-NEXT: slli a0, a0, 5
1244 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1245 ; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
1246 define zeroext i32 @sext_ashr_zext_i8(i8 %a) nounwind {
1247 ; RV64I-LABEL: sext_ashr_zext_i8:
1249 ; RV64I-NEXT: slli a0, a0, 24
1250 ; RV64I-NEXT: sraiw a0, a0, 31
1251 ; RV64I-NEXT: slli a0, a0, 32
1252 ; RV64I-NEXT: srli a0, a0, 32
1255 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i8:
1256 ; RV64ZBANOZBB: # %bb.0:
1257 ; RV64ZBANOZBB-NEXT: slli a0, a0, 24
1258 ; RV64ZBANOZBB-NEXT: sraiw a0, a0, 31
1259 ; RV64ZBANOZBB-NEXT: zext.w a0, a0
1260 ; RV64ZBANOZBB-NEXT: ret
1262 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i8:
1263 ; RV64ZBAZBB: # %bb.0:
1264 ; RV64ZBAZBB-NEXT: sext.b a0, a0
1265 ; RV64ZBAZBB-NEXT: sraiw a0, a0, 9
1266 ; RV64ZBAZBB-NEXT: zext.w a0, a0
1267 ; RV64ZBAZBB-NEXT: ret
1268 %ext = sext i8 %a to i32
1269 %1 = ashr i32 %ext, 9
1273 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1274 ; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
1275 define zeroext i32 @sext_ashr_zext_i16(i16 %a) nounwind {
1276 ; RV64I-LABEL: sext_ashr_zext_i16:
1278 ; RV64I-NEXT: slli a0, a0, 16
1279 ; RV64I-NEXT: sraiw a0, a0, 25
1280 ; RV64I-NEXT: slli a0, a0, 32
1281 ; RV64I-NEXT: srli a0, a0, 32
1284 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i16:
1285 ; RV64ZBANOZBB: # %bb.0:
1286 ; RV64ZBANOZBB-NEXT: slli a0, a0, 16
1287 ; RV64ZBANOZBB-NEXT: sraiw a0, a0, 25
1288 ; RV64ZBANOZBB-NEXT: zext.w a0, a0
1289 ; RV64ZBANOZBB-NEXT: ret
1291 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i16:
1292 ; RV64ZBAZBB: # %bb.0:
1293 ; RV64ZBAZBB-NEXT: slli a0, a0, 48
1294 ; RV64ZBAZBB-NEXT: srai a0, a0, 57
1295 ; RV64ZBAZBB-NEXT: zext.w a0, a0
1296 ; RV64ZBAZBB-NEXT: ret
1297 %ext = sext i16 %a to i32
1298 %1 = ashr i32 %ext, 9
1302 ; This the IR you get from InstCombine if take the difference of 2 pointers and
1303 ; cast is to unsigned before using as an index.
1304 define signext i16 @sh1adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1305 ; RV64I-LABEL: sh1adduw_ptrdiff:
1307 ; RV64I-NEXT: li a2, 1
1308 ; RV64I-NEXT: slli a2, a2, 33
1309 ; RV64I-NEXT: addi a2, a2, -2
1310 ; RV64I-NEXT: and a0, a0, a2
1311 ; RV64I-NEXT: add a0, a1, a0
1312 ; RV64I-NEXT: lh a0, 0(a0)
1315 ; RV64ZBA-LABEL: sh1adduw_ptrdiff:
1317 ; RV64ZBA-NEXT: srli a0, a0, 1
1318 ; RV64ZBA-NEXT: sh1add.uw a0, a0, a1
1319 ; RV64ZBA-NEXT: lh a0, 0(a0)
1321 %ptrdiff = lshr exact i64 %diff, 1
1322 %cast = and i64 %ptrdiff, 4294967295
1323 %ptr = getelementptr inbounds i16, ptr %baseptr, i64 %cast
1324 %res = load i16, ptr %ptr
1328 define signext i32 @sh2adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1329 ; RV64I-LABEL: sh2adduw_ptrdiff:
1331 ; RV64I-NEXT: li a2, 1
1332 ; RV64I-NEXT: slli a2, a2, 34
1333 ; RV64I-NEXT: addi a2, a2, -4
1334 ; RV64I-NEXT: and a0, a0, a2
1335 ; RV64I-NEXT: add a0, a1, a0
1336 ; RV64I-NEXT: lw a0, 0(a0)
1339 ; RV64ZBA-LABEL: sh2adduw_ptrdiff:
1341 ; RV64ZBA-NEXT: srli a0, a0, 2
1342 ; RV64ZBA-NEXT: sh2add.uw a0, a0, a1
1343 ; RV64ZBA-NEXT: lw a0, 0(a0)
1345 %ptrdiff = lshr exact i64 %diff, 2
1346 %cast = and i64 %ptrdiff, 4294967295
1347 %ptr = getelementptr inbounds i32, ptr %baseptr, i64 %cast
1348 %res = load i32, ptr %ptr
1352 define i64 @sh3adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1353 ; RV64I-LABEL: sh3adduw_ptrdiff:
1355 ; RV64I-NEXT: li a2, 1
1356 ; RV64I-NEXT: slli a2, a2, 35
1357 ; RV64I-NEXT: addi a2, a2, -8
1358 ; RV64I-NEXT: and a0, a0, a2
1359 ; RV64I-NEXT: add a0, a1, a0
1360 ; RV64I-NEXT: ld a0, 0(a0)
1363 ; RV64ZBA-LABEL: sh3adduw_ptrdiff:
1365 ; RV64ZBA-NEXT: srli a0, a0, 3
1366 ; RV64ZBA-NEXT: sh3add.uw a0, a0, a1
1367 ; RV64ZBA-NEXT: ld a0, 0(a0)
1369 %ptrdiff = lshr exact i64 %diff, 3
1370 %cast = and i64 %ptrdiff, 4294967295
1371 %ptr = getelementptr inbounds i64, ptr %baseptr, i64 %cast
1372 %res = load i64, ptr %ptr
1376 define signext i16 @srliw_1_sh1add(ptr %0, i32 signext %1) {
1377 ; RV64I-LABEL: srliw_1_sh1add:
1379 ; RV64I-NEXT: srliw a1, a1, 1
1380 ; RV64I-NEXT: slli a1, a1, 1
1381 ; RV64I-NEXT: add a0, a0, a1
1382 ; RV64I-NEXT: lh a0, 0(a0)
1385 ; RV64ZBA-LABEL: srliw_1_sh1add:
1387 ; RV64ZBA-NEXT: srliw a1, a1, 1
1388 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1389 ; RV64ZBA-NEXT: lh a0, 0(a0)
1392 %4 = zext i32 %3 to i64
1393 %5 = getelementptr inbounds i16, ptr %0, i64 %4
1394 %6 = load i16, ptr %5, align 2
1398 define i128 @slliuw_ptrdiff(i64 %diff, ptr %baseptr) {
1399 ; RV64I-LABEL: slliuw_ptrdiff:
1401 ; RV64I-NEXT: li a2, 1
1402 ; RV64I-NEXT: slli a2, a2, 36
1403 ; RV64I-NEXT: addi a2, a2, -16
1404 ; RV64I-NEXT: and a0, a0, a2
1405 ; RV64I-NEXT: add a1, a1, a0
1406 ; RV64I-NEXT: ld a0, 0(a1)
1407 ; RV64I-NEXT: ld a1, 8(a1)
1410 ; RV64ZBA-LABEL: slliuw_ptrdiff:
1412 ; RV64ZBA-NEXT: srli a0, a0, 4
1413 ; RV64ZBA-NEXT: slli.uw a0, a0, 4
1414 ; RV64ZBA-NEXT: add a1, a1, a0
1415 ; RV64ZBA-NEXT: ld a0, 0(a1)
1416 ; RV64ZBA-NEXT: ld a1, 8(a1)
1418 %ptrdiff = lshr exact i64 %diff, 4
1419 %cast = and i64 %ptrdiff, 4294967295
1420 %ptr = getelementptr inbounds i128, ptr %baseptr, i64 %cast
1421 %res = load i128, ptr %ptr
1425 define signext i32 @srliw_2_sh2add(ptr %0, i32 signext %1) {
1426 ; RV64I-LABEL: srliw_2_sh2add:
1428 ; RV64I-NEXT: srliw a1, a1, 2
1429 ; RV64I-NEXT: slli a1, a1, 2
1430 ; RV64I-NEXT: add a0, a0, a1
1431 ; RV64I-NEXT: lw a0, 0(a0)
1434 ; RV64ZBA-LABEL: srliw_2_sh2add:
1436 ; RV64ZBA-NEXT: srliw a1, a1, 2
1437 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1438 ; RV64ZBA-NEXT: lw a0, 0(a0)
1441 %4 = zext i32 %3 to i64
1442 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1443 %6 = load i32, ptr %5, align 4
1447 define i64 @srliw_3_sh3add(ptr %0, i32 signext %1) {
1448 ; RV64I-LABEL: srliw_3_sh3add:
1450 ; RV64I-NEXT: srliw a1, a1, 3
1451 ; RV64I-NEXT: slli a1, a1, 3
1452 ; RV64I-NEXT: add a0, a0, a1
1453 ; RV64I-NEXT: ld a0, 0(a0)
1456 ; RV64ZBA-LABEL: srliw_3_sh3add:
1458 ; RV64ZBA-NEXT: srliw a1, a1, 3
1459 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1460 ; RV64ZBA-NEXT: ld a0, 0(a0)
1463 %4 = zext i32 %3 to i64
1464 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1465 %6 = load i64, ptr %5, align 8
1469 define signext i32 @srliw_1_sh2add(ptr %0, i32 signext %1) {
1470 ; RV64I-LABEL: srliw_1_sh2add:
1472 ; RV64I-NEXT: srliw a1, a1, 1
1473 ; RV64I-NEXT: slli a1, a1, 32
1474 ; RV64I-NEXT: srli a1, a1, 32
1475 ; RV64I-NEXT: slli a1, a1, 2
1476 ; RV64I-NEXT: add a0, a0, a1
1477 ; RV64I-NEXT: lw a0, 0(a0)
1480 ; RV64ZBA-LABEL: srliw_1_sh2add:
1482 ; RV64ZBA-NEXT: srliw a1, a1, 1
1483 ; RV64ZBA-NEXT: zext.w a1, a1
1484 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1485 ; RV64ZBA-NEXT: lw a0, 0(a0)
1488 %4 = zext i32 %3 to i64
1489 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1490 %6 = load i32, ptr %5, align 4
1494 define i64 @srliw_1_sh3add(ptr %0, i32 signext %1) {
1495 ; RV64I-LABEL: srliw_1_sh3add:
1497 ; RV64I-NEXT: srliw a1, a1, 1
1498 ; RV64I-NEXT: slli a1, a1, 32
1499 ; RV64I-NEXT: srli a1, a1, 32
1500 ; RV64I-NEXT: slli a1, a1, 3
1501 ; RV64I-NEXT: add a0, a0, a1
1502 ; RV64I-NEXT: ld a0, 0(a0)
1505 ; RV64ZBA-LABEL: srliw_1_sh3add:
1507 ; RV64ZBA-NEXT: srliw a1, a1, 1
1508 ; RV64ZBA-NEXT: zext.w a1, a1
1509 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1510 ; RV64ZBA-NEXT: ld a0, 0(a0)
1513 %4 = zext i32 %3 to i64
1514 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1515 %6 = load i64, ptr %5, align 8
1519 define i64 @srliw_2_sh3add(ptr %0, i32 signext %1) {
1520 ; RV64I-LABEL: srliw_2_sh3add:
1522 ; RV64I-NEXT: srliw a1, a1, 2
1523 ; RV64I-NEXT: slli a1, a1, 32
1524 ; RV64I-NEXT: srli a1, a1, 32
1525 ; RV64I-NEXT: slli a1, a1, 3
1526 ; RV64I-NEXT: add a0, a0, a1
1527 ; RV64I-NEXT: ld a0, 0(a0)
1530 ; RV64ZBA-LABEL: srliw_2_sh3add:
1532 ; RV64ZBA-NEXT: srliw a1, a1, 2
1533 ; RV64ZBA-NEXT: zext.w a1, a1
1534 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1535 ; RV64ZBA-NEXT: ld a0, 0(a0)
1538 %4 = zext i32 %3 to i64
1539 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1540 %6 = load i64, ptr %5, align 8
1544 define signext i16 @srliw_2_sh1add(ptr %0, i32 signext %1) {
1545 ; RV64I-LABEL: srliw_2_sh1add:
1547 ; RV64I-NEXT: srliw a1, a1, 2
1548 ; RV64I-NEXT: slli a1, a1, 32
1549 ; RV64I-NEXT: srli a1, a1, 32
1550 ; RV64I-NEXT: slli a1, a1, 1
1551 ; RV64I-NEXT: add a0, a0, a1
1552 ; RV64I-NEXT: lh a0, 0(a0)
1555 ; RV64ZBA-LABEL: srliw_2_sh1add:
1557 ; RV64ZBA-NEXT: srliw a1, a1, 2
1558 ; RV64ZBA-NEXT: zext.w a1, a1
1559 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1560 ; RV64ZBA-NEXT: lh a0, 0(a0)
1563 %4 = zext i32 %3 to i64
1564 %5 = getelementptr inbounds i16, ptr %0, i64 %4
1565 %6 = load i16, ptr %5, align 2
1570 define signext i32 @srliw_3_sh2add(ptr %0, i32 signext %1) {
1571 ; RV64I-LABEL: srliw_3_sh2add:
1573 ; RV64I-NEXT: srliw a1, a1, 3
1574 ; RV64I-NEXT: slli a1, a1, 32
1575 ; RV64I-NEXT: srli a1, a1, 32
1576 ; RV64I-NEXT: slli a1, a1, 2
1577 ; RV64I-NEXT: add a0, a0, a1
1578 ; RV64I-NEXT: lw a0, 0(a0)
1581 ; RV64ZBA-LABEL: srliw_3_sh2add:
1583 ; RV64ZBA-NEXT: srliw a1, a1, 3
1584 ; RV64ZBA-NEXT: zext.w a1, a1
1585 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1586 ; RV64ZBA-NEXT: lw a0, 0(a0)
1589 %4 = zext i32 %3 to i64
1590 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1591 %6 = load i32, ptr %5, align 4
1595 define i64 @srliw_4_sh3add(ptr %0, i32 signext %1) {
1596 ; RV64I-LABEL: srliw_4_sh3add:
1598 ; RV64I-NEXT: srliw a1, a1, 4
1599 ; RV64I-NEXT: slli a1, a1, 32
1600 ; RV64I-NEXT: srli a1, a1, 32
1601 ; RV64I-NEXT: slli a1, a1, 3
1602 ; RV64I-NEXT: add a0, a0, a1
1603 ; RV64I-NEXT: ld a0, 0(a0)
1606 ; RV64ZBA-LABEL: srliw_4_sh3add:
1608 ; RV64ZBA-NEXT: srliw a1, a1, 4
1609 ; RV64ZBA-NEXT: zext.w a1, a1
1610 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1611 ; RV64ZBA-NEXT: ld a0, 0(a0)
1614 %4 = zext i32 %3 to i64
1615 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1616 %6 = load i64, ptr %5, align 8
1620 define signext i32 @srli_1_sh2add(ptr %0, i64 %1) {
1621 ; RV64I-LABEL: srli_1_sh2add:
1623 ; RV64I-NEXT: slli a1, a1, 1
1624 ; RV64I-NEXT: andi a1, a1, -4
1625 ; RV64I-NEXT: add a0, a0, a1
1626 ; RV64I-NEXT: lw a0, 0(a0)
1629 ; RV64ZBA-LABEL: srli_1_sh2add:
1631 ; RV64ZBA-NEXT: srli a1, a1, 1
1632 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1633 ; RV64ZBA-NEXT: lw a0, 0(a0)
1636 %4 = getelementptr inbounds i32, ptr %0, i64 %3
1637 %5 = load i32, ptr %4, align 4
1641 define i64 @srli_2_sh3add(ptr %0, i64 %1) {
1642 ; RV64I-LABEL: srli_2_sh3add:
1644 ; RV64I-NEXT: slli a1, a1, 1
1645 ; RV64I-NEXT: andi a1, a1, -8
1646 ; RV64I-NEXT: add a0, a0, a1
1647 ; RV64I-NEXT: ld a0, 0(a0)
1650 ; RV64ZBA-LABEL: srli_2_sh3add:
1652 ; RV64ZBA-NEXT: srli a1, a1, 2
1653 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1654 ; RV64ZBA-NEXT: ld a0, 0(a0)
1657 %4 = getelementptr inbounds i64, ptr %0, i64 %3
1658 %5 = load i64, ptr %4, align 8
1662 define signext i16 @srli_2_sh1add(ptr %0, i64 %1) {
1663 ; RV64I-LABEL: srli_2_sh1add:
1665 ; RV64I-NEXT: srli a1, a1, 1
1666 ; RV64I-NEXT: andi a1, a1, -2
1667 ; RV64I-NEXT: add a0, a0, a1
1668 ; RV64I-NEXT: lh a0, 0(a0)
1671 ; RV64ZBA-LABEL: srli_2_sh1add:
1673 ; RV64ZBA-NEXT: srli a1, a1, 2
1674 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1675 ; RV64ZBA-NEXT: lh a0, 0(a0)
1678 %4 = getelementptr inbounds i16, ptr %0, i64 %3
1679 %5 = load i16, ptr %4, align 2
1683 define signext i32 @srli_3_sh2add(ptr %0, i64 %1) {
1684 ; RV64I-LABEL: srli_3_sh2add:
1686 ; RV64I-NEXT: srli a1, a1, 1
1687 ; RV64I-NEXT: andi a1, a1, -4
1688 ; RV64I-NEXT: add a0, a0, a1
1689 ; RV64I-NEXT: lw a0, 0(a0)
1692 ; RV64ZBA-LABEL: srli_3_sh2add:
1694 ; RV64ZBA-NEXT: srli a1, a1, 3
1695 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1696 ; RV64ZBA-NEXT: lw a0, 0(a0)
1699 %4 = getelementptr inbounds i32, ptr %0, i64 %3
1700 %5 = load i32, ptr %4, align 4
1704 define i64 @srli_4_sh3add(ptr %0, i64 %1) {
1705 ; RV64I-LABEL: srli_4_sh3add:
1707 ; RV64I-NEXT: srli a1, a1, 1
1708 ; RV64I-NEXT: andi a1, a1, -8
1709 ; RV64I-NEXT: add a0, a0, a1
1710 ; RV64I-NEXT: ld a0, 0(a0)
1713 ; RV64ZBA-LABEL: srli_4_sh3add:
1715 ; RV64ZBA-NEXT: srli a1, a1, 4
1716 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1717 ; RV64ZBA-NEXT: ld a0, 0(a0)
1720 %4 = getelementptr inbounds i64, ptr %0, i64 %3
1721 %5 = load i64, ptr %4, align 8
1725 define signext i16 @shl_2_sh1add(ptr %0, i32 signext %1) {
1726 ; RV64I-LABEL: shl_2_sh1add:
1728 ; RV64I-NEXT: slli a1, a1, 2
1729 ; RV64I-NEXT: slli a1, a1, 32
1730 ; RV64I-NEXT: srli a1, a1, 32
1731 ; RV64I-NEXT: slli a1, a1, 1
1732 ; RV64I-NEXT: add a0, a0, a1
1733 ; RV64I-NEXT: lh a0, 0(a0)
1736 ; RV64ZBA-LABEL: shl_2_sh1add:
1738 ; RV64ZBA-NEXT: slli a1, a1, 2
1739 ; RV64ZBA-NEXT: zext.w a1, a1
1740 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1741 ; RV64ZBA-NEXT: lh a0, 0(a0)
1744 %4 = zext i32 %3 to i64
1745 %5 = getelementptr inbounds i16, ptr %0, i64 %4
1746 %6 = load i16, ptr %5, align 2
1750 define signext i32 @shl_16_sh2add(ptr %0, i32 signext %1) {
1751 ; RV64I-LABEL: shl_16_sh2add:
1753 ; RV64I-NEXT: slli a1, a1, 16
1754 ; RV64I-NEXT: slli a1, a1, 32
1755 ; RV64I-NEXT: srli a1, a1, 32
1756 ; RV64I-NEXT: slli a1, a1, 2
1757 ; RV64I-NEXT: add a0, a0, a1
1758 ; RV64I-NEXT: lw a0, 0(a0)
1761 ; RV64ZBA-LABEL: shl_16_sh2add:
1763 ; RV64ZBA-NEXT: slli a1, a1, 16
1764 ; RV64ZBA-NEXT: zext.w a1, a1
1765 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1766 ; RV64ZBA-NEXT: lw a0, 0(a0)
1769 %4 = zext i32 %3 to i64
1770 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1771 %6 = load i32, ptr %5, align 4
1775 define i64 @shl_31_sh3add(ptr %0, i32 signext %1) {
1776 ; RV64I-LABEL: shl_31_sh3add:
1778 ; RV64I-NEXT: slli a1, a1, 31
1779 ; RV64I-NEXT: slli a1, a1, 32
1780 ; RV64I-NEXT: srli a1, a1, 32
1781 ; RV64I-NEXT: slli a1, a1, 3
1782 ; RV64I-NEXT: add a0, a0, a1
1783 ; RV64I-NEXT: ld a0, 0(a0)
1786 ; RV64ZBA-LABEL: shl_31_sh3add:
1788 ; RV64ZBA-NEXT: slli a1, a1, 31
1789 ; RV64ZBA-NEXT: zext.w a1, a1
1790 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1791 ; RV64ZBA-NEXT: ld a0, 0(a0)
1794 %4 = zext i32 %3 to i64
1795 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1796 %6 = load i64, ptr %5, align 8