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 @mul50(i64 %a) {
573 ; RV64I-LABEL: mul50:
575 ; RV64I-NEXT: li a1, 50
576 ; RV64I-NEXT: mul a0, a0, a1
579 ; RV64ZBA-LABEL: mul50:
581 ; RV64ZBA-NEXT: sh2add a0, a0, a0
582 ; RV64ZBA-NEXT: sh2add a0, a0, a0
583 ; RV64ZBA-NEXT: slli a0, a0, 1
589 define i64 @addmul50(i64 %a, i64 %b) {
590 ; RV64I-LABEL: addmul50:
592 ; RV64I-NEXT: li a2, 50
593 ; RV64I-NEXT: mul a0, a0, a2
594 ; RV64I-NEXT: add a0, a0, a1
597 ; RV64ZBA-LABEL: addmul50:
599 ; RV64ZBA-NEXT: sh2add a0, a0, a0
600 ; RV64ZBA-NEXT: sh2add a0, a0, a0
601 ; RV64ZBA-NEXT: sh1add a0, a0, a1
608 define i64 @mul100(i64 %a) {
609 ; RV64I-LABEL: mul100:
611 ; RV64I-NEXT: li a1, 100
612 ; RV64I-NEXT: mul a0, a0, a1
615 ; RV64ZBA-LABEL: mul100:
617 ; RV64ZBA-NEXT: sh2add a0, a0, a0
618 ; RV64ZBA-NEXT: sh2add a0, a0, a0
619 ; RV64ZBA-NEXT: slli a0, a0, 2
625 define i64 @addmul100(i64 %a, i64 %b) {
626 ; RV64I-LABEL: addmul100:
628 ; RV64I-NEXT: li a2, 100
629 ; RV64I-NEXT: mul a0, a0, a2
630 ; RV64I-NEXT: add a0, a0, a1
633 ; RV64ZBA-LABEL: addmul100:
635 ; RV64ZBA-NEXT: sh2add a0, a0, a0
636 ; RV64ZBA-NEXT: sh2add a0, a0, a0
637 ; RV64ZBA-NEXT: sh2add a0, a0, a1
644 define i64 @mul162(i64 %a) {
645 ; RV64I-LABEL: mul162:
647 ; RV64I-NEXT: li a1, 162
648 ; RV64I-NEXT: mul a0, a0, a1
651 ; RV64ZBA-LABEL: mul162:
653 ; RV64ZBA-NEXT: sh3add a0, a0, a0
654 ; RV64ZBA-NEXT: sh3add a0, a0, a0
655 ; RV64ZBA-NEXT: slli a0, a0, 1
661 define i64 @addmul162(i64 %a, i64 %b) {
662 ; RV64I-LABEL: addmul162:
664 ; RV64I-NEXT: li a2, 162
665 ; RV64I-NEXT: mul a0, a0, a2
666 ; RV64I-NEXT: add a0, a0, a1
669 ; RV64ZBA-LABEL: addmul162:
671 ; RV64ZBA-NEXT: sh3add a0, a0, a0
672 ; RV64ZBA-NEXT: sh3add a0, a0, a0
673 ; RV64ZBA-NEXT: sh1add a0, a0, a1
680 define i64 @mul180(i64 %a) {
681 ; RV64I-LABEL: mul180:
683 ; RV64I-NEXT: li a1, 180
684 ; RV64I-NEXT: mul a0, a0, a1
687 ; RV64ZBA-LABEL: mul180:
689 ; RV64ZBA-NEXT: sh2add a0, a0, a0
690 ; RV64ZBA-NEXT: sh3add a0, a0, a0
691 ; RV64ZBA-NEXT: slli a0, a0, 2
697 define i64 @addmul180(i64 %a, i64 %b) {
698 ; RV64I-LABEL: addmul180:
700 ; RV64I-NEXT: li a2, 180
701 ; RV64I-NEXT: mul a0, a0, a2
702 ; RV64I-NEXT: add a0, a0, a1
705 ; RV64ZBA-LABEL: addmul180:
707 ; RV64ZBA-NEXT: sh2add a0, a0, a0
708 ; RV64ZBA-NEXT: sh3add a0, a0, a0
709 ; RV64ZBA-NEXT: sh2add a0, a0, a1
716 define i64 @add255mul180(i64 %a) {
717 ; RV64I-LABEL: add255mul180:
719 ; RV64I-NEXT: li a1, 180
720 ; RV64I-NEXT: mul a0, a0, a1
721 ; RV64I-NEXT: addi a0, a0, 255
724 ; RV64ZBA-LABEL: add255mul180:
726 ; RV64ZBA-NEXT: sh2add a0, a0, a0
727 ; RV64ZBA-NEXT: sh3add a0, a0, a0
728 ; RV64ZBA-NEXT: slli a0, a0, 2
729 ; RV64ZBA-NEXT: addi a0, a0, 255
736 define i64 @mul200(i64 %a) {
737 ; RV64I-LABEL: mul200:
739 ; RV64I-NEXT: li a1, 200
740 ; RV64I-NEXT: mul a0, a0, a1
743 ; RV64ZBA-LABEL: mul200:
745 ; RV64ZBA-NEXT: sh2add a0, a0, a0
746 ; RV64ZBA-NEXT: sh2add a0, a0, a0
747 ; RV64ZBA-NEXT: slli a0, a0, 3
753 define i64 @addmul200(i64 %a, i64 %b) {
754 ; RV64I-LABEL: addmul200:
756 ; RV64I-NEXT: li a2, 200
757 ; RV64I-NEXT: mul a0, a0, a2
758 ; RV64I-NEXT: add a0, a0, a1
761 ; RV64ZBA-LABEL: addmul200:
763 ; RV64ZBA-NEXT: sh2add a0, a0, a0
764 ; RV64ZBA-NEXT: sh2add a0, a0, a0
765 ; RV64ZBA-NEXT: sh3add a0, a0, a1
772 define i64 @addmul4096(i64 %a, i64 %b) {
773 ; CHECK-LABEL: addmul4096:
775 ; CHECK-NEXT: slli a0, a0, 12
776 ; CHECK-NEXT: add a0, a0, a1
778 %c = mul i64 %a, 4096
783 define i64 @addmul4230(i64 %a, i64 %b) {
784 ; CHECK-LABEL: addmul4230:
786 ; CHECK-NEXT: lui a2, 1
787 ; CHECK-NEXT: addiw a2, a2, 134
788 ; CHECK-NEXT: mul a0, a0, a2
789 ; CHECK-NEXT: add a0, a0, a1
791 %c = mul i64 %a, 4230
796 define i64 @mul96(i64 %a) {
797 ; RV64I-LABEL: mul96:
799 ; RV64I-NEXT: slli a1, a0, 5
800 ; RV64I-NEXT: slli a0, a0, 7
801 ; RV64I-NEXT: sub a0, a0, a1
804 ; RV64ZBA-LABEL: mul96:
806 ; RV64ZBA-NEXT: sh1add a0, a0, a0
807 ; RV64ZBA-NEXT: slli a0, a0, 5
813 define i64 @mul119(i64 %a) {
814 ; RV64I-LABEL: mul119:
816 ; RV64I-NEXT: li a1, 119
817 ; RV64I-NEXT: mul a0, a0, a1
820 ; RV64ZBA-LABEL: mul119:
822 ; RV64ZBA-NEXT: sh3add a1, a0, a0
823 ; RV64ZBA-NEXT: slli a0, a0, 7
824 ; RV64ZBA-NEXT: sub a0, a0, a1
830 define i64 @mul123(i64 %a) {
831 ; RV64I-LABEL: mul123:
833 ; RV64I-NEXT: li a1, 123
834 ; RV64I-NEXT: mul a0, a0, a1
837 ; RV64ZBA-LABEL: mul123:
839 ; RV64ZBA-NEXT: sh2add a1, a0, a0
840 ; RV64ZBA-NEXT: slli a0, a0, 7
841 ; RV64ZBA-NEXT: sub a0, a0, a1
847 define i64 @mul125(i64 %a) {
848 ; RV64I-LABEL: mul125:
850 ; RV64I-NEXT: li a1, 125
851 ; RV64I-NEXT: mul a0, a0, a1
854 ; RV64ZBA-LABEL: mul125:
856 ; RV64ZBA-NEXT: sh1add a1, a0, a0
857 ; RV64ZBA-NEXT: slli a0, a0, 7
858 ; RV64ZBA-NEXT: sub a0, a0, a1
864 define i64 @mul131(i64 %a) {
865 ; RV64I-LABEL: mul131:
867 ; RV64I-NEXT: li a1, 131
868 ; RV64I-NEXT: mul a0, a0, a1
871 ; RV64ZBA-LABEL: mul131:
873 ; RV64ZBA-NEXT: sh1add a1, a0, a0
874 ; RV64ZBA-NEXT: slli a0, a0, 7
875 ; RV64ZBA-NEXT: add a0, a0, a1
881 define i64 @mul133(i64 %a) {
882 ; RV64I-LABEL: mul133:
884 ; RV64I-NEXT: li a1, 133
885 ; RV64I-NEXT: mul a0, a0, a1
888 ; RV64ZBA-LABEL: mul133:
890 ; RV64ZBA-NEXT: sh2add a1, a0, a0
891 ; RV64ZBA-NEXT: slli a0, a0, 7
892 ; RV64ZBA-NEXT: add a0, a0, a1
898 define i64 @mul137(i64 %a) {
899 ; RV64I-LABEL: mul137:
901 ; RV64I-NEXT: li a1, 137
902 ; RV64I-NEXT: mul a0, a0, a1
905 ; RV64ZBA-LABEL: mul137:
907 ; RV64ZBA-NEXT: sh3add a1, a0, a0
908 ; RV64ZBA-NEXT: slli a0, a0, 7
909 ; RV64ZBA-NEXT: add a0, a0, a1
915 define i64 @mul160(i64 %a) {
916 ; RV64I-LABEL: mul160:
918 ; RV64I-NEXT: li a1, 160
919 ; RV64I-NEXT: mul a0, a0, a1
922 ; RV64ZBA-LABEL: mul160:
924 ; RV64ZBA-NEXT: sh2add a0, a0, a0
925 ; RV64ZBA-NEXT: slli a0, a0, 5
931 define i64 @mul288(i64 %a) {
932 ; RV64I-LABEL: mul288:
934 ; RV64I-NEXT: li a1, 288
935 ; RV64I-NEXT: mul a0, a0, a1
938 ; RV64ZBA-LABEL: mul288:
940 ; RV64ZBA-NEXT: sh3add a0, a0, a0
941 ; RV64ZBA-NEXT: slli a0, a0, 5
947 define i64 @zext_mul68(i32 signext %a) {
948 ; RV64I-LABEL: zext_mul68:
950 ; RV64I-NEXT: li a1, 17
951 ; RV64I-NEXT: slli a1, a1, 34
952 ; RV64I-NEXT: slli a0, a0, 32
953 ; RV64I-NEXT: mulhu a0, a0, a1
956 ; RV64ZBA-LABEL: zext_mul68:
958 ; RV64ZBA-NEXT: slli.uw a1, a0, 6
959 ; RV64ZBA-NEXT: sh2add.uw a0, a0, a1
961 %b = zext i32 %a to i64
966 define i64 @zext_mul96(i32 signext %a) {
967 ; RV64I-LABEL: zext_mul96:
969 ; RV64I-NEXT: slli a0, a0, 32
970 ; RV64I-NEXT: srli a1, a0, 27
971 ; RV64I-NEXT: srli a0, a0, 25
972 ; RV64I-NEXT: sub a0, a0, a1
975 ; RV64ZBA-LABEL: zext_mul96:
977 ; RV64ZBA-NEXT: slli.uw a0, a0, 5
978 ; RV64ZBA-NEXT: sh1add a0, a0, a0
980 %b = zext i32 %a to i64
985 define i64 @zext_mul160(i32 signext %a) {
986 ; RV64I-LABEL: zext_mul160:
988 ; RV64I-NEXT: li a1, 5
989 ; RV64I-NEXT: slli a1, a1, 37
990 ; RV64I-NEXT: slli a0, a0, 32
991 ; RV64I-NEXT: mulhu a0, a0, a1
994 ; RV64ZBA-LABEL: zext_mul160:
996 ; RV64ZBA-NEXT: slli.uw a0, a0, 5
997 ; RV64ZBA-NEXT: sh2add a0, a0, a0
999 %b = zext i32 %a to i64
1000 %c = mul i64 %b, 160
1004 define i64 @zext_mul288(i32 signext %a) {
1005 ; RV64I-LABEL: zext_mul288:
1007 ; RV64I-NEXT: li a1, 9
1008 ; RV64I-NEXT: slli a1, a1, 37
1009 ; RV64I-NEXT: slli a0, a0, 32
1010 ; RV64I-NEXT: mulhu a0, a0, a1
1013 ; RV64ZBA-LABEL: zext_mul288:
1015 ; RV64ZBA-NEXT: slli.uw a0, a0, 5
1016 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1018 %b = zext i32 %a to i64
1019 %c = mul i64 %b, 288
1023 ; We can't use slli.uw becaues the shift amount is more than 31.
1024 define i64 @zext_mul12884901888(i32 signext %a) {
1025 ; RV64I-LABEL: zext_mul12884901888:
1027 ; RV64I-NEXT: slli a1, a0, 32
1028 ; RV64I-NEXT: slli a0, a0, 34
1029 ; RV64I-NEXT: sub a0, a0, a1
1032 ; RV64ZBA-LABEL: zext_mul12884901888:
1034 ; RV64ZBA-NEXT: sh1add a0, a0, a0
1035 ; RV64ZBA-NEXT: slli a0, a0, 32
1037 %b = zext i32 %a to i64
1038 %c = mul i64 %b, 12884901888
1042 ; We can't use slli.uw becaues the shift amount is more than 31.
1043 define i64 @zext_mul21474836480(i32 signext %a) {
1044 ; RV64I-LABEL: zext_mul21474836480:
1046 ; RV64I-NEXT: li a1, 5
1047 ; RV64I-NEXT: slli a1, a1, 32
1048 ; RV64I-NEXT: mul a0, a0, a1
1051 ; RV64ZBA-LABEL: zext_mul21474836480:
1053 ; RV64ZBA-NEXT: sh2add a0, a0, a0
1054 ; RV64ZBA-NEXT: slli a0, a0, 32
1056 %b = zext i32 %a to i64
1057 %c = mul i64 %b, 21474836480
1061 ; We can't use slli.uw becaues the shift amount is more than 31.
1062 define i64 @zext_mul38654705664(i32 signext %a) {
1063 ; RV64I-LABEL: zext_mul38654705664:
1065 ; RV64I-NEXT: li a1, 9
1066 ; RV64I-NEXT: slli a1, a1, 32
1067 ; RV64I-NEXT: mul a0, a0, a1
1070 ; RV64ZBA-LABEL: zext_mul38654705664:
1072 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1073 ; RV64ZBA-NEXT: slli a0, a0, 32
1075 %b = zext i32 %a to i64
1076 %c = mul i64 %b, 38654705664
1080 define i64 @sh1add_imm(i64 %0) {
1081 ; CHECK-LABEL: sh1add_imm:
1083 ; CHECK-NEXT: slli a0, a0, 1
1084 ; CHECK-NEXT: addi a0, a0, 5
1091 define i64 @sh2add_imm(i64 %0) {
1092 ; CHECK-LABEL: sh2add_imm:
1094 ; CHECK-NEXT: slli a0, a0, 2
1095 ; CHECK-NEXT: addi a0, a0, -6
1102 define i64 @sh3add_imm(i64 %0) {
1103 ; CHECK-LABEL: sh3add_imm:
1105 ; CHECK-NEXT: slli a0, a0, 3
1106 ; CHECK-NEXT: addi a0, a0, 7
1113 define i64 @sh1adduw_imm(i32 signext %0) {
1114 ; RV64I-LABEL: sh1adduw_imm:
1116 ; RV64I-NEXT: slli a0, a0, 32
1117 ; RV64I-NEXT: srli a0, a0, 31
1118 ; RV64I-NEXT: addi a0, a0, 11
1121 ; RV64ZBA-LABEL: sh1adduw_imm:
1123 ; RV64ZBA-NEXT: slli.uw a0, a0, 1
1124 ; RV64ZBA-NEXT: addi a0, a0, 11
1126 %a = zext i32 %0 to i64
1132 define i64 @sh2adduw_imm(i32 signext %0) {
1133 ; RV64I-LABEL: sh2adduw_imm:
1135 ; RV64I-NEXT: slli a0, a0, 32
1136 ; RV64I-NEXT: srli a0, a0, 30
1137 ; RV64I-NEXT: addi a0, a0, -12
1140 ; RV64ZBA-LABEL: sh2adduw_imm:
1142 ; RV64ZBA-NEXT: slli.uw a0, a0, 2
1143 ; RV64ZBA-NEXT: addi a0, a0, -12
1145 %a = zext i32 %0 to i64
1147 %c = add i64 %b, -12
1151 define i64 @sh3adduw_imm(i32 signext %0) {
1152 ; RV64I-LABEL: sh3adduw_imm:
1154 ; RV64I-NEXT: slli a0, a0, 32
1155 ; RV64I-NEXT: srli a0, a0, 29
1156 ; RV64I-NEXT: addi a0, a0, 13
1159 ; RV64ZBA-LABEL: sh3adduw_imm:
1161 ; RV64ZBA-NEXT: slli.uw a0, a0, 3
1162 ; RV64ZBA-NEXT: addi a0, a0, 13
1164 %a = zext i32 %0 to i64
1170 define i64 @adduw_imm(i32 signext %0) nounwind {
1171 ; RV64I-LABEL: adduw_imm:
1173 ; RV64I-NEXT: slli a0, a0, 32
1174 ; RV64I-NEXT: srli a0, a0, 32
1175 ; RV64I-NEXT: addi a0, a0, 5
1178 ; RV64ZBA-LABEL: adduw_imm:
1180 ; RV64ZBA-NEXT: zext.w a0, a0
1181 ; RV64ZBA-NEXT: addi a0, a0, 5
1183 %a = zext i32 %0 to i64
1188 define i64 @mul258(i64 %a) {
1189 ; RV64I-LABEL: mul258:
1191 ; RV64I-NEXT: li a1, 258
1192 ; RV64I-NEXT: mul a0, a0, a1
1195 ; RV64ZBA-LABEL: mul258:
1197 ; RV64ZBA-NEXT: slli a1, a0, 8
1198 ; RV64ZBA-NEXT: sh1add a0, a0, a1
1200 %c = mul i64 %a, 258
1204 define i64 @mul260(i64 %a) {
1205 ; RV64I-LABEL: mul260:
1207 ; RV64I-NEXT: li a1, 260
1208 ; RV64I-NEXT: mul a0, a0, a1
1211 ; RV64ZBA-LABEL: mul260:
1213 ; RV64ZBA-NEXT: slli a1, a0, 8
1214 ; RV64ZBA-NEXT: sh2add a0, a0, a1
1216 %c = mul i64 %a, 260
1220 define i64 @mul264(i64 %a) {
1221 ; RV64I-LABEL: mul264:
1223 ; RV64I-NEXT: li a1, 264
1224 ; RV64I-NEXT: mul a0, a0, a1
1227 ; RV64ZBA-LABEL: mul264:
1229 ; RV64ZBA-NEXT: slli a1, a0, 8
1230 ; RV64ZBA-NEXT: sh3add a0, a0, a1
1232 %c = mul i64 %a, 264
1236 define i64 @imm_zextw() nounwind {
1237 ; RV64I-LABEL: imm_zextw:
1239 ; RV64I-NEXT: li a0, 1
1240 ; RV64I-NEXT: slli a0, a0, 32
1241 ; RV64I-NEXT: addi a0, a0, -2
1244 ; RV64ZBA-LABEL: imm_zextw:
1246 ; RV64ZBA-NEXT: li a0, -2
1247 ; RV64ZBA-NEXT: zext.w a0, a0
1249 ret i64 4294967294 ; -2 in 32 bits.
1252 define i64 @mul11(i64 %a) {
1253 ; RV64I-LABEL: mul11:
1255 ; RV64I-NEXT: li a1, 11
1256 ; RV64I-NEXT: mul a0, a0, a1
1259 ; RV64ZBA-LABEL: mul11:
1261 ; RV64ZBA-NEXT: sh2add a1, a0, a0
1262 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1268 define i64 @mul19(i64 %a) {
1269 ; RV64I-LABEL: mul19:
1271 ; RV64I-NEXT: li a1, 19
1272 ; RV64I-NEXT: mul a0, a0, a1
1275 ; RV64ZBA-LABEL: mul19:
1277 ; RV64ZBA-NEXT: sh3add a1, a0, a0
1278 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1284 define i64 @mul13(i64 %a) {
1285 ; RV64I-LABEL: mul13:
1287 ; RV64I-NEXT: li a1, 13
1288 ; RV64I-NEXT: mul a0, a0, a1
1291 ; RV64ZBA-LABEL: mul13:
1293 ; RV64ZBA-NEXT: sh1add a1, a0, a0
1294 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1300 define i64 @mul21(i64 %a) {
1301 ; RV64I-LABEL: mul21:
1303 ; RV64I-NEXT: li a1, 21
1304 ; RV64I-NEXT: mul a0, a0, a1
1307 ; RV64ZBA-LABEL: mul21:
1309 ; RV64ZBA-NEXT: sh2add a1, a0, a0
1310 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1316 define i64 @mul37(i64 %a) {
1317 ; RV64I-LABEL: mul37:
1319 ; RV64I-NEXT: li a1, 37
1320 ; RV64I-NEXT: mul a0, a0, a1
1323 ; RV64ZBA-LABEL: mul37:
1325 ; RV64ZBA-NEXT: sh3add a1, a0, a0
1326 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1332 define i64 @mul25(i64 %a) {
1333 ; RV64I-LABEL: mul25:
1335 ; RV64I-NEXT: li a1, 25
1336 ; RV64I-NEXT: mul a0, a0, a1
1339 ; RV64ZBA-LABEL: mul25:
1341 ; RV64ZBA-NEXT: sh2add a0, a0, a0
1342 ; RV64ZBA-NEXT: sh2add a0, a0, a0
1348 define i64 @mul41(i64 %a) {
1349 ; RV64I-LABEL: mul41:
1351 ; RV64I-NEXT: li a1, 41
1352 ; RV64I-NEXT: mul a0, a0, a1
1355 ; RV64ZBA-LABEL: mul41:
1357 ; RV64ZBA-NEXT: sh2add a1, a0, a0
1358 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1364 define i64 @mul73(i64 %a) {
1365 ; RV64I-LABEL: mul73:
1367 ; RV64I-NEXT: li a1, 73
1368 ; RV64I-NEXT: mul a0, a0, a1
1371 ; RV64ZBA-LABEL: mul73:
1373 ; RV64ZBA-NEXT: sh3add a1, a0, a0
1374 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1380 define i64 @mul27(i64 %a) {
1381 ; RV64I-LABEL: mul27:
1383 ; RV64I-NEXT: li a1, 27
1384 ; RV64I-NEXT: mul a0, a0, a1
1387 ; RV64ZBA-LABEL: mul27:
1389 ; RV64ZBA-NEXT: sh1add a0, a0, a0
1390 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1396 define i64 @mul45(i64 %a) {
1397 ; RV64I-LABEL: mul45:
1399 ; RV64I-NEXT: li a1, 45
1400 ; RV64I-NEXT: mul a0, a0, a1
1403 ; RV64ZBA-LABEL: mul45:
1405 ; RV64ZBA-NEXT: sh2add a0, a0, a0
1406 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1412 define i64 @mul81(i64 %a) {
1413 ; RV64I-LABEL: mul81:
1415 ; RV64I-NEXT: li a1, 81
1416 ; RV64I-NEXT: mul a0, a0, a1
1419 ; RV64ZBA-LABEL: mul81:
1421 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1422 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1428 define i64 @mul4098(i64 %a) {
1429 ; RV64I-LABEL: mul4098:
1431 ; RV64I-NEXT: slli a1, a0, 1
1432 ; RV64I-NEXT: slli a0, a0, 12
1433 ; RV64I-NEXT: add a0, a0, a1
1436 ; RV64ZBA-LABEL: mul4098:
1438 ; RV64ZBA-NEXT: slli a1, a0, 12
1439 ; RV64ZBA-NEXT: sh1add a0, a0, a1
1441 %c = mul i64 %a, 4098
1445 define i64 @mul4100(i64 %a) {
1446 ; RV64I-LABEL: mul4100:
1448 ; RV64I-NEXT: slli a1, a0, 2
1449 ; RV64I-NEXT: slli a0, a0, 12
1450 ; RV64I-NEXT: add a0, a0, a1
1453 ; RV64ZBA-LABEL: mul4100:
1455 ; RV64ZBA-NEXT: slli a1, a0, 12
1456 ; RV64ZBA-NEXT: sh2add a0, a0, a1
1458 %c = mul i64 %a, 4100
1462 define i64 @mul4104(i64 %a) {
1463 ; RV64I-LABEL: mul4104:
1465 ; RV64I-NEXT: slli a1, a0, 3
1466 ; RV64I-NEXT: slli a0, a0, 12
1467 ; RV64I-NEXT: add a0, a0, a1
1470 ; RV64ZBA-LABEL: mul4104:
1472 ; RV64ZBA-NEXT: slli a1, a0, 12
1473 ; RV64ZBA-NEXT: sh3add a0, a0, a1
1475 %c = mul i64 %a, 4104
1479 define signext i32 @mulw192(i32 signext %a) {
1480 ; RV64I-LABEL: mulw192:
1482 ; RV64I-NEXT: slli a1, a0, 6
1483 ; RV64I-NEXT: slli a0, a0, 8
1484 ; RV64I-NEXT: subw a0, a0, a1
1487 ; RV64ZBA-LABEL: mulw192:
1489 ; RV64ZBA-NEXT: sh1add a0, a0, a0
1490 ; RV64ZBA-NEXT: slliw a0, a0, 6
1492 %c = mul i32 %a, 192
1496 define signext i32 @mulw320(i32 signext %a) {
1497 ; RV64I-LABEL: mulw320:
1499 ; RV64I-NEXT: li a1, 320
1500 ; RV64I-NEXT: mulw a0, a0, a1
1503 ; RV64ZBA-LABEL: mulw320:
1505 ; RV64ZBA-NEXT: sh2add a0, a0, a0
1506 ; RV64ZBA-NEXT: slliw a0, a0, 6
1508 %c = mul i32 %a, 320
1512 define signext i32 @mulw576(i32 signext %a) {
1513 ; RV64I-LABEL: mulw576:
1515 ; RV64I-NEXT: li a1, 576
1516 ; RV64I-NEXT: mulw a0, a0, a1
1519 ; RV64ZBA-LABEL: mulw576:
1521 ; RV64ZBA-NEXT: sh3add a0, a0, a0
1522 ; RV64ZBA-NEXT: slliw a0, a0, 6
1524 %c = mul i32 %a, 576
1528 define i64 @add4104(i64 %a) {
1529 ; RV64I-LABEL: add4104:
1531 ; RV64I-NEXT: lui a1, 1
1532 ; RV64I-NEXT: addiw a1, a1, 8
1533 ; RV64I-NEXT: add a0, a0, a1
1536 ; RV64ZBA-LABEL: add4104:
1538 ; RV64ZBA-NEXT: li a1, 1026
1539 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1541 %c = add i64 %a, 4104
1545 define i64 @add4104_2(i64 %a) {
1546 ; RV64I-LABEL: add4104_2:
1548 ; RV64I-NEXT: lui a1, 1
1549 ; RV64I-NEXT: addiw a1, a1, 8
1550 ; RV64I-NEXT: or a0, a0, a1
1553 ; RV64ZBA-LABEL: add4104_2:
1555 ; RV64ZBA-NEXT: li a1, 1026
1556 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1558 %c = or disjoint i64 %a, 4104
1562 define i64 @add8208(i64 %a) {
1563 ; RV64I-LABEL: add8208:
1565 ; RV64I-NEXT: lui a1, 2
1566 ; RV64I-NEXT: addiw a1, a1, 16
1567 ; RV64I-NEXT: add a0, a0, a1
1570 ; RV64ZBA-LABEL: add8208:
1572 ; RV64ZBA-NEXT: li a1, 1026
1573 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1575 %c = add i64 %a, 8208
1579 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1580 define signext i32 @add8192_i32(i32 signext %a) {
1581 ; CHECK-LABEL: add8192_i32:
1583 ; CHECK-NEXT: lui a1, 2
1584 ; CHECK-NEXT: addw a0, a0, a1
1586 %c = add i32 %a, 8192
1590 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1591 define i64 @add8192(i64 %a) {
1592 ; CHECK-LABEL: add8192:
1594 ; CHECK-NEXT: lui a1, 2
1595 ; CHECK-NEXT: add a0, a0, a1
1597 %c = add i64 %a, 8192
1601 define signext i32 @addshl32_5_6(i32 signext %a, i32 signext %b) {
1602 ; RV64I-LABEL: addshl32_5_6:
1604 ; RV64I-NEXT: slli a0, a0, 5
1605 ; RV64I-NEXT: slli a1, a1, 6
1606 ; RV64I-NEXT: addw a0, a0, a1
1609 ; RV64ZBA-LABEL: addshl32_5_6:
1611 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1612 ; RV64ZBA-NEXT: slliw a0, a0, 5
1620 define i64 @addshl64_5_6(i64 %a, i64 %b) {
1621 ; RV64I-LABEL: addshl64_5_6:
1623 ; RV64I-NEXT: slli a0, a0, 5
1624 ; RV64I-NEXT: slli a1, a1, 6
1625 ; RV64I-NEXT: add a0, a0, a1
1628 ; RV64ZBA-LABEL: addshl64_5_6:
1630 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1631 ; RV64ZBA-NEXT: slli a0, a0, 5
1639 define signext i32 @addshl32_5_7(i32 signext %a, i32 signext %b) {
1640 ; RV64I-LABEL: addshl32_5_7:
1642 ; RV64I-NEXT: slli a0, a0, 5
1643 ; RV64I-NEXT: slli a1, a1, 7
1644 ; RV64I-NEXT: addw a0, a0, a1
1647 ; RV64ZBA-LABEL: addshl32_5_7:
1649 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1650 ; RV64ZBA-NEXT: slliw a0, a0, 5
1658 define i64 @addshl64_5_7(i64 %a, i64 %b) {
1659 ; RV64I-LABEL: addshl64_5_7:
1661 ; RV64I-NEXT: slli a0, a0, 5
1662 ; RV64I-NEXT: slli a1, a1, 7
1663 ; RV64I-NEXT: add a0, a0, a1
1666 ; RV64ZBA-LABEL: addshl64_5_7:
1668 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1669 ; RV64ZBA-NEXT: slli a0, a0, 5
1677 define signext i32 @addshl32_5_8(i32 signext %a, i32 signext %b) {
1678 ; RV64I-LABEL: addshl32_5_8:
1680 ; RV64I-NEXT: slli a0, a0, 5
1681 ; RV64I-NEXT: slli a1, a1, 8
1682 ; RV64I-NEXT: addw a0, a0, a1
1685 ; RV64ZBA-LABEL: addshl32_5_8:
1687 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1688 ; RV64ZBA-NEXT: slliw a0, a0, 5
1696 define i64 @addshl64_5_8(i64 %a, i64 %b) {
1697 ; RV64I-LABEL: addshl64_5_8:
1699 ; RV64I-NEXT: slli a0, a0, 5
1700 ; RV64I-NEXT: slli a1, a1, 8
1701 ; RV64I-NEXT: add a0, a0, a1
1704 ; RV64ZBA-LABEL: addshl64_5_8:
1706 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1707 ; RV64ZBA-NEXT: slli a0, a0, 5
1715 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1716 define zeroext i32 @sext_ashr_zext_i8(i8 %a) nounwind {
1717 ; RV64I-LABEL: sext_ashr_zext_i8:
1719 ; RV64I-NEXT: slli a0, a0, 56
1720 ; RV64I-NEXT: srai a0, a0, 31
1721 ; RV64I-NEXT: srli a0, a0, 32
1724 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i8:
1725 ; RV64ZBANOZBB: # %bb.0:
1726 ; RV64ZBANOZBB-NEXT: slli a0, a0, 56
1727 ; RV64ZBANOZBB-NEXT: srai a0, a0, 31
1728 ; RV64ZBANOZBB-NEXT: srli a0, a0, 32
1729 ; RV64ZBANOZBB-NEXT: ret
1731 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i8:
1732 ; RV64ZBAZBB: # %bb.0:
1733 ; RV64ZBAZBB-NEXT: sext.b a0, a0
1734 ; RV64ZBAZBB-NEXT: slli a0, a0, 23
1735 ; RV64ZBAZBB-NEXT: srli a0, a0, 32
1736 ; RV64ZBAZBB-NEXT: ret
1737 %ext = sext i8 %a to i32
1738 %1 = ashr i32 %ext, 9
1742 define i64 @sh6_sh3_add1(i64 noundef %x, i64 noundef %y, i64 noundef %z) {
1743 ; RV64I-LABEL: sh6_sh3_add1:
1744 ; RV64I: # %bb.0: # %entry
1745 ; RV64I-NEXT: slli a2, a2, 3
1746 ; RV64I-NEXT: slli a1, a1, 6
1747 ; RV64I-NEXT: add a1, a1, a2
1748 ; RV64I-NEXT: add a0, a1, a0
1751 ; RV64ZBA-LABEL: sh6_sh3_add1:
1752 ; RV64ZBA: # %bb.0: # %entry
1753 ; RV64ZBA-NEXT: sh3add a1, a1, a2
1754 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1757 %shl = shl i64 %z, 3
1758 %shl1 = shl i64 %y, 6
1759 %add = add nsw i64 %shl1, %shl
1760 %add2 = add nsw i64 %add, %x
1764 define i64 @sh6_sh3_add2(i64 noundef %x, i64 noundef %y, i64 noundef %z) {
1765 ; RV64I-LABEL: sh6_sh3_add2:
1766 ; RV64I: # %bb.0: # %entry
1767 ; RV64I-NEXT: slli a2, a2, 3
1768 ; RV64I-NEXT: slli a1, a1, 6
1769 ; RV64I-NEXT: add a0, a1, a0
1770 ; RV64I-NEXT: add a0, a0, a2
1773 ; RV64ZBA-LABEL: sh6_sh3_add2:
1774 ; RV64ZBA: # %bb.0: # %entry
1775 ; RV64ZBA-NEXT: sh3add a1, a1, a2
1776 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1779 %shl = shl i64 %z, 3
1780 %shl1 = shl i64 %y, 6
1781 %add = add nsw i64 %shl1, %x
1782 %add2 = add nsw i64 %add, %shl
1786 define i64 @sh6_sh3_add3(i64 noundef %x, i64 noundef %y, i64 noundef %z) {
1787 ; RV64I-LABEL: sh6_sh3_add3:
1788 ; RV64I: # %bb.0: # %entry
1789 ; RV64I-NEXT: slli a2, a2, 3
1790 ; RV64I-NEXT: slli a1, a1, 6
1791 ; RV64I-NEXT: add a1, a1, a2
1792 ; RV64I-NEXT: add a0, a0, a1
1795 ; RV64ZBA-LABEL: sh6_sh3_add3:
1796 ; RV64ZBA: # %bb.0: # %entry
1797 ; RV64ZBA-NEXT: sh3add a1, a1, a2
1798 ; RV64ZBA-NEXT: sh3add a0, a1, a0
1801 %shl = shl i64 %z, 3
1802 %shl1 = shl i64 %y, 6
1803 %add = add nsw i64 %shl1, %shl
1804 %add2 = add nsw i64 %x, %add
1808 define i64 @sh6_sh3_add4(i64 noundef %x, i64 noundef %y, i64 noundef %z) {
1809 ; RV64I-LABEL: sh6_sh3_add4:
1810 ; RV64I: # %bb.0: # %entry
1811 ; RV64I-NEXT: slli a2, a2, 3
1812 ; RV64I-NEXT: slli a1, a1, 6
1813 ; RV64I-NEXT: add a0, a0, a2
1814 ; RV64I-NEXT: add a0, a0, a1
1817 ; RV64ZBA-LABEL: sh6_sh3_add4:
1818 ; RV64ZBA: # %bb.0: # %entry
1819 ; RV64ZBA-NEXT: slli a1, a1, 6
1820 ; RV64ZBA-NEXT: sh3add a0, a2, a0
1821 ; RV64ZBA-NEXT: add a0, a0, a1
1824 %shl = shl i64 %z, 3
1825 %shl1 = shl i64 %y, 6
1826 %add = add nsw i64 %x, %shl
1827 %add2 = add nsw i64 %add, %shl1
1831 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1832 define zeroext i32 @sext_ashr_zext_i16(i16 %a) nounwind {
1833 ; RV64I-LABEL: sext_ashr_zext_i16:
1835 ; RV64I-NEXT: slli a0, a0, 48
1836 ; RV64I-NEXT: srai a0, a0, 25
1837 ; RV64I-NEXT: srli a0, a0, 32
1840 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i16:
1841 ; RV64ZBANOZBB: # %bb.0:
1842 ; RV64ZBANOZBB-NEXT: slli a0, a0, 48
1843 ; RV64ZBANOZBB-NEXT: srai a0, a0, 25
1844 ; RV64ZBANOZBB-NEXT: srli a0, a0, 32
1845 ; RV64ZBANOZBB-NEXT: ret
1847 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i16:
1848 ; RV64ZBAZBB: # %bb.0:
1849 ; RV64ZBAZBB-NEXT: sext.h a0, a0
1850 ; RV64ZBAZBB-NEXT: slli a0, a0, 23
1851 ; RV64ZBAZBB-NEXT: srli a0, a0, 32
1852 ; RV64ZBAZBB-NEXT: ret
1853 %ext = sext i16 %a to i32
1854 %1 = ashr i32 %ext, 9
1858 ; This the IR you get from InstCombine if take the difference of 2 pointers and
1859 ; cast is to unsigned before using as an index.
1860 define signext i16 @sh1adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1861 ; RV64I-LABEL: sh1adduw_ptrdiff:
1863 ; RV64I-NEXT: li a2, 1
1864 ; RV64I-NEXT: slli a2, a2, 33
1865 ; RV64I-NEXT: addi a2, a2, -2
1866 ; RV64I-NEXT: and a0, a0, a2
1867 ; RV64I-NEXT: add a0, a1, a0
1868 ; RV64I-NEXT: lh a0, 0(a0)
1871 ; RV64ZBA-LABEL: sh1adduw_ptrdiff:
1873 ; RV64ZBA-NEXT: srli a0, a0, 1
1874 ; RV64ZBA-NEXT: sh1add.uw a0, a0, a1
1875 ; RV64ZBA-NEXT: lh a0, 0(a0)
1877 %ptrdiff = lshr exact i64 %diff, 1
1878 %cast = and i64 %ptrdiff, 4294967295
1879 %ptr = getelementptr inbounds i16, ptr %baseptr, i64 %cast
1880 %res = load i16, ptr %ptr
1884 define signext i32 @sh2adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1885 ; RV64I-LABEL: sh2adduw_ptrdiff:
1887 ; RV64I-NEXT: li a2, 1
1888 ; RV64I-NEXT: slli a2, a2, 34
1889 ; RV64I-NEXT: addi a2, a2, -4
1890 ; RV64I-NEXT: and a0, a0, a2
1891 ; RV64I-NEXT: add a0, a1, a0
1892 ; RV64I-NEXT: lw a0, 0(a0)
1895 ; RV64ZBA-LABEL: sh2adduw_ptrdiff:
1897 ; RV64ZBA-NEXT: srli a0, a0, 2
1898 ; RV64ZBA-NEXT: sh2add.uw a0, a0, a1
1899 ; RV64ZBA-NEXT: lw a0, 0(a0)
1901 %ptrdiff = lshr exact i64 %diff, 2
1902 %cast = and i64 %ptrdiff, 4294967295
1903 %ptr = getelementptr inbounds i32, ptr %baseptr, i64 %cast
1904 %res = load i32, ptr %ptr
1908 define i64 @sh3adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1909 ; RV64I-LABEL: sh3adduw_ptrdiff:
1911 ; RV64I-NEXT: li a2, 1
1912 ; RV64I-NEXT: slli a2, a2, 35
1913 ; RV64I-NEXT: addi a2, a2, -8
1914 ; RV64I-NEXT: and a0, a0, a2
1915 ; RV64I-NEXT: add a0, a1, a0
1916 ; RV64I-NEXT: ld a0, 0(a0)
1919 ; RV64ZBA-LABEL: sh3adduw_ptrdiff:
1921 ; RV64ZBA-NEXT: srli a0, a0, 3
1922 ; RV64ZBA-NEXT: sh3add.uw a0, a0, a1
1923 ; RV64ZBA-NEXT: ld a0, 0(a0)
1925 %ptrdiff = lshr exact i64 %diff, 3
1926 %cast = and i64 %ptrdiff, 4294967295
1927 %ptr = getelementptr inbounds i64, ptr %baseptr, i64 %cast
1928 %res = load i64, ptr %ptr
1932 define signext i16 @srliw_1_sh1add(ptr %0, i32 signext %1) {
1933 ; RV64I-LABEL: srliw_1_sh1add:
1935 ; RV64I-NEXT: srliw a1, a1, 1
1936 ; RV64I-NEXT: slli a1, a1, 1
1937 ; RV64I-NEXT: add a0, a0, a1
1938 ; RV64I-NEXT: lh a0, 0(a0)
1941 ; RV64ZBA-LABEL: srliw_1_sh1add:
1943 ; RV64ZBA-NEXT: srliw a1, a1, 1
1944 ; RV64ZBA-NEXT: sh1add a0, a1, a0
1945 ; RV64ZBA-NEXT: lh a0, 0(a0)
1948 %4 = zext i32 %3 to i64
1949 %5 = getelementptr inbounds i16, ptr %0, i64 %4
1950 %6 = load i16, ptr %5, align 2
1954 define i128 @slliuw_ptrdiff(i64 %diff, ptr %baseptr) {
1955 ; RV64I-LABEL: slliuw_ptrdiff:
1957 ; RV64I-NEXT: li a2, 1
1958 ; RV64I-NEXT: slli a2, a2, 36
1959 ; RV64I-NEXT: addi a2, a2, -16
1960 ; RV64I-NEXT: and a0, a0, a2
1961 ; RV64I-NEXT: add a1, a1, a0
1962 ; RV64I-NEXT: ld a0, 0(a1)
1963 ; RV64I-NEXT: ld a1, 8(a1)
1966 ; RV64ZBA-LABEL: slliuw_ptrdiff:
1968 ; RV64ZBA-NEXT: srli a0, a0, 4
1969 ; RV64ZBA-NEXT: slli.uw a0, a0, 4
1970 ; RV64ZBA-NEXT: add a1, a1, a0
1971 ; RV64ZBA-NEXT: ld a0, 0(a1)
1972 ; RV64ZBA-NEXT: ld a1, 8(a1)
1974 %ptrdiff = lshr exact i64 %diff, 4
1975 %cast = and i64 %ptrdiff, 4294967295
1976 %ptr = getelementptr inbounds i128, ptr %baseptr, i64 %cast
1977 %res = load i128, ptr %ptr
1981 define signext i32 @srliw_2_sh2add(ptr %0, i32 signext %1) {
1982 ; RV64I-LABEL: srliw_2_sh2add:
1984 ; RV64I-NEXT: srliw a1, a1, 2
1985 ; RV64I-NEXT: slli a1, a1, 2
1986 ; RV64I-NEXT: add a0, a0, a1
1987 ; RV64I-NEXT: lw a0, 0(a0)
1990 ; RV64ZBA-LABEL: srliw_2_sh2add:
1992 ; RV64ZBA-NEXT: srliw a1, a1, 2
1993 ; RV64ZBA-NEXT: sh2add a0, a1, a0
1994 ; RV64ZBA-NEXT: lw a0, 0(a0)
1997 %4 = zext i32 %3 to i64
1998 %5 = getelementptr inbounds i32, ptr %0, i64 %4
1999 %6 = load i32, ptr %5, align 4
2003 define i64 @srliw_3_sh3add(ptr %0, i32 signext %1) {
2004 ; RV64I-LABEL: srliw_3_sh3add:
2006 ; RV64I-NEXT: srliw a1, a1, 3
2007 ; RV64I-NEXT: slli a1, a1, 3
2008 ; RV64I-NEXT: add a0, a0, a1
2009 ; RV64I-NEXT: ld a0, 0(a0)
2012 ; RV64ZBA-LABEL: srliw_3_sh3add:
2014 ; RV64ZBA-NEXT: srliw a1, a1, 3
2015 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2016 ; RV64ZBA-NEXT: ld a0, 0(a0)
2019 %4 = zext i32 %3 to i64
2020 %5 = getelementptr inbounds i64, ptr %0, i64 %4
2021 %6 = load i64, ptr %5, align 8
2025 define signext i32 @srliw_1_sh2add(ptr %0, i32 signext %1) {
2026 ; RV64I-LABEL: srliw_1_sh2add:
2028 ; RV64I-NEXT: srliw a1, a1, 1
2029 ; RV64I-NEXT: slli a1, a1, 2
2030 ; RV64I-NEXT: add a0, a0, a1
2031 ; RV64I-NEXT: lw a0, 0(a0)
2034 ; RV64ZBA-LABEL: srliw_1_sh2add:
2036 ; RV64ZBA-NEXT: srliw a1, a1, 1
2037 ; RV64ZBA-NEXT: sh2add a0, a1, a0
2038 ; RV64ZBA-NEXT: lw a0, 0(a0)
2041 %4 = zext i32 %3 to i64
2042 %5 = getelementptr inbounds i32, ptr %0, i64 %4
2043 %6 = load i32, ptr %5, align 4
2047 define i64 @srliw_1_sh3add(ptr %0, i32 signext %1) {
2048 ; RV64I-LABEL: srliw_1_sh3add:
2050 ; RV64I-NEXT: srliw a1, a1, 1
2051 ; RV64I-NEXT: slli a1, a1, 3
2052 ; RV64I-NEXT: add a0, a0, a1
2053 ; RV64I-NEXT: ld a0, 0(a0)
2056 ; RV64ZBA-LABEL: srliw_1_sh3add:
2058 ; RV64ZBA-NEXT: srliw a1, a1, 1
2059 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2060 ; RV64ZBA-NEXT: ld a0, 0(a0)
2063 %4 = zext i32 %3 to i64
2064 %5 = getelementptr inbounds i64, ptr %0, i64 %4
2065 %6 = load i64, ptr %5, align 8
2069 define i64 @srliw_2_sh3add(ptr %0, i32 signext %1) {
2070 ; RV64I-LABEL: srliw_2_sh3add:
2072 ; RV64I-NEXT: srliw a1, a1, 2
2073 ; RV64I-NEXT: slli a1, a1, 3
2074 ; RV64I-NEXT: add a0, a0, a1
2075 ; RV64I-NEXT: ld a0, 0(a0)
2078 ; RV64ZBA-LABEL: srliw_2_sh3add:
2080 ; RV64ZBA-NEXT: srliw a1, a1, 2
2081 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2082 ; RV64ZBA-NEXT: ld a0, 0(a0)
2085 %4 = zext i32 %3 to i64
2086 %5 = getelementptr inbounds i64, ptr %0, i64 %4
2087 %6 = load i64, ptr %5, align 8
2091 define signext i16 @srliw_2_sh1add(ptr %0, i32 signext %1) {
2092 ; RV64I-LABEL: srliw_2_sh1add:
2094 ; RV64I-NEXT: srliw a1, a1, 2
2095 ; RV64I-NEXT: slli a1, a1, 1
2096 ; RV64I-NEXT: add a0, a0, a1
2097 ; RV64I-NEXT: lh a0, 0(a0)
2100 ; RV64ZBA-LABEL: srliw_2_sh1add:
2102 ; RV64ZBA-NEXT: srliw a1, a1, 2
2103 ; RV64ZBA-NEXT: sh1add a0, a1, a0
2104 ; RV64ZBA-NEXT: lh a0, 0(a0)
2107 %4 = zext i32 %3 to i64
2108 %5 = getelementptr inbounds i16, ptr %0, i64 %4
2109 %6 = load i16, ptr %5, align 2
2114 define signext i32 @srliw_3_sh2add(ptr %0, i32 signext %1) {
2115 ; RV64I-LABEL: srliw_3_sh2add:
2117 ; RV64I-NEXT: srliw a1, a1, 3
2118 ; RV64I-NEXT: slli a1, a1, 2
2119 ; RV64I-NEXT: add a0, a0, a1
2120 ; RV64I-NEXT: lw a0, 0(a0)
2123 ; RV64ZBA-LABEL: srliw_3_sh2add:
2125 ; RV64ZBA-NEXT: srliw a1, a1, 3
2126 ; RV64ZBA-NEXT: sh2add a0, a1, a0
2127 ; RV64ZBA-NEXT: lw a0, 0(a0)
2130 %4 = zext i32 %3 to i64
2131 %5 = getelementptr inbounds i32, ptr %0, i64 %4
2132 %6 = load i32, ptr %5, align 4
2136 define i64 @srliw_4_sh3add(ptr %0, i32 signext %1) {
2137 ; RV64I-LABEL: srliw_4_sh3add:
2139 ; RV64I-NEXT: srliw a1, a1, 4
2140 ; RV64I-NEXT: slli a1, a1, 3
2141 ; RV64I-NEXT: add a0, a0, a1
2142 ; RV64I-NEXT: ld a0, 0(a0)
2145 ; RV64ZBA-LABEL: srliw_4_sh3add:
2147 ; RV64ZBA-NEXT: srliw a1, a1, 4
2148 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2149 ; RV64ZBA-NEXT: ld a0, 0(a0)
2152 %4 = zext i32 %3 to i64
2153 %5 = getelementptr inbounds i64, ptr %0, i64 %4
2154 %6 = load i64, ptr %5, align 8
2158 define signext i32 @srli_1_sh2add(ptr %0, i64 %1) {
2159 ; RV64I-LABEL: srli_1_sh2add:
2161 ; RV64I-NEXT: slli a1, a1, 1
2162 ; RV64I-NEXT: andi a1, a1, -4
2163 ; RV64I-NEXT: add a0, a0, a1
2164 ; RV64I-NEXT: lw a0, 0(a0)
2167 ; RV64ZBA-LABEL: srli_1_sh2add:
2169 ; RV64ZBA-NEXT: srli a1, a1, 1
2170 ; RV64ZBA-NEXT: sh2add a0, a1, a0
2171 ; RV64ZBA-NEXT: lw a0, 0(a0)
2174 %4 = getelementptr inbounds i32, ptr %0, i64 %3
2175 %5 = load i32, ptr %4, align 4
2179 define i64 @srli_2_sh3add(ptr %0, i64 %1) {
2180 ; RV64I-LABEL: srli_2_sh3add:
2182 ; RV64I-NEXT: slli a1, a1, 1
2183 ; RV64I-NEXT: andi a1, a1, -8
2184 ; RV64I-NEXT: add a0, a0, a1
2185 ; RV64I-NEXT: ld a0, 0(a0)
2188 ; RV64ZBA-LABEL: srli_2_sh3add:
2190 ; RV64ZBA-NEXT: srli a1, a1, 2
2191 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2192 ; RV64ZBA-NEXT: ld a0, 0(a0)
2195 %4 = getelementptr inbounds i64, ptr %0, i64 %3
2196 %5 = load i64, ptr %4, align 8
2200 define signext i16 @srli_2_sh1add(ptr %0, i64 %1) {
2201 ; RV64I-LABEL: srli_2_sh1add:
2203 ; RV64I-NEXT: srli a1, a1, 1
2204 ; RV64I-NEXT: andi a1, a1, -2
2205 ; RV64I-NEXT: add a0, a0, a1
2206 ; RV64I-NEXT: lh a0, 0(a0)
2209 ; RV64ZBA-LABEL: srli_2_sh1add:
2211 ; RV64ZBA-NEXT: srli a1, a1, 2
2212 ; RV64ZBA-NEXT: sh1add a0, a1, a0
2213 ; RV64ZBA-NEXT: lh a0, 0(a0)
2216 %4 = getelementptr inbounds i16, ptr %0, i64 %3
2217 %5 = load i16, ptr %4, align 2
2221 define signext i32 @srli_3_sh2add(ptr %0, i64 %1) {
2222 ; RV64I-LABEL: srli_3_sh2add:
2224 ; RV64I-NEXT: srli a1, a1, 1
2225 ; RV64I-NEXT: andi a1, a1, -4
2226 ; RV64I-NEXT: add a0, a0, a1
2227 ; RV64I-NEXT: lw a0, 0(a0)
2230 ; RV64ZBA-LABEL: srli_3_sh2add:
2232 ; RV64ZBA-NEXT: srli a1, a1, 3
2233 ; RV64ZBA-NEXT: sh2add a0, a1, a0
2234 ; RV64ZBA-NEXT: lw a0, 0(a0)
2237 %4 = getelementptr inbounds i32, ptr %0, i64 %3
2238 %5 = load i32, ptr %4, align 4
2242 define i64 @srli_4_sh3add(ptr %0, i64 %1) {
2243 ; RV64I-LABEL: srli_4_sh3add:
2245 ; RV64I-NEXT: srli a1, a1, 1
2246 ; RV64I-NEXT: andi a1, a1, -8
2247 ; RV64I-NEXT: add a0, a0, a1
2248 ; RV64I-NEXT: ld a0, 0(a0)
2251 ; RV64ZBA-LABEL: srli_4_sh3add:
2253 ; RV64ZBA-NEXT: srli a1, a1, 4
2254 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2255 ; RV64ZBA-NEXT: ld a0, 0(a0)
2258 %4 = getelementptr inbounds i64, ptr %0, i64 %3
2259 %5 = load i64, ptr %4, align 8
2263 define signext i16 @shl_2_sh1adduw(ptr %0, i32 signext %1) {
2264 ; RV64I-LABEL: shl_2_sh1adduw:
2266 ; RV64I-NEXT: slli a1, a1, 34
2267 ; RV64I-NEXT: srli a1, a1, 31
2268 ; RV64I-NEXT: add a0, a0, a1
2269 ; RV64I-NEXT: lh a0, 0(a0)
2272 ; RV64ZBA-LABEL: shl_2_sh1adduw:
2274 ; RV64ZBA-NEXT: slli a1, a1, 2
2275 ; RV64ZBA-NEXT: sh1add.uw a0, a1, a0
2276 ; RV64ZBA-NEXT: lh a0, 0(a0)
2279 %4 = zext i32 %3 to i64
2280 %5 = getelementptr inbounds i16, ptr %0, i64 %4
2281 %6 = load i16, ptr %5, align 2
2285 define signext i32 @shl_16_sh2adduw(ptr %0, i32 signext %1) {
2286 ; RV64I-LABEL: shl_16_sh2adduw:
2288 ; RV64I-NEXT: slli a1, a1, 48
2289 ; RV64I-NEXT: srli a1, a1, 30
2290 ; RV64I-NEXT: add a0, a0, a1
2291 ; RV64I-NEXT: lw a0, 0(a0)
2294 ; RV64ZBA-LABEL: shl_16_sh2adduw:
2296 ; RV64ZBA-NEXT: slli a1, a1, 16
2297 ; RV64ZBA-NEXT: sh2add.uw a0, a1, a0
2298 ; RV64ZBA-NEXT: lw a0, 0(a0)
2301 %4 = zext i32 %3 to i64
2302 %5 = getelementptr inbounds i32, ptr %0, i64 %4
2303 %6 = load i32, ptr %5, align 4
2307 define i64 @shl_31_sh3adduw(ptr %0, i32 signext %1) {
2308 ; RV64I-LABEL: shl_31_sh3adduw:
2310 ; RV64I-NEXT: slli a1, a1, 63
2311 ; RV64I-NEXT: srli a1, a1, 29
2312 ; RV64I-NEXT: add a0, a0, a1
2313 ; RV64I-NEXT: ld a0, 0(a0)
2316 ; RV64ZBA-LABEL: shl_31_sh3adduw:
2318 ; RV64ZBA-NEXT: slli a1, a1, 31
2319 ; RV64ZBA-NEXT: sh3add.uw a0, a1, a0
2320 ; RV64ZBA-NEXT: ld a0, 0(a0)
2323 %4 = zext i32 %3 to i64
2324 %5 = getelementptr inbounds i64, ptr %0, i64 %4
2325 %6 = load i64, ptr %5, align 8
2329 define i64 @pack_i64(i64 %a, i64 %b) nounwind {
2330 ; RV64I-LABEL: pack_i64:
2332 ; RV64I-NEXT: slli a0, a0, 32
2333 ; RV64I-NEXT: srli a0, a0, 32
2334 ; RV64I-NEXT: slli a1, a1, 32
2335 ; RV64I-NEXT: or a0, a1, a0
2338 ; RV64ZBA-LABEL: pack_i64:
2340 ; RV64ZBA-NEXT: slli a1, a1, 32
2341 ; RV64ZBA-NEXT: add.uw a0, a0, a1
2343 %shl = and i64 %a, 4294967295
2344 %shl1 = shl i64 %b, 32
2345 %or = or i64 %shl1, %shl
2349 define i64 @pack_i64_2(i32 signext %a, i32 signext %b) nounwind {
2350 ; RV64I-LABEL: pack_i64_2:
2352 ; RV64I-NEXT: slli a0, a0, 32
2353 ; RV64I-NEXT: srli a0, a0, 32
2354 ; RV64I-NEXT: slli a1, a1, 32
2355 ; RV64I-NEXT: or a0, a1, a0
2358 ; RV64ZBA-LABEL: pack_i64_2:
2360 ; RV64ZBA-NEXT: slli a1, a1, 32
2361 ; RV64ZBA-NEXT: add.uw a0, a0, a1
2363 %zexta = zext i32 %a to i64
2364 %zextb = zext i32 %b to i64
2365 %shl1 = shl i64 %zextb, 32
2366 %or = or i64 %shl1, %zexta
2370 define i64 @pack_i64_disjoint(i64 %a, i64 %b) nounwind {
2371 ; RV64I-LABEL: pack_i64_disjoint:
2373 ; RV64I-NEXT: slli a0, a0, 32
2374 ; RV64I-NEXT: srli a0, a0, 32
2375 ; RV64I-NEXT: or a0, a1, a0
2378 ; RV64ZBA-LABEL: pack_i64_disjoint:
2380 ; RV64ZBA-NEXT: add.uw a0, a0, a1
2382 %shl = and i64 %a, 4294967295
2383 %or = or disjoint i64 %b, %shl
2387 define i64 @pack_i64_disjoint_2(i32 signext %a, i64 %b) nounwind {
2388 ; RV64I-LABEL: pack_i64_disjoint_2:
2390 ; RV64I-NEXT: slli a0, a0, 32
2391 ; RV64I-NEXT: srli a0, a0, 32
2392 ; RV64I-NEXT: or a0, a1, a0
2395 ; RV64ZBA-LABEL: pack_i64_disjoint_2:
2397 ; RV64ZBA-NEXT: add.uw a0, a0, a1
2399 %zexta = zext i32 %a to i64
2400 %or = or disjoint i64 %b, %zexta
2404 define i8 @array_index_sh1_sh0(ptr %p, i64 %idx1, i64 %idx2) {
2405 ; RV64I-LABEL: array_index_sh1_sh0:
2407 ; RV64I-NEXT: slli a1, a1, 1
2408 ; RV64I-NEXT: add a0, a0, a2
2409 ; RV64I-NEXT: add a0, a0, a1
2410 ; RV64I-NEXT: lbu a0, 0(a0)
2413 ; RV64ZBA-LABEL: array_index_sh1_sh0:
2415 ; RV64ZBA-NEXT: sh1add a0, a1, a0
2416 ; RV64ZBA-NEXT: add a0, a0, a2
2417 ; RV64ZBA-NEXT: lbu a0, 0(a0)
2419 %a = getelementptr inbounds [2 x i8], ptr %p, i64 %idx1, i64 %idx2
2420 %b = load i8, ptr %a, align 1
2424 define i16 @array_index_sh1_sh1(ptr %p, i64 %idx1, i64 %idx2) {
2425 ; RV64I-LABEL: array_index_sh1_sh1:
2427 ; RV64I-NEXT: slli a1, a1, 2
2428 ; RV64I-NEXT: add a0, a0, a1
2429 ; RV64I-NEXT: slli a2, a2, 1
2430 ; RV64I-NEXT: add a0, a0, a2
2431 ; RV64I-NEXT: lh a0, 0(a0)
2434 ; RV64ZBA-LABEL: array_index_sh1_sh1:
2436 ; RV64ZBA-NEXT: sh2add a0, a1, a0
2437 ; RV64ZBA-NEXT: sh1add a0, a2, a0
2438 ; RV64ZBA-NEXT: lh a0, 0(a0)
2440 %a = getelementptr inbounds [2 x i16], ptr %p, i64 %idx1, i64 %idx2
2441 %b = load i16, ptr %a, align 2
2445 define i32 @array_index_sh1_sh2(ptr %p, i64 %idx1, i64 %idx2) {
2446 ; RV64I-LABEL: array_index_sh1_sh2:
2448 ; RV64I-NEXT: slli a1, a1, 3
2449 ; RV64I-NEXT: add a0, a0, a1
2450 ; RV64I-NEXT: slli a2, a2, 2
2451 ; RV64I-NEXT: add a0, a0, a2
2452 ; RV64I-NEXT: lw a0, 0(a0)
2455 ; RV64ZBA-LABEL: array_index_sh1_sh2:
2457 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2458 ; RV64ZBA-NEXT: sh2add a0, a2, a0
2459 ; RV64ZBA-NEXT: lw a0, 0(a0)
2461 %a = getelementptr inbounds [2 x i32], ptr %p, i64 %idx1, i64 %idx2
2462 %b = load i32, ptr %a, align 4
2466 define i64 @array_index_sh1_sh3(ptr %p, i64 %idx1, i64 %idx2) {
2467 ; RV64I-LABEL: array_index_sh1_sh3:
2469 ; RV64I-NEXT: slli a1, a1, 4
2470 ; RV64I-NEXT: add a0, a0, a1
2471 ; RV64I-NEXT: slli a2, a2, 3
2472 ; RV64I-NEXT: add a0, a0, a2
2473 ; RV64I-NEXT: ld a0, 0(a0)
2476 ; RV64ZBA-LABEL: array_index_sh1_sh3:
2478 ; RV64ZBA-NEXT: sh1add a1, a1, a2
2479 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2480 ; RV64ZBA-NEXT: ld a0, 0(a0)
2482 %a = getelementptr inbounds [2 x i64], ptr %p, i64 %idx1, i64 %idx2
2483 %b = load i64, ptr %a, align 8
2487 define i8 @array_index_sh2_sh0(ptr %p, i64 %idx1, i64 %idx2) {
2488 ; RV64I-LABEL: array_index_sh2_sh0:
2490 ; RV64I-NEXT: slli a1, a1, 2
2491 ; RV64I-NEXT: add a0, a0, a2
2492 ; RV64I-NEXT: add a0, a0, a1
2493 ; RV64I-NEXT: lbu a0, 0(a0)
2496 ; RV64ZBA-LABEL: array_index_sh2_sh0:
2498 ; RV64ZBA-NEXT: sh2add a0, a1, a0
2499 ; RV64ZBA-NEXT: add a0, a0, a2
2500 ; RV64ZBA-NEXT: lbu a0, 0(a0)
2502 %a = getelementptr inbounds [4 x i8], ptr %p, i64 %idx1, i64 %idx2
2503 %b = load i8, ptr %a, align 1
2507 define i16 @array_index_sh2_sh1(ptr %p, i64 %idx1, i64 %idx2) {
2508 ; RV64I-LABEL: array_index_sh2_sh1:
2510 ; RV64I-NEXT: slli a1, a1, 3
2511 ; RV64I-NEXT: add a0, a0, a1
2512 ; RV64I-NEXT: slli a2, a2, 1
2513 ; RV64I-NEXT: add a0, a0, a2
2514 ; RV64I-NEXT: lh a0, 0(a0)
2517 ; RV64ZBA-LABEL: array_index_sh2_sh1:
2519 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2520 ; RV64ZBA-NEXT: sh1add a0, a2, a0
2521 ; RV64ZBA-NEXT: lh a0, 0(a0)
2523 %a = getelementptr inbounds [4 x i16], ptr %p, i64 %idx1, i64 %idx2
2524 %b = load i16, ptr %a, align 2
2528 define i32 @array_index_sh2_sh2(ptr %p, i64 %idx1, i64 %idx2) {
2529 ; RV64I-LABEL: array_index_sh2_sh2:
2531 ; RV64I-NEXT: slli a1, a1, 4
2532 ; RV64I-NEXT: add a0, a0, a1
2533 ; RV64I-NEXT: slli a2, a2, 2
2534 ; RV64I-NEXT: add a0, a0, a2
2535 ; RV64I-NEXT: lw a0, 0(a0)
2538 ; RV64ZBA-LABEL: array_index_sh2_sh2:
2540 ; RV64ZBA-NEXT: sh2add a1, a1, a2
2541 ; RV64ZBA-NEXT: sh2add a0, a1, a0
2542 ; RV64ZBA-NEXT: lw a0, 0(a0)
2544 %a = getelementptr inbounds [4 x i32], ptr %p, i64 %idx1, i64 %idx2
2545 %b = load i32, ptr %a, align 4
2549 define i64 @array_index_sh2_sh3(ptr %p, i64 %idx1, i64 %idx2) {
2550 ; RV64I-LABEL: array_index_sh2_sh3:
2552 ; RV64I-NEXT: slli a1, a1, 5
2553 ; RV64I-NEXT: add a0, a0, a1
2554 ; RV64I-NEXT: slli a2, a2, 3
2555 ; RV64I-NEXT: add a0, a0, a2
2556 ; RV64I-NEXT: ld a0, 0(a0)
2559 ; RV64ZBA-LABEL: array_index_sh2_sh3:
2561 ; RV64ZBA-NEXT: sh2add a1, a1, a2
2562 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2563 ; RV64ZBA-NEXT: ld a0, 0(a0)
2565 %a = getelementptr inbounds [4 x i64], ptr %p, i64 %idx1, i64 %idx2
2566 %b = load i64, ptr %a, align 8
2570 define i8 @array_index_sh3_sh0(ptr %p, i64 %idx1, i64 %idx2) {
2571 ; RV64I-LABEL: array_index_sh3_sh0:
2573 ; RV64I-NEXT: slli a1, a1, 3
2574 ; RV64I-NEXT: add a0, a0, a2
2575 ; RV64I-NEXT: add a0, a0, a1
2576 ; RV64I-NEXT: lbu a0, 0(a0)
2579 ; RV64ZBA-LABEL: array_index_sh3_sh0:
2581 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2582 ; RV64ZBA-NEXT: add a0, a0, a2
2583 ; RV64ZBA-NEXT: lbu a0, 0(a0)
2585 %a = getelementptr inbounds [8 x i8], ptr %p, i64 %idx1, i64 %idx2
2586 %b = load i8, ptr %a, align 1
2590 define i16 @array_index_sh3_sh1(ptr %p, i64 %idx1, i64 %idx2) {
2591 ; RV64I-LABEL: array_index_sh3_sh1:
2593 ; RV64I-NEXT: slli a1, a1, 4
2594 ; RV64I-NEXT: add a0, a0, a1
2595 ; RV64I-NEXT: slli a2, a2, 1
2596 ; RV64I-NEXT: add a0, a0, a2
2597 ; RV64I-NEXT: lh a0, 0(a0)
2600 ; RV64ZBA-LABEL: array_index_sh3_sh1:
2602 ; RV64ZBA-NEXT: sh3add a1, a1, a2
2603 ; RV64ZBA-NEXT: sh1add a0, a1, a0
2604 ; RV64ZBA-NEXT: lh a0, 0(a0)
2606 %a = getelementptr inbounds [8 x i16], ptr %p, i64 %idx1, i64 %idx2
2607 %b = load i16, ptr %a, align 2
2611 define i32 @array_index_sh3_sh2(ptr %p, i64 %idx1, i64 %idx2) {
2612 ; RV64I-LABEL: array_index_sh3_sh2:
2614 ; RV64I-NEXT: slli a1, a1, 5
2615 ; RV64I-NEXT: add a0, a0, a1
2616 ; RV64I-NEXT: slli a2, a2, 2
2617 ; RV64I-NEXT: add a0, a0, a2
2618 ; RV64I-NEXT: lw a0, 0(a0)
2621 ; RV64ZBA-LABEL: array_index_sh3_sh2:
2623 ; RV64ZBA-NEXT: sh3add a1, a1, a2
2624 ; RV64ZBA-NEXT: sh2add a0, a1, a0
2625 ; RV64ZBA-NEXT: lw a0, 0(a0)
2627 %a = getelementptr inbounds [8 x i32], ptr %p, i64 %idx1, i64 %idx2
2628 %b = load i32, ptr %a, align 4
2632 define i64 @array_index_sh3_sh3(ptr %p, i64 %idx1, i64 %idx2) {
2633 ; RV64I-LABEL: array_index_sh3_sh3:
2635 ; RV64I-NEXT: slli a1, a1, 6
2636 ; RV64I-NEXT: add a0, a0, a1
2637 ; RV64I-NEXT: slli a2, a2, 3
2638 ; RV64I-NEXT: add a0, a0, a2
2639 ; RV64I-NEXT: ld a0, 0(a0)
2642 ; RV64ZBA-LABEL: array_index_sh3_sh3:
2644 ; RV64ZBA-NEXT: sh3add a1, a1, a2
2645 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2646 ; RV64ZBA-NEXT: ld a0, 0(a0)
2648 %a = getelementptr inbounds [8 x i64], ptr %p, i64 %idx1, i64 %idx2
2649 %b = load i64, ptr %a, align 8
2653 ; Similar to above, but with a lshr on one of the indices. This requires
2654 ; special handling during isel to form a shift pair.
2655 define i64 @array_index_lshr_sh3_sh3(ptr %p, i64 %idx1, i64 %idx2) {
2656 ; RV64I-LABEL: array_index_lshr_sh3_sh3:
2658 ; RV64I-NEXT: srli a1, a1, 58
2659 ; RV64I-NEXT: slli a2, a2, 3
2660 ; RV64I-NEXT: slli a1, a1, 6
2661 ; RV64I-NEXT: add a0, a0, a2
2662 ; RV64I-NEXT: add a0, a0, a1
2663 ; RV64I-NEXT: ld a0, 0(a0)
2666 ; RV64ZBA-LABEL: array_index_lshr_sh3_sh3:
2668 ; RV64ZBA-NEXT: srli a1, a1, 58
2669 ; RV64ZBA-NEXT: sh3add a1, a1, a2
2670 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2671 ; RV64ZBA-NEXT: ld a0, 0(a0)
2673 %shr = lshr i64 %idx1, 58
2674 %a = getelementptr inbounds [8 x i64], ptr %p, i64 %shr, i64 %idx2
2675 %b = load i64, ptr %a, align 8
2679 define i8 @array_index_sh4_sh0(ptr %p, i64 %idx1, i64 %idx2) {
2680 ; CHECK-LABEL: array_index_sh4_sh0:
2682 ; CHECK-NEXT: slli a1, a1, 4
2683 ; CHECK-NEXT: add a0, a0, a2
2684 ; CHECK-NEXT: add a0, a0, a1
2685 ; CHECK-NEXT: lbu a0, 0(a0)
2687 %a = getelementptr inbounds [16 x i8], ptr %p, i64 %idx1, i64 %idx2
2688 %b = load i8, ptr %a, align 1
2692 define i16 @array_index_sh4_sh1(ptr %p, i64 %idx1, i64 %idx2) {
2693 ; RV64I-LABEL: array_index_sh4_sh1:
2695 ; RV64I-NEXT: slli a1, a1, 5
2696 ; RV64I-NEXT: add a0, a0, a1
2697 ; RV64I-NEXT: slli a2, a2, 1
2698 ; RV64I-NEXT: add a0, a0, a2
2699 ; RV64I-NEXT: lh a0, 0(a0)
2702 ; RV64ZBA-LABEL: array_index_sh4_sh1:
2704 ; RV64ZBA-NEXT: slli a1, a1, 5
2705 ; RV64ZBA-NEXT: add a0, a0, a1
2706 ; RV64ZBA-NEXT: sh1add a0, a2, a0
2707 ; RV64ZBA-NEXT: lh a0, 0(a0)
2709 %a = getelementptr inbounds [16 x i16], ptr %p, i64 %idx1, i64 %idx2
2710 %b = load i16, ptr %a, align 2
2714 define i32 @array_index_sh4_sh2(ptr %p, i64 %idx1, i64 %idx2) {
2715 ; RV64I-LABEL: array_index_sh4_sh2:
2717 ; RV64I-NEXT: slli a1, a1, 6
2718 ; RV64I-NEXT: add a0, a0, a1
2719 ; RV64I-NEXT: slli a2, a2, 2
2720 ; RV64I-NEXT: add a0, a0, a2
2721 ; RV64I-NEXT: lw a0, 0(a0)
2724 ; RV64ZBA-LABEL: array_index_sh4_sh2:
2726 ; RV64ZBA-NEXT: slli a1, a1, 6
2727 ; RV64ZBA-NEXT: add a0, a0, a1
2728 ; RV64ZBA-NEXT: sh2add a0, a2, a0
2729 ; RV64ZBA-NEXT: lw a0, 0(a0)
2731 %a = getelementptr inbounds [16 x i32], ptr %p, i64 %idx1, i64 %idx2
2732 %b = load i32, ptr %a, align 4
2736 define i64 @array_index_sh4_sh3(ptr %p, i64 %idx1, i64 %idx2) {
2737 ; RV64I-LABEL: array_index_sh4_sh3:
2739 ; RV64I-NEXT: slli a1, a1, 7
2740 ; RV64I-NEXT: add a0, a0, a1
2741 ; RV64I-NEXT: slli a2, a2, 3
2742 ; RV64I-NEXT: add a0, a0, a2
2743 ; RV64I-NEXT: ld a0, 0(a0)
2746 ; RV64ZBA-LABEL: array_index_sh4_sh3:
2748 ; RV64ZBA-NEXT: slli a1, a1, 7
2749 ; RV64ZBA-NEXT: add a0, a0, a1
2750 ; RV64ZBA-NEXT: sh3add a0, a2, a0
2751 ; RV64ZBA-NEXT: ld a0, 0(a0)
2753 %a = getelementptr inbounds [16 x i64], ptr %p, i64 %idx1, i64 %idx2
2754 %b = load i64, ptr %a, align 8
2758 define ptr @test_gep_gep_dont_crash(ptr %p, i64 %a1, i64 %a2) {
2759 ; RV64I-LABEL: test_gep_gep_dont_crash:
2761 ; RV64I-NEXT: srliw a2, a2, 6
2762 ; RV64I-NEXT: slli a1, a1, 3
2763 ; RV64I-NEXT: slli a2, a2, 3
2764 ; RV64I-NEXT: add a0, a0, a1
2765 ; RV64I-NEXT: add a0, a0, a2
2768 ; RV64ZBA-LABEL: test_gep_gep_dont_crash:
2770 ; RV64ZBA-NEXT: srliw a2, a2, 6
2771 ; RV64ZBA-NEXT: add a1, a2, a1
2772 ; RV64ZBA-NEXT: sh3add a0, a1, a0
2774 %lshr = lshr i64 %a2, 6
2775 %and = and i64 %lshr, 67108863
2776 %gep1 = getelementptr i64, ptr %p, i64 %and
2777 %gep2 = getelementptr i64, ptr %gep1, i64 %a1
2781 define i64 @regression(i32 signext %x, i32 signext %y) {
2782 ; RV64I-LABEL: regression:
2784 ; RV64I-NEXT: subw a0, a0, a1
2785 ; RV64I-NEXT: slli a0, a0, 32
2786 ; RV64I-NEXT: srli a1, a0, 29
2787 ; RV64I-NEXT: srli a0, a0, 27
2788 ; RV64I-NEXT: sub a0, a0, a1
2791 ; RV64ZBA-LABEL: regression:
2793 ; RV64ZBA-NEXT: subw a0, a0, a1
2794 ; RV64ZBA-NEXT: slli.uw a0, a0, 3
2795 ; RV64ZBA-NEXT: sh1add a0, a0, a0
2797 %sub = sub i32 %x, %y
2798 %ext = zext i32 %sub to i64
2799 %res = mul nuw nsw i64 %ext, 24
2803 define i64 @mul_neg1(i64 %a) {
2804 ; CHECK-LABEL: mul_neg1:
2806 ; CHECK-NEXT: neg a0, a0
2812 define i64 @mul_neg2(i64 %a) {
2813 ; CHECK-LABEL: mul_neg2:
2815 ; CHECK-NEXT: slli a0, a0, 1
2816 ; CHECK-NEXT: neg a0, a0
2822 define i64 @mul_neg3(i64 %a) {
2823 ; RV64I-LABEL: mul_neg3:
2825 ; RV64I-NEXT: slli a1, a0, 1
2826 ; RV64I-NEXT: neg a0, a0
2827 ; RV64I-NEXT: sub a0, a0, a1
2830 ; RV64ZBA-LABEL: mul_neg3:
2832 ; RV64ZBA-NEXT: sh1add a0, a0, a0
2833 ; RV64ZBA-NEXT: neg a0, a0
2839 define i64 @mul_neg4(i64 %a) {
2840 ; CHECK-LABEL: mul_neg4:
2842 ; CHECK-NEXT: slli a0, a0, 2
2843 ; CHECK-NEXT: neg a0, a0
2849 define i64 @mul_neg5(i64 %a) {
2850 ; RV64I-LABEL: mul_neg5:
2852 ; RV64I-NEXT: slli a1, a0, 2
2853 ; RV64I-NEXT: neg a0, a0
2854 ; RV64I-NEXT: sub a0, a0, a1
2857 ; RV64ZBA-LABEL: mul_neg5:
2859 ; RV64ZBA-NEXT: sh2add a0, a0, a0
2860 ; RV64ZBA-NEXT: neg a0, a0
2866 define i64 @mul_neg6(i64 %a) {
2867 ; CHECK-LABEL: mul_neg6:
2869 ; CHECK-NEXT: li a1, -6
2870 ; CHECK-NEXT: mul a0, a0, a1
2876 define i64 @mul_neg7(i64 %a) {
2877 ; CHECK-LABEL: mul_neg7:
2879 ; CHECK-NEXT: slli a1, a0, 3
2880 ; CHECK-NEXT: sub a0, a0, a1
2886 define i64 @mul_neg8(i64 %a) {
2887 ; CHECK-LABEL: mul_neg8:
2889 ; CHECK-NEXT: slli a0, a0, 3
2890 ; CHECK-NEXT: neg a0, a0
2896 define i64 @bext_mul12(i32 %1, i32 %2) {
2897 ; RV64I-LABEL: bext_mul12:
2898 ; RV64I: # %bb.0: # %entry
2899 ; RV64I-NEXT: srlw a0, a0, a1
2900 ; RV64I-NEXT: andi a0, a0, 1
2901 ; RV64I-NEXT: slli a1, a0, 2
2902 ; RV64I-NEXT: slli a0, a0, 4
2903 ; RV64I-NEXT: sub a0, a0, a1
2906 ; RV64ZBANOZBB-LABEL: bext_mul12:
2907 ; RV64ZBANOZBB: # %bb.0: # %entry
2908 ; RV64ZBANOZBB-NEXT: srlw a0, a0, a1
2909 ; RV64ZBANOZBB-NEXT: andi a0, a0, 1
2910 ; RV64ZBANOZBB-NEXT: sh1add a0, a0, a0
2911 ; RV64ZBANOZBB-NEXT: slli a0, a0, 2
2912 ; RV64ZBANOZBB-NEXT: ret
2914 ; RV64ZBAZBBNOZBS-LABEL: bext_mul12:
2915 ; RV64ZBAZBBNOZBS: # %bb.0: # %entry
2916 ; RV64ZBAZBBNOZBS-NEXT: srlw a0, a0, a1
2917 ; RV64ZBAZBBNOZBS-NEXT: andi a0, a0, 1
2918 ; RV64ZBAZBBNOZBS-NEXT: sh1add a0, a0, a0
2919 ; RV64ZBAZBBNOZBS-NEXT: slli a0, a0, 2
2920 ; RV64ZBAZBBNOZBS-NEXT: ret
2922 ; RV64ZBAZBBZBS-LABEL: bext_mul12:
2923 ; RV64ZBAZBBZBS: # %bb.0: # %entry
2924 ; RV64ZBAZBBZBS-NEXT: bext a0, a0, a1
2925 ; RV64ZBAZBBZBS-NEXT: sh1add a0, a0, a0
2926 ; RV64ZBAZBBZBS-NEXT: slli a0, a0, 2
2927 ; RV64ZBAZBBZBS-NEXT: ret
2929 %3 = lshr i32 %1, %2
2931 %5 = zext nneg i32 %4 to i64
2936 define i64 @bext_mul45(i32 %1, i32 %2) {
2937 ; RV64I-LABEL: bext_mul45:
2938 ; RV64I: # %bb.0: # %entry
2939 ; RV64I-NEXT: srlw a0, a0, a1
2940 ; RV64I-NEXT: andi a0, a0, 1
2941 ; RV64I-NEXT: li a1, 45
2942 ; RV64I-NEXT: mul a0, a0, a1
2945 ; RV64ZBANOZBB-LABEL: bext_mul45:
2946 ; RV64ZBANOZBB: # %bb.0: # %entry
2947 ; RV64ZBANOZBB-NEXT: srlw a0, a0, a1
2948 ; RV64ZBANOZBB-NEXT: andi a0, a0, 1
2949 ; RV64ZBANOZBB-NEXT: sh2add a0, a0, a0
2950 ; RV64ZBANOZBB-NEXT: sh3add a0, a0, a0
2951 ; RV64ZBANOZBB-NEXT: ret
2953 ; RV64ZBAZBBNOZBS-LABEL: bext_mul45:
2954 ; RV64ZBAZBBNOZBS: # %bb.0: # %entry
2955 ; RV64ZBAZBBNOZBS-NEXT: srlw a0, a0, a1
2956 ; RV64ZBAZBBNOZBS-NEXT: andi a0, a0, 1
2957 ; RV64ZBAZBBNOZBS-NEXT: sh2add a0, a0, a0
2958 ; RV64ZBAZBBNOZBS-NEXT: sh3add a0, a0, a0
2959 ; RV64ZBAZBBNOZBS-NEXT: ret
2961 ; RV64ZBAZBBZBS-LABEL: bext_mul45:
2962 ; RV64ZBAZBBZBS: # %bb.0: # %entry
2963 ; RV64ZBAZBBZBS-NEXT: bext a0, a0, a1
2964 ; RV64ZBAZBBZBS-NEXT: sh2add a0, a0, a0
2965 ; RV64ZBAZBBZBS-NEXT: sh3add a0, a0, a0
2966 ; RV64ZBAZBBZBS-NEXT: ret
2968 %3 = lshr i32 %1, %2
2970 %5 = zext nneg i32 %4 to i64
2975 define i64 @bext_mul132(i32 %1, i32 %2) {
2976 ; RV64I-LABEL: bext_mul132:
2977 ; RV64I: # %bb.0: # %entry
2978 ; RV64I-NEXT: srlw a0, a0, a1
2979 ; RV64I-NEXT: andi a0, a0, 1
2980 ; RV64I-NEXT: li a1, 132
2981 ; RV64I-NEXT: mul a0, a0, a1
2984 ; RV64ZBANOZBB-LABEL: bext_mul132:
2985 ; RV64ZBANOZBB: # %bb.0: # %entry
2986 ; RV64ZBANOZBB-NEXT: srlw a0, a0, a1
2987 ; RV64ZBANOZBB-NEXT: andi a0, a0, 1
2988 ; RV64ZBANOZBB-NEXT: slli a1, a0, 7
2989 ; RV64ZBANOZBB-NEXT: sh2add a0, a0, a1
2990 ; RV64ZBANOZBB-NEXT: ret
2992 ; RV64ZBAZBBNOZBS-LABEL: bext_mul132:
2993 ; RV64ZBAZBBNOZBS: # %bb.0: # %entry
2994 ; RV64ZBAZBBNOZBS-NEXT: srlw a0, a0, a1
2995 ; RV64ZBAZBBNOZBS-NEXT: andi a0, a0, 1
2996 ; RV64ZBAZBBNOZBS-NEXT: slli a1, a0, 7
2997 ; RV64ZBAZBBNOZBS-NEXT: sh2add a0, a0, a1
2998 ; RV64ZBAZBBNOZBS-NEXT: ret
3000 ; RV64ZBAZBBZBS-LABEL: bext_mul132:
3001 ; RV64ZBAZBBZBS: # %bb.0: # %entry
3002 ; RV64ZBAZBBZBS-NEXT: bext a0, a0, a1
3003 ; RV64ZBAZBBZBS-NEXT: slli a1, a0, 7
3004 ; RV64ZBAZBBZBS-NEXT: sh2add a0, a0, a1
3005 ; RV64ZBAZBBZBS-NEXT: ret
3007 %3 = lshr i32 %1, %2
3009 %5 = zext nneg i32 %4 to i64
3010 %6 = mul i64 %5, 132
3014 define ptr @gep_lshr_i32(ptr %0, i64 %1) {
3015 ; RV64I-LABEL: gep_lshr_i32:
3016 ; RV64I: # %bb.0: # %entry
3017 ; RV64I-NEXT: srli a1, a1, 2
3018 ; RV64I-NEXT: li a2, 5
3019 ; RV64I-NEXT: slli a2, a2, 36
3020 ; RV64I-NEXT: slli a1, a1, 32
3021 ; RV64I-NEXT: mulhu a1, a1, a2
3022 ; RV64I-NEXT: add a0, a0, a1
3025 ; RV64ZBA-LABEL: gep_lshr_i32:
3026 ; RV64ZBA: # %bb.0: # %entry
3027 ; RV64ZBA-NEXT: srli a1, a1, 2
3028 ; RV64ZBA-NEXT: slli.uw a1, a1, 4
3029 ; RV64ZBA-NEXT: sh2add a1, a1, a1
3030 ; RV64ZBA-NEXT: add a0, a0, a1
3033 %2 = lshr exact i64 %1, 2
3034 %3 = and i64 %2, 4294967295
3035 %5 = getelementptr [80 x i8], ptr %0, i64 %3
3039 define i64 @srli_slliuw(i64 %1) {
3040 ; RV64I-LABEL: srli_slliuw:
3041 ; RV64I: # %bb.0: # %entry
3042 ; RV64I-NEXT: slli a0, a0, 2
3043 ; RV64I-NEXT: li a1, 1
3044 ; RV64I-NEXT: slli a1, a1, 36
3045 ; RV64I-NEXT: addi a1, a1, -16
3046 ; RV64I-NEXT: and a0, a0, a1
3049 ; RV64ZBA-LABEL: srli_slliuw:
3050 ; RV64ZBA: # %bb.0: # %entry
3051 ; RV64ZBA-NEXT: srli a0, a0, 2
3052 ; RV64ZBA-NEXT: slli.uw a0, a0, 4
3055 %2 = lshr exact i64 %1, 2
3056 %3 = and i64 %2, 4294967295
3061 define i64 @srli_slliuw_canonical(i64 %0) {
3062 ; RV64I-LABEL: srli_slliuw_canonical:
3063 ; RV64I: # %bb.0: # %entry
3064 ; RV64I-NEXT: slli a0, a0, 2
3065 ; RV64I-NEXT: li a1, 1
3066 ; RV64I-NEXT: slli a1, a1, 36
3067 ; RV64I-NEXT: addi a1, a1, -16
3068 ; RV64I-NEXT: and a0, a0, a1
3071 ; RV64ZBA-LABEL: srli_slliuw_canonical:
3072 ; RV64ZBA: # %bb.0: # %entry
3073 ; RV64ZBA-NEXT: srli a0, a0, 2
3074 ; RV64ZBA-NEXT: slli.uw a0, a0, 4
3078 %2 = and i64 %1, 68719476720
3082 ; Make sure we don't accidentally use slli.uw with a shift of 32.
3083 define i64 @srli_slliuw_negative_test(i64 %0) {
3084 ; CHECK-LABEL: srli_slliuw_negative_test:
3085 ; CHECK: # %bb.0: # %entry
3086 ; CHECK-NEXT: srli a0, a0, 6
3087 ; CHECK-NEXT: slli a0, a0, 32
3095 define i64 @srli_slli_i16(i64 %1) {
3096 ; CHECK-LABEL: srli_slli_i16:
3097 ; CHECK: # %bb.0: # %entry
3098 ; CHECK-NEXT: slli a0, a0, 2
3099 ; CHECK-NEXT: lui a1, 256
3100 ; CHECK-NEXT: addiw a1, a1, -16
3101 ; CHECK-NEXT: and a0, a0, a1
3104 %2 = lshr exact i64 %1, 2
3105 %3 = and i64 %2, 65535
3110 define i64 @srli_slliuw_2(i64 %1) {
3111 ; RV64I-LABEL: srli_slliuw_2:
3112 ; RV64I: # %bb.0: # %entry
3113 ; RV64I-NEXT: srli a0, a0, 15
3114 ; RV64I-NEXT: li a1, 1
3115 ; RV64I-NEXT: slli a1, a1, 35
3116 ; RV64I-NEXT: addi a1, a1, -8
3117 ; RV64I-NEXT: and a0, a0, a1
3120 ; RV64ZBA-LABEL: srli_slliuw_2:
3121 ; RV64ZBA: # %bb.0: # %entry
3122 ; RV64ZBA-NEXT: srli a0, a0, 18
3123 ; RV64ZBA-NEXT: slli.uw a0, a0, 3
3126 %2 = lshr i64 %1, 18
3127 %3 = and i64 %2, 4294967295
3132 define i64 @srli_slliuw_canonical_2(i64 %0) {
3133 ; RV64I-LABEL: srli_slliuw_canonical_2:
3134 ; RV64I: # %bb.0: # %entry
3135 ; RV64I-NEXT: srli a0, a0, 15
3136 ; RV64I-NEXT: li a1, 1
3137 ; RV64I-NEXT: slli a1, a1, 35
3138 ; RV64I-NEXT: addi a1, a1, -8
3139 ; RV64I-NEXT: and a0, a0, a1
3142 ; RV64ZBA-LABEL: srli_slliuw_canonical_2:
3143 ; RV64ZBA: # %bb.0: # %entry
3144 ; RV64ZBA-NEXT: srli a0, a0, 18
3145 ; RV64ZBA-NEXT: slli.uw a0, a0, 3
3148 %1 = lshr i64 %0, 15
3149 %2 = and i64 %1, 34359738360
3153 define ptr @srai_srli_sh3add(ptr %0, i64 %1) nounwind {
3154 ; RV64I-LABEL: srai_srli_sh3add:
3155 ; RV64I: # %bb.0: # %entry
3156 ; RV64I-NEXT: srai a1, a1, 32
3157 ; RV64I-NEXT: srli a1, a1, 6
3158 ; RV64I-NEXT: slli a1, a1, 3
3159 ; RV64I-NEXT: add a0, a0, a1
3162 ; RV64ZBA-LABEL: srai_srli_sh3add:
3163 ; RV64ZBA: # %bb.0: # %entry
3164 ; RV64ZBA-NEXT: srai a1, a1, 32
3165 ; RV64ZBA-NEXT: srli a1, a1, 6
3166 ; RV64ZBA-NEXT: sh3add a0, a1, a0
3169 %2 = ashr i64 %1, 32
3171 %4 = getelementptr i64, ptr %0, i64 %3
3175 define ptr @srai_srli_slli(ptr %0, i64 %1) nounwind {
3176 ; CHECK-LABEL: srai_srli_slli:
3177 ; CHECK: # %bb.0: # %entry
3178 ; CHECK-NEXT: srai a1, a1, 32
3179 ; CHECK-NEXT: srli a1, a1, 6
3180 ; CHECK-NEXT: slli a1, a1, 4
3181 ; CHECK-NEXT: add a0, a0, a1
3184 %2 = ashr i64 %1, 32
3186 %4 = getelementptr i128, ptr %0, i64 %3
3190 ; Negative to make sure the peephole added for srai_srli_slli and
3191 ; srai_srli_sh3add doesn't break this.
3192 define i64 @srai_andi(i64 %x) nounwind {
3193 ; CHECK-LABEL: srai_andi:
3194 ; CHECK: # %bb.0: # %entry
3195 ; CHECK-NEXT: srai a0, a0, 8
3196 ; CHECK-NEXT: andi a0, a0, -8
3204 ; Negative to make sure the peephole added for srai_srli_slli and
3205 ; srai_srli_sh3add doesn't break this.
3206 define i64 @srai_lui_and(i64 %x) nounwind {
3207 ; CHECK-LABEL: srai_lui_and:
3208 ; CHECK: # %bb.0: # %entry
3209 ; CHECK-NEXT: srai a0, a0, 8
3210 ; CHECK-NEXT: lui a1, 1048574
3211 ; CHECK-NEXT: and a0, a0, a1
3215 %z = and i64 %y, -8192
3219 define i64 @add_u32simm32_zextw(i64 %x) nounwind {
3220 ; RV64I-LABEL: add_u32simm32_zextw:
3221 ; RV64I: # %bb.0: # %entry
3222 ; RV64I-NEXT: li a1, 1
3223 ; RV64I-NEXT: slli a1, a1, 32
3224 ; RV64I-NEXT: addi a1, a1, -2
3225 ; RV64I-NEXT: add a0, a0, a1
3226 ; RV64I-NEXT: addi a1, a1, 1
3227 ; RV64I-NEXT: and a0, a0, a1
3230 ; RV64ZBA-LABEL: add_u32simm32_zextw:
3231 ; RV64ZBA: # %bb.0: # %entry
3232 ; RV64ZBA-NEXT: addi a0, a0, -2
3233 ; RV64ZBA-NEXT: zext.w a0, a0
3236 %add = add i64 %x, 4294967294
3237 %and = and i64 %add, 4294967295