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 i128 @slliuw_3(i32 signext %0, ptr %1) {
49 ; RV64I-LABEL: slliuw_3:
51 ; RV64I-NEXT: addi a0, a0, 1
52 ; RV64I-NEXT: slli a0, a0, 32
53 ; RV64I-NEXT: srli a0, a0, 28
54 ; RV64I-NEXT: add a1, a1, a0
55 ; RV64I-NEXT: ld a0, 0(a1)
56 ; RV64I-NEXT: ld a1, 8(a1)
59 ; RV64ZBA-LABEL: slliuw_3:
61 ; RV64ZBA-NEXT: addi a0, a0, 1
62 ; RV64ZBA-NEXT: slli.uw a0, a0, 4
63 ; RV64ZBA-NEXT: add a1, a1, a0
64 ; RV64ZBA-NEXT: ld a0, 0(a1)
65 ; RV64ZBA-NEXT: ld a1, 8(a1)
68 %3 = zext i32 %add to i64
69 %4 = getelementptr inbounds i128, ptr %1, i64 %3
70 %5 = load i128, ptr %4
74 define i64 @adduw(i64 %a, i64 %b) nounwind {
77 ; RV64I-NEXT: slli a1, a1, 32
78 ; RV64I-NEXT: srli a1, a1, 32
79 ; RV64I-NEXT: add a0, a1, a0
82 ; RV64ZBA-LABEL: adduw:
84 ; RV64ZBA-NEXT: add.uw a0, a1, a0
86 %and = and i64 %b, 4294967295
87 %add = add i64 %and, %a
91 define signext i8 @adduw_2(i32 signext %0, ptr %1) {
92 ; RV64I-LABEL: adduw_2:
94 ; RV64I-NEXT: slli a0, a0, 32
95 ; RV64I-NEXT: srli a0, a0, 32
96 ; RV64I-NEXT: add a0, a1, a0
97 ; RV64I-NEXT: lb a0, 0(a0)
100 ; RV64ZBA-LABEL: adduw_2:
102 ; RV64ZBA-NEXT: add.uw a0, a0, a1
103 ; RV64ZBA-NEXT: lb a0, 0(a0)
105 %3 = zext i32 %0 to i64
106 %4 = getelementptr inbounds i8, ptr %1, i64 %3
111 define signext i8 @adduw_3(i32 signext %0, ptr %1) {
112 ; RV64I-LABEL: adduw_3:
114 ; RV64I-NEXT: addi a0, a0, 1
115 ; RV64I-NEXT: slli a0, a0, 32
116 ; RV64I-NEXT: srli a0, a0, 32
117 ; RV64I-NEXT: add a0, a1, a0
118 ; RV64I-NEXT: lb a0, 0(a0)
121 ; RV64ZBA-LABEL: adduw_3:
123 ; RV64ZBA-NEXT: addi a0, a0, 1
124 ; RV64ZBA-NEXT: add.uw a0, a0, a1
125 ; RV64ZBA-NEXT: lb a0, 0(a0)
128 %3 = zext i32 %add to i64
129 %4 = getelementptr inbounds i8, ptr %1, i64 %3
134 define i64 @zextw_i64(i64 %a) nounwind {
135 ; RV64I-LABEL: zextw_i64:
137 ; RV64I-NEXT: slli a0, a0, 32
138 ; RV64I-NEXT: srli a0, a0, 32
141 ; RV64ZBA-LABEL: zextw_i64:
143 ; RV64ZBA-NEXT: zext.w a0, a0
145 %and = and i64 %a, 4294967295
149 ; This makes sure targetShrinkDemandedConstant changes the and immmediate to
150 ; allow zext.w or slli+srli.
151 define i64 @zextw_demandedbits_i64(i64 %0) {
152 ; RV64I-LABEL: zextw_demandedbits_i64:
154 ; RV64I-NEXT: ori a0, a0, 1
155 ; RV64I-NEXT: slli a0, a0, 32
156 ; RV64I-NEXT: srli a0, a0, 32
159 ; RV64ZBA-LABEL: zextw_demandedbits_i64:
161 ; RV64ZBA-NEXT: ori a0, a0, 1
162 ; RV64ZBA-NEXT: zext.w a0, a0
164 %2 = and i64 %0, 4294967294
169 define signext i16 @sh1add(i64 %0, ptr %1) {
170 ; RV64I-LABEL: sh1add:
172 ; RV64I-NEXT: slli a0, a0, 1
173 ; RV64I-NEXT: add a0, a1, a0
174 ; RV64I-NEXT: lh a0, 0(a0)
177 ; RV64ZBA-LABEL: sh1add:
179 ; RV64ZBA-NEXT: sh1add a0, a0, a1
180 ; RV64ZBA-NEXT: lh a0, 0(a0)
182 %3 = getelementptr inbounds i16, ptr %1, i64 %0
183 %4 = load i16, ptr %3
187 define signext i32 @sh2add(i64 %0, ptr %1) {
188 ; RV64I-LABEL: sh2add:
190 ; RV64I-NEXT: slli a0, a0, 2
191 ; RV64I-NEXT: add a0, a1, a0
192 ; RV64I-NEXT: lw a0, 0(a0)
195 ; RV64ZBA-LABEL: sh2add:
197 ; RV64ZBA-NEXT: sh2add a0, a0, a1
198 ; RV64ZBA-NEXT: lw a0, 0(a0)
200 %3 = getelementptr inbounds i32, ptr %1, i64 %0
201 %4 = load i32, ptr %3
205 define i64 @sh3add(i64 %0, ptr %1) {
206 ; RV64I-LABEL: sh3add:
208 ; RV64I-NEXT: slli a0, a0, 3
209 ; RV64I-NEXT: add a0, a1, a0
210 ; RV64I-NEXT: ld a0, 0(a0)
213 ; RV64ZBA-LABEL: sh3add:
215 ; RV64ZBA-NEXT: sh3add a0, a0, a1
216 ; RV64ZBA-NEXT: ld a0, 0(a0)
218 %3 = getelementptr inbounds i64, ptr %1, i64 %0
219 %4 = load i64, ptr %3
223 define signext i16 @sh1adduw(i32 signext %0, ptr %1) {
224 ; RV64I-LABEL: sh1adduw:
226 ; RV64I-NEXT: slli a0, a0, 32
227 ; RV64I-NEXT: srli a0, a0, 31
228 ; RV64I-NEXT: add a0, a1, a0
229 ; RV64I-NEXT: lh a0, 0(a0)
232 ; RV64ZBA-LABEL: sh1adduw:
234 ; RV64ZBA-NEXT: sh1add.uw a0, a0, a1
235 ; RV64ZBA-NEXT: lh a0, 0(a0)
237 %3 = zext i32 %0 to i64
238 %4 = getelementptr inbounds i16, ptr %1, i64 %3
239 %5 = load i16, ptr %4
243 define i64 @sh1adduw_2(i64 %0, i64 %1) {
244 ; RV64I-LABEL: sh1adduw_2:
246 ; RV64I-NEXT: slli a0, a0, 32
247 ; RV64I-NEXT: srli a0, a0, 31
248 ; RV64I-NEXT: add a0, a0, a1
251 ; RV64ZBA-LABEL: sh1adduw_2:
253 ; RV64ZBA-NEXT: sh1add.uw a0, a0, a1
256 %4 = and i64 %3, 8589934590
261 define signext i32 @sh2adduw(i32 signext %0, ptr %1) {
262 ; RV64I-LABEL: sh2adduw:
264 ; RV64I-NEXT: slli a0, a0, 32
265 ; RV64I-NEXT: srli a0, a0, 30
266 ; RV64I-NEXT: add a0, a1, a0
267 ; RV64I-NEXT: lw a0, 0(a0)
270 ; RV64ZBA-LABEL: sh2adduw:
272 ; RV64ZBA-NEXT: sh2add.uw a0, a0, a1
273 ; RV64ZBA-NEXT: lw a0, 0(a0)
275 %3 = zext i32 %0 to i64
276 %4 = getelementptr inbounds i32, ptr %1, i64 %3
277 %5 = load i32, ptr %4
281 define i64 @sh2adduw_2(i64 %0, i64 %1) {
282 ; RV64I-LABEL: sh2adduw_2:
284 ; RV64I-NEXT: slli a0, a0, 32
285 ; RV64I-NEXT: srli a0, a0, 30
286 ; RV64I-NEXT: add a0, a0, a1
289 ; RV64ZBA-LABEL: sh2adduw_2:
291 ; RV64ZBA-NEXT: sh2add.uw a0, a0, a1
294 %4 = and i64 %3, 17179869180
299 define i64 @sh3adduw(i32 signext %0, ptr %1) {
300 ; RV64I-LABEL: sh3adduw:
302 ; RV64I-NEXT: slli a0, a0, 32
303 ; RV64I-NEXT: srli a0, a0, 29
304 ; RV64I-NEXT: add a0, a1, a0
305 ; RV64I-NEXT: ld a0, 0(a0)
308 ; RV64ZBA-LABEL: sh3adduw:
310 ; RV64ZBA-NEXT: sh3add.uw a0, a0, a1
311 ; RV64ZBA-NEXT: ld a0, 0(a0)
313 %3 = zext i32 %0 to i64
314 %4 = getelementptr inbounds i64, ptr %1, i64 %3
315 %5 = load i64, ptr %4
319 define i64 @sh3adduw_2(i64 %0, i64 %1) {
320 ; RV64I-LABEL: sh3adduw_2:
322 ; RV64I-NEXT: slli a0, a0, 32
323 ; RV64I-NEXT: srli a0, a0, 29
324 ; RV64I-NEXT: add a0, a0, a1
327 ; RV64ZBA-LABEL: sh3adduw_2:
329 ; RV64ZBA-NEXT: sh3add.uw a0, a0, a1
332 %4 = and i64 %3, 34359738360
337 ; Type legalization inserts a sext_inreg after the first add. That add will be
338 ; selected as sh2add which does not sign extend. SimplifyDemandedBits is unable
339 ; to remove the sext_inreg because it has multiple uses. The ashr will use the
340 ; sext_inreg to become sraiw. This leaves the sext_inreg only used by the shl.
341 ; If the shl is selected as sllw, we don't need the sext_inreg.
342 define i64 @sh2add_extra_sext(i32 %x, i32 %y, i32 %z) {
343 ; RV64I-LABEL: sh2add_extra_sext:
345 ; RV64I-NEXT: slli a0, a0, 2
346 ; RV64I-NEXT: add a0, a0, a1
347 ; RV64I-NEXT: sllw a1, a2, a0
348 ; RV64I-NEXT: sraiw a0, a0, 2
349 ; RV64I-NEXT: mul a0, a1, a0
352 ; RV64ZBA-LABEL: sh2add_extra_sext:
354 ; RV64ZBA-NEXT: sh2add a0, a0, a1
355 ; RV64ZBA-NEXT: sllw a1, a2, a0
356 ; RV64ZBA-NEXT: sraiw a0, a0, 2
357 ; RV64ZBA-NEXT: mul a0, a1, a0
363 %e = sext i32 %c to i64
364 %f = sext i32 %d to i64
369 define i64 @addmul6(i64 %a, i64 %b) {
370 ; RV64I-LABEL: addmul6:
372 ; RV64I-NEXT: li a2, 6
373 ; RV64I-NEXT: mul a0, a0, a2
374 ; RV64I-NEXT: add a0, a0, a1
377 ; RV64ZBA-LABEL: addmul6:
379 ; RV64ZBA-NEXT: sh1add a0, a0, a0
380 ; RV64ZBA-NEXT: sh1add a0, a0, a1
387 define i64 @addmul10(i64 %a, i64 %b) {
388 ; RV64I-LABEL: addmul10:
390 ; RV64I-NEXT: li a2, 10
391 ; RV64I-NEXT: mul a0, a0, a2
392 ; RV64I-NEXT: add a0, a0, a1
395 ; RV64ZBA-LABEL: addmul10:
397 ; RV64ZBA-NEXT: sh2add a0, a0, a0
398 ; RV64ZBA-NEXT: sh1add a0, a0, a1
405 define i64 @addmul12(i64 %a, i64 %b) {
406 ; RV64I-LABEL: addmul12:
408 ; RV64I-NEXT: li a2, 12
409 ; RV64I-NEXT: mul a0, a0, a2
410 ; RV64I-NEXT: add a0, a0, a1
413 ; RV64ZBA-LABEL: addmul12:
415 ; RV64ZBA-NEXT: sh1add a0, a0, a0
416 ; RV64ZBA-NEXT: sh2add a0, a0, a1
423 define i64 @addmul18(i64 %a, i64 %b) {
424 ; RV64I-LABEL: addmul18:
426 ; RV64I-NEXT: li a2, 18
427 ; RV64I-NEXT: mul a0, a0, a2
428 ; RV64I-NEXT: add a0, a0, a1
431 ; RV64ZBA-LABEL: addmul18:
433 ; RV64ZBA-NEXT: sh3add a0, a0, a0
434 ; RV64ZBA-NEXT: sh1add a0, a0, a1
441 define i64 @addmul20(i64 %a, i64 %b) {
442 ; RV64I-LABEL: addmul20:
444 ; RV64I-NEXT: li a2, 20
445 ; RV64I-NEXT: mul a0, a0, a2
446 ; RV64I-NEXT: add a0, a0, a1
449 ; RV64ZBA-LABEL: addmul20:
451 ; RV64ZBA-NEXT: sh2add a0, a0, a0
452 ; RV64ZBA-NEXT: sh2add a0, a0, a1
459 define i64 @addmul24(i64 %a, i64 %b) {
460 ; RV64I-LABEL: addmul24:
462 ; RV64I-NEXT: li a2, 24
463 ; RV64I-NEXT: mul a0, a0, a2
464 ; RV64I-NEXT: add a0, a0, a1
467 ; RV64ZBA-LABEL: addmul24:
469 ; RV64ZBA-NEXT: sh1add a0, a0, a0
470 ; RV64ZBA-NEXT: sh3add a0, a0, a1
477 define i64 @addmul36(i64 %a, i64 %b) {
478 ; RV64I-LABEL: addmul36:
480 ; RV64I-NEXT: li a2, 36
481 ; RV64I-NEXT: mul a0, a0, a2
482 ; RV64I-NEXT: add a0, a0, a1
485 ; RV64ZBA-LABEL: addmul36:
487 ; RV64ZBA-NEXT: sh3add a0, a0, a0
488 ; RV64ZBA-NEXT: sh2add a0, a0, a1
495 define i64 @addmul40(i64 %a, i64 %b) {
496 ; RV64I-LABEL: addmul40:
498 ; RV64I-NEXT: li a2, 40
499 ; RV64I-NEXT: mul a0, a0, a2
500 ; RV64I-NEXT: add a0, a0, a1
503 ; RV64ZBA-LABEL: addmul40:
505 ; RV64ZBA-NEXT: sh2add a0, a0, a0
506 ; RV64ZBA-NEXT: sh3add a0, a0, a1
513 define i64 @addmul72(i64 %a, i64 %b) {
514 ; RV64I-LABEL: addmul72:
516 ; RV64I-NEXT: li a2, 72
517 ; RV64I-NEXT: mul a0, a0, a2
518 ; RV64I-NEXT: add a0, a0, a1
521 ; RV64ZBA-LABEL: addmul72:
523 ; RV64ZBA-NEXT: sh3add a0, a0, a0
524 ; RV64ZBA-NEXT: sh3add a0, a0, a1
531 define i64 @mul96(i64 %a) {
532 ; RV64I-LABEL: mul96:
534 ; RV64I-NEXT: li a1, 96
535 ; RV64I-NEXT: mul a0, a0, a1
538 ; RV64ZBA-LABEL: mul96:
540 ; RV64ZBA-NEXT: sh1add a0, a0, a0
541 ; RV64ZBA-NEXT: slli a0, a0, 5
547 define i64 @mul160(i64 %a) {
548 ; RV64I-LABEL: mul160:
550 ; RV64I-NEXT: li a1, 160
551 ; RV64I-NEXT: mul a0, a0, a1
554 ; RV64ZBA-LABEL: mul160:
556 ; RV64ZBA-NEXT: sh2add a0, a0, a0
557 ; RV64ZBA-NEXT: slli a0, a0, 5
563 define i64 @mul288(i64 %a) {
564 ; RV64I-LABEL: mul288:
566 ; RV64I-NEXT: li a1, 288
567 ; RV64I-NEXT: mul a0, a0, a1
570 ; RV64ZBA-LABEL: mul288:
572 ; RV64ZBA-NEXT: sh3add a0, a0, a0
573 ; RV64ZBA-NEXT: slli a0, a0, 5
579 define i64 @zext_mul96(i32 signext %a) {
580 ; RV64I-LABEL: zext_mul96:
582 ; RV64I-NEXT: li a1, 3
583 ; RV64I-NEXT: slli a1, a1, 37
584 ; RV64I-NEXT: slli a0, a0, 32
585 ; RV64I-NEXT: mulhu a0, a0, a1
588 ; RV64ZBA-LABEL: zext_mul96:
590 ; RV64ZBA-NEXT: slli.uw a0, a0, 5
591 ; RV64ZBA-NEXT: sh1add a0, a0, a0
593 %b = zext i32 %a to i64
598 define i64 @zext_mul160(i32 signext %a) {
599 ; RV64I-LABEL: zext_mul160:
601 ; RV64I-NEXT: li a1, 5
602 ; RV64I-NEXT: slli a1, a1, 37
603 ; RV64I-NEXT: slli a0, a0, 32
604 ; RV64I-NEXT: mulhu a0, a0, a1
607 ; RV64ZBA-LABEL: zext_mul160:
609 ; RV64ZBA-NEXT: slli.uw a0, a0, 5
610 ; RV64ZBA-NEXT: sh2add a0, a0, a0
612 %b = zext i32 %a to i64
617 define i64 @zext_mul288(i32 signext %a) {
618 ; RV64I-LABEL: zext_mul288:
620 ; RV64I-NEXT: li a1, 9
621 ; RV64I-NEXT: slli a1, a1, 37
622 ; RV64I-NEXT: slli a0, a0, 32
623 ; RV64I-NEXT: mulhu a0, a0, a1
626 ; RV64ZBA-LABEL: zext_mul288:
628 ; RV64ZBA-NEXT: slli.uw a0, a0, 5
629 ; RV64ZBA-NEXT: sh3add a0, a0, a0
631 %b = zext i32 %a to i64
636 ; We can't use slli.uw becaues the shift amount is more than 31.
637 ; FIXME: The zext.w is unneeded.
638 define i64 @zext_mul12884901888(i32 signext %a) {
639 ; RV64I-LABEL: zext_mul12884901888:
641 ; RV64I-NEXT: slli a0, a0, 32
642 ; RV64I-NEXT: srli a0, a0, 32
643 ; RV64I-NEXT: li a1, 3
644 ; RV64I-NEXT: slli a1, a1, 32
645 ; RV64I-NEXT: mul a0, a0, a1
648 ; RV64ZBA-LABEL: zext_mul12884901888:
650 ; RV64ZBA-NEXT: andi a0, a0, -1
651 ; RV64ZBA-NEXT: sh1add a0, a0, a0
652 ; RV64ZBA-NEXT: slli a0, a0, 32
654 %b = zext i32 %a to i64
655 %c = mul i64 %b, 12884901888
659 ; We can't use slli.uw becaues the shift amount is more than 31.
660 ; FIXME: The zext.w is unneeded.
661 define i64 @zext_mul21474836480(i32 signext %a) {
662 ; RV64I-LABEL: zext_mul21474836480:
664 ; RV64I-NEXT: slli a0, a0, 32
665 ; RV64I-NEXT: srli a0, a0, 32
666 ; RV64I-NEXT: li a1, 5
667 ; RV64I-NEXT: slli a1, a1, 32
668 ; RV64I-NEXT: mul a0, a0, a1
671 ; RV64ZBA-LABEL: zext_mul21474836480:
673 ; RV64ZBA-NEXT: andi a0, a0, -1
674 ; RV64ZBA-NEXT: sh2add a0, a0, a0
675 ; RV64ZBA-NEXT: slli a0, a0, 32
677 %b = zext i32 %a to i64
678 %c = mul i64 %b, 21474836480
682 ; We can't use slli.uw becaues the shift amount is more than 31.
683 ; FIXME: The zext.w is unneeded.
684 define i64 @zext_mul38654705664(i32 signext %a) {
685 ; RV64I-LABEL: zext_mul38654705664:
687 ; RV64I-NEXT: slli a0, a0, 32
688 ; RV64I-NEXT: srli a0, a0, 32
689 ; RV64I-NEXT: li a1, 9
690 ; RV64I-NEXT: slli a1, a1, 32
691 ; RV64I-NEXT: mul a0, a0, a1
694 ; RV64ZBA-LABEL: zext_mul38654705664:
696 ; RV64ZBA-NEXT: andi a0, a0, -1
697 ; RV64ZBA-NEXT: sh3add a0, a0, a0
698 ; RV64ZBA-NEXT: slli a0, a0, 32
700 %b = zext i32 %a to i64
701 %c = mul i64 %b, 38654705664
705 define i64 @sh1add_imm(i64 %0) {
706 ; CHECK-LABEL: sh1add_imm:
708 ; CHECK-NEXT: slli a0, a0, 1
709 ; CHECK-NEXT: addi a0, a0, 5
716 define i64 @sh2add_imm(i64 %0) {
717 ; CHECK-LABEL: sh2add_imm:
719 ; CHECK-NEXT: slli a0, a0, 2
720 ; CHECK-NEXT: addi a0, a0, -6
727 define i64 @sh3add_imm(i64 %0) {
728 ; CHECK-LABEL: sh3add_imm:
730 ; CHECK-NEXT: slli a0, a0, 3
731 ; CHECK-NEXT: addi a0, a0, 7
738 define i64 @sh1adduw_imm(i32 signext %0) {
739 ; RV64I-LABEL: sh1adduw_imm:
741 ; RV64I-NEXT: slli a0, a0, 32
742 ; RV64I-NEXT: srli a0, a0, 31
743 ; RV64I-NEXT: addi a0, a0, 11
746 ; RV64ZBA-LABEL: sh1adduw_imm:
748 ; RV64ZBA-NEXT: slli.uw a0, a0, 1
749 ; RV64ZBA-NEXT: addi a0, a0, 11
751 %a = zext i32 %0 to i64
757 define i64 @sh2adduw_imm(i32 signext %0) {
758 ; RV64I-LABEL: sh2adduw_imm:
760 ; RV64I-NEXT: slli a0, a0, 32
761 ; RV64I-NEXT: srli a0, a0, 30
762 ; RV64I-NEXT: addi a0, a0, -12
765 ; RV64ZBA-LABEL: sh2adduw_imm:
767 ; RV64ZBA-NEXT: slli.uw a0, a0, 2
768 ; RV64ZBA-NEXT: addi a0, a0, -12
770 %a = zext i32 %0 to i64
776 define i64 @sh3adduw_imm(i32 signext %0) {
777 ; RV64I-LABEL: sh3adduw_imm:
779 ; RV64I-NEXT: slli a0, a0, 32
780 ; RV64I-NEXT: srli a0, a0, 29
781 ; RV64I-NEXT: addi a0, a0, 13
784 ; RV64ZBA-LABEL: sh3adduw_imm:
786 ; RV64ZBA-NEXT: slli.uw a0, a0, 3
787 ; RV64ZBA-NEXT: addi a0, a0, 13
789 %a = zext i32 %0 to i64
795 define i64 @adduw_imm(i32 signext %0) nounwind {
796 ; RV64I-LABEL: adduw_imm:
798 ; RV64I-NEXT: slli a0, a0, 32
799 ; RV64I-NEXT: srli a0, a0, 32
800 ; RV64I-NEXT: addi a0, a0, 5
803 ; RV64ZBA-LABEL: adduw_imm:
805 ; RV64ZBA-NEXT: zext.w a0, a0
806 ; RV64ZBA-NEXT: addi a0, a0, 5
808 %a = zext i32 %0 to i64
813 define i64 @mul258(i64 %a) {
814 ; CHECK-LABEL: mul258:
816 ; CHECK-NEXT: li a1, 258
817 ; CHECK-NEXT: mul a0, a0, a1
823 define i64 @mul260(i64 %a) {
824 ; CHECK-LABEL: mul260:
826 ; CHECK-NEXT: li a1, 260
827 ; CHECK-NEXT: mul a0, a0, a1
833 define i64 @mul264(i64 %a) {
834 ; CHECK-LABEL: mul264:
836 ; CHECK-NEXT: li a1, 264
837 ; CHECK-NEXT: mul a0, a0, a1
843 define i64 @imm_zextw() nounwind {
844 ; RV64I-LABEL: imm_zextw:
846 ; RV64I-NEXT: li a0, 1
847 ; RV64I-NEXT: slli a0, a0, 32
848 ; RV64I-NEXT: addi a0, a0, -2
851 ; RV64ZBA-LABEL: imm_zextw:
853 ; RV64ZBA-NEXT: li a0, -2
854 ; RV64ZBA-NEXT: zext.w a0, a0
856 ret i64 4294967294 ; -2 in 32 bits.
859 define i64 @mul11(i64 %a) {
860 ; RV64I-LABEL: mul11:
862 ; RV64I-NEXT: li a1, 11
863 ; RV64I-NEXT: mul a0, a0, a1
866 ; RV64ZBA-LABEL: mul11:
868 ; RV64ZBA-NEXT: sh2add a1, a0, a0
869 ; RV64ZBA-NEXT: sh1add a0, a1, a0
875 define i64 @mul19(i64 %a) {
876 ; RV64I-LABEL: mul19:
878 ; RV64I-NEXT: li a1, 19
879 ; RV64I-NEXT: mul a0, a0, a1
882 ; RV64ZBA-LABEL: mul19:
884 ; RV64ZBA-NEXT: sh3add a1, a0, a0
885 ; RV64ZBA-NEXT: sh1add a0, a1, a0
891 define i64 @mul13(i64 %a) {
892 ; RV64I-LABEL: mul13:
894 ; RV64I-NEXT: li a1, 13
895 ; RV64I-NEXT: mul a0, a0, a1
898 ; RV64ZBA-LABEL: mul13:
900 ; RV64ZBA-NEXT: sh1add a1, a0, a0
901 ; RV64ZBA-NEXT: sh2add a0, a1, a0
907 define i64 @mul21(i64 %a) {
908 ; RV64I-LABEL: mul21:
910 ; RV64I-NEXT: li a1, 21
911 ; RV64I-NEXT: mul a0, a0, a1
914 ; RV64ZBA-LABEL: mul21:
916 ; RV64ZBA-NEXT: sh2add a1, a0, a0
917 ; RV64ZBA-NEXT: sh2add a0, a1, a0
923 define i64 @mul37(i64 %a) {
924 ; RV64I-LABEL: mul37:
926 ; RV64I-NEXT: li a1, 37
927 ; RV64I-NEXT: mul a0, a0, a1
930 ; RV64ZBA-LABEL: mul37:
932 ; RV64ZBA-NEXT: sh3add a1, a0, a0
933 ; RV64ZBA-NEXT: sh2add a0, a1, a0
939 define i64 @mul25(i64 %a) {
940 ; RV64I-LABEL: mul25:
942 ; RV64I-NEXT: li a1, 25
943 ; RV64I-NEXT: mul a0, a0, a1
946 ; RV64ZBA-LABEL: mul25:
948 ; RV64ZBA-NEXT: sh1add a1, a0, a0
949 ; RV64ZBA-NEXT: sh3add a0, a1, a0
955 define i64 @mul41(i64 %a) {
956 ; RV64I-LABEL: mul41:
958 ; RV64I-NEXT: li a1, 41
959 ; RV64I-NEXT: mul a0, a0, a1
962 ; RV64ZBA-LABEL: mul41:
964 ; RV64ZBA-NEXT: sh2add a1, a0, a0
965 ; RV64ZBA-NEXT: sh3add a0, a1, a0
971 define i64 @mul73(i64 %a) {
972 ; RV64I-LABEL: mul73:
974 ; RV64I-NEXT: li a1, 73
975 ; RV64I-NEXT: mul a0, a0, a1
978 ; RV64ZBA-LABEL: mul73:
980 ; RV64ZBA-NEXT: sh3add a1, a0, a0
981 ; RV64ZBA-NEXT: sh3add a0, a1, a0
987 define i64 @mul27(i64 %a) {
988 ; RV64I-LABEL: mul27:
990 ; RV64I-NEXT: li a1, 27
991 ; RV64I-NEXT: mul a0, a0, a1
994 ; RV64ZBA-LABEL: mul27:
996 ; RV64ZBA-NEXT: sh3add a0, a0, a0
997 ; RV64ZBA-NEXT: sh1add a0, a0, a0
1003 define i64 @mul45(i64 %a) {
1004 ; RV64I-LABEL: mul45:
1006 ; RV64I-NEXT: li a1, 45
1007 ; RV64I-NEXT: mul a0, a0, a1
1010 ; RV64ZBA-LABEL: mul45:
1012 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1013 ; RV64ZBA-NEXT: sh2add a0, a0, a0
1019 define i64 @mul81(i64 %a) {
1020 ; RV64I-LABEL: mul81:
1022 ; RV64I-NEXT: li a1, 81
1023 ; RV64I-NEXT: mul a0, a0, a1
1026 ; RV64ZBA-LABEL: mul81:
1028 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1029 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1035 define i64 @mul4098(i64 %a) {
1036 ; RV64I-LABEL: mul4098:
1038 ; RV64I-NEXT: slli a1, a0, 1
1039 ; RV64I-NEXT: slli a0, a0, 12
1040 ; RV64I-NEXT: add a0, a0, a1
1043 ; RV64ZBA-LABEL: mul4098:
1045 ; RV64ZBA-NEXT: slli a1, a0, 12
1046 ; RV64ZBA-NEXT: sh1add a0, a0, a1
1048 %c = mul i64 %a, 4098
1052 define i64 @mul4100(i64 %a) {
1053 ; RV64I-LABEL: mul4100:
1055 ; RV64I-NEXT: slli a1, a0, 2
1056 ; RV64I-NEXT: slli a0, a0, 12
1057 ; RV64I-NEXT: add a0, a0, a1
1060 ; RV64ZBA-LABEL: mul4100:
1062 ; RV64ZBA-NEXT: slli a1, a0, 12
1063 ; RV64ZBA-NEXT: sh2add a0, a0, a1
1065 %c = mul i64 %a, 4100
1069 define i64 @mul4104(i64 %a) {
1070 ; RV64I-LABEL: mul4104:
1072 ; RV64I-NEXT: slli a1, a0, 3
1073 ; RV64I-NEXT: slli a0, a0, 12
1074 ; RV64I-NEXT: add a0, a0, a1
1077 ; RV64ZBA-LABEL: mul4104:
1079 ; RV64ZBA-NEXT: slli a1, a0, 12
1080 ; RV64ZBA-NEXT: sh3add a0, a0, a1
1082 %c = mul i64 %a, 4104
1086 define signext i32 @mulw192(i32 signext %a) {
1087 ; CHECK-LABEL: mulw192:
1089 ; CHECK-NEXT: li a1, 192
1090 ; CHECK-NEXT: mulw a0, a0, a1
1092 %c = mul i32 %a, 192
1096 define signext i32 @mulw320(i32 signext %a) {
1097 ; CHECK-LABEL: mulw320:
1099 ; CHECK-NEXT: li a1, 320
1100 ; CHECK-NEXT: mulw a0, a0, a1
1102 %c = mul i32 %a, 320
1106 define signext i32 @mulw576(i32 signext %a) {
1107 ; CHECK-LABEL: mulw576:
1109 ; CHECK-NEXT: li a1, 576
1110 ; CHECK-NEXT: mulw a0, a0, a1
1112 %c = mul i32 %a, 576
1116 define i64 @add4104(i64 %a) {
1117 ; RV64I-LABEL: add4104:
1119 ; RV64I-NEXT: lui a1, 1
1120 ; RV64I-NEXT: addiw a1, a1, 8
1121 ; RV64I-NEXT: add a0, a0, a1
1124 ; RV64ZBA-LABEL: add4104:
1126 ; RV64ZBA-NEXT: li a1, 1026
1127 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1129 %c = add i64 %a, 4104
1133 define i64 @add8208(i64 %a) {
1134 ; RV64I-LABEL: add8208:
1136 ; RV64I-NEXT: lui a1, 2
1137 ; RV64I-NEXT: addiw a1, a1, 16
1138 ; RV64I-NEXT: add a0, a0, a1
1141 ; RV64ZBA-LABEL: add8208:
1143 ; RV64ZBA-NEXT: li a1, 1026
1144 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1146 %c = add i64 %a, 8208
1150 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1151 define signext i32 @add8192_i32(i32 signext %a) {
1152 ; CHECK-LABEL: add8192_i32:
1154 ; CHECK-NEXT: lui a1, 2
1155 ; CHECK-NEXT: addw a0, a0, a1
1157 %c = add i32 %a, 8192
1161 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1162 define i64 @add8192(i64 %a) {
1163 ; CHECK-LABEL: add8192:
1165 ; CHECK-NEXT: lui a1, 2
1166 ; CHECK-NEXT: add a0, a0, a1
1168 %c = add i64 %a, 8192
1172 define signext i32 @addshl32_5_6(i32 signext %a, i32 signext %b) {
1173 ; RV64I-LABEL: addshl32_5_6:
1175 ; RV64I-NEXT: slli a0, a0, 5
1176 ; RV64I-NEXT: slli a1, a1, 6
1177 ; RV64I-NEXT: addw a0, a0, a1
1180 ; RV64ZBA-LABEL: addshl32_5_6:
1182 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1183 ; RV64ZBA-NEXT: slliw a0, a0, 5
1191 define i64 @addshl64_5_6(i64 %a, i64 %b) {
1192 ; RV64I-LABEL: addshl64_5_6:
1194 ; RV64I-NEXT: slli a0, a0, 5
1195 ; RV64I-NEXT: slli a1, a1, 6
1196 ; RV64I-NEXT: add a0, a0, a1
1199 ; RV64ZBA-LABEL: addshl64_5_6:
1201 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1202 ; RV64ZBA-NEXT: slli a0, a0, 5
1210 define signext i32 @addshl32_5_7(i32 signext %a, i32 signext %b) {
1211 ; RV64I-LABEL: addshl32_5_7:
1213 ; RV64I-NEXT: slli a0, a0, 5
1214 ; RV64I-NEXT: slli a1, a1, 7
1215 ; RV64I-NEXT: addw a0, a0, a1
1218 ; RV64ZBA-LABEL: addshl32_5_7:
1220 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1221 ; RV64ZBA-NEXT: slliw a0, a0, 5
1229 define i64 @addshl64_5_7(i64 %a, i64 %b) {
1230 ; RV64I-LABEL: addshl64_5_7:
1232 ; RV64I-NEXT: slli a0, a0, 5
1233 ; RV64I-NEXT: slli a1, a1, 7
1234 ; RV64I-NEXT: add a0, a0, a1
1237 ; RV64ZBA-LABEL: addshl64_5_7:
1239 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1240 ; RV64ZBA-NEXT: slli a0, a0, 5
1248 define signext i32 @addshl32_5_8(i32 signext %a, i32 signext %b) {
1249 ; RV64I-LABEL: addshl32_5_8:
1251 ; RV64I-NEXT: slli a0, a0, 5
1252 ; RV64I-NEXT: slli a1, a1, 8
1253 ; RV64I-NEXT: addw a0, a0, a1
1256 ; RV64ZBA-LABEL: addshl32_5_8:
1258 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1259 ; RV64ZBA-NEXT: slliw a0, a0, 5
1267 define i64 @addshl64_5_8(i64 %a, i64 %b) {
1268 ; RV64I-LABEL: addshl64_5_8:
1270 ; RV64I-NEXT: slli a0, a0, 5
1271 ; RV64I-NEXT: slli a1, a1, 8
1272 ; RV64I-NEXT: add a0, a0, a1
1275 ; RV64ZBA-LABEL: addshl64_5_8:
1277 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1278 ; RV64ZBA-NEXT: slli a0, a0, 5
1286 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1287 ; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
1288 define zeroext i32 @sext_ashr_zext_i8(i8 %a) nounwind {
1289 ; RV64I-LABEL: sext_ashr_zext_i8:
1291 ; RV64I-NEXT: slli a0, a0, 24
1292 ; RV64I-NEXT: sraiw a0, a0, 31
1293 ; RV64I-NEXT: slli a0, a0, 32
1294 ; RV64I-NEXT: srli a0, a0, 32
1297 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i8:
1298 ; RV64ZBANOZBB: # %bb.0:
1299 ; RV64ZBANOZBB-NEXT: slli a0, a0, 24
1300 ; RV64ZBANOZBB-NEXT: sraiw a0, a0, 31
1301 ; RV64ZBANOZBB-NEXT: zext.w a0, a0
1302 ; RV64ZBANOZBB-NEXT: ret
1304 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i8:
1305 ; RV64ZBAZBB: # %bb.0:
1306 ; RV64ZBAZBB-NEXT: sext.b a0, a0
1307 ; RV64ZBAZBB-NEXT: sraiw a0, a0, 9
1308 ; RV64ZBAZBB-NEXT: zext.w a0, a0
1309 ; RV64ZBAZBB-NEXT: ret
1310 %ext = sext i8 %a to i32
1311 %1 = ashr i32 %ext, 9
1315 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1316 ; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
1317 define zeroext i32 @sext_ashr_zext_i16(i16 %a) nounwind {
1318 ; RV64I-LABEL: sext_ashr_zext_i16:
1320 ; RV64I-NEXT: slli a0, a0, 16
1321 ; RV64I-NEXT: sraiw a0, a0, 25
1322 ; RV64I-NEXT: slli a0, a0, 32
1323 ; RV64I-NEXT: srli a0, a0, 32
1326 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i16:
1327 ; RV64ZBANOZBB: # %bb.0:
1328 ; RV64ZBANOZBB-NEXT: slli a0, a0, 16
1329 ; RV64ZBANOZBB-NEXT: sraiw a0, a0, 25
1330 ; RV64ZBANOZBB-NEXT: zext.w a0, a0
1331 ; RV64ZBANOZBB-NEXT: ret
1333 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i16:
1334 ; RV64ZBAZBB: # %bb.0:
1335 ; RV64ZBAZBB-NEXT: slli a0, a0, 48
1336 ; RV64ZBAZBB-NEXT: srai a0, a0, 57
1337 ; RV64ZBAZBB-NEXT: zext.w a0, a0
1338 ; RV64ZBAZBB-NEXT: ret
1339 %ext = sext i16 %a to i32
1340 %1 = ashr i32 %ext, 9
1344 ; This the IR you get from InstCombine if take the difference of 2 pointers and
1345 ; cast is to unsigned before using as an index.
1346 define signext i16 @sh1adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1347 ; RV64I-LABEL: sh1adduw_ptrdiff:
1349 ; RV64I-NEXT: li a2, 1
1350 ; RV64I-NEXT: slli a2, a2, 33
1351 ; RV64I-NEXT: addi a2, a2, -2
1352 ; RV64I-NEXT: and a0, a0, a2
1353 ; RV64I-NEXT: add a0, a1, a0
1354 ; RV64I-NEXT: lh a0, 0(a0)
1357 ; RV64ZBA-LABEL: sh1adduw_ptrdiff:
1359 ; RV64ZBA-NEXT: srli a0, a0, 1
1360 ; RV64ZBA-NEXT: sh1add.uw a0, a0, a1
1361 ; RV64ZBA-NEXT: lh a0, 0(a0)
1363 %ptrdiff = lshr exact i64 %diff, 1
1364 %cast = and i64 %ptrdiff, 4294967295
1365 %ptr = getelementptr inbounds i16, ptr %baseptr, i64 %cast
1366 %res = load i16, ptr %ptr
1370 define signext i32 @sh2adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1371 ; RV64I-LABEL: sh2adduw_ptrdiff:
1373 ; RV64I-NEXT: li a2, 1
1374 ; RV64I-NEXT: slli a2, a2, 34
1375 ; RV64I-NEXT: addi a2, a2, -4
1376 ; RV64I-NEXT: and a0, a0, a2
1377 ; RV64I-NEXT: add a0, a1, a0
1378 ; RV64I-NEXT: lw a0, 0(a0)
1381 ; RV64ZBA-LABEL: sh2adduw_ptrdiff:
1383 ; RV64ZBA-NEXT: srli a0, a0, 2
1384 ; RV64ZBA-NEXT: sh2add.uw a0, a0, a1
1385 ; RV64ZBA-NEXT: lw a0, 0(a0)
1387 %ptrdiff = lshr exact i64 %diff, 2
1388 %cast = and i64 %ptrdiff, 4294967295
1389 %ptr = getelementptr inbounds i32, ptr %baseptr, i64 %cast
1390 %res = load i32, ptr %ptr
1394 define i64 @sh3adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1395 ; RV64I-LABEL: sh3adduw_ptrdiff:
1397 ; RV64I-NEXT: li a2, 1
1398 ; RV64I-NEXT: slli a2, a2, 35
1399 ; RV64I-NEXT: addi a2, a2, -8
1400 ; RV64I-NEXT: and a0, a0, a2
1401 ; RV64I-NEXT: add a0, a1, a0
1402 ; RV64I-NEXT: ld a0, 0(a0)
1405 ; RV64ZBA-LABEL: sh3adduw_ptrdiff:
1407 ; RV64ZBA-NEXT: srli a0, a0, 3
1408 ; RV64ZBA-NEXT: sh3add.uw a0, a0, a1
1409 ; RV64ZBA-NEXT: ld a0, 0(a0)
1411 %ptrdiff = lshr exact i64 %diff, 3
1412 %cast = and i64 %ptrdiff, 4294967295
1413 %ptr = getelementptr inbounds i64, ptr %baseptr, i64 %cast
1414 %res = load i64, ptr %ptr
1418 define signext i16 @srliw_1_sh1add(ptr %0, i32 signext %1) {
1419 ; RV64I-LABEL: srliw_1_sh1add:
1421 ; RV64I-NEXT: srliw a1, a1, 1
1422 ; RV64I-NEXT: slli a1, a1, 1
1423 ; RV64I-NEXT: add a0, a0, a1
1424 ; RV64I-NEXT: lh a0, 0(a0)
1427 ; RV64ZBA-LABEL: srliw_1_sh1add:
1429 ; RV64ZBA-NEXT: srliw a1, a1, 1
1430 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1431 ; RV64ZBA-NEXT: lh a0, 0(a0)
1434 %4 = zext i32 %3 to i64
1435 %5 = getelementptr inbounds i16, ptr %0, i64 %4
1436 %6 = load i16, ptr %5, align 2
1440 define i128 @slliuw_ptrdiff(i64 %diff, ptr %baseptr) {
1441 ; RV64I-LABEL: slliuw_ptrdiff:
1443 ; RV64I-NEXT: li a2, 1
1444 ; RV64I-NEXT: slli a2, a2, 36
1445 ; RV64I-NEXT: addi a2, a2, -16
1446 ; RV64I-NEXT: and a0, a0, a2
1447 ; RV64I-NEXT: add a1, a1, a0
1448 ; RV64I-NEXT: ld a0, 0(a1)
1449 ; RV64I-NEXT: ld a1, 8(a1)
1452 ; RV64ZBA-LABEL: slliuw_ptrdiff:
1454 ; RV64ZBA-NEXT: srli a0, a0, 4
1455 ; RV64ZBA-NEXT: slli.uw a0, a0, 4
1456 ; RV64ZBA-NEXT: add a1, a1, a0
1457 ; RV64ZBA-NEXT: ld a0, 0(a1)
1458 ; RV64ZBA-NEXT: ld a1, 8(a1)
1460 %ptrdiff = lshr exact i64 %diff, 4
1461 %cast = and i64 %ptrdiff, 4294967295
1462 %ptr = getelementptr inbounds i128, ptr %baseptr, i64 %cast
1463 %res = load i128, ptr %ptr
1467 define signext i32 @srliw_2_sh2add(ptr %0, i32 signext %1) {
1468 ; RV64I-LABEL: srliw_2_sh2add:
1470 ; RV64I-NEXT: srliw a1, a1, 2
1471 ; RV64I-NEXT: slli a1, a1, 2
1472 ; RV64I-NEXT: add a0, a0, a1
1473 ; RV64I-NEXT: lw a0, 0(a0)
1476 ; RV64ZBA-LABEL: srliw_2_sh2add:
1478 ; RV64ZBA-NEXT: srliw a1, a1, 2
1479 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1480 ; RV64ZBA-NEXT: lw a0, 0(a0)
1483 %4 = zext i32 %3 to i64
1484 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1485 %6 = load i32, ptr %5, align 4
1489 define i64 @srliw_3_sh3add(ptr %0, i32 signext %1) {
1490 ; RV64I-LABEL: srliw_3_sh3add:
1492 ; RV64I-NEXT: srliw a1, a1, 3
1493 ; RV64I-NEXT: slli a1, a1, 3
1494 ; RV64I-NEXT: add a0, a0, a1
1495 ; RV64I-NEXT: ld a0, 0(a0)
1498 ; RV64ZBA-LABEL: srliw_3_sh3add:
1500 ; RV64ZBA-NEXT: srliw a1, a1, 3
1501 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1502 ; RV64ZBA-NEXT: ld a0, 0(a0)
1505 %4 = zext i32 %3 to i64
1506 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1507 %6 = load i64, ptr %5, align 8
1511 define signext i32 @srliw_1_sh2add(ptr %0, i32 signext %1) {
1512 ; RV64I-LABEL: srliw_1_sh2add:
1514 ; RV64I-NEXT: srliw a1, a1, 1
1515 ; RV64I-NEXT: slli a1, a1, 32
1516 ; RV64I-NEXT: srli a1, a1, 30
1517 ; RV64I-NEXT: add a0, a0, a1
1518 ; RV64I-NEXT: lw a0, 0(a0)
1521 ; RV64ZBA-LABEL: srliw_1_sh2add:
1523 ; RV64ZBA-NEXT: srliw a1, a1, 1
1524 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1525 ; RV64ZBA-NEXT: lw a0, 0(a0)
1528 %4 = zext i32 %3 to i64
1529 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1530 %6 = load i32, ptr %5, align 4
1534 define i64 @srliw_1_sh3add(ptr %0, i32 signext %1) {
1535 ; RV64I-LABEL: srliw_1_sh3add:
1537 ; RV64I-NEXT: srliw a1, a1, 1
1538 ; RV64I-NEXT: slli a1, a1, 32
1539 ; RV64I-NEXT: srli a1, a1, 29
1540 ; RV64I-NEXT: add a0, a0, a1
1541 ; RV64I-NEXT: ld a0, 0(a0)
1544 ; RV64ZBA-LABEL: srliw_1_sh3add:
1546 ; RV64ZBA-NEXT: srliw a1, a1, 1
1547 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1548 ; RV64ZBA-NEXT: ld a0, 0(a0)
1551 %4 = zext i32 %3 to i64
1552 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1553 %6 = load i64, ptr %5, align 8
1557 define i64 @srliw_2_sh3add(ptr %0, i32 signext %1) {
1558 ; RV64I-LABEL: srliw_2_sh3add:
1560 ; RV64I-NEXT: srliw a1, a1, 2
1561 ; RV64I-NEXT: slli a1, a1, 32
1562 ; RV64I-NEXT: srli a1, a1, 29
1563 ; RV64I-NEXT: add a0, a0, a1
1564 ; RV64I-NEXT: ld a0, 0(a0)
1567 ; RV64ZBA-LABEL: srliw_2_sh3add:
1569 ; RV64ZBA-NEXT: srliw a1, a1, 2
1570 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1571 ; RV64ZBA-NEXT: ld a0, 0(a0)
1574 %4 = zext i32 %3 to i64
1575 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1576 %6 = load i64, ptr %5, align 8
1580 define signext i16 @srliw_2_sh1add(ptr %0, i32 signext %1) {
1581 ; RV64I-LABEL: srliw_2_sh1add:
1583 ; RV64I-NEXT: srliw a1, a1, 2
1584 ; RV64I-NEXT: slli a1, a1, 32
1585 ; RV64I-NEXT: srli a1, a1, 31
1586 ; RV64I-NEXT: add a0, a0, a1
1587 ; RV64I-NEXT: lh a0, 0(a0)
1590 ; RV64ZBA-LABEL: srliw_2_sh1add:
1592 ; RV64ZBA-NEXT: srliw a1, a1, 2
1593 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1594 ; RV64ZBA-NEXT: lh a0, 0(a0)
1597 %4 = zext i32 %3 to i64
1598 %5 = getelementptr inbounds i16, ptr %0, i64 %4
1599 %6 = load i16, ptr %5, align 2
1604 define signext i32 @srliw_3_sh2add(ptr %0, i32 signext %1) {
1605 ; RV64I-LABEL: srliw_3_sh2add:
1607 ; RV64I-NEXT: srliw a1, a1, 3
1608 ; RV64I-NEXT: slli a1, a1, 32
1609 ; RV64I-NEXT: srli a1, a1, 30
1610 ; RV64I-NEXT: add a0, a0, a1
1611 ; RV64I-NEXT: lw a0, 0(a0)
1614 ; RV64ZBA-LABEL: srliw_3_sh2add:
1616 ; RV64ZBA-NEXT: srliw a1, a1, 3
1617 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1618 ; RV64ZBA-NEXT: lw a0, 0(a0)
1621 %4 = zext i32 %3 to i64
1622 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1623 %6 = load i32, ptr %5, align 4
1627 define i64 @srliw_4_sh3add(ptr %0, i32 signext %1) {
1628 ; RV64I-LABEL: srliw_4_sh3add:
1630 ; RV64I-NEXT: srliw a1, a1, 4
1631 ; RV64I-NEXT: slli a1, a1, 32
1632 ; RV64I-NEXT: srli a1, a1, 29
1633 ; RV64I-NEXT: add a0, a0, a1
1634 ; RV64I-NEXT: ld a0, 0(a0)
1637 ; RV64ZBA-LABEL: srliw_4_sh3add:
1639 ; RV64ZBA-NEXT: srliw a1, a1, 4
1640 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1641 ; RV64ZBA-NEXT: ld a0, 0(a0)
1644 %4 = zext i32 %3 to i64
1645 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1646 %6 = load i64, ptr %5, align 8
1650 define signext i32 @srli_1_sh2add(ptr %0, i64 %1) {
1651 ; RV64I-LABEL: srli_1_sh2add:
1653 ; RV64I-NEXT: slli a1, a1, 1
1654 ; RV64I-NEXT: andi a1, a1, -4
1655 ; RV64I-NEXT: add a0, a0, a1
1656 ; RV64I-NEXT: lw a0, 0(a0)
1659 ; RV64ZBA-LABEL: srli_1_sh2add:
1661 ; RV64ZBA-NEXT: srli a1, a1, 1
1662 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1663 ; RV64ZBA-NEXT: lw a0, 0(a0)
1666 %4 = getelementptr inbounds i32, ptr %0, i64 %3
1667 %5 = load i32, ptr %4, align 4
1671 define i64 @srli_2_sh3add(ptr %0, i64 %1) {
1672 ; RV64I-LABEL: srli_2_sh3add:
1674 ; RV64I-NEXT: slli a1, a1, 1
1675 ; RV64I-NEXT: andi a1, a1, -8
1676 ; RV64I-NEXT: add a0, a0, a1
1677 ; RV64I-NEXT: ld a0, 0(a0)
1680 ; RV64ZBA-LABEL: srli_2_sh3add:
1682 ; RV64ZBA-NEXT: srli a1, a1, 2
1683 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1684 ; RV64ZBA-NEXT: ld a0, 0(a0)
1687 %4 = getelementptr inbounds i64, ptr %0, i64 %3
1688 %5 = load i64, ptr %4, align 8
1692 define signext i16 @srli_2_sh1add(ptr %0, i64 %1) {
1693 ; RV64I-LABEL: srli_2_sh1add:
1695 ; RV64I-NEXT: srli a1, a1, 1
1696 ; RV64I-NEXT: andi a1, a1, -2
1697 ; RV64I-NEXT: add a0, a0, a1
1698 ; RV64I-NEXT: lh a0, 0(a0)
1701 ; RV64ZBA-LABEL: srli_2_sh1add:
1703 ; RV64ZBA-NEXT: srli a1, a1, 2
1704 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1705 ; RV64ZBA-NEXT: lh a0, 0(a0)
1708 %4 = getelementptr inbounds i16, ptr %0, i64 %3
1709 %5 = load i16, ptr %4, align 2
1713 define signext i32 @srli_3_sh2add(ptr %0, i64 %1) {
1714 ; RV64I-LABEL: srli_3_sh2add:
1716 ; RV64I-NEXT: srli a1, a1, 1
1717 ; RV64I-NEXT: andi a1, a1, -4
1718 ; RV64I-NEXT: add a0, a0, a1
1719 ; RV64I-NEXT: lw a0, 0(a0)
1722 ; RV64ZBA-LABEL: srli_3_sh2add:
1724 ; RV64ZBA-NEXT: srli a1, a1, 3
1725 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1726 ; RV64ZBA-NEXT: lw a0, 0(a0)
1729 %4 = getelementptr inbounds i32, ptr %0, i64 %3
1730 %5 = load i32, ptr %4, align 4
1734 define i64 @srli_4_sh3add(ptr %0, i64 %1) {
1735 ; RV64I-LABEL: srli_4_sh3add:
1737 ; RV64I-NEXT: srli a1, a1, 1
1738 ; RV64I-NEXT: andi a1, a1, -8
1739 ; RV64I-NEXT: add a0, a0, a1
1740 ; RV64I-NEXT: ld a0, 0(a0)
1743 ; RV64ZBA-LABEL: srli_4_sh3add:
1745 ; RV64ZBA-NEXT: srli a1, a1, 4
1746 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1747 ; RV64ZBA-NEXT: ld a0, 0(a0)
1750 %4 = getelementptr inbounds i64, ptr %0, i64 %3
1751 %5 = load i64, ptr %4, align 8
1755 define signext i16 @shl_2_sh1add(ptr %0, i32 signext %1) {
1756 ; RV64I-LABEL: shl_2_sh1add:
1758 ; RV64I-NEXT: slli a1, a1, 2
1759 ; RV64I-NEXT: slli a1, a1, 32
1760 ; RV64I-NEXT: srli a1, a1, 31
1761 ; RV64I-NEXT: add a0, a0, a1
1762 ; RV64I-NEXT: lh a0, 0(a0)
1765 ; RV64ZBA-LABEL: shl_2_sh1add:
1767 ; RV64ZBA-NEXT: slli a1, a1, 2
1768 ; RV64ZBA-NEXT: zext.w a1, a1
1769 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1770 ; RV64ZBA-NEXT: lh a0, 0(a0)
1773 %4 = zext i32 %3 to i64
1774 %5 = getelementptr inbounds i16, ptr %0, i64 %4
1775 %6 = load i16, ptr %5, align 2
1779 define signext i32 @shl_16_sh2add(ptr %0, i32 signext %1) {
1780 ; RV64I-LABEL: shl_16_sh2add:
1782 ; RV64I-NEXT: slli a1, a1, 16
1783 ; RV64I-NEXT: slli a1, a1, 32
1784 ; RV64I-NEXT: srli a1, a1, 30
1785 ; RV64I-NEXT: add a0, a0, a1
1786 ; RV64I-NEXT: lw a0, 0(a0)
1789 ; RV64ZBA-LABEL: shl_16_sh2add:
1791 ; RV64ZBA-NEXT: slli a1, a1, 16
1792 ; RV64ZBA-NEXT: zext.w a1, a1
1793 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1794 ; RV64ZBA-NEXT: lw a0, 0(a0)
1797 %4 = zext i32 %3 to i64
1798 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1799 %6 = load i32, ptr %5, align 4
1803 define i64 @shl_31_sh3add(ptr %0, i32 signext %1) {
1804 ; RV64I-LABEL: shl_31_sh3add:
1806 ; RV64I-NEXT: slli a1, a1, 31
1807 ; RV64I-NEXT: slli a1, a1, 32
1808 ; RV64I-NEXT: srli a1, a1, 29
1809 ; RV64I-NEXT: add a0, a0, a1
1810 ; RV64I-NEXT: ld a0, 0(a0)
1813 ; RV64ZBA-LABEL: shl_31_sh3add:
1815 ; RV64ZBA-NEXT: slli a1, a1, 31
1816 ; RV64ZBA-NEXT: zext.w a1, a1
1817 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1818 ; RV64ZBA-NEXT: ld a0, 0(a0)
1821 %4 = zext i32 %3 to i64
1822 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1823 %6 = load i64, ptr %5, align 8
1827 define i64 @pack_i64(i64 %a, i64 %b) nounwind {
1828 ; RV64I-LABEL: pack_i64:
1830 ; RV64I-NEXT: slli a0, a0, 32
1831 ; RV64I-NEXT: srli a0, a0, 32
1832 ; RV64I-NEXT: slli a1, a1, 32
1833 ; RV64I-NEXT: or a0, a1, a0
1836 ; RV64ZBA-LABEL: pack_i64:
1838 ; RV64ZBA-NEXT: slli a1, a1, 32
1839 ; RV64ZBA-NEXT: add.uw a0, a0, a1
1841 %shl = and i64 %a, 4294967295
1842 %shl1 = shl i64 %b, 32
1843 %or = or i64 %shl1, %shl
1847 define i64 @pack_i64_2(i32 signext %a, i32 signext %b) nounwind {
1848 ; RV64I-LABEL: pack_i64_2:
1850 ; RV64I-NEXT: slli a0, a0, 32
1851 ; RV64I-NEXT: srli a0, a0, 32
1852 ; RV64I-NEXT: slli a1, a1, 32
1853 ; RV64I-NEXT: or a0, a1, a0
1856 ; RV64ZBA-LABEL: pack_i64_2:
1858 ; RV64ZBA-NEXT: slli a1, a1, 32
1859 ; RV64ZBA-NEXT: add.uw a0, a0, a1
1861 %zexta = zext i32 %a to i64
1862 %zextb = zext i32 %b to i64
1863 %shl1 = shl i64 %zextb, 32
1864 %or = or i64 %shl1, %zexta
1868 define i64 @pack_i64_3(i32 signext %a, i32 signext %b) nounwind {
1869 ; RV64I-LABEL: pack_i64_3:
1871 ; RV64I-NEXT: addi a0, a0, 1
1872 ; RV64I-NEXT: addi a1, a1, 1
1873 ; RV64I-NEXT: slli a0, a0, 32
1874 ; RV64I-NEXT: srli a0, a0, 32
1875 ; RV64I-NEXT: slli a1, a1, 32
1876 ; RV64I-NEXT: or a0, a1, a0
1879 ; RV64ZBA-LABEL: pack_i64_3:
1881 ; RV64ZBA-NEXT: addi a0, a0, 1
1882 ; RV64ZBA-NEXT: addi a1, a1, 1
1883 ; RV64ZBA-NEXT: slli a1, a1, 32
1884 ; RV64ZBA-NEXT: add.uw a0, a0, a1
1886 %adda = add i32 %a, 1
1887 %addb = add i32 %b, 1
1888 %zexta = zext i32 %adda to i64
1889 %zextb = zext i32 %addb to i64
1890 %shl1 = shl i64 %zextb, 32
1891 %or = or i64 %shl1, %zexta