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,RV64ZBAZBBNOZBS
8 ; RUN: llc -mtriple=riscv64 -mattr=+m,+zba,+zbb,+zbs -verify-machineinstrs < %s \
9 ; RUN: | FileCheck %s -check-prefixes=CHECK,RV64ZBA,RV64ZBAZBB,RV64ZBAZBBZBS
11 define i64 @slliuw(i64 %a) nounwind {
12 ; RV64I-LABEL: slliuw:
14 ; RV64I-NEXT: slli a0, a0, 32
15 ; RV64I-NEXT: srli a0, a0, 31
18 ; RV64ZBA-LABEL: slliuw:
20 ; RV64ZBA-NEXT: slli.uw a0, a0, 1
22 %conv1 = shl i64 %a, 1
23 %shl = and i64 %conv1, 8589934590
27 define i128 @slliuw_2(i32 signext %0, ptr %1) {
28 ; RV64I-LABEL: slliuw_2:
30 ; RV64I-NEXT: slli a0, a0, 32
31 ; RV64I-NEXT: srli a0, a0, 28
32 ; RV64I-NEXT: add a1, a1, a0
33 ; RV64I-NEXT: ld a0, 0(a1)
34 ; RV64I-NEXT: ld a1, 8(a1)
37 ; RV64ZBA-LABEL: slliuw_2:
39 ; RV64ZBA-NEXT: slli.uw a0, a0, 4
40 ; RV64ZBA-NEXT: add a1, a1, a0
41 ; RV64ZBA-NEXT: ld a0, 0(a1)
42 ; RV64ZBA-NEXT: ld a1, 8(a1)
44 %3 = zext i32 %0 to i64
45 %4 = getelementptr inbounds i128, ptr %1, i64 %3
46 %5 = load i128, ptr %4
50 define i64 @adduw(i64 %a, i64 %b) nounwind {
53 ; RV64I-NEXT: slli a1, a1, 32
54 ; RV64I-NEXT: srli a1, a1, 32
55 ; RV64I-NEXT: add a0, a1, a0
58 ; RV64ZBA-LABEL: adduw:
60 ; RV64ZBA-NEXT: add.uw a0, a1, a0
62 %and = and i64 %b, 4294967295
63 %add = add i64 %and, %a
67 define signext i8 @adduw_2(i32 signext %0, ptr %1) {
68 ; RV64I-LABEL: adduw_2:
70 ; RV64I-NEXT: slli a0, a0, 32
71 ; RV64I-NEXT: srli a0, a0, 32
72 ; RV64I-NEXT: add a0, a1, a0
73 ; RV64I-NEXT: lb a0, 0(a0)
76 ; RV64ZBA-LABEL: adduw_2:
78 ; RV64ZBA-NEXT: add.uw a0, a0, a1
79 ; RV64ZBA-NEXT: lb a0, 0(a0)
81 %3 = zext i32 %0 to i64
82 %4 = getelementptr inbounds i8, ptr %1, i64 %3
87 define i64 @zextw_i64(i64 %a) nounwind {
88 ; RV64I-LABEL: zextw_i64:
90 ; RV64I-NEXT: slli a0, a0, 32
91 ; RV64I-NEXT: srli a0, a0, 32
94 ; RV64ZBA-LABEL: zextw_i64:
96 ; RV64ZBA-NEXT: zext.w a0, a0
98 %and = and i64 %a, 4294967295
102 ; This makes sure targetShrinkDemandedConstant changes the and immmediate to
103 ; allow zext.w or slli+srli.
104 define i64 @zextw_demandedbits_i64(i64 %0) {
105 ; RV64I-LABEL: zextw_demandedbits_i64:
107 ; RV64I-NEXT: ori a0, a0, 1
108 ; RV64I-NEXT: slli a0, a0, 32
109 ; RV64I-NEXT: srli a0, a0, 32
112 ; RV64ZBA-LABEL: zextw_demandedbits_i64:
114 ; RV64ZBA-NEXT: ori a0, a0, 1
115 ; RV64ZBA-NEXT: zext.w a0, a0
117 %2 = and i64 %0, 4294967294
122 define signext i16 @sh1add(i64 %0, ptr %1) {
123 ; RV64I-LABEL: sh1add:
125 ; RV64I-NEXT: slli a0, a0, 1
126 ; RV64I-NEXT: add a0, a1, a0
127 ; RV64I-NEXT: lh a0, 0(a0)
130 ; RV64ZBA-LABEL: sh1add:
132 ; RV64ZBA-NEXT: sh1add a0, a0, a1
133 ; RV64ZBA-NEXT: lh a0, 0(a0)
135 %3 = getelementptr inbounds i16, ptr %1, i64 %0
136 %4 = load i16, ptr %3
140 define signext i32 @sh2add(i64 %0, ptr %1) {
141 ; RV64I-LABEL: sh2add:
143 ; RV64I-NEXT: slli a0, a0, 2
144 ; RV64I-NEXT: add a0, a1, a0
145 ; RV64I-NEXT: lw a0, 0(a0)
148 ; RV64ZBA-LABEL: sh2add:
150 ; RV64ZBA-NEXT: sh2add a0, a0, a1
151 ; RV64ZBA-NEXT: lw a0, 0(a0)
153 %3 = getelementptr inbounds i32, ptr %1, i64 %0
154 %4 = load i32, ptr %3
158 define i64 @sh3add(i64 %0, ptr %1) {
159 ; RV64I-LABEL: sh3add:
161 ; RV64I-NEXT: slli a0, a0, 3
162 ; RV64I-NEXT: add a0, a1, a0
163 ; RV64I-NEXT: ld a0, 0(a0)
166 ; RV64ZBA-LABEL: sh3add:
168 ; RV64ZBA-NEXT: sh3add a0, a0, a1
169 ; RV64ZBA-NEXT: ld a0, 0(a0)
171 %3 = getelementptr inbounds i64, ptr %1, i64 %0
172 %4 = load i64, ptr %3
176 define signext i16 @sh1adduw(i32 signext %0, ptr %1) {
177 ; RV64I-LABEL: sh1adduw:
179 ; RV64I-NEXT: slli a0, a0, 32
180 ; RV64I-NEXT: srli a0, a0, 31
181 ; RV64I-NEXT: add a0, a1, a0
182 ; RV64I-NEXT: lh a0, 0(a0)
185 ; RV64ZBA-LABEL: sh1adduw:
187 ; RV64ZBA-NEXT: sh1add.uw a0, a0, a1
188 ; RV64ZBA-NEXT: lh a0, 0(a0)
190 %3 = zext i32 %0 to i64
191 %4 = getelementptr inbounds i16, ptr %1, i64 %3
192 %5 = load i16, ptr %4
196 define i64 @sh1adduw_2(i64 %0, i64 %1) {
197 ; RV64I-LABEL: sh1adduw_2:
199 ; RV64I-NEXT: slli a0, a0, 32
200 ; RV64I-NEXT: srli a0, a0, 31
201 ; RV64I-NEXT: add a0, a0, a1
204 ; RV64ZBA-LABEL: sh1adduw_2:
206 ; RV64ZBA-NEXT: sh1add.uw a0, a0, a1
209 %4 = and i64 %3, 8589934590
214 define i64 @sh1adduw_3(i64 %0, i64 %1) {
215 ; RV64I-LABEL: sh1adduw_3:
217 ; RV64I-NEXT: slli a0, a0, 32
218 ; RV64I-NEXT: srli a0, a0, 31
219 ; RV64I-NEXT: or a0, a0, a1
222 ; RV64ZBA-LABEL: sh1adduw_3:
224 ; RV64ZBA-NEXT: sh1add.uw a0, a0, a1
227 %4 = and i64 %3, 8589934590
228 %5 = or disjoint i64 %4, %1
232 define signext i32 @sh2adduw(i32 signext %0, ptr %1) {
233 ; RV64I-LABEL: sh2adduw:
235 ; RV64I-NEXT: slli a0, a0, 32
236 ; RV64I-NEXT: srli a0, a0, 30
237 ; RV64I-NEXT: add a0, a1, a0
238 ; RV64I-NEXT: lw a0, 0(a0)
241 ; RV64ZBA-LABEL: sh2adduw:
243 ; RV64ZBA-NEXT: sh2add.uw a0, a0, a1
244 ; RV64ZBA-NEXT: lw a0, 0(a0)
246 %3 = zext i32 %0 to i64
247 %4 = getelementptr inbounds i32, ptr %1, i64 %3
248 %5 = load i32, ptr %4
252 define i64 @sh2adduw_2(i64 %0, i64 %1) {
253 ; RV64I-LABEL: sh2adduw_2:
255 ; RV64I-NEXT: slli a0, a0, 32
256 ; RV64I-NEXT: srli a0, a0, 30
257 ; RV64I-NEXT: add a0, a0, a1
260 ; RV64ZBA-LABEL: sh2adduw_2:
262 ; RV64ZBA-NEXT: sh2add.uw a0, a0, a1
265 %4 = and i64 %3, 17179869180
270 define i64 @sh2adduw_3(i64 %0, i64 %1) {
271 ; RV64I-LABEL: sh2adduw_3:
273 ; RV64I-NEXT: slli a0, a0, 32
274 ; RV64I-NEXT: srli a0, a0, 30
275 ; RV64I-NEXT: or a0, a0, a1
278 ; RV64ZBA-LABEL: sh2adduw_3:
280 ; RV64ZBA-NEXT: sh2add.uw a0, a0, a1
283 %4 = and i64 %3, 17179869180
284 %5 = or disjoint i64 %4, %1
288 define i64 @sh3adduw(i32 signext %0, ptr %1) {
289 ; RV64I-LABEL: sh3adduw:
291 ; RV64I-NEXT: slli a0, a0, 32
292 ; RV64I-NEXT: srli a0, a0, 29
293 ; RV64I-NEXT: add a0, a1, a0
294 ; RV64I-NEXT: ld a0, 0(a0)
297 ; RV64ZBA-LABEL: sh3adduw:
299 ; RV64ZBA-NEXT: sh3add.uw a0, a0, a1
300 ; RV64ZBA-NEXT: ld a0, 0(a0)
302 %3 = zext i32 %0 to i64
303 %4 = getelementptr inbounds i64, ptr %1, i64 %3
304 %5 = load i64, ptr %4
308 define i64 @sh3adduw_2(i64 %0, i64 %1) {
309 ; RV64I-LABEL: sh3adduw_2:
311 ; RV64I-NEXT: slli a0, a0, 32
312 ; RV64I-NEXT: srli a0, a0, 29
313 ; RV64I-NEXT: add a0, a0, a1
316 ; RV64ZBA-LABEL: sh3adduw_2:
318 ; RV64ZBA-NEXT: sh3add.uw a0, a0, a1
321 %4 = and i64 %3, 34359738360
326 define i64 @sh3adduw_3(i64 %0, i64 %1) {
327 ; RV64I-LABEL: sh3adduw_3:
329 ; RV64I-NEXT: slli a0, a0, 32
330 ; RV64I-NEXT: srli a0, a0, 29
331 ; RV64I-NEXT: or a0, a0, a1
334 ; RV64ZBA-LABEL: sh3adduw_3:
336 ; RV64ZBA-NEXT: sh3add.uw a0, a0, a1
339 %4 = and i64 %3, 34359738360
340 %5 = or disjoint i64 %4, %1
344 ; Type legalization inserts a sext_inreg after the first add. That add will be
345 ; selected as sh2add which does not sign extend. SimplifyDemandedBits is unable
346 ; to remove the sext_inreg because it has multiple uses. The ashr will use the
347 ; sext_inreg to become sraiw. This leaves the sext_inreg only used by the shl.
348 ; If the shl is selected as sllw, we don't need the sext_inreg.
349 define i64 @sh2add_extra_sext(i32 %x, i32 %y, i32 %z) {
350 ; RV64I-LABEL: sh2add_extra_sext:
352 ; RV64I-NEXT: slli a0, a0, 2
353 ; RV64I-NEXT: add a0, a0, a1
354 ; RV64I-NEXT: sllw a1, a2, a0
355 ; RV64I-NEXT: sraiw a0, a0, 2
356 ; RV64I-NEXT: mul a0, a1, a0
359 ; RV64ZBA-LABEL: sh2add_extra_sext:
361 ; RV64ZBA-NEXT: sh2add a0, a0, a1
362 ; RV64ZBA-NEXT: sllw a1, a2, a0
363 ; RV64ZBA-NEXT: sraiw a0, a0, 2
364 ; RV64ZBA-NEXT: mul a0, a1, a0
370 %e = sext i32 %c to i64
371 %f = sext i32 %d to i64
376 define i64 @addmul6(i64 %a, i64 %b) {
377 ; RV64I-LABEL: addmul6:
379 ; RV64I-NEXT: slli a2, a0, 1
380 ; RV64I-NEXT: slli a0, a0, 3
381 ; RV64I-NEXT: sub a0, a0, a2
382 ; RV64I-NEXT: add a0, a0, a1
385 ; RV64ZBA-LABEL: addmul6:
387 ; RV64ZBA-NEXT: sh1add a0, a0, a0
388 ; RV64ZBA-NEXT: sh1add a0, a0, a1
395 define i64 @disjointormul6(i64 %a, i64 %b) {
396 ; RV64I-LABEL: disjointormul6:
398 ; RV64I-NEXT: slli a2, a0, 1
399 ; RV64I-NEXT: slli a0, a0, 3
400 ; RV64I-NEXT: sub a0, a0, a2
401 ; RV64I-NEXT: or a0, a0, a1
404 ; RV64ZBA-LABEL: disjointormul6:
406 ; RV64ZBA-NEXT: sh1add a0, a0, a0
407 ; RV64ZBA-NEXT: sh1add a0, a0, a1
410 %d = or disjoint i64 %c, %b
414 define i64 @addmul10(i64 %a, i64 %b) {
415 ; RV64I-LABEL: addmul10:
417 ; RV64I-NEXT: li a2, 10
418 ; RV64I-NEXT: mul a0, a0, a2
419 ; RV64I-NEXT: add a0, a0, a1
422 ; RV64ZBA-LABEL: addmul10:
424 ; RV64ZBA-NEXT: sh2add a0, a0, a0
425 ; RV64ZBA-NEXT: sh1add a0, a0, a1
432 define i64 @addmul12(i64 %a, i64 %b) {
433 ; RV64I-LABEL: addmul12:
435 ; RV64I-NEXT: slli a2, a0, 2
436 ; RV64I-NEXT: slli a0, a0, 4
437 ; RV64I-NEXT: sub a0, a0, a2
438 ; RV64I-NEXT: add a0, a0, a1
441 ; RV64ZBA-LABEL: addmul12:
443 ; RV64ZBA-NEXT: sh1add a0, a0, a0
444 ; RV64ZBA-NEXT: sh2add a0, a0, a1
451 define i64 @addmul18(i64 %a, i64 %b) {
452 ; RV64I-LABEL: addmul18:
454 ; RV64I-NEXT: li a2, 18
455 ; RV64I-NEXT: mul a0, a0, a2
456 ; RV64I-NEXT: add a0, a0, a1
459 ; RV64ZBA-LABEL: addmul18:
461 ; RV64ZBA-NEXT: sh3add a0, a0, a0
462 ; RV64ZBA-NEXT: sh1add a0, a0, a1
469 define i64 @addmul20(i64 %a, i64 %b) {
470 ; RV64I-LABEL: addmul20:
472 ; RV64I-NEXT: li a2, 20
473 ; RV64I-NEXT: mul a0, a0, a2
474 ; RV64I-NEXT: add a0, a0, a1
477 ; RV64ZBA-LABEL: addmul20:
479 ; RV64ZBA-NEXT: sh2add a0, a0, a0
480 ; RV64ZBA-NEXT: sh2add a0, a0, a1
487 define i64 @addmul22(i64 %a, i64 %b) {
488 ; CHECK-LABEL: addmul22:
490 ; CHECK-NEXT: li a2, 22
491 ; CHECK-NEXT: mul a0, a0, a2
492 ; CHECK-NEXT: add a0, a0, a1
499 define i64 @addmul24(i64 %a, i64 %b) {
500 ; RV64I-LABEL: addmul24:
502 ; RV64I-NEXT: slli a2, a0, 3
503 ; RV64I-NEXT: slli a0, a0, 5
504 ; RV64I-NEXT: sub a0, a0, a2
505 ; RV64I-NEXT: add a0, a0, a1
508 ; RV64ZBA-LABEL: addmul24:
510 ; RV64ZBA-NEXT: sh1add a0, a0, a0
511 ; RV64ZBA-NEXT: sh3add a0, a0, a1
518 define i64 @addmul36(i64 %a, i64 %b) {
519 ; RV64I-LABEL: addmul36:
521 ; RV64I-NEXT: li a2, 36
522 ; RV64I-NEXT: mul a0, a0, a2
523 ; RV64I-NEXT: add a0, a0, a1
526 ; RV64ZBA-LABEL: addmul36:
528 ; RV64ZBA-NEXT: sh3add a0, a0, a0
529 ; RV64ZBA-NEXT: sh2add a0, a0, a1
536 define i64 @addmul40(i64 %a, i64 %b) {
537 ; RV64I-LABEL: addmul40:
539 ; RV64I-NEXT: li a2, 40
540 ; RV64I-NEXT: mul a0, a0, a2
541 ; RV64I-NEXT: add a0, a0, a1
544 ; RV64ZBA-LABEL: addmul40:
546 ; RV64ZBA-NEXT: sh2add a0, a0, a0
547 ; RV64ZBA-NEXT: sh3add a0, a0, a1
554 define i64 @addmul72(i64 %a, i64 %b) {
555 ; RV64I-LABEL: addmul72:
557 ; RV64I-NEXT: li a2, 72
558 ; RV64I-NEXT: mul a0, a0, a2
559 ; RV64I-NEXT: add a0, a0, a1
562 ; RV64ZBA-LABEL: addmul72:
564 ; RV64ZBA-NEXT: sh3add a0, a0, a0
565 ; RV64ZBA-NEXT: sh3add a0, a0, a1
572 define i64 @addmul162(i64 %a, i64 %b) {
573 ; CHECK-LABEL: addmul162:
575 ; CHECK-NEXT: li a2, 162
576 ; CHECK-NEXT: mul a0, a0, a2
577 ; CHECK-NEXT: add a0, a0, a1
584 define i64 @addmul180(i64 %a, i64 %b) {
585 ; CHECK-LABEL: addmul180:
587 ; CHECK-NEXT: li a2, 180
588 ; CHECK-NEXT: mul a0, a0, a2
589 ; CHECK-NEXT: add a0, a0, a1
596 define i64 @add255mul180(i64 %a) {
597 ; CHECK-LABEL: add255mul180:
599 ; CHECK-NEXT: li a1, 180
600 ; CHECK-NEXT: mul a0, a0, a1
601 ; CHECK-NEXT: addi a0, a0, 255
609 define i64 @addmul4096(i64 %a, i64 %b) {
610 ; CHECK-LABEL: addmul4096:
612 ; CHECK-NEXT: slli a0, a0, 12
613 ; CHECK-NEXT: add a0, a0, a1
615 %c = mul i64 %a, 4096
620 define i64 @addmul4230(i64 %a, i64 %b) {
621 ; CHECK-LABEL: addmul4230:
623 ; CHECK-NEXT: lui a2, 1
624 ; CHECK-NEXT: addiw a2, a2, 134
625 ; CHECK-NEXT: mul a0, a0, a2
626 ; CHECK-NEXT: add a0, a0, a1
628 %c = mul i64 %a, 4230
633 define i64 @mul96(i64 %a) {
634 ; RV64I-LABEL: mul96:
636 ; RV64I-NEXT: slli a1, a0, 5
637 ; RV64I-NEXT: slli a0, a0, 7
638 ; RV64I-NEXT: sub a0, a0, a1
641 ; RV64ZBA-LABEL: mul96:
643 ; RV64ZBA-NEXT: sh1add a0, a0, a0
644 ; RV64ZBA-NEXT: slli a0, a0, 5
650 define i64 @mul119(i64 %a) {
651 ; RV64I-LABEL: mul119:
653 ; RV64I-NEXT: li a1, 119
654 ; RV64I-NEXT: mul a0, a0, a1
657 ; RV64ZBA-LABEL: mul119:
659 ; RV64ZBA-NEXT: sh3add a1, a0, a0
660 ; RV64ZBA-NEXT: slli a0, a0, 7
661 ; RV64ZBA-NEXT: sub a0, a0, a1
667 define i64 @mul123(i64 %a) {
668 ; RV64I-LABEL: mul123:
670 ; RV64I-NEXT: li a1, 123
671 ; RV64I-NEXT: mul a0, a0, a1
674 ; RV64ZBA-LABEL: mul123:
676 ; RV64ZBA-NEXT: sh2add a1, a0, a0
677 ; RV64ZBA-NEXT: slli a0, a0, 7
678 ; RV64ZBA-NEXT: sub a0, a0, a1
684 define i64 @mul125(i64 %a) {
685 ; RV64I-LABEL: mul125:
687 ; RV64I-NEXT: li a1, 125
688 ; RV64I-NEXT: mul a0, a0, a1
691 ; RV64ZBA-LABEL: mul125:
693 ; RV64ZBA-NEXT: sh1add a1, a0, a0
694 ; RV64ZBA-NEXT: slli a0, a0, 7
695 ; RV64ZBA-NEXT: sub a0, a0, a1
701 define i64 @mul131(i64 %a) {
702 ; RV64I-LABEL: mul131:
704 ; RV64I-NEXT: li a1, 131
705 ; RV64I-NEXT: mul a0, a0, a1
708 ; RV64ZBA-LABEL: mul131:
710 ; RV64ZBA-NEXT: sh1add a1, a0, a0
711 ; RV64ZBA-NEXT: slli a0, a0, 7
712 ; RV64ZBA-NEXT: add a0, a0, a1
718 define i64 @mul133(i64 %a) {
719 ; RV64I-LABEL: mul133:
721 ; RV64I-NEXT: li a1, 133
722 ; RV64I-NEXT: mul a0, a0, a1
725 ; RV64ZBA-LABEL: mul133:
727 ; RV64ZBA-NEXT: sh2add a1, a0, a0
728 ; RV64ZBA-NEXT: slli a0, a0, 7
729 ; RV64ZBA-NEXT: add a0, a0, a1
735 define i64 @mul137(i64 %a) {
736 ; RV64I-LABEL: mul137:
738 ; RV64I-NEXT: li a1, 137
739 ; RV64I-NEXT: mul a0, a0, a1
742 ; RV64ZBA-LABEL: mul137:
744 ; RV64ZBA-NEXT: sh3add a1, a0, a0
745 ; RV64ZBA-NEXT: slli a0, a0, 7
746 ; RV64ZBA-NEXT: add a0, a0, a1
752 define i64 @mul160(i64 %a) {
753 ; RV64I-LABEL: mul160:
755 ; RV64I-NEXT: li a1, 160
756 ; RV64I-NEXT: mul a0, a0, a1
759 ; RV64ZBA-LABEL: mul160:
761 ; RV64ZBA-NEXT: sh2add a0, a0, a0
762 ; RV64ZBA-NEXT: slli a0, a0, 5
768 define i64 @mul288(i64 %a) {
769 ; RV64I-LABEL: mul288:
771 ; RV64I-NEXT: li a1, 288
772 ; RV64I-NEXT: mul a0, a0, a1
775 ; RV64ZBA-LABEL: mul288:
777 ; RV64ZBA-NEXT: sh3add a0, a0, a0
778 ; RV64ZBA-NEXT: slli a0, a0, 5
784 define i64 @zext_mul68(i32 signext %a) {
785 ; RV64I-LABEL: zext_mul68:
787 ; RV64I-NEXT: li a1, 17
788 ; RV64I-NEXT: slli a1, a1, 34
789 ; RV64I-NEXT: slli a0, a0, 32
790 ; RV64I-NEXT: mulhu a0, a0, a1
793 ; RV64ZBA-LABEL: zext_mul68:
795 ; RV64ZBA-NEXT: slli.uw a1, a0, 6
796 ; RV64ZBA-NEXT: sh2add.uw a0, a0, a1
798 %b = zext i32 %a to i64
803 define i64 @zext_mul96(i32 signext %a) {
804 ; RV64I-LABEL: zext_mul96:
806 ; RV64I-NEXT: slli a0, a0, 32
807 ; RV64I-NEXT: srli a1, a0, 27
808 ; RV64I-NEXT: srli a0, a0, 25
809 ; RV64I-NEXT: sub a0, a0, a1
812 ; RV64ZBA-LABEL: zext_mul96:
814 ; RV64ZBA-NEXT: slli.uw a0, a0, 5
815 ; RV64ZBA-NEXT: sh1add a0, a0, a0
817 %b = zext i32 %a to i64
822 define i64 @zext_mul160(i32 signext %a) {
823 ; RV64I-LABEL: zext_mul160:
825 ; RV64I-NEXT: li a1, 5
826 ; RV64I-NEXT: slli a1, a1, 37
827 ; RV64I-NEXT: slli a0, a0, 32
828 ; RV64I-NEXT: mulhu a0, a0, a1
831 ; RV64ZBA-LABEL: zext_mul160:
833 ; RV64ZBA-NEXT: slli.uw a0, a0, 5
834 ; RV64ZBA-NEXT: sh2add a0, a0, a0
836 %b = zext i32 %a to i64
841 define i64 @zext_mul288(i32 signext %a) {
842 ; RV64I-LABEL: zext_mul288:
844 ; RV64I-NEXT: li a1, 9
845 ; RV64I-NEXT: slli a1, a1, 37
846 ; RV64I-NEXT: slli a0, a0, 32
847 ; RV64I-NEXT: mulhu a0, a0, a1
850 ; RV64ZBA-LABEL: zext_mul288:
852 ; RV64ZBA-NEXT: slli.uw a0, a0, 5
853 ; RV64ZBA-NEXT: sh3add a0, a0, a0
855 %b = zext i32 %a to i64
860 ; We can't use slli.uw becaues the shift amount is more than 31.
861 define i64 @zext_mul12884901888(i32 signext %a) {
862 ; RV64I-LABEL: zext_mul12884901888:
864 ; RV64I-NEXT: slli a1, a0, 32
865 ; RV64I-NEXT: slli a0, a0, 34
866 ; RV64I-NEXT: sub a0, a0, a1
869 ; RV64ZBA-LABEL: zext_mul12884901888:
871 ; RV64ZBA-NEXT: sh1add a0, a0, a0
872 ; RV64ZBA-NEXT: slli a0, a0, 32
874 %b = zext i32 %a to i64
875 %c = mul i64 %b, 12884901888
879 ; We can't use slli.uw becaues the shift amount is more than 31.
880 define i64 @zext_mul21474836480(i32 signext %a) {
881 ; RV64I-LABEL: zext_mul21474836480:
883 ; RV64I-NEXT: li a1, 5
884 ; RV64I-NEXT: slli a1, a1, 32
885 ; RV64I-NEXT: mul a0, a0, a1
888 ; RV64ZBA-LABEL: zext_mul21474836480:
890 ; RV64ZBA-NEXT: sh2add a0, a0, a0
891 ; RV64ZBA-NEXT: slli a0, a0, 32
893 %b = zext i32 %a to i64
894 %c = mul i64 %b, 21474836480
898 ; We can't use slli.uw becaues the shift amount is more than 31.
899 define i64 @zext_mul38654705664(i32 signext %a) {
900 ; RV64I-LABEL: zext_mul38654705664:
902 ; RV64I-NEXT: li a1, 9
903 ; RV64I-NEXT: slli a1, a1, 32
904 ; RV64I-NEXT: mul a0, a0, a1
907 ; RV64ZBA-LABEL: zext_mul38654705664:
909 ; RV64ZBA-NEXT: sh3add a0, a0, a0
910 ; RV64ZBA-NEXT: slli a0, a0, 32
912 %b = zext i32 %a to i64
913 %c = mul i64 %b, 38654705664
917 define i64 @sh1add_imm(i64 %0) {
918 ; CHECK-LABEL: sh1add_imm:
920 ; CHECK-NEXT: slli a0, a0, 1
921 ; CHECK-NEXT: addi a0, a0, 5
928 define i64 @sh2add_imm(i64 %0) {
929 ; CHECK-LABEL: sh2add_imm:
931 ; CHECK-NEXT: slli a0, a0, 2
932 ; CHECK-NEXT: addi a0, a0, -6
939 define i64 @sh3add_imm(i64 %0) {
940 ; CHECK-LABEL: sh3add_imm:
942 ; CHECK-NEXT: slli a0, a0, 3
943 ; CHECK-NEXT: addi a0, a0, 7
950 define i64 @sh1adduw_imm(i32 signext %0) {
951 ; RV64I-LABEL: sh1adduw_imm:
953 ; RV64I-NEXT: slli a0, a0, 32
954 ; RV64I-NEXT: srli a0, a0, 31
955 ; RV64I-NEXT: addi a0, a0, 11
958 ; RV64ZBA-LABEL: sh1adduw_imm:
960 ; RV64ZBA-NEXT: slli.uw a0, a0, 1
961 ; RV64ZBA-NEXT: addi a0, a0, 11
963 %a = zext i32 %0 to i64
969 define i64 @sh2adduw_imm(i32 signext %0) {
970 ; RV64I-LABEL: sh2adduw_imm:
972 ; RV64I-NEXT: slli a0, a0, 32
973 ; RV64I-NEXT: srli a0, a0, 30
974 ; RV64I-NEXT: addi a0, a0, -12
977 ; RV64ZBA-LABEL: sh2adduw_imm:
979 ; RV64ZBA-NEXT: slli.uw a0, a0, 2
980 ; RV64ZBA-NEXT: addi a0, a0, -12
982 %a = zext i32 %0 to i64
988 define i64 @sh3adduw_imm(i32 signext %0) {
989 ; RV64I-LABEL: sh3adduw_imm:
991 ; RV64I-NEXT: slli a0, a0, 32
992 ; RV64I-NEXT: srli a0, a0, 29
993 ; RV64I-NEXT: addi a0, a0, 13
996 ; RV64ZBA-LABEL: sh3adduw_imm:
998 ; RV64ZBA-NEXT: slli.uw a0, a0, 3
999 ; RV64ZBA-NEXT: addi a0, a0, 13
1001 %a = zext i32 %0 to i64
1007 define i64 @adduw_imm(i32 signext %0) nounwind {
1008 ; RV64I-LABEL: adduw_imm:
1010 ; RV64I-NEXT: slli a0, a0, 32
1011 ; RV64I-NEXT: srli a0, a0, 32
1012 ; RV64I-NEXT: addi a0, a0, 5
1015 ; RV64ZBA-LABEL: adduw_imm:
1017 ; RV64ZBA-NEXT: zext.w a0, a0
1018 ; RV64ZBA-NEXT: addi a0, a0, 5
1020 %a = zext i32 %0 to i64
1025 define i64 @mul258(i64 %a) {
1026 ; RV64I-LABEL: mul258:
1028 ; RV64I-NEXT: li a1, 258
1029 ; RV64I-NEXT: mul a0, a0, a1
1032 ; RV64ZBA-LABEL: mul258:
1034 ; RV64ZBA-NEXT: slli a1, a0, 8
1035 ; RV64ZBA-NEXT: sh1add a0, a0, a1
1037 %c = mul i64 %a, 258
1041 define i64 @mul260(i64 %a) {
1042 ; RV64I-LABEL: mul260:
1044 ; RV64I-NEXT: li a1, 260
1045 ; RV64I-NEXT: mul a0, a0, a1
1048 ; RV64ZBA-LABEL: mul260:
1050 ; RV64ZBA-NEXT: slli a1, a0, 8
1051 ; RV64ZBA-NEXT: sh2add a0, a0, a1
1053 %c = mul i64 %a, 260
1057 define i64 @mul264(i64 %a) {
1058 ; RV64I-LABEL: mul264:
1060 ; RV64I-NEXT: li a1, 264
1061 ; RV64I-NEXT: mul a0, a0, a1
1064 ; RV64ZBA-LABEL: mul264:
1066 ; RV64ZBA-NEXT: slli a1, a0, 8
1067 ; RV64ZBA-NEXT: sh3add a0, a0, a1
1069 %c = mul i64 %a, 264
1073 define i64 @imm_zextw() nounwind {
1074 ; RV64I-LABEL: imm_zextw:
1076 ; RV64I-NEXT: li a0, 1
1077 ; RV64I-NEXT: slli a0, a0, 32
1078 ; RV64I-NEXT: addi a0, a0, -2
1081 ; RV64ZBA-LABEL: imm_zextw:
1083 ; RV64ZBA-NEXT: li a0, -2
1084 ; RV64ZBA-NEXT: zext.w a0, a0
1086 ret i64 4294967294 ; -2 in 32 bits.
1089 define i64 @mul11(i64 %a) {
1090 ; RV64I-LABEL: mul11:
1092 ; RV64I-NEXT: li a1, 11
1093 ; RV64I-NEXT: mul a0, a0, a1
1096 ; RV64ZBA-LABEL: mul11:
1098 ; RV64ZBA-NEXT: sh2add a1, a0, a0
1099 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1105 define i64 @mul19(i64 %a) {
1106 ; RV64I-LABEL: mul19:
1108 ; RV64I-NEXT: li a1, 19
1109 ; RV64I-NEXT: mul a0, a0, a1
1112 ; RV64ZBA-LABEL: mul19:
1114 ; RV64ZBA-NEXT: sh3add a1, a0, a0
1115 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1121 define i64 @mul13(i64 %a) {
1122 ; RV64I-LABEL: mul13:
1124 ; RV64I-NEXT: li a1, 13
1125 ; RV64I-NEXT: mul a0, a0, a1
1128 ; RV64ZBA-LABEL: mul13:
1130 ; RV64ZBA-NEXT: sh1add a1, a0, a0
1131 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1137 define i64 @mul21(i64 %a) {
1138 ; RV64I-LABEL: mul21:
1140 ; RV64I-NEXT: li a1, 21
1141 ; RV64I-NEXT: mul a0, a0, a1
1144 ; RV64ZBA-LABEL: mul21:
1146 ; RV64ZBA-NEXT: sh2add a1, a0, a0
1147 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1153 define i64 @mul37(i64 %a) {
1154 ; RV64I-LABEL: mul37:
1156 ; RV64I-NEXT: li a1, 37
1157 ; RV64I-NEXT: mul a0, a0, a1
1160 ; RV64ZBA-LABEL: mul37:
1162 ; RV64ZBA-NEXT: sh3add a1, a0, a0
1163 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1169 define i64 @mul25(i64 %a) {
1170 ; RV64I-LABEL: mul25:
1172 ; RV64I-NEXT: li a1, 25
1173 ; RV64I-NEXT: mul a0, a0, a1
1176 ; RV64ZBA-LABEL: mul25:
1178 ; RV64ZBA-NEXT: sh2add a0, a0, a0
1179 ; RV64ZBA-NEXT: sh2add a0, a0, a0
1185 define i64 @mul41(i64 %a) {
1186 ; RV64I-LABEL: mul41:
1188 ; RV64I-NEXT: li a1, 41
1189 ; RV64I-NEXT: mul a0, a0, a1
1192 ; RV64ZBA-LABEL: mul41:
1194 ; RV64ZBA-NEXT: sh2add a1, a0, a0
1195 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1201 define i64 @mul73(i64 %a) {
1202 ; RV64I-LABEL: mul73:
1204 ; RV64I-NEXT: li a1, 73
1205 ; RV64I-NEXT: mul a0, a0, a1
1208 ; RV64ZBA-LABEL: mul73:
1210 ; RV64ZBA-NEXT: sh3add a1, a0, a0
1211 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1217 define i64 @mul27(i64 %a) {
1218 ; RV64I-LABEL: mul27:
1220 ; RV64I-NEXT: li a1, 27
1221 ; RV64I-NEXT: mul a0, a0, a1
1224 ; RV64ZBA-LABEL: mul27:
1226 ; RV64ZBA-NEXT: sh1add a0, a0, a0
1227 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1233 define i64 @mul45(i64 %a) {
1234 ; RV64I-LABEL: mul45:
1236 ; RV64I-NEXT: li a1, 45
1237 ; RV64I-NEXT: mul a0, a0, a1
1240 ; RV64ZBA-LABEL: mul45:
1242 ; RV64ZBA-NEXT: sh2add a0, a0, a0
1243 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1249 define i64 @mul81(i64 %a) {
1250 ; RV64I-LABEL: mul81:
1252 ; RV64I-NEXT: li a1, 81
1253 ; RV64I-NEXT: mul a0, a0, a1
1256 ; RV64ZBA-LABEL: mul81:
1258 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1259 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1265 define i64 @mul4098(i64 %a) {
1266 ; RV64I-LABEL: mul4098:
1268 ; RV64I-NEXT: slli a1, a0, 1
1269 ; RV64I-NEXT: slli a0, a0, 12
1270 ; RV64I-NEXT: add a0, a0, a1
1273 ; RV64ZBA-LABEL: mul4098:
1275 ; RV64ZBA-NEXT: slli a1, a0, 12
1276 ; RV64ZBA-NEXT: sh1add a0, a0, a1
1278 %c = mul i64 %a, 4098
1282 define i64 @mul4100(i64 %a) {
1283 ; RV64I-LABEL: mul4100:
1285 ; RV64I-NEXT: slli a1, a0, 2
1286 ; RV64I-NEXT: slli a0, a0, 12
1287 ; RV64I-NEXT: add a0, a0, a1
1290 ; RV64ZBA-LABEL: mul4100:
1292 ; RV64ZBA-NEXT: slli a1, a0, 12
1293 ; RV64ZBA-NEXT: sh2add a0, a0, a1
1295 %c = mul i64 %a, 4100
1299 define i64 @mul4104(i64 %a) {
1300 ; RV64I-LABEL: mul4104:
1302 ; RV64I-NEXT: slli a1, a0, 3
1303 ; RV64I-NEXT: slli a0, a0, 12
1304 ; RV64I-NEXT: add a0, a0, a1
1307 ; RV64ZBA-LABEL: mul4104:
1309 ; RV64ZBA-NEXT: slli a1, a0, 12
1310 ; RV64ZBA-NEXT: sh3add a0, a0, a1
1312 %c = mul i64 %a, 4104
1316 define signext i32 @mulw192(i32 signext %a) {
1317 ; RV64I-LABEL: mulw192:
1319 ; RV64I-NEXT: slli a1, a0, 6
1320 ; RV64I-NEXT: slli a0, a0, 8
1321 ; RV64I-NEXT: subw a0, a0, a1
1324 ; RV64ZBA-LABEL: mulw192:
1326 ; RV64ZBA-NEXT: sh1add a0, a0, a0
1327 ; RV64ZBA-NEXT: slliw a0, a0, 6
1329 %c = mul i32 %a, 192
1333 define signext i32 @mulw320(i32 signext %a) {
1334 ; RV64I-LABEL: mulw320:
1336 ; RV64I-NEXT: li a1, 320
1337 ; RV64I-NEXT: mulw a0, a0, a1
1340 ; RV64ZBA-LABEL: mulw320:
1342 ; RV64ZBA-NEXT: sh2add a0, a0, a0
1343 ; RV64ZBA-NEXT: slliw a0, a0, 6
1345 %c = mul i32 %a, 320
1349 define signext i32 @mulw576(i32 signext %a) {
1350 ; RV64I-LABEL: mulw576:
1352 ; RV64I-NEXT: li a1, 576
1353 ; RV64I-NEXT: mulw a0, a0, a1
1356 ; RV64ZBA-LABEL: mulw576:
1358 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1359 ; RV64ZBA-NEXT: slliw a0, a0, 6
1361 %c = mul i32 %a, 576
1365 define i64 @add4104(i64 %a) {
1366 ; RV64I-LABEL: add4104:
1368 ; RV64I-NEXT: lui a1, 1
1369 ; RV64I-NEXT: addiw a1, a1, 8
1370 ; RV64I-NEXT: add a0, a0, a1
1373 ; RV64ZBA-LABEL: add4104:
1375 ; RV64ZBA-NEXT: li a1, 1026
1376 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1378 %c = add i64 %a, 4104
1382 define i64 @add4104_2(i64 %a) {
1383 ; RV64I-LABEL: add4104_2:
1385 ; RV64I-NEXT: lui a1, 1
1386 ; RV64I-NEXT: addiw a1, a1, 8
1387 ; RV64I-NEXT: or a0, a0, a1
1390 ; RV64ZBA-LABEL: add4104_2:
1392 ; RV64ZBA-NEXT: li a1, 1026
1393 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1395 %c = or disjoint i64 %a, 4104
1399 define i64 @add8208(i64 %a) {
1400 ; RV64I-LABEL: add8208:
1402 ; RV64I-NEXT: lui a1, 2
1403 ; RV64I-NEXT: addiw a1, a1, 16
1404 ; RV64I-NEXT: add a0, a0, a1
1407 ; RV64ZBA-LABEL: add8208:
1409 ; RV64ZBA-NEXT: li a1, 1026
1410 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1412 %c = add i64 %a, 8208
1416 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1417 define signext i32 @add8192_i32(i32 signext %a) {
1418 ; CHECK-LABEL: add8192_i32:
1420 ; CHECK-NEXT: lui a1, 2
1421 ; CHECK-NEXT: addw a0, a0, a1
1423 %c = add i32 %a, 8192
1427 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1428 define i64 @add8192(i64 %a) {
1429 ; CHECK-LABEL: add8192:
1431 ; CHECK-NEXT: lui a1, 2
1432 ; CHECK-NEXT: add a0, a0, a1
1434 %c = add i64 %a, 8192
1438 define signext i32 @addshl32_5_6(i32 signext %a, i32 signext %b) {
1439 ; RV64I-LABEL: addshl32_5_6:
1441 ; RV64I-NEXT: slli a0, a0, 5
1442 ; RV64I-NEXT: slli a1, a1, 6
1443 ; RV64I-NEXT: addw a0, a0, a1
1446 ; RV64ZBA-LABEL: addshl32_5_6:
1448 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1449 ; RV64ZBA-NEXT: slliw a0, a0, 5
1457 define i64 @addshl64_5_6(i64 %a, i64 %b) {
1458 ; RV64I-LABEL: addshl64_5_6:
1460 ; RV64I-NEXT: slli a0, a0, 5
1461 ; RV64I-NEXT: slli a1, a1, 6
1462 ; RV64I-NEXT: add a0, a0, a1
1465 ; RV64ZBA-LABEL: addshl64_5_6:
1467 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1468 ; RV64ZBA-NEXT: slli a0, a0, 5
1476 define signext i32 @addshl32_5_7(i32 signext %a, i32 signext %b) {
1477 ; RV64I-LABEL: addshl32_5_7:
1479 ; RV64I-NEXT: slli a0, a0, 5
1480 ; RV64I-NEXT: slli a1, a1, 7
1481 ; RV64I-NEXT: addw a0, a0, a1
1484 ; RV64ZBA-LABEL: addshl32_5_7:
1486 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1487 ; RV64ZBA-NEXT: slliw a0, a0, 5
1495 define i64 @addshl64_5_7(i64 %a, i64 %b) {
1496 ; RV64I-LABEL: addshl64_5_7:
1498 ; RV64I-NEXT: slli a0, a0, 5
1499 ; RV64I-NEXT: slli a1, a1, 7
1500 ; RV64I-NEXT: add a0, a0, a1
1503 ; RV64ZBA-LABEL: addshl64_5_7:
1505 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1506 ; RV64ZBA-NEXT: slli a0, a0, 5
1514 define signext i32 @addshl32_5_8(i32 signext %a, i32 signext %b) {
1515 ; RV64I-LABEL: addshl32_5_8:
1517 ; RV64I-NEXT: slli a0, a0, 5
1518 ; RV64I-NEXT: slli a1, a1, 8
1519 ; RV64I-NEXT: addw a0, a0, a1
1522 ; RV64ZBA-LABEL: addshl32_5_8:
1524 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1525 ; RV64ZBA-NEXT: slliw a0, a0, 5
1533 define i64 @addshl64_5_8(i64 %a, i64 %b) {
1534 ; RV64I-LABEL: addshl64_5_8:
1536 ; RV64I-NEXT: slli a0, a0, 5
1537 ; RV64I-NEXT: slli a1, a1, 8
1538 ; RV64I-NEXT: add a0, a0, a1
1541 ; RV64ZBA-LABEL: addshl64_5_8:
1543 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1544 ; RV64ZBA-NEXT: slli a0, a0, 5
1552 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1553 ; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
1554 define zeroext i32 @sext_ashr_zext_i8(i8 %a) nounwind {
1555 ; RV64I-LABEL: sext_ashr_zext_i8:
1557 ; RV64I-NEXT: slli a0, a0, 56
1558 ; RV64I-NEXT: srai a0, a0, 56
1559 ; RV64I-NEXT: slli a0, a0, 23
1560 ; RV64I-NEXT: srli a0, a0, 32
1563 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i8:
1564 ; RV64ZBANOZBB: # %bb.0:
1565 ; RV64ZBANOZBB-NEXT: slli a0, a0, 56
1566 ; RV64ZBANOZBB-NEXT: srai a0, a0, 56
1567 ; RV64ZBANOZBB-NEXT: slli a0, a0, 23
1568 ; RV64ZBANOZBB-NEXT: srli a0, a0, 32
1569 ; RV64ZBANOZBB-NEXT: ret
1571 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i8:
1572 ; RV64ZBAZBB: # %bb.0:
1573 ; RV64ZBAZBB-NEXT: sext.b a0, a0
1574 ; RV64ZBAZBB-NEXT: slli a0, a0, 23
1575 ; RV64ZBAZBB-NEXT: srli a0, a0, 32
1576 ; RV64ZBAZBB-NEXT: ret
1577 %ext = sext i8 %a to i32
1578 %1 = ashr i32 %ext, 9
1582 define i64 @sh6_sh3_add1(i64 noundef %x, i64 noundef %y, i64 noundef %z) {
1583 ; RV64I-LABEL: sh6_sh3_add1:
1584 ; RV64I: # %bb.0: # %entry
1585 ; RV64I-NEXT: slli a2, a2, 3
1586 ; RV64I-NEXT: slli a1, a1, 6
1587 ; RV64I-NEXT: add a1, a1, a2
1588 ; RV64I-NEXT: add a0, a1, a0
1591 ; RV64ZBA-LABEL: sh6_sh3_add1:
1592 ; RV64ZBA: # %bb.0: # %entry
1593 ; RV64ZBA-NEXT: sh3add a1, a1, a2
1594 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1597 %shl = shl i64 %z, 3
1598 %shl1 = shl i64 %y, 6
1599 %add = add nsw i64 %shl1, %shl
1600 %add2 = add nsw i64 %add, %x
1604 define i64 @sh6_sh3_add2(i64 noundef %x, i64 noundef %y, i64 noundef %z) {
1605 ; RV64I-LABEL: sh6_sh3_add2:
1606 ; RV64I: # %bb.0: # %entry
1607 ; RV64I-NEXT: slli a2, a2, 3
1608 ; RV64I-NEXT: slli a1, a1, 6
1609 ; RV64I-NEXT: add a0, a1, a0
1610 ; RV64I-NEXT: add a0, a0, a2
1613 ; RV64ZBA-LABEL: sh6_sh3_add2:
1614 ; RV64ZBA: # %bb.0: # %entry
1615 ; RV64ZBA-NEXT: sh3add a1, a1, a2
1616 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1619 %shl = shl i64 %z, 3
1620 %shl1 = shl i64 %y, 6
1621 %add = add nsw i64 %shl1, %x
1622 %add2 = add nsw i64 %add, %shl
1626 define i64 @sh6_sh3_add3(i64 noundef %x, i64 noundef %y, i64 noundef %z) {
1627 ; RV64I-LABEL: sh6_sh3_add3:
1628 ; RV64I: # %bb.0: # %entry
1629 ; RV64I-NEXT: slli a2, a2, 3
1630 ; RV64I-NEXT: slli a1, a1, 6
1631 ; RV64I-NEXT: add a1, a1, a2
1632 ; RV64I-NEXT: add a0, a0, a1
1635 ; RV64ZBA-LABEL: sh6_sh3_add3:
1636 ; RV64ZBA: # %bb.0: # %entry
1637 ; RV64ZBA-NEXT: sh3add a1, a1, a2
1638 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1641 %shl = shl i64 %z, 3
1642 %shl1 = shl i64 %y, 6
1643 %add = add nsw i64 %shl1, %shl
1644 %add2 = add nsw i64 %x, %add
1648 define i64 @sh6_sh3_add4(i64 noundef %x, i64 noundef %y, i64 noundef %z) {
1649 ; RV64I-LABEL: sh6_sh3_add4:
1650 ; RV64I: # %bb.0: # %entry
1651 ; RV64I-NEXT: slli a2, a2, 3
1652 ; RV64I-NEXT: slli a1, a1, 6
1653 ; RV64I-NEXT: add a0, a0, a2
1654 ; RV64I-NEXT: add a0, a0, a1
1657 ; RV64ZBA-LABEL: sh6_sh3_add4:
1658 ; RV64ZBA: # %bb.0: # %entry
1659 ; RV64ZBA-NEXT: slli a1, a1, 6
1660 ; RV64ZBA-NEXT: sh3add a0, a2, a0
1661 ; RV64ZBA-NEXT: add a0, a0, a1
1664 %shl = shl i64 %z, 3
1665 %shl1 = shl i64 %y, 6
1666 %add = add nsw i64 %x, %shl
1667 %add2 = add nsw i64 %add, %shl1
1671 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1672 ; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
1673 define zeroext i32 @sext_ashr_zext_i16(i16 %a) nounwind {
1674 ; RV64I-LABEL: sext_ashr_zext_i16:
1676 ; RV64I-NEXT: slli a0, a0, 48
1677 ; RV64I-NEXT: srai a0, a0, 48
1678 ; RV64I-NEXT: slli a0, a0, 23
1679 ; RV64I-NEXT: srli a0, a0, 32
1682 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i16:
1683 ; RV64ZBANOZBB: # %bb.0:
1684 ; RV64ZBANOZBB-NEXT: slli a0, a0, 48
1685 ; RV64ZBANOZBB-NEXT: srai a0, a0, 48
1686 ; RV64ZBANOZBB-NEXT: slli a0, a0, 23
1687 ; RV64ZBANOZBB-NEXT: srli a0, a0, 32
1688 ; RV64ZBANOZBB-NEXT: ret
1690 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i16:
1691 ; RV64ZBAZBB: # %bb.0:
1692 ; RV64ZBAZBB-NEXT: sext.h a0, a0
1693 ; RV64ZBAZBB-NEXT: slli a0, a0, 23
1694 ; RV64ZBAZBB-NEXT: srli a0, a0, 32
1695 ; RV64ZBAZBB-NEXT: ret
1696 %ext = sext i16 %a to i32
1697 %1 = ashr i32 %ext, 9
1701 ; This the IR you get from InstCombine if take the difference of 2 pointers and
1702 ; cast is to unsigned before using as an index.
1703 define signext i16 @sh1adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1704 ; RV64I-LABEL: sh1adduw_ptrdiff:
1706 ; RV64I-NEXT: li a2, 1
1707 ; RV64I-NEXT: slli a2, a2, 33
1708 ; RV64I-NEXT: addi a2, a2, -2
1709 ; RV64I-NEXT: and a0, a0, a2
1710 ; RV64I-NEXT: add a0, a1, a0
1711 ; RV64I-NEXT: lh a0, 0(a0)
1714 ; RV64ZBA-LABEL: sh1adduw_ptrdiff:
1716 ; RV64ZBA-NEXT: srli a0, a0, 1
1717 ; RV64ZBA-NEXT: sh1add.uw a0, a0, a1
1718 ; RV64ZBA-NEXT: lh a0, 0(a0)
1720 %ptrdiff = lshr exact i64 %diff, 1
1721 %cast = and i64 %ptrdiff, 4294967295
1722 %ptr = getelementptr inbounds i16, ptr %baseptr, i64 %cast
1723 %res = load i16, ptr %ptr
1727 define signext i32 @sh2adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1728 ; RV64I-LABEL: sh2adduw_ptrdiff:
1730 ; RV64I-NEXT: li a2, 1
1731 ; RV64I-NEXT: slli a2, a2, 34
1732 ; RV64I-NEXT: addi a2, a2, -4
1733 ; RV64I-NEXT: and a0, a0, a2
1734 ; RV64I-NEXT: add a0, a1, a0
1735 ; RV64I-NEXT: lw a0, 0(a0)
1738 ; RV64ZBA-LABEL: sh2adduw_ptrdiff:
1740 ; RV64ZBA-NEXT: srli a0, a0, 2
1741 ; RV64ZBA-NEXT: sh2add.uw a0, a0, a1
1742 ; RV64ZBA-NEXT: lw a0, 0(a0)
1744 %ptrdiff = lshr exact i64 %diff, 2
1745 %cast = and i64 %ptrdiff, 4294967295
1746 %ptr = getelementptr inbounds i32, ptr %baseptr, i64 %cast
1747 %res = load i32, ptr %ptr
1751 define i64 @sh3adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1752 ; RV64I-LABEL: sh3adduw_ptrdiff:
1754 ; RV64I-NEXT: li a2, 1
1755 ; RV64I-NEXT: slli a2, a2, 35
1756 ; RV64I-NEXT: addi a2, a2, -8
1757 ; RV64I-NEXT: and a0, a0, a2
1758 ; RV64I-NEXT: add a0, a1, a0
1759 ; RV64I-NEXT: ld a0, 0(a0)
1762 ; RV64ZBA-LABEL: sh3adduw_ptrdiff:
1764 ; RV64ZBA-NEXT: srli a0, a0, 3
1765 ; RV64ZBA-NEXT: sh3add.uw a0, a0, a1
1766 ; RV64ZBA-NEXT: ld a0, 0(a0)
1768 %ptrdiff = lshr exact i64 %diff, 3
1769 %cast = and i64 %ptrdiff, 4294967295
1770 %ptr = getelementptr inbounds i64, ptr %baseptr, i64 %cast
1771 %res = load i64, ptr %ptr
1775 define signext i16 @srliw_1_sh1add(ptr %0, i32 signext %1) {
1776 ; RV64I-LABEL: srliw_1_sh1add:
1778 ; RV64I-NEXT: srliw a1, a1, 1
1779 ; RV64I-NEXT: slli a1, a1, 1
1780 ; RV64I-NEXT: add a0, a0, a1
1781 ; RV64I-NEXT: lh a0, 0(a0)
1784 ; RV64ZBA-LABEL: srliw_1_sh1add:
1786 ; RV64ZBA-NEXT: srliw a1, a1, 1
1787 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1788 ; RV64ZBA-NEXT: lh a0, 0(a0)
1791 %4 = zext i32 %3 to i64
1792 %5 = getelementptr inbounds i16, ptr %0, i64 %4
1793 %6 = load i16, ptr %5, align 2
1797 define i128 @slliuw_ptrdiff(i64 %diff, ptr %baseptr) {
1798 ; RV64I-LABEL: slliuw_ptrdiff:
1800 ; RV64I-NEXT: li a2, 1
1801 ; RV64I-NEXT: slli a2, a2, 36
1802 ; RV64I-NEXT: addi a2, a2, -16
1803 ; RV64I-NEXT: and a0, a0, a2
1804 ; RV64I-NEXT: add a1, a1, a0
1805 ; RV64I-NEXT: ld a0, 0(a1)
1806 ; RV64I-NEXT: ld a1, 8(a1)
1809 ; RV64ZBA-LABEL: slliuw_ptrdiff:
1811 ; RV64ZBA-NEXT: srli a0, a0, 4
1812 ; RV64ZBA-NEXT: slli.uw a0, a0, 4
1813 ; RV64ZBA-NEXT: add a1, a1, a0
1814 ; RV64ZBA-NEXT: ld a0, 0(a1)
1815 ; RV64ZBA-NEXT: ld a1, 8(a1)
1817 %ptrdiff = lshr exact i64 %diff, 4
1818 %cast = and i64 %ptrdiff, 4294967295
1819 %ptr = getelementptr inbounds i128, ptr %baseptr, i64 %cast
1820 %res = load i128, ptr %ptr
1824 define signext i32 @srliw_2_sh2add(ptr %0, i32 signext %1) {
1825 ; RV64I-LABEL: srliw_2_sh2add:
1827 ; RV64I-NEXT: srliw a1, a1, 2
1828 ; RV64I-NEXT: slli a1, a1, 2
1829 ; RV64I-NEXT: add a0, a0, a1
1830 ; RV64I-NEXT: lw a0, 0(a0)
1833 ; RV64ZBA-LABEL: srliw_2_sh2add:
1835 ; RV64ZBA-NEXT: srliw a1, a1, 2
1836 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1837 ; RV64ZBA-NEXT: lw a0, 0(a0)
1840 %4 = zext i32 %3 to i64
1841 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1842 %6 = load i32, ptr %5, align 4
1846 define i64 @srliw_3_sh3add(ptr %0, i32 signext %1) {
1847 ; RV64I-LABEL: srliw_3_sh3add:
1849 ; RV64I-NEXT: srliw a1, a1, 3
1850 ; RV64I-NEXT: slli a1, a1, 3
1851 ; RV64I-NEXT: add a0, a0, a1
1852 ; RV64I-NEXT: ld a0, 0(a0)
1855 ; RV64ZBA-LABEL: srliw_3_sh3add:
1857 ; RV64ZBA-NEXT: srliw a1, a1, 3
1858 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1859 ; RV64ZBA-NEXT: ld a0, 0(a0)
1862 %4 = zext i32 %3 to i64
1863 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1864 %6 = load i64, ptr %5, align 8
1868 define signext i32 @srliw_1_sh2add(ptr %0, i32 signext %1) {
1869 ; RV64I-LABEL: srliw_1_sh2add:
1871 ; RV64I-NEXT: srliw a1, a1, 1
1872 ; RV64I-NEXT: slli a1, a1, 2
1873 ; RV64I-NEXT: add a0, a0, a1
1874 ; RV64I-NEXT: lw a0, 0(a0)
1877 ; RV64ZBA-LABEL: srliw_1_sh2add:
1879 ; RV64ZBA-NEXT: srliw a1, a1, 1
1880 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1881 ; RV64ZBA-NEXT: lw a0, 0(a0)
1884 %4 = zext i32 %3 to i64
1885 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1886 %6 = load i32, ptr %5, align 4
1890 define i64 @srliw_1_sh3add(ptr %0, i32 signext %1) {
1891 ; RV64I-LABEL: srliw_1_sh3add:
1893 ; RV64I-NEXT: srliw a1, a1, 1
1894 ; RV64I-NEXT: slli a1, a1, 3
1895 ; RV64I-NEXT: add a0, a0, a1
1896 ; RV64I-NEXT: ld a0, 0(a0)
1899 ; RV64ZBA-LABEL: srliw_1_sh3add:
1901 ; RV64ZBA-NEXT: srliw a1, a1, 1
1902 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1903 ; RV64ZBA-NEXT: ld a0, 0(a0)
1906 %4 = zext i32 %3 to i64
1907 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1908 %6 = load i64, ptr %5, align 8
1912 define i64 @srliw_2_sh3add(ptr %0, i32 signext %1) {
1913 ; RV64I-LABEL: srliw_2_sh3add:
1915 ; RV64I-NEXT: srliw a1, a1, 2
1916 ; RV64I-NEXT: slli a1, a1, 3
1917 ; RV64I-NEXT: add a0, a0, a1
1918 ; RV64I-NEXT: ld a0, 0(a0)
1921 ; RV64ZBA-LABEL: srliw_2_sh3add:
1923 ; RV64ZBA-NEXT: srliw a1, a1, 2
1924 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1925 ; RV64ZBA-NEXT: ld a0, 0(a0)
1928 %4 = zext i32 %3 to i64
1929 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1930 %6 = load i64, ptr %5, align 8
1934 define signext i16 @srliw_2_sh1add(ptr %0, i32 signext %1) {
1935 ; RV64I-LABEL: srliw_2_sh1add:
1937 ; RV64I-NEXT: srliw a1, a1, 2
1938 ; RV64I-NEXT: slli a1, a1, 1
1939 ; RV64I-NEXT: add a0, a0, a1
1940 ; RV64I-NEXT: lh a0, 0(a0)
1943 ; RV64ZBA-LABEL: srliw_2_sh1add:
1945 ; RV64ZBA-NEXT: srliw a1, a1, 2
1946 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1947 ; RV64ZBA-NEXT: lh a0, 0(a0)
1950 %4 = zext i32 %3 to i64
1951 %5 = getelementptr inbounds i16, ptr %0, i64 %4
1952 %6 = load i16, ptr %5, align 2
1957 define signext i32 @srliw_3_sh2add(ptr %0, i32 signext %1) {
1958 ; RV64I-LABEL: srliw_3_sh2add:
1960 ; RV64I-NEXT: srliw a1, a1, 3
1961 ; RV64I-NEXT: slli a1, a1, 2
1962 ; RV64I-NEXT: add a0, a0, a1
1963 ; RV64I-NEXT: lw a0, 0(a0)
1966 ; RV64ZBA-LABEL: srliw_3_sh2add:
1968 ; RV64ZBA-NEXT: srliw a1, a1, 3
1969 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1970 ; RV64ZBA-NEXT: lw a0, 0(a0)
1973 %4 = zext i32 %3 to i64
1974 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1975 %6 = load i32, ptr %5, align 4
1979 define i64 @srliw_4_sh3add(ptr %0, i32 signext %1) {
1980 ; RV64I-LABEL: srliw_4_sh3add:
1982 ; RV64I-NEXT: srliw a1, a1, 4
1983 ; RV64I-NEXT: slli a1, a1, 3
1984 ; RV64I-NEXT: add a0, a0, a1
1985 ; RV64I-NEXT: ld a0, 0(a0)
1988 ; RV64ZBA-LABEL: srliw_4_sh3add:
1990 ; RV64ZBA-NEXT: srliw a1, a1, 4
1991 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1992 ; RV64ZBA-NEXT: ld a0, 0(a0)
1995 %4 = zext i32 %3 to i64
1996 %5 = getelementptr inbounds i64, ptr %0, i64 %4
1997 %6 = load i64, ptr %5, align 8
2001 define signext i32 @srli_1_sh2add(ptr %0, i64 %1) {
2002 ; RV64I-LABEL: srli_1_sh2add:
2004 ; RV64I-NEXT: slli a1, a1, 1
2005 ; RV64I-NEXT: andi a1, a1, -4
2006 ; RV64I-NEXT: add a0, a0, a1
2007 ; RV64I-NEXT: lw a0, 0(a0)
2010 ; RV64ZBA-LABEL: srli_1_sh2add:
2012 ; RV64ZBA-NEXT: srli a1, a1, 1
2013 ; RV64ZBA-NEXT: sh2add a0, a1, a0
2014 ; RV64ZBA-NEXT: lw a0, 0(a0)
2017 %4 = getelementptr inbounds i32, ptr %0, i64 %3
2018 %5 = load i32, ptr %4, align 4
2022 define i64 @srli_2_sh3add(ptr %0, i64 %1) {
2023 ; RV64I-LABEL: srli_2_sh3add:
2025 ; RV64I-NEXT: slli a1, a1, 1
2026 ; RV64I-NEXT: andi a1, a1, -8
2027 ; RV64I-NEXT: add a0, a0, a1
2028 ; RV64I-NEXT: ld a0, 0(a0)
2031 ; RV64ZBA-LABEL: srli_2_sh3add:
2033 ; RV64ZBA-NEXT: srli a1, a1, 2
2034 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2035 ; RV64ZBA-NEXT: ld a0, 0(a0)
2038 %4 = getelementptr inbounds i64, ptr %0, i64 %3
2039 %5 = load i64, ptr %4, align 8
2043 define signext i16 @srli_2_sh1add(ptr %0, i64 %1) {
2044 ; RV64I-LABEL: srli_2_sh1add:
2046 ; RV64I-NEXT: srli a1, a1, 1
2047 ; RV64I-NEXT: andi a1, a1, -2
2048 ; RV64I-NEXT: add a0, a0, a1
2049 ; RV64I-NEXT: lh a0, 0(a0)
2052 ; RV64ZBA-LABEL: srli_2_sh1add:
2054 ; RV64ZBA-NEXT: srli a1, a1, 2
2055 ; RV64ZBA-NEXT: sh1add a0, a1, a0
2056 ; RV64ZBA-NEXT: lh a0, 0(a0)
2059 %4 = getelementptr inbounds i16, ptr %0, i64 %3
2060 %5 = load i16, ptr %4, align 2
2064 define signext i32 @srli_3_sh2add(ptr %0, i64 %1) {
2065 ; RV64I-LABEL: srli_3_sh2add:
2067 ; RV64I-NEXT: srli a1, a1, 1
2068 ; RV64I-NEXT: andi a1, a1, -4
2069 ; RV64I-NEXT: add a0, a0, a1
2070 ; RV64I-NEXT: lw a0, 0(a0)
2073 ; RV64ZBA-LABEL: srli_3_sh2add:
2075 ; RV64ZBA-NEXT: srli a1, a1, 3
2076 ; RV64ZBA-NEXT: sh2add a0, a1, a0
2077 ; RV64ZBA-NEXT: lw a0, 0(a0)
2080 %4 = getelementptr inbounds i32, ptr %0, i64 %3
2081 %5 = load i32, ptr %4, align 4
2085 define i64 @srli_4_sh3add(ptr %0, i64 %1) {
2086 ; RV64I-LABEL: srli_4_sh3add:
2088 ; RV64I-NEXT: srli a1, a1, 1
2089 ; RV64I-NEXT: andi a1, a1, -8
2090 ; RV64I-NEXT: add a0, a0, a1
2091 ; RV64I-NEXT: ld a0, 0(a0)
2094 ; RV64ZBA-LABEL: srli_4_sh3add:
2096 ; RV64ZBA-NEXT: srli a1, a1, 4
2097 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2098 ; RV64ZBA-NEXT: ld a0, 0(a0)
2101 %4 = getelementptr inbounds i64, ptr %0, i64 %3
2102 %5 = load i64, ptr %4, align 8
2106 define signext i16 @shl_2_sh1add(ptr %0, i32 signext %1) {
2107 ; RV64I-LABEL: shl_2_sh1add:
2109 ; RV64I-NEXT: slli a1, a1, 34
2110 ; RV64I-NEXT: srli a1, a1, 31
2111 ; RV64I-NEXT: add a0, a0, a1
2112 ; RV64I-NEXT: lh a0, 0(a0)
2115 ; RV64ZBA-LABEL: shl_2_sh1add:
2117 ; RV64ZBA-NEXT: slli a1, a1, 2
2118 ; RV64ZBA-NEXT: sh1add.uw a0, a1, a0
2119 ; RV64ZBA-NEXT: lh a0, 0(a0)
2122 %4 = zext i32 %3 to i64
2123 %5 = getelementptr inbounds i16, ptr %0, i64 %4
2124 %6 = load i16, ptr %5, align 2
2128 define signext i32 @shl_16_sh2add(ptr %0, i32 signext %1) {
2129 ; RV64I-LABEL: shl_16_sh2add:
2131 ; RV64I-NEXT: slli a1, a1, 48
2132 ; RV64I-NEXT: srli a1, a1, 30
2133 ; RV64I-NEXT: add a0, a0, a1
2134 ; RV64I-NEXT: lw a0, 0(a0)
2137 ; RV64ZBA-LABEL: shl_16_sh2add:
2139 ; RV64ZBA-NEXT: slli a1, a1, 16
2140 ; RV64ZBA-NEXT: sh2add.uw a0, a1, a0
2141 ; RV64ZBA-NEXT: lw a0, 0(a0)
2144 %4 = zext i32 %3 to i64
2145 %5 = getelementptr inbounds i32, ptr %0, i64 %4
2146 %6 = load i32, ptr %5, align 4
2150 define i64 @shl_31_sh3add(ptr %0, i32 signext %1) {
2151 ; RV64I-LABEL: shl_31_sh3add:
2153 ; RV64I-NEXT: slli a1, a1, 63
2154 ; RV64I-NEXT: srli a1, a1, 29
2155 ; RV64I-NEXT: add a0, a0, a1
2156 ; RV64I-NEXT: ld a0, 0(a0)
2159 ; RV64ZBA-LABEL: shl_31_sh3add:
2161 ; RV64ZBA-NEXT: slli a1, a1, 31
2162 ; RV64ZBA-NEXT: sh3add.uw a0, a1, a0
2163 ; RV64ZBA-NEXT: ld a0, 0(a0)
2166 %4 = zext i32 %3 to i64
2167 %5 = getelementptr inbounds i64, ptr %0, i64 %4
2168 %6 = load i64, ptr %5, align 8
2172 define i64 @pack_i64(i64 %a, i64 %b) nounwind {
2173 ; RV64I-LABEL: pack_i64:
2175 ; RV64I-NEXT: slli a0, a0, 32
2176 ; RV64I-NEXT: srli a0, a0, 32
2177 ; RV64I-NEXT: slli a1, a1, 32
2178 ; RV64I-NEXT: or a0, a1, a0
2181 ; RV64ZBA-LABEL: pack_i64:
2183 ; RV64ZBA-NEXT: slli a1, a1, 32
2184 ; RV64ZBA-NEXT: add.uw a0, a0, a1
2186 %shl = and i64 %a, 4294967295
2187 %shl1 = shl i64 %b, 32
2188 %or = or i64 %shl1, %shl
2192 define i64 @pack_i64_2(i32 signext %a, i32 signext %b) nounwind {
2193 ; RV64I-LABEL: pack_i64_2:
2195 ; RV64I-NEXT: slli a0, a0, 32
2196 ; RV64I-NEXT: srli a0, a0, 32
2197 ; RV64I-NEXT: slli a1, a1, 32
2198 ; RV64I-NEXT: or a0, a1, a0
2201 ; RV64ZBA-LABEL: pack_i64_2:
2203 ; RV64ZBA-NEXT: slli a1, a1, 32
2204 ; RV64ZBA-NEXT: add.uw a0, a0, a1
2206 %zexta = zext i32 %a to i64
2207 %zextb = zext i32 %b to i64
2208 %shl1 = shl i64 %zextb, 32
2209 %or = or i64 %shl1, %zexta
2213 define i64 @pack_i64_disjoint(i64 %a, i64 %b) nounwind {
2214 ; RV64I-LABEL: pack_i64_disjoint:
2216 ; RV64I-NEXT: slli a0, a0, 32
2217 ; RV64I-NEXT: srli a0, a0, 32
2218 ; RV64I-NEXT: or a0, a1, a0
2221 ; RV64ZBA-LABEL: pack_i64_disjoint:
2223 ; RV64ZBA-NEXT: add.uw a0, a0, a1
2225 %shl = and i64 %a, 4294967295
2226 %or = or disjoint i64 %b, %shl
2230 define i64 @pack_i64_disjoint_2(i32 signext %a, i64 %b) nounwind {
2231 ; RV64I-LABEL: pack_i64_disjoint_2:
2233 ; RV64I-NEXT: slli a0, a0, 32
2234 ; RV64I-NEXT: srli a0, a0, 32
2235 ; RV64I-NEXT: or a0, a1, a0
2238 ; RV64ZBA-LABEL: pack_i64_disjoint_2:
2240 ; RV64ZBA-NEXT: add.uw a0, a0, a1
2242 %zexta = zext i32 %a to i64
2243 %or = or disjoint i64 %b, %zexta
2247 define i8 @array_index_sh1_sh0(ptr %p, i64 %idx1, i64 %idx2) {
2248 ; RV64I-LABEL: array_index_sh1_sh0:
2250 ; RV64I-NEXT: slli a1, a1, 1
2251 ; RV64I-NEXT: add a0, a0, a2
2252 ; RV64I-NEXT: add a0, a0, a1
2253 ; RV64I-NEXT: lbu a0, 0(a0)
2256 ; RV64ZBA-LABEL: array_index_sh1_sh0:
2258 ; RV64ZBA-NEXT: sh1add a0, a1, a0
2259 ; RV64ZBA-NEXT: add a0, a0, a2
2260 ; RV64ZBA-NEXT: lbu a0, 0(a0)
2262 %a = getelementptr inbounds [2 x i8], ptr %p, i64 %idx1, i64 %idx2
2263 %b = load i8, ptr %a, align 1
2267 define i16 @array_index_sh1_sh1(ptr %p, i64 %idx1, i64 %idx2) {
2268 ; RV64I-LABEL: array_index_sh1_sh1:
2270 ; RV64I-NEXT: slli a1, a1, 2
2271 ; RV64I-NEXT: add a0, a0, a1
2272 ; RV64I-NEXT: slli a2, a2, 1
2273 ; RV64I-NEXT: add a0, a0, a2
2274 ; RV64I-NEXT: lh a0, 0(a0)
2277 ; RV64ZBA-LABEL: array_index_sh1_sh1:
2279 ; RV64ZBA-NEXT: sh2add a0, a1, a0
2280 ; RV64ZBA-NEXT: sh1add a0, a2, a0
2281 ; RV64ZBA-NEXT: lh a0, 0(a0)
2283 %a = getelementptr inbounds [2 x i16], ptr %p, i64 %idx1, i64 %idx2
2284 %b = load i16, ptr %a, align 2
2288 define i32 @array_index_sh1_sh2(ptr %p, i64 %idx1, i64 %idx2) {
2289 ; RV64I-LABEL: array_index_sh1_sh2:
2291 ; RV64I-NEXT: slli a1, a1, 3
2292 ; RV64I-NEXT: add a0, a0, a1
2293 ; RV64I-NEXT: slli a2, a2, 2
2294 ; RV64I-NEXT: add a0, a0, a2
2295 ; RV64I-NEXT: lw a0, 0(a0)
2298 ; RV64ZBA-LABEL: array_index_sh1_sh2:
2300 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2301 ; RV64ZBA-NEXT: sh2add a0, a2, a0
2302 ; RV64ZBA-NEXT: lw a0, 0(a0)
2304 %a = getelementptr inbounds [2 x i32], ptr %p, i64 %idx1, i64 %idx2
2305 %b = load i32, ptr %a, align 4
2309 define i64 @array_index_sh1_sh3(ptr %p, i64 %idx1, i64 %idx2) {
2310 ; RV64I-LABEL: array_index_sh1_sh3:
2312 ; RV64I-NEXT: slli a1, a1, 4
2313 ; RV64I-NEXT: add a0, a0, a1
2314 ; RV64I-NEXT: slli a2, a2, 3
2315 ; RV64I-NEXT: add a0, a0, a2
2316 ; RV64I-NEXT: ld a0, 0(a0)
2319 ; RV64ZBA-LABEL: array_index_sh1_sh3:
2321 ; RV64ZBA-NEXT: sh1add a1, a1, a2
2322 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2323 ; RV64ZBA-NEXT: ld a0, 0(a0)
2325 %a = getelementptr inbounds [2 x i64], ptr %p, i64 %idx1, i64 %idx2
2326 %b = load i64, ptr %a, align 8
2330 define i8 @array_index_sh2_sh0(ptr %p, i64 %idx1, i64 %idx2) {
2331 ; RV64I-LABEL: array_index_sh2_sh0:
2333 ; RV64I-NEXT: slli a1, a1, 2
2334 ; RV64I-NEXT: add a0, a0, a2
2335 ; RV64I-NEXT: add a0, a0, a1
2336 ; RV64I-NEXT: lbu a0, 0(a0)
2339 ; RV64ZBA-LABEL: array_index_sh2_sh0:
2341 ; RV64ZBA-NEXT: sh2add a0, a1, a0
2342 ; RV64ZBA-NEXT: add a0, a0, a2
2343 ; RV64ZBA-NEXT: lbu a0, 0(a0)
2345 %a = getelementptr inbounds [4 x i8], ptr %p, i64 %idx1, i64 %idx2
2346 %b = load i8, ptr %a, align 1
2350 define i16 @array_index_sh2_sh1(ptr %p, i64 %idx1, i64 %idx2) {
2351 ; RV64I-LABEL: array_index_sh2_sh1:
2353 ; RV64I-NEXT: slli a1, a1, 3
2354 ; RV64I-NEXT: add a0, a0, a1
2355 ; RV64I-NEXT: slli a2, a2, 1
2356 ; RV64I-NEXT: add a0, a0, a2
2357 ; RV64I-NEXT: lh a0, 0(a0)
2360 ; RV64ZBA-LABEL: array_index_sh2_sh1:
2362 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2363 ; RV64ZBA-NEXT: sh1add a0, a2, a0
2364 ; RV64ZBA-NEXT: lh a0, 0(a0)
2366 %a = getelementptr inbounds [4 x i16], ptr %p, i64 %idx1, i64 %idx2
2367 %b = load i16, ptr %a, align 2
2371 define i32 @array_index_sh2_sh2(ptr %p, i64 %idx1, i64 %idx2) {
2372 ; RV64I-LABEL: array_index_sh2_sh2:
2374 ; RV64I-NEXT: slli a1, a1, 4
2375 ; RV64I-NEXT: add a0, a0, a1
2376 ; RV64I-NEXT: slli a2, a2, 2
2377 ; RV64I-NEXT: add a0, a0, a2
2378 ; RV64I-NEXT: lw a0, 0(a0)
2381 ; RV64ZBA-LABEL: array_index_sh2_sh2:
2383 ; RV64ZBA-NEXT: sh2add a1, a1, a2
2384 ; RV64ZBA-NEXT: sh2add a0, a1, a0
2385 ; RV64ZBA-NEXT: lw a0, 0(a0)
2387 %a = getelementptr inbounds [4 x i32], ptr %p, i64 %idx1, i64 %idx2
2388 %b = load i32, ptr %a, align 4
2392 define i64 @array_index_sh2_sh3(ptr %p, i64 %idx1, i64 %idx2) {
2393 ; RV64I-LABEL: array_index_sh2_sh3:
2395 ; RV64I-NEXT: slli a1, a1, 5
2396 ; RV64I-NEXT: add a0, a0, a1
2397 ; RV64I-NEXT: slli a2, a2, 3
2398 ; RV64I-NEXT: add a0, a0, a2
2399 ; RV64I-NEXT: ld a0, 0(a0)
2402 ; RV64ZBA-LABEL: array_index_sh2_sh3:
2404 ; RV64ZBA-NEXT: sh2add a1, a1, a2
2405 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2406 ; RV64ZBA-NEXT: ld a0, 0(a0)
2408 %a = getelementptr inbounds [4 x i64], ptr %p, i64 %idx1, i64 %idx2
2409 %b = load i64, ptr %a, align 8
2413 define i8 @array_index_sh3_sh0(ptr %p, i64 %idx1, i64 %idx2) {
2414 ; RV64I-LABEL: array_index_sh3_sh0:
2416 ; RV64I-NEXT: slli a1, a1, 3
2417 ; RV64I-NEXT: add a0, a0, a2
2418 ; RV64I-NEXT: add a0, a0, a1
2419 ; RV64I-NEXT: lbu a0, 0(a0)
2422 ; RV64ZBA-LABEL: array_index_sh3_sh0:
2424 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2425 ; RV64ZBA-NEXT: add a0, a0, a2
2426 ; RV64ZBA-NEXT: lbu a0, 0(a0)
2428 %a = getelementptr inbounds [8 x i8], ptr %p, i64 %idx1, i64 %idx2
2429 %b = load i8, ptr %a, align 1
2433 define i16 @array_index_sh3_sh1(ptr %p, i64 %idx1, i64 %idx2) {
2434 ; RV64I-LABEL: array_index_sh3_sh1:
2436 ; RV64I-NEXT: slli a1, a1, 4
2437 ; RV64I-NEXT: add a0, a0, a1
2438 ; RV64I-NEXT: slli a2, a2, 1
2439 ; RV64I-NEXT: add a0, a0, a2
2440 ; RV64I-NEXT: lh a0, 0(a0)
2443 ; RV64ZBA-LABEL: array_index_sh3_sh1:
2445 ; RV64ZBA-NEXT: sh3add a1, a1, a2
2446 ; RV64ZBA-NEXT: sh1add a0, a1, a0
2447 ; RV64ZBA-NEXT: lh a0, 0(a0)
2449 %a = getelementptr inbounds [8 x i16], ptr %p, i64 %idx1, i64 %idx2
2450 %b = load i16, ptr %a, align 2
2454 define i32 @array_index_sh3_sh2(ptr %p, i64 %idx1, i64 %idx2) {
2455 ; RV64I-LABEL: array_index_sh3_sh2:
2457 ; RV64I-NEXT: slli a1, a1, 5
2458 ; RV64I-NEXT: add a0, a0, a1
2459 ; RV64I-NEXT: slli a2, a2, 2
2460 ; RV64I-NEXT: add a0, a0, a2
2461 ; RV64I-NEXT: lw a0, 0(a0)
2464 ; RV64ZBA-LABEL: array_index_sh3_sh2:
2466 ; RV64ZBA-NEXT: sh3add a1, a1, a2
2467 ; RV64ZBA-NEXT: sh2add a0, a1, a0
2468 ; RV64ZBA-NEXT: lw a0, 0(a0)
2470 %a = getelementptr inbounds [8 x i32], ptr %p, i64 %idx1, i64 %idx2
2471 %b = load i32, ptr %a, align 4
2475 define i64 @array_index_sh3_sh3(ptr %p, i64 %idx1, i64 %idx2) {
2476 ; RV64I-LABEL: array_index_sh3_sh3:
2478 ; RV64I-NEXT: slli a1, a1, 6
2479 ; RV64I-NEXT: add a0, a0, a1
2480 ; RV64I-NEXT: slli a2, a2, 3
2481 ; RV64I-NEXT: add a0, a0, a2
2482 ; RV64I-NEXT: ld a0, 0(a0)
2485 ; RV64ZBA-LABEL: array_index_sh3_sh3:
2487 ; RV64ZBA-NEXT: sh3add a1, a1, a2
2488 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2489 ; RV64ZBA-NEXT: ld a0, 0(a0)
2491 %a = getelementptr inbounds [8 x i64], ptr %p, i64 %idx1, i64 %idx2
2492 %b = load i64, ptr %a, align 8
2496 ; Similar to above, but with a lshr on one of the indices. This requires
2497 ; special handling during isel to form a shift pair.
2498 define i64 @array_index_lshr_sh3_sh3(ptr %p, i64 %idx1, i64 %idx2) {
2499 ; RV64I-LABEL: array_index_lshr_sh3_sh3:
2501 ; RV64I-NEXT: srli a1, a1, 58
2502 ; RV64I-NEXT: slli a1, a1, 6
2503 ; RV64I-NEXT: slli a2, a2, 3
2504 ; RV64I-NEXT: add a0, a0, a2
2505 ; RV64I-NEXT: add a0, a0, a1
2506 ; RV64I-NEXT: ld a0, 0(a0)
2509 ; RV64ZBA-LABEL: array_index_lshr_sh3_sh3:
2511 ; RV64ZBA-NEXT: srli a1, a1, 58
2512 ; RV64ZBA-NEXT: sh3add a1, a1, a2
2513 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2514 ; RV64ZBA-NEXT: ld a0, 0(a0)
2516 %shr = lshr i64 %idx1, 58
2517 %a = getelementptr inbounds [8 x i64], ptr %p, i64 %shr, i64 %idx2
2518 %b = load i64, ptr %a, align 8
2522 define i8 @array_index_sh4_sh0(ptr %p, i64 %idx1, i64 %idx2) {
2523 ; CHECK-LABEL: array_index_sh4_sh0:
2525 ; CHECK-NEXT: slli a1, a1, 4
2526 ; CHECK-NEXT: add a0, a0, a2
2527 ; CHECK-NEXT: add a0, a0, a1
2528 ; CHECK-NEXT: lbu a0, 0(a0)
2530 %a = getelementptr inbounds [16 x i8], ptr %p, i64 %idx1, i64 %idx2
2531 %b = load i8, ptr %a, align 1
2535 define i16 @array_index_sh4_sh1(ptr %p, i64 %idx1, i64 %idx2) {
2536 ; RV64I-LABEL: array_index_sh4_sh1:
2538 ; RV64I-NEXT: slli a1, a1, 5
2539 ; RV64I-NEXT: add a0, a0, a1
2540 ; RV64I-NEXT: slli a2, a2, 1
2541 ; RV64I-NEXT: add a0, a0, a2
2542 ; RV64I-NEXT: lh a0, 0(a0)
2545 ; RV64ZBA-LABEL: array_index_sh4_sh1:
2547 ; RV64ZBA-NEXT: slli a1, a1, 5
2548 ; RV64ZBA-NEXT: add a0, a0, a1
2549 ; RV64ZBA-NEXT: sh1add a0, a2, a0
2550 ; RV64ZBA-NEXT: lh a0, 0(a0)
2552 %a = getelementptr inbounds [16 x i16], ptr %p, i64 %idx1, i64 %idx2
2553 %b = load i16, ptr %a, align 2
2557 define i32 @array_index_sh4_sh2(ptr %p, i64 %idx1, i64 %idx2) {
2558 ; RV64I-LABEL: array_index_sh4_sh2:
2560 ; RV64I-NEXT: slli a1, a1, 6
2561 ; RV64I-NEXT: add a0, a0, a1
2562 ; RV64I-NEXT: slli a2, a2, 2
2563 ; RV64I-NEXT: add a0, a0, a2
2564 ; RV64I-NEXT: lw a0, 0(a0)
2567 ; RV64ZBA-LABEL: array_index_sh4_sh2:
2569 ; RV64ZBA-NEXT: slli a1, a1, 6
2570 ; RV64ZBA-NEXT: add a0, a0, a1
2571 ; RV64ZBA-NEXT: sh2add a0, a2, a0
2572 ; RV64ZBA-NEXT: lw a0, 0(a0)
2574 %a = getelementptr inbounds [16 x i32], ptr %p, i64 %idx1, i64 %idx2
2575 %b = load i32, ptr %a, align 4
2579 define i64 @array_index_sh4_sh3(ptr %p, i64 %idx1, i64 %idx2) {
2580 ; RV64I-LABEL: array_index_sh4_sh3:
2582 ; RV64I-NEXT: slli a1, a1, 7
2583 ; RV64I-NEXT: add a0, a0, a1
2584 ; RV64I-NEXT: slli a2, a2, 3
2585 ; RV64I-NEXT: add a0, a0, a2
2586 ; RV64I-NEXT: ld a0, 0(a0)
2589 ; RV64ZBA-LABEL: array_index_sh4_sh3:
2591 ; RV64ZBA-NEXT: slli a1, a1, 7
2592 ; RV64ZBA-NEXT: add a0, a0, a1
2593 ; RV64ZBA-NEXT: sh3add a0, a2, a0
2594 ; RV64ZBA-NEXT: ld a0, 0(a0)
2596 %a = getelementptr inbounds [16 x i64], ptr %p, i64 %idx1, i64 %idx2
2597 %b = load i64, ptr %a, align 8
2601 define ptr @test_gep_gep_dont_crash(ptr %p, i64 %a1, i64 %a2) {
2602 ; RV64I-LABEL: test_gep_gep_dont_crash:
2604 ; RV64I-NEXT: srliw a2, a2, 6
2605 ; RV64I-NEXT: slli a2, a2, 3
2606 ; RV64I-NEXT: slli a1, a1, 3
2607 ; RV64I-NEXT: add a0, a0, a1
2608 ; RV64I-NEXT: add a0, a0, a2
2611 ; RV64ZBA-LABEL: test_gep_gep_dont_crash:
2613 ; RV64ZBA-NEXT: srliw a2, a2, 6
2614 ; RV64ZBA-NEXT: add a1, a2, a1
2615 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2617 %lshr = lshr i64 %a2, 6
2618 %and = and i64 %lshr, 67108863
2619 %gep1 = getelementptr i64, ptr %p, i64 %and
2620 %gep2 = getelementptr i64, ptr %gep1, i64 %a1
2624 define i64 @regression(i32 signext %x, i32 signext %y) {
2625 ; RV64I-LABEL: regression:
2627 ; RV64I-NEXT: subw a0, a0, a1
2628 ; RV64I-NEXT: slli a0, a0, 32
2629 ; RV64I-NEXT: srli a1, a0, 29
2630 ; RV64I-NEXT: srli a0, a0, 27
2631 ; RV64I-NEXT: sub a0, a0, a1
2634 ; RV64ZBA-LABEL: regression:
2636 ; RV64ZBA-NEXT: subw a0, a0, a1
2637 ; RV64ZBA-NEXT: slli.uw a0, a0, 3
2638 ; RV64ZBA-NEXT: sh1add a0, a0, a0
2640 %sub = sub i32 %x, %y
2641 %ext = zext i32 %sub to i64
2642 %res = mul nuw nsw i64 %ext, 24
2646 define i64 @mul_neg1(i64 %a) {
2647 ; CHECK-LABEL: mul_neg1:
2649 ; CHECK-NEXT: neg a0, a0
2655 define i64 @mul_neg2(i64 %a) {
2656 ; CHECK-LABEL: mul_neg2:
2658 ; CHECK-NEXT: slli a0, a0, 1
2659 ; CHECK-NEXT: neg a0, a0
2665 define i64 @mul_neg3(i64 %a) {
2666 ; RV64I-LABEL: mul_neg3:
2668 ; RV64I-NEXT: slli a1, a0, 1
2669 ; RV64I-NEXT: neg a0, a0
2670 ; RV64I-NEXT: sub a0, a0, a1
2673 ; RV64ZBA-LABEL: mul_neg3:
2675 ; RV64ZBA-NEXT: sh1add a0, a0, a0
2676 ; RV64ZBA-NEXT: neg a0, a0
2682 define i64 @mul_neg4(i64 %a) {
2683 ; CHECK-LABEL: mul_neg4:
2685 ; CHECK-NEXT: slli a0, a0, 2
2686 ; CHECK-NEXT: neg a0, a0
2692 define i64 @mul_neg5(i64 %a) {
2693 ; RV64I-LABEL: mul_neg5:
2695 ; RV64I-NEXT: slli a1, a0, 2
2696 ; RV64I-NEXT: neg a0, a0
2697 ; RV64I-NEXT: sub a0, a0, a1
2700 ; RV64ZBA-LABEL: mul_neg5:
2702 ; RV64ZBA-NEXT: sh2add a0, a0, a0
2703 ; RV64ZBA-NEXT: neg a0, a0
2709 define i64 @mul_neg6(i64 %a) {
2710 ; CHECK-LABEL: mul_neg6:
2712 ; CHECK-NEXT: li a1, -6
2713 ; CHECK-NEXT: mul a0, a0, a1
2719 define i64 @mul_neg7(i64 %a) {
2720 ; CHECK-LABEL: mul_neg7:
2722 ; CHECK-NEXT: slli a1, a0, 3
2723 ; CHECK-NEXT: sub a0, a0, a1
2729 define i64 @mul_neg8(i64 %a) {
2730 ; CHECK-LABEL: mul_neg8:
2732 ; CHECK-NEXT: slli a0, a0, 3
2733 ; CHECK-NEXT: neg a0, a0
2739 define i64 @bext_mul12(i32 %1, i32 %2) {
2740 ; RV64I-LABEL: bext_mul12:
2741 ; RV64I: # %bb.0: # %entry
2742 ; RV64I-NEXT: srlw a0, a0, a1
2743 ; RV64I-NEXT: andi a0, a0, 1
2744 ; RV64I-NEXT: slli a1, a0, 2
2745 ; RV64I-NEXT: slli a0, a0, 4
2746 ; RV64I-NEXT: sub a0, a0, a1
2749 ; RV64ZBANOZBB-LABEL: bext_mul12:
2750 ; RV64ZBANOZBB: # %bb.0: # %entry
2751 ; RV64ZBANOZBB-NEXT: srlw a0, a0, a1
2752 ; RV64ZBANOZBB-NEXT: andi a0, a0, 1
2753 ; RV64ZBANOZBB-NEXT: sh1add a0, a0, a0
2754 ; RV64ZBANOZBB-NEXT: slli a0, a0, 2
2755 ; RV64ZBANOZBB-NEXT: ret
2757 ; RV64ZBAZBBNOZBS-LABEL: bext_mul12:
2758 ; RV64ZBAZBBNOZBS: # %bb.0: # %entry
2759 ; RV64ZBAZBBNOZBS-NEXT: srlw a0, a0, a1
2760 ; RV64ZBAZBBNOZBS-NEXT: andi a0, a0, 1
2761 ; RV64ZBAZBBNOZBS-NEXT: sh1add a0, a0, a0
2762 ; RV64ZBAZBBNOZBS-NEXT: slli a0, a0, 2
2763 ; RV64ZBAZBBNOZBS-NEXT: ret
2765 ; RV64ZBAZBBZBS-LABEL: bext_mul12:
2766 ; RV64ZBAZBBZBS: # %bb.0: # %entry
2767 ; RV64ZBAZBBZBS-NEXT: bext a0, a0, a1
2768 ; RV64ZBAZBBZBS-NEXT: sh1add a0, a0, a0
2769 ; RV64ZBAZBBZBS-NEXT: slli a0, a0, 2
2770 ; RV64ZBAZBBZBS-NEXT: ret
2772 %3 = lshr i32 %1, %2
2774 %5 = zext nneg i32 %4 to i64
2779 define i64 @bext_mul45(i32 %1, i32 %2) {
2780 ; RV64I-LABEL: bext_mul45:
2781 ; RV64I: # %bb.0: # %entry
2782 ; RV64I-NEXT: srlw a0, a0, a1
2783 ; RV64I-NEXT: andi a0, a0, 1
2784 ; RV64I-NEXT: li a1, 45
2785 ; RV64I-NEXT: mul a0, a0, a1
2788 ; RV64ZBANOZBB-LABEL: bext_mul45:
2789 ; RV64ZBANOZBB: # %bb.0: # %entry
2790 ; RV64ZBANOZBB-NEXT: srlw a0, a0, a1
2791 ; RV64ZBANOZBB-NEXT: andi a0, a0, 1
2792 ; RV64ZBANOZBB-NEXT: sh2add a0, a0, a0
2793 ; RV64ZBANOZBB-NEXT: sh3add a0, a0, a0
2794 ; RV64ZBANOZBB-NEXT: ret
2796 ; RV64ZBAZBBNOZBS-LABEL: bext_mul45:
2797 ; RV64ZBAZBBNOZBS: # %bb.0: # %entry
2798 ; RV64ZBAZBBNOZBS-NEXT: srlw a0, a0, a1
2799 ; RV64ZBAZBBNOZBS-NEXT: andi a0, a0, 1
2800 ; RV64ZBAZBBNOZBS-NEXT: sh2add a0, a0, a0
2801 ; RV64ZBAZBBNOZBS-NEXT: sh3add a0, a0, a0
2802 ; RV64ZBAZBBNOZBS-NEXT: ret
2804 ; RV64ZBAZBBZBS-LABEL: bext_mul45:
2805 ; RV64ZBAZBBZBS: # %bb.0: # %entry
2806 ; RV64ZBAZBBZBS-NEXT: bext a0, a0, a1
2807 ; RV64ZBAZBBZBS-NEXT: sh2add a0, a0, a0
2808 ; RV64ZBAZBBZBS-NEXT: sh3add a0, a0, a0
2809 ; RV64ZBAZBBZBS-NEXT: ret
2811 %3 = lshr i32 %1, %2
2813 %5 = zext nneg i32 %4 to i64
2818 define i64 @bext_mul132(i32 %1, i32 %2) {
2819 ; RV64I-LABEL: bext_mul132:
2820 ; RV64I: # %bb.0: # %entry
2821 ; RV64I-NEXT: srlw a0, a0, a1
2822 ; RV64I-NEXT: andi a0, a0, 1
2823 ; RV64I-NEXT: li a1, 132
2824 ; RV64I-NEXT: mul a0, a0, a1
2827 ; RV64ZBANOZBB-LABEL: bext_mul132:
2828 ; RV64ZBANOZBB: # %bb.0: # %entry
2829 ; RV64ZBANOZBB-NEXT: srlw a0, a0, a1
2830 ; RV64ZBANOZBB-NEXT: andi a0, a0, 1
2831 ; RV64ZBANOZBB-NEXT: slli a1, a0, 7
2832 ; RV64ZBANOZBB-NEXT: sh2add a0, a0, a1
2833 ; RV64ZBANOZBB-NEXT: ret
2835 ; RV64ZBAZBBNOZBS-LABEL: bext_mul132:
2836 ; RV64ZBAZBBNOZBS: # %bb.0: # %entry
2837 ; RV64ZBAZBBNOZBS-NEXT: srlw a0, a0, a1
2838 ; RV64ZBAZBBNOZBS-NEXT: andi a0, a0, 1
2839 ; RV64ZBAZBBNOZBS-NEXT: slli a1, a0, 7
2840 ; RV64ZBAZBBNOZBS-NEXT: sh2add a0, a0, a1
2841 ; RV64ZBAZBBNOZBS-NEXT: ret
2843 ; RV64ZBAZBBZBS-LABEL: bext_mul132:
2844 ; RV64ZBAZBBZBS: # %bb.0: # %entry
2845 ; RV64ZBAZBBZBS-NEXT: bext a0, a0, a1
2846 ; RV64ZBAZBBZBS-NEXT: slli a1, a0, 7
2847 ; RV64ZBAZBBZBS-NEXT: sh2add a0, a0, a1
2848 ; RV64ZBAZBBZBS-NEXT: ret
2850 %3 = lshr i32 %1, %2
2852 %5 = zext nneg i32 %4 to i64
2853 %6 = mul i64 %5, 132
2857 define ptr @gep_lshr_i32(ptr %0, i64 %1) {
2858 ; RV64I-LABEL: gep_lshr_i32:
2859 ; RV64I: # %bb.0: # %entry
2860 ; RV64I-NEXT: srli a1, a1, 2
2861 ; RV64I-NEXT: li a2, 5
2862 ; RV64I-NEXT: slli a2, a2, 36
2863 ; RV64I-NEXT: slli a1, a1, 32
2864 ; RV64I-NEXT: mulhu a1, a1, a2
2865 ; RV64I-NEXT: add a0, a0, a1
2868 ; RV64ZBA-LABEL: gep_lshr_i32:
2869 ; RV64ZBA: # %bb.0: # %entry
2870 ; RV64ZBA-NEXT: srli a1, a1, 2
2871 ; RV64ZBA-NEXT: slli.uw a1, a1, 4
2872 ; RV64ZBA-NEXT: sh2add a1, a1, a1
2873 ; RV64ZBA-NEXT: add a0, a0, a1
2876 %2 = lshr exact i64 %1, 2
2877 %3 = and i64 %2, 4294967295
2878 %5 = getelementptr [80 x i8], ptr %0, i64 %3
2882 define i64 @srli_slliw(i64 %1) {
2883 ; RV64I-LABEL: srli_slliw:
2884 ; RV64I: # %bb.0: # %entry
2885 ; RV64I-NEXT: slli a0, a0, 2
2886 ; RV64I-NEXT: li a1, 1
2887 ; RV64I-NEXT: slli a1, a1, 36
2888 ; RV64I-NEXT: addi a1, a1, -16
2889 ; RV64I-NEXT: and a0, a0, a1
2892 ; RV64ZBA-LABEL: srli_slliw:
2893 ; RV64ZBA: # %bb.0: # %entry
2894 ; RV64ZBA-NEXT: srli a0, a0, 2
2895 ; RV64ZBA-NEXT: slli.uw a0, a0, 4
2898 %2 = lshr exact i64 %1, 2
2899 %3 = and i64 %2, 4294967295
2904 define i64 @srli_slliw_canonical(i64 %0) {
2905 ; RV64I-LABEL: srli_slliw_canonical:
2906 ; RV64I: # %bb.0: # %entry
2907 ; RV64I-NEXT: slli a0, a0, 2
2908 ; RV64I-NEXT: li a1, 1
2909 ; RV64I-NEXT: slli a1, a1, 36
2910 ; RV64I-NEXT: addi a1, a1, -16
2911 ; RV64I-NEXT: and a0, a0, a1
2914 ; RV64ZBA-LABEL: srli_slliw_canonical:
2915 ; RV64ZBA: # %bb.0: # %entry
2916 ; RV64ZBA-NEXT: srli a0, a0, 2
2917 ; RV64ZBA-NEXT: slli.uw a0, a0, 4
2921 %2 = and i64 %1, 68719476720
2925 ; Make sure we don't accidentally use slli.uw with a shift of 32.
2926 define i64 @srli_slliuw_negative_test(i64 %0) {
2927 ; CHECK-LABEL: srli_slliuw_negative_test:
2928 ; CHECK: # %bb.0: # %entry
2929 ; CHECK-NEXT: srli a0, a0, 6
2930 ; CHECK-NEXT: slli a0, a0, 32
2938 define i64 @srli_slli_i16(i64 %1) {
2939 ; CHECK-LABEL: srli_slli_i16:
2940 ; CHECK: # %bb.0: # %entry
2941 ; CHECK-NEXT: slli a0, a0, 2
2942 ; CHECK-NEXT: lui a1, 256
2943 ; CHECK-NEXT: addiw a1, a1, -16
2944 ; CHECK-NEXT: and a0, a0, a1
2947 %2 = lshr exact i64 %1, 2
2948 %3 = and i64 %2, 65535