Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / RISCV / rv64zba.ll
blob7cb2452e1a148d94f087b971577df5a1c166fa14
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:
13 ; RV64I:       # %bb.0:
14 ; RV64I-NEXT:    slli a0, a0, 32
15 ; RV64I-NEXT:    srli a0, a0, 31
16 ; RV64I-NEXT:    ret
18 ; RV64ZBA-LABEL: slliuw:
19 ; RV64ZBA:       # %bb.0:
20 ; RV64ZBA-NEXT:    slli.uw a0, a0, 1
21 ; RV64ZBA-NEXT:    ret
22   %conv1 = shl i64 %a, 1
23   %shl = and i64 %conv1, 8589934590
24   ret i64 %shl
27 define i128 @slliuw_2(i32 signext %0, ptr %1) {
28 ; RV64I-LABEL: slliuw_2:
29 ; RV64I:       # %bb.0:
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)
35 ; RV64I-NEXT:    ret
37 ; RV64ZBA-LABEL: slliuw_2:
38 ; RV64ZBA:       # %bb.0:
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)
43 ; RV64ZBA-NEXT:    ret
44   %3 = zext i32 %0 to i64
45   %4 = getelementptr inbounds i128, ptr %1, i64 %3
46   %5 = load i128, ptr %4
47   ret i128 %5
50 define i64 @adduw(i64 %a, i64 %b) nounwind {
51 ; RV64I-LABEL: adduw:
52 ; RV64I:       # %bb.0:
53 ; RV64I-NEXT:    slli a1, a1, 32
54 ; RV64I-NEXT:    srli a1, a1, 32
55 ; RV64I-NEXT:    add a0, a1, a0
56 ; RV64I-NEXT:    ret
58 ; RV64ZBA-LABEL: adduw:
59 ; RV64ZBA:       # %bb.0:
60 ; RV64ZBA-NEXT:    add.uw a0, a1, a0
61 ; RV64ZBA-NEXT:    ret
62   %and = and i64 %b, 4294967295
63   %add = add i64 %and, %a
64   ret i64 %add
67 define signext i8 @adduw_2(i32 signext %0, ptr %1) {
68 ; RV64I-LABEL: adduw_2:
69 ; RV64I:       # %bb.0:
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)
74 ; RV64I-NEXT:    ret
76 ; RV64ZBA-LABEL: adduw_2:
77 ; RV64ZBA:       # %bb.0:
78 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
79 ; RV64ZBA-NEXT:    lb a0, 0(a0)
80 ; RV64ZBA-NEXT:    ret
81   %3 = zext i32 %0 to i64
82   %4 = getelementptr inbounds i8, ptr %1, i64 %3
83   %5 = load i8, ptr %4
84   ret i8 %5
87 define i64 @zextw_i64(i64 %a) nounwind {
88 ; RV64I-LABEL: zextw_i64:
89 ; RV64I:       # %bb.0:
90 ; RV64I-NEXT:    slli a0, a0, 32
91 ; RV64I-NEXT:    srli a0, a0, 32
92 ; RV64I-NEXT:    ret
94 ; RV64ZBA-LABEL: zextw_i64:
95 ; RV64ZBA:       # %bb.0:
96 ; RV64ZBA-NEXT:    zext.w a0, a0
97 ; RV64ZBA-NEXT:    ret
98   %and = and i64 %a, 4294967295
99   ret i64 %and
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:
106 ; RV64I:       # %bb.0:
107 ; RV64I-NEXT:    ori a0, a0, 1
108 ; RV64I-NEXT:    slli a0, a0, 32
109 ; RV64I-NEXT:    srli a0, a0, 32
110 ; RV64I-NEXT:    ret
112 ; RV64ZBA-LABEL: zextw_demandedbits_i64:
113 ; RV64ZBA:       # %bb.0:
114 ; RV64ZBA-NEXT:    ori a0, a0, 1
115 ; RV64ZBA-NEXT:    zext.w a0, a0
116 ; RV64ZBA-NEXT:    ret
117   %2 = and i64 %0, 4294967294
118   %3 = or i64 %2, 1
119   ret i64 %3
122 define signext i16 @sh1add(i64 %0, ptr %1) {
123 ; RV64I-LABEL: sh1add:
124 ; RV64I:       # %bb.0:
125 ; RV64I-NEXT:    slli a0, a0, 1
126 ; RV64I-NEXT:    add a0, a1, a0
127 ; RV64I-NEXT:    lh a0, 0(a0)
128 ; RV64I-NEXT:    ret
130 ; RV64ZBA-LABEL: sh1add:
131 ; RV64ZBA:       # %bb.0:
132 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
133 ; RV64ZBA-NEXT:    lh a0, 0(a0)
134 ; RV64ZBA-NEXT:    ret
135   %3 = getelementptr inbounds i16, ptr %1, i64 %0
136   %4 = load i16, ptr %3
137   ret i16 %4
140 define signext i32 @sh2add(i64 %0, ptr %1) {
141 ; RV64I-LABEL: sh2add:
142 ; RV64I:       # %bb.0:
143 ; RV64I-NEXT:    slli a0, a0, 2
144 ; RV64I-NEXT:    add a0, a1, a0
145 ; RV64I-NEXT:    lw a0, 0(a0)
146 ; RV64I-NEXT:    ret
148 ; RV64ZBA-LABEL: sh2add:
149 ; RV64ZBA:       # %bb.0:
150 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
151 ; RV64ZBA-NEXT:    lw a0, 0(a0)
152 ; RV64ZBA-NEXT:    ret
153   %3 = getelementptr inbounds i32, ptr %1, i64 %0
154   %4 = load i32, ptr %3
155   ret i32 %4
158 define i64 @sh3add(i64 %0, ptr %1) {
159 ; RV64I-LABEL: sh3add:
160 ; RV64I:       # %bb.0:
161 ; RV64I-NEXT:    slli a0, a0, 3
162 ; RV64I-NEXT:    add a0, a1, a0
163 ; RV64I-NEXT:    ld a0, 0(a0)
164 ; RV64I-NEXT:    ret
166 ; RV64ZBA-LABEL: sh3add:
167 ; RV64ZBA:       # %bb.0:
168 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
169 ; RV64ZBA-NEXT:    ld a0, 0(a0)
170 ; RV64ZBA-NEXT:    ret
171   %3 = getelementptr inbounds i64, ptr %1, i64 %0
172   %4 = load i64, ptr %3
173   ret i64 %4
176 define signext i16 @sh1adduw(i32 signext %0, ptr %1) {
177 ; RV64I-LABEL: sh1adduw:
178 ; RV64I:       # %bb.0:
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)
183 ; RV64I-NEXT:    ret
185 ; RV64ZBA-LABEL: sh1adduw:
186 ; RV64ZBA:       # %bb.0:
187 ; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
188 ; RV64ZBA-NEXT:    lh a0, 0(a0)
189 ; RV64ZBA-NEXT:    ret
190   %3 = zext i32 %0 to i64
191   %4 = getelementptr inbounds i16, ptr %1, i64 %3
192   %5 = load i16, ptr %4
193   ret i16 %5
196 define i64 @sh1adduw_2(i64 %0, i64 %1) {
197 ; RV64I-LABEL: sh1adduw_2:
198 ; RV64I:       # %bb.0:
199 ; RV64I-NEXT:    slli a0, a0, 32
200 ; RV64I-NEXT:    srli a0, a0, 31
201 ; RV64I-NEXT:    add a0, a0, a1
202 ; RV64I-NEXT:    ret
204 ; RV64ZBA-LABEL: sh1adduw_2:
205 ; RV64ZBA:       # %bb.0:
206 ; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
207 ; RV64ZBA-NEXT:    ret
208   %3 = shl i64 %0, 1
209   %4 = and i64 %3, 8589934590
210   %5 = add i64 %4, %1
211   ret i64 %5
214 define i64 @sh1adduw_3(i64 %0, i64 %1) {
215 ; RV64I-LABEL: sh1adduw_3:
216 ; RV64I:       # %bb.0:
217 ; RV64I-NEXT:    slli a0, a0, 32
218 ; RV64I-NEXT:    srli a0, a0, 31
219 ; RV64I-NEXT:    or a0, a0, a1
220 ; RV64I-NEXT:    ret
222 ; RV64ZBA-LABEL: sh1adduw_3:
223 ; RV64ZBA:       # %bb.0:
224 ; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
225 ; RV64ZBA-NEXT:    ret
226   %3 = shl i64 %0, 1
227   %4 = and i64 %3, 8589934590
228   %5 = or disjoint i64 %4, %1
229   ret i64 %5
232 define signext i32 @sh2adduw(i32 signext %0, ptr %1) {
233 ; RV64I-LABEL: sh2adduw:
234 ; RV64I:       # %bb.0:
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)
239 ; RV64I-NEXT:    ret
241 ; RV64ZBA-LABEL: sh2adduw:
242 ; RV64ZBA:       # %bb.0:
243 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
244 ; RV64ZBA-NEXT:    lw a0, 0(a0)
245 ; RV64ZBA-NEXT:    ret
246   %3 = zext i32 %0 to i64
247   %4 = getelementptr inbounds i32, ptr %1, i64 %3
248   %5 = load i32, ptr %4
249   ret i32 %5
252 define i64 @sh2adduw_2(i64 %0, i64 %1) {
253 ; RV64I-LABEL: sh2adduw_2:
254 ; RV64I:       # %bb.0:
255 ; RV64I-NEXT:    slli a0, a0, 32
256 ; RV64I-NEXT:    srli a0, a0, 30
257 ; RV64I-NEXT:    add a0, a0, a1
258 ; RV64I-NEXT:    ret
260 ; RV64ZBA-LABEL: sh2adduw_2:
261 ; RV64ZBA:       # %bb.0:
262 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
263 ; RV64ZBA-NEXT:    ret
264   %3 = shl i64 %0, 2
265   %4 = and i64 %3, 17179869180
266   %5 = add i64 %4, %1
267   ret i64 %5
270 define i64 @sh2adduw_3(i64 %0, i64 %1) {
271 ; RV64I-LABEL: sh2adduw_3:
272 ; RV64I:       # %bb.0:
273 ; RV64I-NEXT:    slli a0, a0, 32
274 ; RV64I-NEXT:    srli a0, a0, 30
275 ; RV64I-NEXT:    or a0, a0, a1
276 ; RV64I-NEXT:    ret
278 ; RV64ZBA-LABEL: sh2adduw_3:
279 ; RV64ZBA:       # %bb.0:
280 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
281 ; RV64ZBA-NEXT:    ret
282   %3 = shl i64 %0, 2
283   %4 = and i64 %3, 17179869180
284   %5 = or disjoint i64 %4, %1
285   ret i64 %5
288 define i64 @sh3adduw(i32 signext %0, ptr %1) {
289 ; RV64I-LABEL: sh3adduw:
290 ; RV64I:       # %bb.0:
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)
295 ; RV64I-NEXT:    ret
297 ; RV64ZBA-LABEL: sh3adduw:
298 ; RV64ZBA:       # %bb.0:
299 ; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
300 ; RV64ZBA-NEXT:    ld a0, 0(a0)
301 ; RV64ZBA-NEXT:    ret
302   %3 = zext i32 %0 to i64
303   %4 = getelementptr inbounds i64, ptr %1, i64 %3
304   %5 = load i64, ptr %4
305   ret i64 %5
308 define i64 @sh3adduw_2(i64 %0, i64 %1) {
309 ; RV64I-LABEL: sh3adduw_2:
310 ; RV64I:       # %bb.0:
311 ; RV64I-NEXT:    slli a0, a0, 32
312 ; RV64I-NEXT:    srli a0, a0, 29
313 ; RV64I-NEXT:    add a0, a0, a1
314 ; RV64I-NEXT:    ret
316 ; RV64ZBA-LABEL: sh3adduw_2:
317 ; RV64ZBA:       # %bb.0:
318 ; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
319 ; RV64ZBA-NEXT:    ret
320   %3 = shl i64 %0, 3
321   %4 = and i64 %3, 34359738360
322   %5 = add i64 %4, %1
323   ret i64 %5
326 define i64 @sh3adduw_3(i64 %0, i64 %1) {
327 ; RV64I-LABEL: sh3adduw_3:
328 ; RV64I:       # %bb.0:
329 ; RV64I-NEXT:    slli a0, a0, 32
330 ; RV64I-NEXT:    srli a0, a0, 29
331 ; RV64I-NEXT:    or a0, a0, a1
332 ; RV64I-NEXT:    ret
334 ; RV64ZBA-LABEL: sh3adduw_3:
335 ; RV64ZBA:       # %bb.0:
336 ; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
337 ; RV64ZBA-NEXT:    ret
338   %3 = shl i64 %0, 3
339   %4 = and i64 %3, 34359738360
340   %5 = or disjoint i64 %4, %1
341   ret i64 %5
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:
351 ; RV64I:       # %bb.0:
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
357 ; RV64I-NEXT:    ret
359 ; RV64ZBA-LABEL: sh2add_extra_sext:
360 ; RV64ZBA:       # %bb.0:
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
365 ; RV64ZBA-NEXT:    ret
366   %a = shl i32 %x, 2
367   %b = add i32 %a, %y
368   %c = shl i32 %z, %b
369   %d = ashr i32 %b, 2
370   %e = sext i32 %c to i64
371   %f = sext i32 %d to i64
372   %g = mul i64 %e, %f
373   ret i64 %g
376 define i64 @addmul6(i64 %a, i64 %b) {
377 ; RV64I-LABEL: addmul6:
378 ; RV64I:       # %bb.0:
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
383 ; RV64I-NEXT:    ret
385 ; RV64ZBA-LABEL: addmul6:
386 ; RV64ZBA:       # %bb.0:
387 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
388 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
389 ; RV64ZBA-NEXT:    ret
390   %c = mul i64 %a, 6
391   %d = add i64 %c, %b
392   ret i64 %d
395 define i64 @disjointormul6(i64 %a, i64 %b) {
396 ; RV64I-LABEL: disjointormul6:
397 ; RV64I:       # %bb.0:
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
402 ; RV64I-NEXT:    ret
404 ; RV64ZBA-LABEL: disjointormul6:
405 ; RV64ZBA:       # %bb.0:
406 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
407 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
408 ; RV64ZBA-NEXT:    ret
409   %c = mul i64 %a, 6
410   %d = or disjoint i64 %c, %b
411   ret i64 %d
414 define i64 @addmul10(i64 %a, i64 %b) {
415 ; RV64I-LABEL: addmul10:
416 ; RV64I:       # %bb.0:
417 ; RV64I-NEXT:    li a2, 10
418 ; RV64I-NEXT:    mul a0, a0, a2
419 ; RV64I-NEXT:    add a0, a0, a1
420 ; RV64I-NEXT:    ret
422 ; RV64ZBA-LABEL: addmul10:
423 ; RV64ZBA:       # %bb.0:
424 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
425 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
426 ; RV64ZBA-NEXT:    ret
427   %c = mul i64 %a, 10
428   %d = add i64 %c, %b
429   ret i64 %d
432 define i64 @addmul12(i64 %a, i64 %b) {
433 ; RV64I-LABEL: addmul12:
434 ; RV64I:       # %bb.0:
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
439 ; RV64I-NEXT:    ret
441 ; RV64ZBA-LABEL: addmul12:
442 ; RV64ZBA:       # %bb.0:
443 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
444 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
445 ; RV64ZBA-NEXT:    ret
446   %c = mul i64 %a, 12
447   %d = add i64 %c, %b
448   ret i64 %d
451 define i64 @addmul18(i64 %a, i64 %b) {
452 ; RV64I-LABEL: addmul18:
453 ; RV64I:       # %bb.0:
454 ; RV64I-NEXT:    li a2, 18
455 ; RV64I-NEXT:    mul a0, a0, a2
456 ; RV64I-NEXT:    add a0, a0, a1
457 ; RV64I-NEXT:    ret
459 ; RV64ZBA-LABEL: addmul18:
460 ; RV64ZBA:       # %bb.0:
461 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
462 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
463 ; RV64ZBA-NEXT:    ret
464   %c = mul i64 %a, 18
465   %d = add i64 %c, %b
466   ret i64 %d
469 define i64 @addmul20(i64 %a, i64 %b) {
470 ; RV64I-LABEL: addmul20:
471 ; RV64I:       # %bb.0:
472 ; RV64I-NEXT:    li a2, 20
473 ; RV64I-NEXT:    mul a0, a0, a2
474 ; RV64I-NEXT:    add a0, a0, a1
475 ; RV64I-NEXT:    ret
477 ; RV64ZBA-LABEL: addmul20:
478 ; RV64ZBA:       # %bb.0:
479 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
480 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
481 ; RV64ZBA-NEXT:    ret
482   %c = mul i64 %a, 20
483   %d = add i64 %c, %b
484   ret i64 %d
487 define i64 @addmul22(i64 %a, i64 %b) {
488 ; CHECK-LABEL: addmul22:
489 ; CHECK:       # %bb.0:
490 ; CHECK-NEXT:    li a2, 22
491 ; CHECK-NEXT:    mul a0, a0, a2
492 ; CHECK-NEXT:    add a0, a0, a1
493 ; CHECK-NEXT:    ret
494   %c = mul i64 %a, 22
495   %d = add i64 %c, %b
496   ret i64 %d
499 define i64 @addmul24(i64 %a, i64 %b) {
500 ; RV64I-LABEL: addmul24:
501 ; RV64I:       # %bb.0:
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
506 ; RV64I-NEXT:    ret
508 ; RV64ZBA-LABEL: addmul24:
509 ; RV64ZBA:       # %bb.0:
510 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
511 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
512 ; RV64ZBA-NEXT:    ret
513   %c = mul i64 %a, 24
514   %d = add i64 %c, %b
515   ret i64 %d
518 define i64 @addmul36(i64 %a, i64 %b) {
519 ; RV64I-LABEL: addmul36:
520 ; RV64I:       # %bb.0:
521 ; RV64I-NEXT:    li a2, 36
522 ; RV64I-NEXT:    mul a0, a0, a2
523 ; RV64I-NEXT:    add a0, a0, a1
524 ; RV64I-NEXT:    ret
526 ; RV64ZBA-LABEL: addmul36:
527 ; RV64ZBA:       # %bb.0:
528 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
529 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
530 ; RV64ZBA-NEXT:    ret
531   %c = mul i64 %a, 36
532   %d = add i64 %c, %b
533   ret i64 %d
536 define i64 @addmul40(i64 %a, i64 %b) {
537 ; RV64I-LABEL: addmul40:
538 ; RV64I:       # %bb.0:
539 ; RV64I-NEXT:    li a2, 40
540 ; RV64I-NEXT:    mul a0, a0, a2
541 ; RV64I-NEXT:    add a0, a0, a1
542 ; RV64I-NEXT:    ret
544 ; RV64ZBA-LABEL: addmul40:
545 ; RV64ZBA:       # %bb.0:
546 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
547 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
548 ; RV64ZBA-NEXT:    ret
549   %c = mul i64 %a, 40
550   %d = add i64 %c, %b
551   ret i64 %d
554 define i64 @addmul72(i64 %a, i64 %b) {
555 ; RV64I-LABEL: addmul72:
556 ; RV64I:       # %bb.0:
557 ; RV64I-NEXT:    li a2, 72
558 ; RV64I-NEXT:    mul a0, a0, a2
559 ; RV64I-NEXT:    add a0, a0, a1
560 ; RV64I-NEXT:    ret
562 ; RV64ZBA-LABEL: addmul72:
563 ; RV64ZBA:       # %bb.0:
564 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
565 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
566 ; RV64ZBA-NEXT:    ret
567   %c = mul i64 %a, 72
568   %d = add i64 %c, %b
569   ret i64 %d
572 define i64 @addmul162(i64 %a, i64 %b) {
573 ; CHECK-LABEL: addmul162:
574 ; CHECK:       # %bb.0:
575 ; CHECK-NEXT:    li a2, 162
576 ; CHECK-NEXT:    mul a0, a0, a2
577 ; CHECK-NEXT:    add a0, a0, a1
578 ; CHECK-NEXT:    ret
579   %c = mul i64 %a, 162
580   %d = add i64 %c, %b
581   ret i64 %d
584 define i64 @addmul180(i64 %a, i64 %b) {
585 ; CHECK-LABEL: addmul180:
586 ; CHECK:       # %bb.0:
587 ; CHECK-NEXT:    li a2, 180
588 ; CHECK-NEXT:    mul a0, a0, a2
589 ; CHECK-NEXT:    add a0, a0, a1
590 ; CHECK-NEXT:    ret
591   %c = mul i64 %a, 180
592   %d = add i64 %c, %b
593   ret i64 %d
596 define i64 @add255mul180(i64 %a) {
597 ; CHECK-LABEL: add255mul180:
598 ; CHECK:       # %bb.0:
599 ; CHECK-NEXT:    li a1, 180
600 ; CHECK-NEXT:    mul a0, a0, a1
601 ; CHECK-NEXT:    addi a0, a0, 255
602 ; CHECK-NEXT:    ret
603   %c = mul i64 %a, 180
604   %d = add i64 %c, 255
605   ret i64 %d
609 define i64 @addmul4096(i64 %a, i64 %b) {
610 ; CHECK-LABEL: addmul4096:
611 ; CHECK:       # %bb.0:
612 ; CHECK-NEXT:    slli a0, a0, 12
613 ; CHECK-NEXT:    add a0, a0, a1
614 ; CHECK-NEXT:    ret
615   %c = mul i64 %a, 4096
616   %d = add i64 %c, %b
617   ret i64 %d
620 define i64 @addmul4230(i64 %a, i64 %b) {
621 ; CHECK-LABEL: addmul4230:
622 ; CHECK:       # %bb.0:
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
627 ; CHECK-NEXT:    ret
628   %c = mul i64 %a, 4230
629   %d = add i64 %c, %b
630   ret i64 %d
633 define i64 @mul96(i64 %a) {
634 ; RV64I-LABEL: mul96:
635 ; RV64I:       # %bb.0:
636 ; RV64I-NEXT:    slli a1, a0, 5
637 ; RV64I-NEXT:    slli a0, a0, 7
638 ; RV64I-NEXT:    sub a0, a0, a1
639 ; RV64I-NEXT:    ret
641 ; RV64ZBA-LABEL: mul96:
642 ; RV64ZBA:       # %bb.0:
643 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
644 ; RV64ZBA-NEXT:    slli a0, a0, 5
645 ; RV64ZBA-NEXT:    ret
646   %c = mul i64 %a, 96
647   ret i64 %c
650 define i64 @mul119(i64 %a) {
651 ; RV64I-LABEL: mul119:
652 ; RV64I:       # %bb.0:
653 ; RV64I-NEXT:    li a1, 119
654 ; RV64I-NEXT:    mul a0, a0, a1
655 ; RV64I-NEXT:    ret
657 ; RV64ZBA-LABEL: mul119:
658 ; RV64ZBA:       # %bb.0:
659 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
660 ; RV64ZBA-NEXT:    slli a0, a0, 7
661 ; RV64ZBA-NEXT:    sub a0, a0, a1
662 ; RV64ZBA-NEXT:    ret
663   %c = mul i64 %a, 119
664   ret i64 %c
667 define i64 @mul123(i64 %a) {
668 ; RV64I-LABEL: mul123:
669 ; RV64I:       # %bb.0:
670 ; RV64I-NEXT:    li a1, 123
671 ; RV64I-NEXT:    mul a0, a0, a1
672 ; RV64I-NEXT:    ret
674 ; RV64ZBA-LABEL: mul123:
675 ; RV64ZBA:       # %bb.0:
676 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
677 ; RV64ZBA-NEXT:    slli a0, a0, 7
678 ; RV64ZBA-NEXT:    sub a0, a0, a1
679 ; RV64ZBA-NEXT:    ret
680   %c = mul i64 %a, 123
681   ret i64 %c
684 define i64 @mul125(i64 %a) {
685 ; RV64I-LABEL: mul125:
686 ; RV64I:       # %bb.0:
687 ; RV64I-NEXT:    li a1, 125
688 ; RV64I-NEXT:    mul a0, a0, a1
689 ; RV64I-NEXT:    ret
691 ; RV64ZBA-LABEL: mul125:
692 ; RV64ZBA:       # %bb.0:
693 ; RV64ZBA-NEXT:    sh1add a1, a0, a0
694 ; RV64ZBA-NEXT:    slli a0, a0, 7
695 ; RV64ZBA-NEXT:    sub a0, a0, a1
696 ; RV64ZBA-NEXT:    ret
697   %c = mul i64 %a, 125
698   ret i64 %c
701 define i64 @mul131(i64 %a) {
702 ; RV64I-LABEL: mul131:
703 ; RV64I:       # %bb.0:
704 ; RV64I-NEXT:    li a1, 131
705 ; RV64I-NEXT:    mul a0, a0, a1
706 ; RV64I-NEXT:    ret
708 ; RV64ZBA-LABEL: mul131:
709 ; RV64ZBA:       # %bb.0:
710 ; RV64ZBA-NEXT:    sh1add a1, a0, a0
711 ; RV64ZBA-NEXT:    slli a0, a0, 7
712 ; RV64ZBA-NEXT:    add a0, a0, a1
713 ; RV64ZBA-NEXT:    ret
714   %c = mul i64 %a, 131
715   ret i64 %c
718 define i64 @mul133(i64 %a) {
719 ; RV64I-LABEL: mul133:
720 ; RV64I:       # %bb.0:
721 ; RV64I-NEXT:    li a1, 133
722 ; RV64I-NEXT:    mul a0, a0, a1
723 ; RV64I-NEXT:    ret
725 ; RV64ZBA-LABEL: mul133:
726 ; RV64ZBA:       # %bb.0:
727 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
728 ; RV64ZBA-NEXT:    slli a0, a0, 7
729 ; RV64ZBA-NEXT:    add a0, a0, a1
730 ; RV64ZBA-NEXT:    ret
731   %c = mul i64 %a, 133
732   ret i64 %c
735 define i64 @mul137(i64 %a) {
736 ; RV64I-LABEL: mul137:
737 ; RV64I:       # %bb.0:
738 ; RV64I-NEXT:    li a1, 137
739 ; RV64I-NEXT:    mul a0, a0, a1
740 ; RV64I-NEXT:    ret
742 ; RV64ZBA-LABEL: mul137:
743 ; RV64ZBA:       # %bb.0:
744 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
745 ; RV64ZBA-NEXT:    slli a0, a0, 7
746 ; RV64ZBA-NEXT:    add a0, a0, a1
747 ; RV64ZBA-NEXT:    ret
748   %c = mul i64 %a, 137
749   ret i64 %c
752 define i64 @mul160(i64 %a) {
753 ; RV64I-LABEL: mul160:
754 ; RV64I:       # %bb.0:
755 ; RV64I-NEXT:    li a1, 160
756 ; RV64I-NEXT:    mul a0, a0, a1
757 ; RV64I-NEXT:    ret
759 ; RV64ZBA-LABEL: mul160:
760 ; RV64ZBA:       # %bb.0:
761 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
762 ; RV64ZBA-NEXT:    slli a0, a0, 5
763 ; RV64ZBA-NEXT:    ret
764   %c = mul i64 %a, 160
765   ret i64 %c
768 define i64 @mul288(i64 %a) {
769 ; RV64I-LABEL: mul288:
770 ; RV64I:       # %bb.0:
771 ; RV64I-NEXT:    li a1, 288
772 ; RV64I-NEXT:    mul a0, a0, a1
773 ; RV64I-NEXT:    ret
775 ; RV64ZBA-LABEL: mul288:
776 ; RV64ZBA:       # %bb.0:
777 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
778 ; RV64ZBA-NEXT:    slli a0, a0, 5
779 ; RV64ZBA-NEXT:    ret
780   %c = mul i64 %a, 288
781   ret i64 %c
784 define i64 @zext_mul68(i32 signext %a) {
785 ; RV64I-LABEL: zext_mul68:
786 ; RV64I:       # %bb.0:
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
791 ; RV64I-NEXT:    ret
793 ; RV64ZBA-LABEL: zext_mul68:
794 ; RV64ZBA:       # %bb.0:
795 ; RV64ZBA-NEXT:    slli.uw a1, a0, 6
796 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
797 ; RV64ZBA-NEXT:    ret
798   %b = zext i32 %a to i64
799   %c = mul i64 %b, 68
800   ret i64 %c
803 define i64 @zext_mul96(i32 signext %a) {
804 ; RV64I-LABEL: zext_mul96:
805 ; RV64I:       # %bb.0:
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
810 ; RV64I-NEXT:    ret
812 ; RV64ZBA-LABEL: zext_mul96:
813 ; RV64ZBA:       # %bb.0:
814 ; RV64ZBA-NEXT:    slli.uw a0, a0, 5
815 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
816 ; RV64ZBA-NEXT:    ret
817   %b = zext i32 %a to i64
818   %c = mul i64 %b, 96
819   ret i64 %c
822 define i64 @zext_mul160(i32 signext %a) {
823 ; RV64I-LABEL: zext_mul160:
824 ; RV64I:       # %bb.0:
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
829 ; RV64I-NEXT:    ret
831 ; RV64ZBA-LABEL: zext_mul160:
832 ; RV64ZBA:       # %bb.0:
833 ; RV64ZBA-NEXT:    slli.uw a0, a0, 5
834 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
835 ; RV64ZBA-NEXT:    ret
836   %b = zext i32 %a to i64
837   %c = mul i64 %b, 160
838   ret i64 %c
841 define i64 @zext_mul288(i32 signext %a) {
842 ; RV64I-LABEL: zext_mul288:
843 ; RV64I:       # %bb.0:
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
848 ; RV64I-NEXT:    ret
850 ; RV64ZBA-LABEL: zext_mul288:
851 ; RV64ZBA:       # %bb.0:
852 ; RV64ZBA-NEXT:    slli.uw a0, a0, 5
853 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
854 ; RV64ZBA-NEXT:    ret
855   %b = zext i32 %a to i64
856   %c = mul i64 %b, 288
857   ret i64 %c
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:
863 ; RV64I:       # %bb.0:
864 ; RV64I-NEXT:    slli a1, a0, 32
865 ; RV64I-NEXT:    slli a0, a0, 34
866 ; RV64I-NEXT:    sub a0, a0, a1
867 ; RV64I-NEXT:    ret
869 ; RV64ZBA-LABEL: zext_mul12884901888:
870 ; RV64ZBA:       # %bb.0:
871 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
872 ; RV64ZBA-NEXT:    slli a0, a0, 32
873 ; RV64ZBA-NEXT:    ret
874   %b = zext i32 %a to i64
875   %c = mul i64 %b, 12884901888
876   ret i64 %c
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:
882 ; RV64I:       # %bb.0:
883 ; RV64I-NEXT:    li a1, 5
884 ; RV64I-NEXT:    slli a1, a1, 32
885 ; RV64I-NEXT:    mul a0, a0, a1
886 ; RV64I-NEXT:    ret
888 ; RV64ZBA-LABEL: zext_mul21474836480:
889 ; RV64ZBA:       # %bb.0:
890 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
891 ; RV64ZBA-NEXT:    slli a0, a0, 32
892 ; RV64ZBA-NEXT:    ret
893   %b = zext i32 %a to i64
894   %c = mul i64 %b, 21474836480
895   ret i64 %c
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:
901 ; RV64I:       # %bb.0:
902 ; RV64I-NEXT:    li a1, 9
903 ; RV64I-NEXT:    slli a1, a1, 32
904 ; RV64I-NEXT:    mul a0, a0, a1
905 ; RV64I-NEXT:    ret
907 ; RV64ZBA-LABEL: zext_mul38654705664:
908 ; RV64ZBA:       # %bb.0:
909 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
910 ; RV64ZBA-NEXT:    slli a0, a0, 32
911 ; RV64ZBA-NEXT:    ret
912   %b = zext i32 %a to i64
913   %c = mul i64 %b, 38654705664
914   ret i64 %c
917 define i64 @sh1add_imm(i64 %0) {
918 ; CHECK-LABEL: sh1add_imm:
919 ; CHECK:       # %bb.0:
920 ; CHECK-NEXT:    slli a0, a0, 1
921 ; CHECK-NEXT:    addi a0, a0, 5
922 ; CHECK-NEXT:    ret
923   %a = shl i64 %0, 1
924   %b = add i64 %a, 5
925   ret i64 %b
928 define i64 @sh2add_imm(i64 %0) {
929 ; CHECK-LABEL: sh2add_imm:
930 ; CHECK:       # %bb.0:
931 ; CHECK-NEXT:    slli a0, a0, 2
932 ; CHECK-NEXT:    addi a0, a0, -6
933 ; CHECK-NEXT:    ret
934   %a = shl i64 %0, 2
935   %b = add i64 %a, -6
936   ret i64 %b
939 define i64 @sh3add_imm(i64 %0) {
940 ; CHECK-LABEL: sh3add_imm:
941 ; CHECK:       # %bb.0:
942 ; CHECK-NEXT:    slli a0, a0, 3
943 ; CHECK-NEXT:    addi a0, a0, 7
944 ; CHECK-NEXT:    ret
945   %a = shl i64 %0, 3
946   %b = add i64 %a, 7
947   ret i64 %b
950 define i64 @sh1adduw_imm(i32 signext %0) {
951 ; RV64I-LABEL: sh1adduw_imm:
952 ; RV64I:       # %bb.0:
953 ; RV64I-NEXT:    slli a0, a0, 32
954 ; RV64I-NEXT:    srli a0, a0, 31
955 ; RV64I-NEXT:    addi a0, a0, 11
956 ; RV64I-NEXT:    ret
958 ; RV64ZBA-LABEL: sh1adduw_imm:
959 ; RV64ZBA:       # %bb.0:
960 ; RV64ZBA-NEXT:    slli.uw a0, a0, 1
961 ; RV64ZBA-NEXT:    addi a0, a0, 11
962 ; RV64ZBA-NEXT:    ret
963   %a = zext i32 %0 to i64
964   %b = shl i64 %a, 1
965   %c = add i64 %b, 11
966   ret i64 %c
969 define i64 @sh2adduw_imm(i32 signext %0) {
970 ; RV64I-LABEL: sh2adduw_imm:
971 ; RV64I:       # %bb.0:
972 ; RV64I-NEXT:    slli a0, a0, 32
973 ; RV64I-NEXT:    srli a0, a0, 30
974 ; RV64I-NEXT:    addi a0, a0, -12
975 ; RV64I-NEXT:    ret
977 ; RV64ZBA-LABEL: sh2adduw_imm:
978 ; RV64ZBA:       # %bb.0:
979 ; RV64ZBA-NEXT:    slli.uw a0, a0, 2
980 ; RV64ZBA-NEXT:    addi a0, a0, -12
981 ; RV64ZBA-NEXT:    ret
982   %a = zext i32 %0 to i64
983   %b = shl i64 %a, 2
984   %c = add i64 %b, -12
985   ret i64 %c
988 define i64 @sh3adduw_imm(i32 signext %0) {
989 ; RV64I-LABEL: sh3adduw_imm:
990 ; RV64I:       # %bb.0:
991 ; RV64I-NEXT:    slli a0, a0, 32
992 ; RV64I-NEXT:    srli a0, a0, 29
993 ; RV64I-NEXT:    addi a0, a0, 13
994 ; RV64I-NEXT:    ret
996 ; RV64ZBA-LABEL: sh3adduw_imm:
997 ; RV64ZBA:       # %bb.0:
998 ; RV64ZBA-NEXT:    slli.uw a0, a0, 3
999 ; RV64ZBA-NEXT:    addi a0, a0, 13
1000 ; RV64ZBA-NEXT:    ret
1001   %a = zext i32 %0 to i64
1002   %b = shl i64 %a, 3
1003   %c = add i64 %b, 13
1004   ret i64 %c
1007 define i64 @adduw_imm(i32 signext %0) nounwind {
1008 ; RV64I-LABEL: adduw_imm:
1009 ; RV64I:       # %bb.0:
1010 ; RV64I-NEXT:    slli a0, a0, 32
1011 ; RV64I-NEXT:    srli a0, a0, 32
1012 ; RV64I-NEXT:    addi a0, a0, 5
1013 ; RV64I-NEXT:    ret
1015 ; RV64ZBA-LABEL: adduw_imm:
1016 ; RV64ZBA:       # %bb.0:
1017 ; RV64ZBA-NEXT:    zext.w a0, a0
1018 ; RV64ZBA-NEXT:    addi a0, a0, 5
1019 ; RV64ZBA-NEXT:    ret
1020   %a = zext i32 %0 to i64
1021   %b = add i64 %a, 5
1022   ret i64 %b
1025 define i64 @mul258(i64 %a) {
1026 ; RV64I-LABEL: mul258:
1027 ; RV64I:       # %bb.0:
1028 ; RV64I-NEXT:    li a1, 258
1029 ; RV64I-NEXT:    mul a0, a0, a1
1030 ; RV64I-NEXT:    ret
1032 ; RV64ZBA-LABEL: mul258:
1033 ; RV64ZBA:       # %bb.0:
1034 ; RV64ZBA-NEXT:    slli a1, a0, 8
1035 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
1036 ; RV64ZBA-NEXT:    ret
1037   %c = mul i64 %a, 258
1038   ret i64 %c
1041 define i64 @mul260(i64 %a) {
1042 ; RV64I-LABEL: mul260:
1043 ; RV64I:       # %bb.0:
1044 ; RV64I-NEXT:    li a1, 260
1045 ; RV64I-NEXT:    mul a0, a0, a1
1046 ; RV64I-NEXT:    ret
1048 ; RV64ZBA-LABEL: mul260:
1049 ; RV64ZBA:       # %bb.0:
1050 ; RV64ZBA-NEXT:    slli a1, a0, 8
1051 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
1052 ; RV64ZBA-NEXT:    ret
1053   %c = mul i64 %a, 260
1054   ret i64 %c
1057 define i64 @mul264(i64 %a) {
1058 ; RV64I-LABEL: mul264:
1059 ; RV64I:       # %bb.0:
1060 ; RV64I-NEXT:    li a1, 264
1061 ; RV64I-NEXT:    mul a0, a0, a1
1062 ; RV64I-NEXT:    ret
1064 ; RV64ZBA-LABEL: mul264:
1065 ; RV64ZBA:       # %bb.0:
1066 ; RV64ZBA-NEXT:    slli a1, a0, 8
1067 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
1068 ; RV64ZBA-NEXT:    ret
1069   %c = mul i64 %a, 264
1070   ret i64 %c
1073 define i64 @imm_zextw() nounwind {
1074 ; RV64I-LABEL: imm_zextw:
1075 ; RV64I:       # %bb.0:
1076 ; RV64I-NEXT:    li a0, 1
1077 ; RV64I-NEXT:    slli a0, a0, 32
1078 ; RV64I-NEXT:    addi a0, a0, -2
1079 ; RV64I-NEXT:    ret
1081 ; RV64ZBA-LABEL: imm_zextw:
1082 ; RV64ZBA:       # %bb.0:
1083 ; RV64ZBA-NEXT:    li a0, -2
1084 ; RV64ZBA-NEXT:    zext.w a0, a0
1085 ; RV64ZBA-NEXT:    ret
1086   ret i64 4294967294 ; -2 in 32 bits.
1089 define i64 @mul11(i64 %a) {
1090 ; RV64I-LABEL: mul11:
1091 ; RV64I:       # %bb.0:
1092 ; RV64I-NEXT:    li a1, 11
1093 ; RV64I-NEXT:    mul a0, a0, a1
1094 ; RV64I-NEXT:    ret
1096 ; RV64ZBA-LABEL: mul11:
1097 ; RV64ZBA:       # %bb.0:
1098 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
1099 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1100 ; RV64ZBA-NEXT:    ret
1101   %c = mul i64 %a, 11
1102   ret i64 %c
1105 define i64 @mul19(i64 %a) {
1106 ; RV64I-LABEL: mul19:
1107 ; RV64I:       # %bb.0:
1108 ; RV64I-NEXT:    li a1, 19
1109 ; RV64I-NEXT:    mul a0, a0, a1
1110 ; RV64I-NEXT:    ret
1112 ; RV64ZBA-LABEL: mul19:
1113 ; RV64ZBA:       # %bb.0:
1114 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
1115 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1116 ; RV64ZBA-NEXT:    ret
1117   %c = mul i64 %a, 19
1118   ret i64 %c
1121 define i64 @mul13(i64 %a) {
1122 ; RV64I-LABEL: mul13:
1123 ; RV64I:       # %bb.0:
1124 ; RV64I-NEXT:    li a1, 13
1125 ; RV64I-NEXT:    mul a0, a0, a1
1126 ; RV64I-NEXT:    ret
1128 ; RV64ZBA-LABEL: mul13:
1129 ; RV64ZBA:       # %bb.0:
1130 ; RV64ZBA-NEXT:    sh1add a1, a0, a0
1131 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1132 ; RV64ZBA-NEXT:    ret
1133   %c = mul i64 %a, 13
1134   ret i64 %c
1137 define i64 @mul21(i64 %a) {
1138 ; RV64I-LABEL: mul21:
1139 ; RV64I:       # %bb.0:
1140 ; RV64I-NEXT:    li a1, 21
1141 ; RV64I-NEXT:    mul a0, a0, a1
1142 ; RV64I-NEXT:    ret
1144 ; RV64ZBA-LABEL: mul21:
1145 ; RV64ZBA:       # %bb.0:
1146 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
1147 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1148 ; RV64ZBA-NEXT:    ret
1149   %c = mul i64 %a, 21
1150   ret i64 %c
1153 define i64 @mul37(i64 %a) {
1154 ; RV64I-LABEL: mul37:
1155 ; RV64I:       # %bb.0:
1156 ; RV64I-NEXT:    li a1, 37
1157 ; RV64I-NEXT:    mul a0, a0, a1
1158 ; RV64I-NEXT:    ret
1160 ; RV64ZBA-LABEL: mul37:
1161 ; RV64ZBA:       # %bb.0:
1162 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
1163 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1164 ; RV64ZBA-NEXT:    ret
1165   %c = mul i64 %a, 37
1166   ret i64 %c
1169 define i64 @mul25(i64 %a) {
1170 ; RV64I-LABEL: mul25:
1171 ; RV64I:       # %bb.0:
1172 ; RV64I-NEXT:    li a1, 25
1173 ; RV64I-NEXT:    mul a0, a0, a1
1174 ; RV64I-NEXT:    ret
1176 ; RV64ZBA-LABEL: mul25:
1177 ; RV64ZBA:       # %bb.0:
1178 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
1179 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
1180 ; RV64ZBA-NEXT:    ret
1181   %c = mul i64 %a, 25
1182   ret i64 %c
1185 define i64 @mul41(i64 %a) {
1186 ; RV64I-LABEL: mul41:
1187 ; RV64I:       # %bb.0:
1188 ; RV64I-NEXT:    li a1, 41
1189 ; RV64I-NEXT:    mul a0, a0, a1
1190 ; RV64I-NEXT:    ret
1192 ; RV64ZBA-LABEL: mul41:
1193 ; RV64ZBA:       # %bb.0:
1194 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
1195 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1196 ; RV64ZBA-NEXT:    ret
1197   %c = mul i64 %a, 41
1198   ret i64 %c
1201 define i64 @mul73(i64 %a) {
1202 ; RV64I-LABEL: mul73:
1203 ; RV64I:       # %bb.0:
1204 ; RV64I-NEXT:    li a1, 73
1205 ; RV64I-NEXT:    mul a0, a0, a1
1206 ; RV64I-NEXT:    ret
1208 ; RV64ZBA-LABEL: mul73:
1209 ; RV64ZBA:       # %bb.0:
1210 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
1211 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1212 ; RV64ZBA-NEXT:    ret
1213   %c = mul i64 %a, 73
1214   ret i64 %c
1217 define i64 @mul27(i64 %a) {
1218 ; RV64I-LABEL: mul27:
1219 ; RV64I:       # %bb.0:
1220 ; RV64I-NEXT:    li a1, 27
1221 ; RV64I-NEXT:    mul a0, a0, a1
1222 ; RV64I-NEXT:    ret
1224 ; RV64ZBA-LABEL: mul27:
1225 ; RV64ZBA:       # %bb.0:
1226 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
1227 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
1228 ; RV64ZBA-NEXT:    ret
1229   %c = mul i64 %a, 27
1230   ret i64 %c
1233 define i64 @mul45(i64 %a) {
1234 ; RV64I-LABEL: mul45:
1235 ; RV64I:       # %bb.0:
1236 ; RV64I-NEXT:    li a1, 45
1237 ; RV64I-NEXT:    mul a0, a0, a1
1238 ; RV64I-NEXT:    ret
1240 ; RV64ZBA-LABEL: mul45:
1241 ; RV64ZBA:       # %bb.0:
1242 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
1243 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
1244 ; RV64ZBA-NEXT:    ret
1245   %c = mul i64 %a, 45
1246   ret i64 %c
1249 define i64 @mul81(i64 %a) {
1250 ; RV64I-LABEL: mul81:
1251 ; RV64I:       # %bb.0:
1252 ; RV64I-NEXT:    li a1, 81
1253 ; RV64I-NEXT:    mul a0, a0, a1
1254 ; RV64I-NEXT:    ret
1256 ; RV64ZBA-LABEL: mul81:
1257 ; RV64ZBA:       # %bb.0:
1258 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
1259 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
1260 ; RV64ZBA-NEXT:    ret
1261   %c = mul i64 %a, 81
1262   ret i64 %c
1265 define i64 @mul4098(i64 %a) {
1266 ; RV64I-LABEL: mul4098:
1267 ; RV64I:       # %bb.0:
1268 ; RV64I-NEXT:    slli a1, a0, 1
1269 ; RV64I-NEXT:    slli a0, a0, 12
1270 ; RV64I-NEXT:    add a0, a0, a1
1271 ; RV64I-NEXT:    ret
1273 ; RV64ZBA-LABEL: mul4098:
1274 ; RV64ZBA:       # %bb.0:
1275 ; RV64ZBA-NEXT:    slli a1, a0, 12
1276 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
1277 ; RV64ZBA-NEXT:    ret
1278   %c = mul i64 %a, 4098
1279   ret i64 %c
1282 define i64 @mul4100(i64 %a) {
1283 ; RV64I-LABEL: mul4100:
1284 ; RV64I:       # %bb.0:
1285 ; RV64I-NEXT:    slli a1, a0, 2
1286 ; RV64I-NEXT:    slli a0, a0, 12
1287 ; RV64I-NEXT:    add a0, a0, a1
1288 ; RV64I-NEXT:    ret
1290 ; RV64ZBA-LABEL: mul4100:
1291 ; RV64ZBA:       # %bb.0:
1292 ; RV64ZBA-NEXT:    slli a1, a0, 12
1293 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
1294 ; RV64ZBA-NEXT:    ret
1295   %c = mul i64 %a, 4100
1296   ret i64 %c
1299 define i64 @mul4104(i64 %a) {
1300 ; RV64I-LABEL: mul4104:
1301 ; RV64I:       # %bb.0:
1302 ; RV64I-NEXT:    slli a1, a0, 3
1303 ; RV64I-NEXT:    slli a0, a0, 12
1304 ; RV64I-NEXT:    add a0, a0, a1
1305 ; RV64I-NEXT:    ret
1307 ; RV64ZBA-LABEL: mul4104:
1308 ; RV64ZBA:       # %bb.0:
1309 ; RV64ZBA-NEXT:    slli a1, a0, 12
1310 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
1311 ; RV64ZBA-NEXT:    ret
1312   %c = mul i64 %a, 4104
1313   ret i64 %c
1316 define signext i32 @mulw192(i32 signext %a) {
1317 ; RV64I-LABEL: mulw192:
1318 ; RV64I:       # %bb.0:
1319 ; RV64I-NEXT:    slli a1, a0, 6
1320 ; RV64I-NEXT:    slli a0, a0, 8
1321 ; RV64I-NEXT:    subw a0, a0, a1
1322 ; RV64I-NEXT:    ret
1324 ; RV64ZBA-LABEL: mulw192:
1325 ; RV64ZBA:       # %bb.0:
1326 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
1327 ; RV64ZBA-NEXT:    slliw a0, a0, 6
1328 ; RV64ZBA-NEXT:    ret
1329   %c = mul i32 %a, 192
1330   ret i32 %c
1333 define signext i32 @mulw320(i32 signext %a) {
1334 ; RV64I-LABEL: mulw320:
1335 ; RV64I:       # %bb.0:
1336 ; RV64I-NEXT:    li a1, 320
1337 ; RV64I-NEXT:    mulw a0, a0, a1
1338 ; RV64I-NEXT:    ret
1340 ; RV64ZBA-LABEL: mulw320:
1341 ; RV64ZBA:       # %bb.0:
1342 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
1343 ; RV64ZBA-NEXT:    slliw a0, a0, 6
1344 ; RV64ZBA-NEXT:    ret
1345   %c = mul i32 %a, 320
1346   ret i32 %c
1349 define signext i32 @mulw576(i32 signext %a) {
1350 ; RV64I-LABEL: mulw576:
1351 ; RV64I:       # %bb.0:
1352 ; RV64I-NEXT:    li a1, 576
1353 ; RV64I-NEXT:    mulw a0, a0, a1
1354 ; RV64I-NEXT:    ret
1356 ; RV64ZBA-LABEL: mulw576:
1357 ; RV64ZBA:       # %bb.0:
1358 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
1359 ; RV64ZBA-NEXT:    slliw a0, a0, 6
1360 ; RV64ZBA-NEXT:    ret
1361   %c = mul i32 %a, 576
1362   ret i32 %c
1365 define i64 @add4104(i64 %a) {
1366 ; RV64I-LABEL: add4104:
1367 ; RV64I:       # %bb.0:
1368 ; RV64I-NEXT:    lui a1, 1
1369 ; RV64I-NEXT:    addiw a1, a1, 8
1370 ; RV64I-NEXT:    add a0, a0, a1
1371 ; RV64I-NEXT:    ret
1373 ; RV64ZBA-LABEL: add4104:
1374 ; RV64ZBA:       # %bb.0:
1375 ; RV64ZBA-NEXT:    li a1, 1026
1376 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1377 ; RV64ZBA-NEXT:    ret
1378   %c = add i64 %a, 4104
1379   ret i64 %c
1382 define i64 @add4104_2(i64 %a) {
1383 ; RV64I-LABEL: add4104_2:
1384 ; RV64I:       # %bb.0:
1385 ; RV64I-NEXT:    lui a1, 1
1386 ; RV64I-NEXT:    addiw a1, a1, 8
1387 ; RV64I-NEXT:    or a0, a0, a1
1388 ; RV64I-NEXT:    ret
1390 ; RV64ZBA-LABEL: add4104_2:
1391 ; RV64ZBA:       # %bb.0:
1392 ; RV64ZBA-NEXT:    li a1, 1026
1393 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1394 ; RV64ZBA-NEXT:    ret
1395   %c = or disjoint i64 %a, 4104
1396   ret i64 %c
1399 define i64 @add8208(i64 %a) {
1400 ; RV64I-LABEL: add8208:
1401 ; RV64I:       # %bb.0:
1402 ; RV64I-NEXT:    lui a1, 2
1403 ; RV64I-NEXT:    addiw a1, a1, 16
1404 ; RV64I-NEXT:    add a0, a0, a1
1405 ; RV64I-NEXT:    ret
1407 ; RV64ZBA-LABEL: add8208:
1408 ; RV64ZBA:       # %bb.0:
1409 ; RV64ZBA-NEXT:    li a1, 1026
1410 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1411 ; RV64ZBA-NEXT:    ret
1412   %c = add i64 %a, 8208
1413   ret i64 %c
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:
1419 ; CHECK:       # %bb.0:
1420 ; CHECK-NEXT:    lui a1, 2
1421 ; CHECK-NEXT:    addw a0, a0, a1
1422 ; CHECK-NEXT:    ret
1423   %c = add i32 %a, 8192
1424   ret i32 %c
1427 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1428 define i64 @add8192(i64 %a) {
1429 ; CHECK-LABEL: add8192:
1430 ; CHECK:       # %bb.0:
1431 ; CHECK-NEXT:    lui a1, 2
1432 ; CHECK-NEXT:    add a0, a0, a1
1433 ; CHECK-NEXT:    ret
1434   %c = add i64 %a, 8192
1435   ret i64 %c
1438 define signext i32 @addshl32_5_6(i32 signext %a, i32 signext %b) {
1439 ; RV64I-LABEL: addshl32_5_6:
1440 ; RV64I:       # %bb.0:
1441 ; RV64I-NEXT:    slli a0, a0, 5
1442 ; RV64I-NEXT:    slli a1, a1, 6
1443 ; RV64I-NEXT:    addw a0, a0, a1
1444 ; RV64I-NEXT:    ret
1446 ; RV64ZBA-LABEL: addshl32_5_6:
1447 ; RV64ZBA:       # %bb.0:
1448 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1449 ; RV64ZBA-NEXT:    slliw a0, a0, 5
1450 ; RV64ZBA-NEXT:    ret
1451   %c = shl i32 %a, 5
1452   %d = shl i32 %b, 6
1453   %e = add i32 %c, %d
1454   ret i32 %e
1457 define i64 @addshl64_5_6(i64 %a, i64 %b) {
1458 ; RV64I-LABEL: addshl64_5_6:
1459 ; RV64I:       # %bb.0:
1460 ; RV64I-NEXT:    slli a0, a0, 5
1461 ; RV64I-NEXT:    slli a1, a1, 6
1462 ; RV64I-NEXT:    add a0, a0, a1
1463 ; RV64I-NEXT:    ret
1465 ; RV64ZBA-LABEL: addshl64_5_6:
1466 ; RV64ZBA:       # %bb.0:
1467 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1468 ; RV64ZBA-NEXT:    slli a0, a0, 5
1469 ; RV64ZBA-NEXT:    ret
1470   %c = shl i64 %a, 5
1471   %d = shl i64 %b, 6
1472   %e = add i64 %c, %d
1473   ret i64 %e
1476 define signext i32 @addshl32_5_7(i32 signext %a, i32 signext %b) {
1477 ; RV64I-LABEL: addshl32_5_7:
1478 ; RV64I:       # %bb.0:
1479 ; RV64I-NEXT:    slli a0, a0, 5
1480 ; RV64I-NEXT:    slli a1, a1, 7
1481 ; RV64I-NEXT:    addw a0, a0, a1
1482 ; RV64I-NEXT:    ret
1484 ; RV64ZBA-LABEL: addshl32_5_7:
1485 ; RV64ZBA:       # %bb.0:
1486 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1487 ; RV64ZBA-NEXT:    slliw a0, a0, 5
1488 ; RV64ZBA-NEXT:    ret
1489   %c = shl i32 %a, 5
1490   %d = shl i32 %b, 7
1491   %e = add i32 %c, %d
1492   ret i32 %e
1495 define i64 @addshl64_5_7(i64 %a, i64 %b) {
1496 ; RV64I-LABEL: addshl64_5_7:
1497 ; RV64I:       # %bb.0:
1498 ; RV64I-NEXT:    slli a0, a0, 5
1499 ; RV64I-NEXT:    slli a1, a1, 7
1500 ; RV64I-NEXT:    add a0, a0, a1
1501 ; RV64I-NEXT:    ret
1503 ; RV64ZBA-LABEL: addshl64_5_7:
1504 ; RV64ZBA:       # %bb.0:
1505 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1506 ; RV64ZBA-NEXT:    slli a0, a0, 5
1507 ; RV64ZBA-NEXT:    ret
1508   %c = shl i64 %a, 5
1509   %d = shl i64 %b, 7
1510   %e = add i64 %c, %d
1511   ret i64 %e
1514 define signext i32 @addshl32_5_8(i32 signext %a, i32 signext %b) {
1515 ; RV64I-LABEL: addshl32_5_8:
1516 ; RV64I:       # %bb.0:
1517 ; RV64I-NEXT:    slli a0, a0, 5
1518 ; RV64I-NEXT:    slli a1, a1, 8
1519 ; RV64I-NEXT:    addw a0, a0, a1
1520 ; RV64I-NEXT:    ret
1522 ; RV64ZBA-LABEL: addshl32_5_8:
1523 ; RV64ZBA:       # %bb.0:
1524 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1525 ; RV64ZBA-NEXT:    slliw a0, a0, 5
1526 ; RV64ZBA-NEXT:    ret
1527   %c = shl i32 %a, 5
1528   %d = shl i32 %b, 8
1529   %e = add i32 %c, %d
1530   ret i32 %e
1533 define i64 @addshl64_5_8(i64 %a, i64 %b) {
1534 ; RV64I-LABEL: addshl64_5_8:
1535 ; RV64I:       # %bb.0:
1536 ; RV64I-NEXT:    slli a0, a0, 5
1537 ; RV64I-NEXT:    slli a1, a1, 8
1538 ; RV64I-NEXT:    add a0, a0, a1
1539 ; RV64I-NEXT:    ret
1541 ; RV64ZBA-LABEL: addshl64_5_8:
1542 ; RV64ZBA:       # %bb.0:
1543 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1544 ; RV64ZBA-NEXT:    slli a0, a0, 5
1545 ; RV64ZBA-NEXT:    ret
1546   %c = shl i64 %a, 5
1547   %d = shl i64 %b, 8
1548   %e = add i64 %c, %d
1549   ret i64 %e
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:
1556 ; RV64I:       # %bb.0:
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
1561 ; RV64I-NEXT:    ret
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
1579   ret i32 %1
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
1589 ; RV64I-NEXT:    ret
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
1595 ; RV64ZBA-NEXT:    ret
1596 entry:
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
1601   ret i64 %add2
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
1611 ; RV64I-NEXT:    ret
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
1617 ; RV64ZBA-NEXT:    ret
1618 entry:
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
1623   ret i64 %add2
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
1633 ; RV64I-NEXT:    ret
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
1639 ; RV64ZBA-NEXT:    ret
1640 entry:
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
1645   ret i64 %add2
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
1655 ; RV64I-NEXT:    ret
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
1662 ; RV64ZBA-NEXT:    ret
1663 entry:
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
1668   ret i64 %add2
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:
1675 ; RV64I:       # %bb.0:
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
1680 ; RV64I-NEXT:    ret
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
1698   ret i32 %1
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:
1705 ; RV64I:       # %bb.0:
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)
1712 ; RV64I-NEXT:    ret
1714 ; RV64ZBA-LABEL: sh1adduw_ptrdiff:
1715 ; RV64ZBA:       # %bb.0:
1716 ; RV64ZBA-NEXT:    srli a0, a0, 1
1717 ; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
1718 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1719 ; RV64ZBA-NEXT:    ret
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
1724   ret i16 %res
1727 define signext i32 @sh2adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1728 ; RV64I-LABEL: sh2adduw_ptrdiff:
1729 ; RV64I:       # %bb.0:
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)
1736 ; RV64I-NEXT:    ret
1738 ; RV64ZBA-LABEL: sh2adduw_ptrdiff:
1739 ; RV64ZBA:       # %bb.0:
1740 ; RV64ZBA-NEXT:    srli a0, a0, 2
1741 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
1742 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1743 ; RV64ZBA-NEXT:    ret
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
1748   ret i32 %res
1751 define i64 @sh3adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1752 ; RV64I-LABEL: sh3adduw_ptrdiff:
1753 ; RV64I:       # %bb.0:
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)
1760 ; RV64I-NEXT:    ret
1762 ; RV64ZBA-LABEL: sh3adduw_ptrdiff:
1763 ; RV64ZBA:       # %bb.0:
1764 ; RV64ZBA-NEXT:    srli a0, a0, 3
1765 ; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
1766 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1767 ; RV64ZBA-NEXT:    ret
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
1772   ret i64 %res
1775 define signext i16 @srliw_1_sh1add(ptr %0, i32 signext %1) {
1776 ; RV64I-LABEL: srliw_1_sh1add:
1777 ; RV64I:       # %bb.0:
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)
1782 ; RV64I-NEXT:    ret
1784 ; RV64ZBA-LABEL: srliw_1_sh1add:
1785 ; RV64ZBA:       # %bb.0:
1786 ; RV64ZBA-NEXT:    srliw a1, a1, 1
1787 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1788 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1789 ; RV64ZBA-NEXT:    ret
1790   %3 = lshr i32 %1, 1
1791   %4 = zext i32 %3 to i64
1792   %5 = getelementptr inbounds i16, ptr %0, i64 %4
1793   %6 = load i16, ptr %5, align 2
1794   ret i16 %6
1797 define i128 @slliuw_ptrdiff(i64 %diff, ptr %baseptr) {
1798 ; RV64I-LABEL: slliuw_ptrdiff:
1799 ; RV64I:       # %bb.0:
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)
1807 ; RV64I-NEXT:    ret
1809 ; RV64ZBA-LABEL: slliuw_ptrdiff:
1810 ; RV64ZBA:       # %bb.0:
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)
1816 ; RV64ZBA-NEXT:    ret
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
1821   ret i128 %res
1824 define signext i32 @srliw_2_sh2add(ptr %0, i32 signext %1) {
1825 ; RV64I-LABEL: srliw_2_sh2add:
1826 ; RV64I:       # %bb.0:
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)
1831 ; RV64I-NEXT:    ret
1833 ; RV64ZBA-LABEL: srliw_2_sh2add:
1834 ; RV64ZBA:       # %bb.0:
1835 ; RV64ZBA-NEXT:    srliw a1, a1, 2
1836 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1837 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1838 ; RV64ZBA-NEXT:    ret
1839   %3 = lshr i32 %1, 2
1840   %4 = zext i32 %3 to i64
1841   %5 = getelementptr inbounds i32, ptr %0, i64 %4
1842   %6 = load i32, ptr %5, align 4
1843   ret i32 %6
1846 define i64 @srliw_3_sh3add(ptr %0, i32 signext %1) {
1847 ; RV64I-LABEL: srliw_3_sh3add:
1848 ; RV64I:       # %bb.0:
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)
1853 ; RV64I-NEXT:    ret
1855 ; RV64ZBA-LABEL: srliw_3_sh3add:
1856 ; RV64ZBA:       # %bb.0:
1857 ; RV64ZBA-NEXT:    srliw a1, a1, 3
1858 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1859 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1860 ; RV64ZBA-NEXT:    ret
1861   %3 = lshr i32 %1, 3
1862   %4 = zext i32 %3 to i64
1863   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1864   %6 = load i64, ptr %5, align 8
1865   ret i64 %6
1868 define signext i32 @srliw_1_sh2add(ptr %0, i32 signext %1) {
1869 ; RV64I-LABEL: srliw_1_sh2add:
1870 ; RV64I:       # %bb.0:
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)
1875 ; RV64I-NEXT:    ret
1877 ; RV64ZBA-LABEL: srliw_1_sh2add:
1878 ; RV64ZBA:       # %bb.0:
1879 ; RV64ZBA-NEXT:    srliw a1, a1, 1
1880 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1881 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1882 ; RV64ZBA-NEXT:    ret
1883   %3 = lshr i32 %1, 1
1884   %4 = zext i32 %3 to i64
1885   %5 = getelementptr inbounds i32, ptr %0, i64 %4
1886   %6 = load i32, ptr %5, align 4
1887   ret i32 %6
1890 define i64 @srliw_1_sh3add(ptr %0, i32 signext %1) {
1891 ; RV64I-LABEL: srliw_1_sh3add:
1892 ; RV64I:       # %bb.0:
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)
1897 ; RV64I-NEXT:    ret
1899 ; RV64ZBA-LABEL: srliw_1_sh3add:
1900 ; RV64ZBA:       # %bb.0:
1901 ; RV64ZBA-NEXT:    srliw a1, a1, 1
1902 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1903 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1904 ; RV64ZBA-NEXT:    ret
1905   %3 = lshr i32 %1, 1
1906   %4 = zext i32 %3 to i64
1907   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1908   %6 = load i64, ptr %5, align 8
1909   ret i64 %6
1912 define i64 @srliw_2_sh3add(ptr %0, i32 signext %1) {
1913 ; RV64I-LABEL: srliw_2_sh3add:
1914 ; RV64I:       # %bb.0:
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)
1919 ; RV64I-NEXT:    ret
1921 ; RV64ZBA-LABEL: srliw_2_sh3add:
1922 ; RV64ZBA:       # %bb.0:
1923 ; RV64ZBA-NEXT:    srliw a1, a1, 2
1924 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1925 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1926 ; RV64ZBA-NEXT:    ret
1927   %3 = lshr i32 %1, 2
1928   %4 = zext i32 %3 to i64
1929   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1930   %6 = load i64, ptr %5, align 8
1931   ret i64 %6
1934 define signext i16 @srliw_2_sh1add(ptr %0, i32 signext %1) {
1935 ; RV64I-LABEL: srliw_2_sh1add:
1936 ; RV64I:       # %bb.0:
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)
1941 ; RV64I-NEXT:    ret
1943 ; RV64ZBA-LABEL: srliw_2_sh1add:
1944 ; RV64ZBA:       # %bb.0:
1945 ; RV64ZBA-NEXT:    srliw a1, a1, 2
1946 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1947 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1948 ; RV64ZBA-NEXT:    ret
1949   %3 = lshr i32 %1, 2
1950   %4 = zext i32 %3 to i64
1951   %5 = getelementptr inbounds i16, ptr %0, i64 %4
1952   %6 = load i16, ptr %5, align 2
1953   ret i16 %6
1957 define signext i32 @srliw_3_sh2add(ptr %0, i32 signext %1) {
1958 ; RV64I-LABEL: srliw_3_sh2add:
1959 ; RV64I:       # %bb.0:
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)
1964 ; RV64I-NEXT:    ret
1966 ; RV64ZBA-LABEL: srliw_3_sh2add:
1967 ; RV64ZBA:       # %bb.0:
1968 ; RV64ZBA-NEXT:    srliw a1, a1, 3
1969 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1970 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1971 ; RV64ZBA-NEXT:    ret
1972   %3 = lshr i32 %1, 3
1973   %4 = zext i32 %3 to i64
1974   %5 = getelementptr inbounds i32, ptr %0, i64 %4
1975   %6 = load i32, ptr %5, align 4
1976   ret i32 %6
1979 define i64 @srliw_4_sh3add(ptr %0, i32 signext %1) {
1980 ; RV64I-LABEL: srliw_4_sh3add:
1981 ; RV64I:       # %bb.0:
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)
1986 ; RV64I-NEXT:    ret
1988 ; RV64ZBA-LABEL: srliw_4_sh3add:
1989 ; RV64ZBA:       # %bb.0:
1990 ; RV64ZBA-NEXT:    srliw a1, a1, 4
1991 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1992 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1993 ; RV64ZBA-NEXT:    ret
1994   %3 = lshr i32 %1, 4
1995   %4 = zext i32 %3 to i64
1996   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1997   %6 = load i64, ptr %5, align 8
1998   ret i64 %6
2001 define signext i32 @srli_1_sh2add(ptr %0, i64 %1) {
2002 ; RV64I-LABEL: srli_1_sh2add:
2003 ; RV64I:       # %bb.0:
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)
2008 ; RV64I-NEXT:    ret
2010 ; RV64ZBA-LABEL: srli_1_sh2add:
2011 ; RV64ZBA:       # %bb.0:
2012 ; RV64ZBA-NEXT:    srli a1, a1, 1
2013 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
2014 ; RV64ZBA-NEXT:    lw a0, 0(a0)
2015 ; RV64ZBA-NEXT:    ret
2016   %3 = lshr i64 %1, 1
2017   %4 = getelementptr inbounds i32, ptr %0, i64 %3
2018   %5 = load i32, ptr %4, align 4
2019   ret i32 %5
2022 define i64 @srli_2_sh3add(ptr %0, i64 %1) {
2023 ; RV64I-LABEL: srli_2_sh3add:
2024 ; RV64I:       # %bb.0:
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)
2029 ; RV64I-NEXT:    ret
2031 ; RV64ZBA-LABEL: srli_2_sh3add:
2032 ; RV64ZBA:       # %bb.0:
2033 ; RV64ZBA-NEXT:    srli a1, a1, 2
2034 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
2035 ; RV64ZBA-NEXT:    ld a0, 0(a0)
2036 ; RV64ZBA-NEXT:    ret
2037   %3 = lshr i64 %1, 2
2038   %4 = getelementptr inbounds i64, ptr %0, i64 %3
2039   %5 = load i64, ptr %4, align 8
2040   ret i64 %5
2043 define signext i16 @srli_2_sh1add(ptr %0, i64 %1) {
2044 ; RV64I-LABEL: srli_2_sh1add:
2045 ; RV64I:       # %bb.0:
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)
2050 ; RV64I-NEXT:    ret
2052 ; RV64ZBA-LABEL: srli_2_sh1add:
2053 ; RV64ZBA:       # %bb.0:
2054 ; RV64ZBA-NEXT:    srli a1, a1, 2
2055 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
2056 ; RV64ZBA-NEXT:    lh a0, 0(a0)
2057 ; RV64ZBA-NEXT:    ret
2058   %3 = lshr i64 %1, 2
2059   %4 = getelementptr inbounds i16, ptr %0, i64 %3
2060   %5 = load i16, ptr %4, align 2
2061   ret i16 %5
2064 define signext i32 @srli_3_sh2add(ptr %0, i64 %1) {
2065 ; RV64I-LABEL: srli_3_sh2add:
2066 ; RV64I:       # %bb.0:
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)
2071 ; RV64I-NEXT:    ret
2073 ; RV64ZBA-LABEL: srli_3_sh2add:
2074 ; RV64ZBA:       # %bb.0:
2075 ; RV64ZBA-NEXT:    srli a1, a1, 3
2076 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
2077 ; RV64ZBA-NEXT:    lw a0, 0(a0)
2078 ; RV64ZBA-NEXT:    ret
2079   %3 = lshr i64 %1, 3
2080   %4 = getelementptr inbounds i32, ptr %0, i64 %3
2081   %5 = load i32, ptr %4, align 4
2082   ret i32 %5
2085 define i64 @srli_4_sh3add(ptr %0, i64 %1) {
2086 ; RV64I-LABEL: srli_4_sh3add:
2087 ; RV64I:       # %bb.0:
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)
2092 ; RV64I-NEXT:    ret
2094 ; RV64ZBA-LABEL: srli_4_sh3add:
2095 ; RV64ZBA:       # %bb.0:
2096 ; RV64ZBA-NEXT:    srli a1, a1, 4
2097 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
2098 ; RV64ZBA-NEXT:    ld a0, 0(a0)
2099 ; RV64ZBA-NEXT:    ret
2100   %3 = lshr i64 %1, 4
2101   %4 = getelementptr inbounds i64, ptr %0, i64 %3
2102   %5 = load i64, ptr %4, align 8
2103   ret i64 %5
2106 define signext i16 @shl_2_sh1add(ptr %0, i32 signext %1) {
2107 ; RV64I-LABEL: shl_2_sh1add:
2108 ; RV64I:       # %bb.0:
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)
2113 ; RV64I-NEXT:    ret
2115 ; RV64ZBA-LABEL: shl_2_sh1add:
2116 ; RV64ZBA:       # %bb.0:
2117 ; RV64ZBA-NEXT:    slli a1, a1, 2
2118 ; RV64ZBA-NEXT:    sh1add.uw a0, a1, a0
2119 ; RV64ZBA-NEXT:    lh a0, 0(a0)
2120 ; RV64ZBA-NEXT:    ret
2121   %3 = shl i32 %1, 2
2122   %4 = zext i32 %3 to i64
2123   %5 = getelementptr inbounds i16, ptr %0, i64 %4
2124   %6 = load i16, ptr %5, align 2
2125   ret i16 %6
2128 define signext i32 @shl_16_sh2add(ptr %0, i32 signext %1) {
2129 ; RV64I-LABEL: shl_16_sh2add:
2130 ; RV64I:       # %bb.0:
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)
2135 ; RV64I-NEXT:    ret
2137 ; RV64ZBA-LABEL: shl_16_sh2add:
2138 ; RV64ZBA:       # %bb.0:
2139 ; RV64ZBA-NEXT:    slli a1, a1, 16
2140 ; RV64ZBA-NEXT:    sh2add.uw a0, a1, a0
2141 ; RV64ZBA-NEXT:    lw a0, 0(a0)
2142 ; RV64ZBA-NEXT:    ret
2143   %3 = shl i32 %1, 16
2144   %4 = zext i32 %3 to i64
2145   %5 = getelementptr inbounds i32, ptr %0, i64 %4
2146   %6 = load i32, ptr %5, align 4
2147   ret i32 %6
2150 define i64 @shl_31_sh3add(ptr %0, i32 signext %1) {
2151 ; RV64I-LABEL: shl_31_sh3add:
2152 ; RV64I:       # %bb.0:
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)
2157 ; RV64I-NEXT:    ret
2159 ; RV64ZBA-LABEL: shl_31_sh3add:
2160 ; RV64ZBA:       # %bb.0:
2161 ; RV64ZBA-NEXT:    slli a1, a1, 31
2162 ; RV64ZBA-NEXT:    sh3add.uw a0, a1, a0
2163 ; RV64ZBA-NEXT:    ld a0, 0(a0)
2164 ; RV64ZBA-NEXT:    ret
2165   %3 = shl i32 %1, 31
2166   %4 = zext i32 %3 to i64
2167   %5 = getelementptr inbounds i64, ptr %0, i64 %4
2168   %6 = load i64, ptr %5, align 8
2169   ret i64 %6
2172 define i64 @pack_i64(i64 %a, i64 %b) nounwind {
2173 ; RV64I-LABEL: pack_i64:
2174 ; RV64I:       # %bb.0:
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
2179 ; RV64I-NEXT:    ret
2181 ; RV64ZBA-LABEL: pack_i64:
2182 ; RV64ZBA:       # %bb.0:
2183 ; RV64ZBA-NEXT:    slli a1, a1, 32
2184 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
2185 ; RV64ZBA-NEXT:    ret
2186   %shl = and i64 %a, 4294967295
2187   %shl1 = shl i64 %b, 32
2188   %or = or i64 %shl1, %shl
2189   ret i64 %or
2192 define i64 @pack_i64_2(i32 signext %a, i32 signext %b) nounwind {
2193 ; RV64I-LABEL: pack_i64_2:
2194 ; RV64I:       # %bb.0:
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
2199 ; RV64I-NEXT:    ret
2201 ; RV64ZBA-LABEL: pack_i64_2:
2202 ; RV64ZBA:       # %bb.0:
2203 ; RV64ZBA-NEXT:    slli a1, a1, 32
2204 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
2205 ; RV64ZBA-NEXT:    ret
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
2210   ret i64 %or
2213 define i64 @pack_i64_disjoint(i64 %a, i64 %b) nounwind {
2214 ; RV64I-LABEL: pack_i64_disjoint:
2215 ; RV64I:       # %bb.0:
2216 ; RV64I-NEXT:    slli a0, a0, 32
2217 ; RV64I-NEXT:    srli a0, a0, 32
2218 ; RV64I-NEXT:    or a0, a1, a0
2219 ; RV64I-NEXT:    ret
2221 ; RV64ZBA-LABEL: pack_i64_disjoint:
2222 ; RV64ZBA:       # %bb.0:
2223 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
2224 ; RV64ZBA-NEXT:    ret
2225   %shl = and i64 %a, 4294967295
2226   %or = or disjoint i64 %b, %shl
2227   ret i64 %or
2230 define i64 @pack_i64_disjoint_2(i32 signext %a, i64 %b) nounwind {
2231 ; RV64I-LABEL: pack_i64_disjoint_2:
2232 ; RV64I:       # %bb.0:
2233 ; RV64I-NEXT:    slli a0, a0, 32
2234 ; RV64I-NEXT:    srli a0, a0, 32
2235 ; RV64I-NEXT:    or a0, a1, a0
2236 ; RV64I-NEXT:    ret
2238 ; RV64ZBA-LABEL: pack_i64_disjoint_2:
2239 ; RV64ZBA:       # %bb.0:
2240 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
2241 ; RV64ZBA-NEXT:    ret
2242   %zexta = zext i32 %a to i64
2243   %or = or disjoint i64 %b, %zexta
2244   ret i64 %or
2247 define i8 @array_index_sh1_sh0(ptr %p, i64 %idx1, i64 %idx2) {
2248 ; RV64I-LABEL: array_index_sh1_sh0:
2249 ; RV64I:       # %bb.0:
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)
2254 ; RV64I-NEXT:    ret
2256 ; RV64ZBA-LABEL: array_index_sh1_sh0:
2257 ; RV64ZBA:       # %bb.0:
2258 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
2259 ; RV64ZBA-NEXT:    add a0, a0, a2
2260 ; RV64ZBA-NEXT:    lbu a0, 0(a0)
2261 ; RV64ZBA-NEXT:    ret
2262   %a = getelementptr inbounds [2 x i8], ptr %p, i64 %idx1, i64 %idx2
2263   %b = load i8, ptr %a, align 1
2264   ret i8 %b
2267 define i16 @array_index_sh1_sh1(ptr %p, i64 %idx1, i64 %idx2) {
2268 ; RV64I-LABEL: array_index_sh1_sh1:
2269 ; RV64I:       # %bb.0:
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)
2275 ; RV64I-NEXT:    ret
2277 ; RV64ZBA-LABEL: array_index_sh1_sh1:
2278 ; RV64ZBA:       # %bb.0:
2279 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
2280 ; RV64ZBA-NEXT:    sh1add a0, a2, a0
2281 ; RV64ZBA-NEXT:    lh a0, 0(a0)
2282 ; RV64ZBA-NEXT:    ret
2283   %a = getelementptr inbounds [2 x i16], ptr %p, i64 %idx1, i64 %idx2
2284   %b = load i16, ptr %a, align 2
2285   ret i16 %b
2288 define i32 @array_index_sh1_sh2(ptr %p, i64 %idx1, i64 %idx2) {
2289 ; RV64I-LABEL: array_index_sh1_sh2:
2290 ; RV64I:       # %bb.0:
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)
2296 ; RV64I-NEXT:    ret
2298 ; RV64ZBA-LABEL: array_index_sh1_sh2:
2299 ; RV64ZBA:       # %bb.0:
2300 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
2301 ; RV64ZBA-NEXT:    sh2add a0, a2, a0
2302 ; RV64ZBA-NEXT:    lw a0, 0(a0)
2303 ; RV64ZBA-NEXT:    ret
2304   %a = getelementptr inbounds [2 x i32], ptr %p, i64 %idx1, i64 %idx2
2305   %b = load i32, ptr %a, align 4
2306   ret i32 %b
2309 define i64 @array_index_sh1_sh3(ptr %p, i64 %idx1, i64 %idx2) {
2310 ; RV64I-LABEL: array_index_sh1_sh3:
2311 ; RV64I:       # %bb.0:
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)
2317 ; RV64I-NEXT:    ret
2319 ; RV64ZBA-LABEL: array_index_sh1_sh3:
2320 ; RV64ZBA:       # %bb.0:
2321 ; RV64ZBA-NEXT:    sh1add a1, a1, a2
2322 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
2323 ; RV64ZBA-NEXT:    ld a0, 0(a0)
2324 ; RV64ZBA-NEXT:    ret
2325   %a = getelementptr inbounds [2 x i64], ptr %p, i64 %idx1, i64 %idx2
2326   %b = load i64, ptr %a, align 8
2327   ret i64 %b
2330 define i8 @array_index_sh2_sh0(ptr %p, i64 %idx1, i64 %idx2) {
2331 ; RV64I-LABEL: array_index_sh2_sh0:
2332 ; RV64I:       # %bb.0:
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)
2337 ; RV64I-NEXT:    ret
2339 ; RV64ZBA-LABEL: array_index_sh2_sh0:
2340 ; RV64ZBA:       # %bb.0:
2341 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
2342 ; RV64ZBA-NEXT:    add a0, a0, a2
2343 ; RV64ZBA-NEXT:    lbu a0, 0(a0)
2344 ; RV64ZBA-NEXT:    ret
2345   %a = getelementptr inbounds [4 x i8], ptr %p, i64 %idx1, i64 %idx2
2346   %b = load i8, ptr %a, align 1
2347   ret i8 %b
2350 define i16 @array_index_sh2_sh1(ptr %p, i64 %idx1, i64 %idx2) {
2351 ; RV64I-LABEL: array_index_sh2_sh1:
2352 ; RV64I:       # %bb.0:
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)
2358 ; RV64I-NEXT:    ret
2360 ; RV64ZBA-LABEL: array_index_sh2_sh1:
2361 ; RV64ZBA:       # %bb.0:
2362 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
2363 ; RV64ZBA-NEXT:    sh1add a0, a2, a0
2364 ; RV64ZBA-NEXT:    lh a0, 0(a0)
2365 ; RV64ZBA-NEXT:    ret
2366   %a = getelementptr inbounds [4 x i16], ptr %p, i64 %idx1, i64 %idx2
2367   %b = load i16, ptr %a, align 2
2368   ret i16 %b
2371 define i32 @array_index_sh2_sh2(ptr %p, i64 %idx1, i64 %idx2) {
2372 ; RV64I-LABEL: array_index_sh2_sh2:
2373 ; RV64I:       # %bb.0:
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)
2379 ; RV64I-NEXT:    ret
2381 ; RV64ZBA-LABEL: array_index_sh2_sh2:
2382 ; RV64ZBA:       # %bb.0:
2383 ; RV64ZBA-NEXT:    sh2add a1, a1, a2
2384 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
2385 ; RV64ZBA-NEXT:    lw a0, 0(a0)
2386 ; RV64ZBA-NEXT:    ret
2387   %a = getelementptr inbounds [4 x i32], ptr %p, i64 %idx1, i64 %idx2
2388   %b = load i32, ptr %a, align 4
2389   ret i32 %b
2392 define i64 @array_index_sh2_sh3(ptr %p, i64 %idx1, i64 %idx2) {
2393 ; RV64I-LABEL: array_index_sh2_sh3:
2394 ; RV64I:       # %bb.0:
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)
2400 ; RV64I-NEXT:    ret
2402 ; RV64ZBA-LABEL: array_index_sh2_sh3:
2403 ; RV64ZBA:       # %bb.0:
2404 ; RV64ZBA-NEXT:    sh2add a1, a1, a2
2405 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
2406 ; RV64ZBA-NEXT:    ld a0, 0(a0)
2407 ; RV64ZBA-NEXT:    ret
2408   %a = getelementptr inbounds [4 x i64], ptr %p, i64 %idx1, i64 %idx2
2409   %b = load i64, ptr %a, align 8
2410   ret i64 %b
2413 define i8 @array_index_sh3_sh0(ptr %p, i64 %idx1, i64 %idx2) {
2414 ; RV64I-LABEL: array_index_sh3_sh0:
2415 ; RV64I:       # %bb.0:
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)
2420 ; RV64I-NEXT:    ret
2422 ; RV64ZBA-LABEL: array_index_sh3_sh0:
2423 ; RV64ZBA:       # %bb.0:
2424 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
2425 ; RV64ZBA-NEXT:    add a0, a0, a2
2426 ; RV64ZBA-NEXT:    lbu a0, 0(a0)
2427 ; RV64ZBA-NEXT:    ret
2428   %a = getelementptr inbounds [8 x i8], ptr %p, i64 %idx1, i64 %idx2
2429   %b = load i8, ptr %a, align 1
2430   ret i8 %b
2433 define i16 @array_index_sh3_sh1(ptr %p, i64 %idx1, i64 %idx2) {
2434 ; RV64I-LABEL: array_index_sh3_sh1:
2435 ; RV64I:       # %bb.0:
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)
2441 ; RV64I-NEXT:    ret
2443 ; RV64ZBA-LABEL: array_index_sh3_sh1:
2444 ; RV64ZBA:       # %bb.0:
2445 ; RV64ZBA-NEXT:    sh3add a1, a1, a2
2446 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
2447 ; RV64ZBA-NEXT:    lh a0, 0(a0)
2448 ; RV64ZBA-NEXT:    ret
2449   %a = getelementptr inbounds [8 x i16], ptr %p, i64 %idx1, i64 %idx2
2450   %b = load i16, ptr %a, align 2
2451   ret i16 %b
2454 define i32 @array_index_sh3_sh2(ptr %p, i64 %idx1, i64 %idx2) {
2455 ; RV64I-LABEL: array_index_sh3_sh2:
2456 ; RV64I:       # %bb.0:
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)
2462 ; RV64I-NEXT:    ret
2464 ; RV64ZBA-LABEL: array_index_sh3_sh2:
2465 ; RV64ZBA:       # %bb.0:
2466 ; RV64ZBA-NEXT:    sh3add a1, a1, a2
2467 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
2468 ; RV64ZBA-NEXT:    lw a0, 0(a0)
2469 ; RV64ZBA-NEXT:    ret
2470   %a = getelementptr inbounds [8 x i32], ptr %p, i64 %idx1, i64 %idx2
2471   %b = load i32, ptr %a, align 4
2472   ret i32 %b
2475 define i64 @array_index_sh3_sh3(ptr %p, i64 %idx1, i64 %idx2) {
2476 ; RV64I-LABEL: array_index_sh3_sh3:
2477 ; RV64I:       # %bb.0:
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)
2483 ; RV64I-NEXT:    ret
2485 ; RV64ZBA-LABEL: array_index_sh3_sh3:
2486 ; RV64ZBA:       # %bb.0:
2487 ; RV64ZBA-NEXT:    sh3add a1, a1, a2
2488 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
2489 ; RV64ZBA-NEXT:    ld a0, 0(a0)
2490 ; RV64ZBA-NEXT:    ret
2491   %a = getelementptr inbounds [8 x i64], ptr %p, i64 %idx1, i64 %idx2
2492   %b = load i64, ptr %a, align 8
2493   ret i64 %b
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:
2500 ; RV64I:       # %bb.0:
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)
2507 ; RV64I-NEXT:    ret
2509 ; RV64ZBA-LABEL: array_index_lshr_sh3_sh3:
2510 ; RV64ZBA:       # %bb.0:
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)
2515 ; RV64ZBA-NEXT:    ret
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
2519   ret i64 %b
2522 define i8 @array_index_sh4_sh0(ptr %p, i64 %idx1, i64 %idx2) {
2523 ; CHECK-LABEL: array_index_sh4_sh0:
2524 ; CHECK:       # %bb.0:
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)
2529 ; CHECK-NEXT:    ret
2530   %a = getelementptr inbounds [16 x i8], ptr %p, i64 %idx1, i64 %idx2
2531   %b = load i8, ptr %a, align 1
2532   ret i8 %b
2535 define i16 @array_index_sh4_sh1(ptr %p, i64 %idx1, i64 %idx2) {
2536 ; RV64I-LABEL: array_index_sh4_sh1:
2537 ; RV64I:       # %bb.0:
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)
2543 ; RV64I-NEXT:    ret
2545 ; RV64ZBA-LABEL: array_index_sh4_sh1:
2546 ; RV64ZBA:       # %bb.0:
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)
2551 ; RV64ZBA-NEXT:    ret
2552   %a = getelementptr inbounds [16 x i16], ptr %p, i64 %idx1, i64 %idx2
2553   %b = load i16, ptr %a, align 2
2554   ret i16 %b
2557 define i32 @array_index_sh4_sh2(ptr %p, i64 %idx1, i64 %idx2) {
2558 ; RV64I-LABEL: array_index_sh4_sh2:
2559 ; RV64I:       # %bb.0:
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)
2565 ; RV64I-NEXT:    ret
2567 ; RV64ZBA-LABEL: array_index_sh4_sh2:
2568 ; RV64ZBA:       # %bb.0:
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)
2573 ; RV64ZBA-NEXT:    ret
2574   %a = getelementptr inbounds [16 x i32], ptr %p, i64 %idx1, i64 %idx2
2575   %b = load i32, ptr %a, align 4
2576   ret i32 %b
2579 define i64 @array_index_sh4_sh3(ptr %p, i64 %idx1, i64 %idx2) {
2580 ; RV64I-LABEL: array_index_sh4_sh3:
2581 ; RV64I:       # %bb.0:
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)
2587 ; RV64I-NEXT:    ret
2589 ; RV64ZBA-LABEL: array_index_sh4_sh3:
2590 ; RV64ZBA:       # %bb.0:
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)
2595 ; RV64ZBA-NEXT:    ret
2596   %a = getelementptr inbounds [16 x i64], ptr %p, i64 %idx1, i64 %idx2
2597   %b = load i64, ptr %a, align 8
2598   ret i64 %b
2601 define ptr @test_gep_gep_dont_crash(ptr %p, i64 %a1, i64 %a2) {
2602 ; RV64I-LABEL: test_gep_gep_dont_crash:
2603 ; RV64I:       # %bb.0:
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
2609 ; RV64I-NEXT:    ret
2611 ; RV64ZBA-LABEL: test_gep_gep_dont_crash:
2612 ; RV64ZBA:       # %bb.0:
2613 ; RV64ZBA-NEXT:    srliw a2, a2, 6
2614 ; RV64ZBA-NEXT:    add a1, a2, a1
2615 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
2616 ; RV64ZBA-NEXT:    ret
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
2621   ret ptr %gep2
2624 define i64 @regression(i32 signext %x, i32 signext %y) {
2625 ; RV64I-LABEL: regression:
2626 ; RV64I:       # %bb.0:
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
2632 ; RV64I-NEXT:    ret
2634 ; RV64ZBA-LABEL: regression:
2635 ; RV64ZBA:       # %bb.0:
2636 ; RV64ZBA-NEXT:    subw a0, a0, a1
2637 ; RV64ZBA-NEXT:    slli.uw a0, a0, 3
2638 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
2639 ; RV64ZBA-NEXT:    ret
2640   %sub = sub i32 %x, %y
2641   %ext = zext i32 %sub to i64
2642   %res = mul nuw nsw i64 %ext, 24
2643   ret i64 %res
2646 define i64 @mul_neg1(i64 %a) {
2647 ; CHECK-LABEL: mul_neg1:
2648 ; CHECK:       # %bb.0:
2649 ; CHECK-NEXT:    neg a0, a0
2650 ; CHECK-NEXT:    ret
2651   %c = mul i64 %a, -1
2652   ret i64 %c
2655 define i64 @mul_neg2(i64 %a) {
2656 ; CHECK-LABEL: mul_neg2:
2657 ; CHECK:       # %bb.0:
2658 ; CHECK-NEXT:    slli a0, a0, 1
2659 ; CHECK-NEXT:    neg a0, a0
2660 ; CHECK-NEXT:    ret
2661   %c = mul i64 %a, -2
2662   ret i64 %c
2665 define i64 @mul_neg3(i64 %a) {
2666 ; RV64I-LABEL: mul_neg3:
2667 ; RV64I:       # %bb.0:
2668 ; RV64I-NEXT:    slli a1, a0, 1
2669 ; RV64I-NEXT:    neg a0, a0
2670 ; RV64I-NEXT:    sub a0, a0, a1
2671 ; RV64I-NEXT:    ret
2673 ; RV64ZBA-LABEL: mul_neg3:
2674 ; RV64ZBA:       # %bb.0:
2675 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
2676 ; RV64ZBA-NEXT:    neg a0, a0
2677 ; RV64ZBA-NEXT:    ret
2678   %c = mul i64 %a, -3
2679   ret i64 %c
2682 define i64 @mul_neg4(i64 %a) {
2683 ; CHECK-LABEL: mul_neg4:
2684 ; CHECK:       # %bb.0:
2685 ; CHECK-NEXT:    slli a0, a0, 2
2686 ; CHECK-NEXT:    neg a0, a0
2687 ; CHECK-NEXT:    ret
2688   %c = mul i64 %a, -4
2689   ret i64 %c
2692 define i64 @mul_neg5(i64 %a) {
2693 ; RV64I-LABEL: mul_neg5:
2694 ; RV64I:       # %bb.0:
2695 ; RV64I-NEXT:    slli a1, a0, 2
2696 ; RV64I-NEXT:    neg a0, a0
2697 ; RV64I-NEXT:    sub a0, a0, a1
2698 ; RV64I-NEXT:    ret
2700 ; RV64ZBA-LABEL: mul_neg5:
2701 ; RV64ZBA:       # %bb.0:
2702 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
2703 ; RV64ZBA-NEXT:    neg a0, a0
2704 ; RV64ZBA-NEXT:    ret
2705   %c = mul i64 %a, -5
2706   ret i64 %c
2709 define i64 @mul_neg6(i64 %a) {
2710 ; CHECK-LABEL: mul_neg6:
2711 ; CHECK:       # %bb.0:
2712 ; CHECK-NEXT:    li a1, -6
2713 ; CHECK-NEXT:    mul a0, a0, a1
2714 ; CHECK-NEXT:    ret
2715   %c = mul i64 %a, -6
2716   ret i64 %c
2719 define i64 @mul_neg7(i64 %a) {
2720 ; CHECK-LABEL: mul_neg7:
2721 ; CHECK:       # %bb.0:
2722 ; CHECK-NEXT:    slli a1, a0, 3
2723 ; CHECK-NEXT:    sub a0, a0, a1
2724 ; CHECK-NEXT:    ret
2725   %c = mul i64 %a, -7
2726   ret i64 %c
2729 define i64 @mul_neg8(i64 %a) {
2730 ; CHECK-LABEL: mul_neg8:
2731 ; CHECK:       # %bb.0:
2732 ; CHECK-NEXT:    slli a0, a0, 3
2733 ; CHECK-NEXT:    neg a0, a0
2734 ; CHECK-NEXT:    ret
2735   %c = mul i64 %a, -8
2736   ret i64 %c
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
2747 ; RV64I-NEXT:    ret
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
2771 entry:
2772   %3 = lshr i32 %1, %2
2773   %4 = and i32 %3, 1
2774   %5 = zext nneg i32 %4 to i64
2775   %6 = mul i64 %5, 12
2776   ret i64 %6
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
2786 ; RV64I-NEXT:    ret
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
2810 entry:
2811   %3 = lshr i32 %1, %2
2812   %4 = and i32 %3, 1
2813   %5 = zext nneg i32 %4 to i64
2814   %6 = mul i64 %5, 45
2815   ret i64 %6
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
2825 ; RV64I-NEXT:    ret
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
2849 entry:
2850   %3 = lshr i32 %1, %2
2851   %4 = and i32 %3, 1
2852   %5 = zext nneg i32 %4 to i64
2853   %6 = mul i64 %5, 132
2854   ret i64 %6
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
2866 ; RV64I-NEXT:    ret
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
2874 ; RV64ZBA-NEXT:    ret
2875 entry:
2876   %2 = lshr exact i64 %1, 2
2877   %3 = and i64 %2, 4294967295
2878   %5 = getelementptr [80 x i8], ptr %0, i64 %3
2879   ret ptr %5
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
2890 ; RV64I-NEXT:    ret
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
2896 ; RV64ZBA-NEXT:    ret
2897 entry:
2898   %2 = lshr exact i64 %1, 2
2899   %3 = and i64 %2, 4294967295
2900   %4 = shl i64 %3, 4
2901   ret i64 %4
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
2912 ; RV64I-NEXT:    ret
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
2918 ; RV64ZBA-NEXT:    ret
2919 entry:
2920   %1 = shl i64 %0, 2
2921   %2 = and i64 %1, 68719476720
2922   ret i64 %2
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
2931 ; CHECK-NEXT:    ret
2932 entry:
2933   %1 = lshr i64 %0, 6
2934   %2 = shl i64 %1, 32
2935   ret i64 %2
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
2945 ; CHECK-NEXT:    ret
2946 entry:
2947   %2 = lshr exact i64 %1, 2
2948   %3 = and i64 %2, 65535
2949   %4 = shl i64 %3, 4
2950   ret i64 %4