Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / RISCV / rv64-legal-i32 / rv64zba.ll
blob8005ad60b8a1105e3a7c120d356ffbbfa5e633d1
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s \
3 ; RUN:   -riscv-experimental-rv64-legal-i32 | FileCheck %s -check-prefixes=CHECK,RV64I
4 ; RUN: llc -mtriple=riscv64 -mattr=+m,+zba -verify-machineinstrs < %s \
5 ; RUN:   -riscv-experimental-rv64-legal-i32 | FileCheck %s -check-prefixes=CHECK,RV64ZBA,RV64ZBANOZBB
6 ; RUN: llc -mtriple=riscv64 -mattr=+m,+zba,+zbb -verify-machineinstrs < %s \
7 ; RUN:   -riscv-experimental-rv64-legal-i32 | FileCheck %s -check-prefixes=CHECK,RV64ZBA,RV64ZBAZBB
9 define i64 @slliuw(i64 %a) nounwind {
10 ; RV64I-LABEL: slliuw:
11 ; RV64I:       # %bb.0:
12 ; RV64I-NEXT:    slli a0, a0, 32
13 ; RV64I-NEXT:    srli a0, a0, 31
14 ; RV64I-NEXT:    ret
16 ; RV64ZBA-LABEL: slliuw:
17 ; RV64ZBA:       # %bb.0:
18 ; RV64ZBA-NEXT:    slli.uw a0, a0, 1
19 ; RV64ZBA-NEXT:    ret
20   %conv1 = shl i64 %a, 1
21   %shl = and i64 %conv1, 8589934590
22   ret i64 %shl
25 define i128 @slliuw_2(i32 signext %0, ptr %1) {
26 ; RV64I-LABEL: slliuw_2:
27 ; RV64I:       # %bb.0:
28 ; RV64I-NEXT:    slli a0, a0, 32
29 ; RV64I-NEXT:    srli a0, a0, 28
30 ; RV64I-NEXT:    add a1, a1, a0
31 ; RV64I-NEXT:    ld a0, 0(a1)
32 ; RV64I-NEXT:    ld a1, 8(a1)
33 ; RV64I-NEXT:    ret
35 ; RV64ZBA-LABEL: slliuw_2:
36 ; RV64ZBA:       # %bb.0:
37 ; RV64ZBA-NEXT:    slli.uw a0, a0, 4
38 ; RV64ZBA-NEXT:    add a1, a1, a0
39 ; RV64ZBA-NEXT:    ld a0, 0(a1)
40 ; RV64ZBA-NEXT:    ld a1, 8(a1)
41 ; RV64ZBA-NEXT:    ret
42   %3 = zext i32 %0 to i64
43   %4 = getelementptr inbounds i128, ptr %1, i64 %3
44   %5 = load i128, ptr %4
45   ret i128 %5
48 define i64 @adduw(i64 %a, i64 %b) nounwind {
49 ; RV64I-LABEL: adduw:
50 ; RV64I:       # %bb.0:
51 ; RV64I-NEXT:    slli a1, a1, 32
52 ; RV64I-NEXT:    srli a1, a1, 32
53 ; RV64I-NEXT:    add a0, a1, a0
54 ; RV64I-NEXT:    ret
56 ; RV64ZBA-LABEL: adduw:
57 ; RV64ZBA:       # %bb.0:
58 ; RV64ZBA-NEXT:    add.uw a0, a1, a0
59 ; RV64ZBA-NEXT:    ret
60   %and = and i64 %b, 4294967295
61   %add = add i64 %and, %a
62   ret i64 %add
65 define signext i8 @adduw_2(i32 signext %0, ptr %1) {
66 ; RV64I-LABEL: adduw_2:
67 ; RV64I:       # %bb.0:
68 ; RV64I-NEXT:    slli a0, a0, 32
69 ; RV64I-NEXT:    srli a0, a0, 32
70 ; RV64I-NEXT:    add a0, a1, a0
71 ; RV64I-NEXT:    lb a0, 0(a0)
72 ; RV64I-NEXT:    ret
74 ; RV64ZBA-LABEL: adduw_2:
75 ; RV64ZBA:       # %bb.0:
76 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
77 ; RV64ZBA-NEXT:    lb a0, 0(a0)
78 ; RV64ZBA-NEXT:    ret
79   %3 = zext i32 %0 to i64
80   %4 = getelementptr inbounds i8, ptr %1, i64 %3
81   %5 = load i8, ptr %4
82   ret i8 %5
85 define i64 @zextw_i64(i64 %a) nounwind {
86 ; RV64I-LABEL: zextw_i64:
87 ; RV64I:       # %bb.0:
88 ; RV64I-NEXT:    slli a0, a0, 32
89 ; RV64I-NEXT:    srli a0, a0, 32
90 ; RV64I-NEXT:    ret
92 ; RV64ZBA-LABEL: zextw_i64:
93 ; RV64ZBA:       # %bb.0:
94 ; RV64ZBA-NEXT:    zext.w a0, a0
95 ; RV64ZBA-NEXT:    ret
96   %and = and i64 %a, 4294967295
97   ret i64 %and
100 ; This makes sure targetShrinkDemandedConstant changes the and immmediate to
101 ; allow zext.w or slli+srli.
102 define i64 @zextw_demandedbits_i64(i64 %0) {
103 ; RV64I-LABEL: zextw_demandedbits_i64:
104 ; RV64I:       # %bb.0:
105 ; RV64I-NEXT:    ori a0, a0, 1
106 ; RV64I-NEXT:    slli a0, a0, 32
107 ; RV64I-NEXT:    srli a0, a0, 32
108 ; RV64I-NEXT:    ret
110 ; RV64ZBA-LABEL: zextw_demandedbits_i64:
111 ; RV64ZBA:       # %bb.0:
112 ; RV64ZBA-NEXT:    ori a0, a0, 1
113 ; RV64ZBA-NEXT:    zext.w a0, a0
114 ; RV64ZBA-NEXT:    ret
115   %2 = and i64 %0, 4294967294
116   %3 = or i64 %2, 1
117   ret i64 %3
120 define signext i16 @sh1add(i64 %0, ptr %1) {
121 ; RV64I-LABEL: sh1add:
122 ; RV64I:       # %bb.0:
123 ; RV64I-NEXT:    slli a0, a0, 1
124 ; RV64I-NEXT:    add a0, a1, a0
125 ; RV64I-NEXT:    lh a0, 0(a0)
126 ; RV64I-NEXT:    ret
128 ; RV64ZBA-LABEL: sh1add:
129 ; RV64ZBA:       # %bb.0:
130 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
131 ; RV64ZBA-NEXT:    lh a0, 0(a0)
132 ; RV64ZBA-NEXT:    ret
133   %3 = getelementptr inbounds i16, ptr %1, i64 %0
134   %4 = load i16, ptr %3
135   ret i16 %4
138 define signext i32 @sh2add(i64 %0, ptr %1) {
139 ; RV64I-LABEL: sh2add:
140 ; RV64I:       # %bb.0:
141 ; RV64I-NEXT:    slli a0, a0, 2
142 ; RV64I-NEXT:    add a0, a1, a0
143 ; RV64I-NEXT:    lw a0, 0(a0)
144 ; RV64I-NEXT:    ret
146 ; RV64ZBA-LABEL: sh2add:
147 ; RV64ZBA:       # %bb.0:
148 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
149 ; RV64ZBA-NEXT:    lw a0, 0(a0)
150 ; RV64ZBA-NEXT:    ret
151   %3 = getelementptr inbounds i32, ptr %1, i64 %0
152   %4 = load i32, ptr %3
153   ret i32 %4
156 define i64 @sh3add(i64 %0, ptr %1) {
157 ; RV64I-LABEL: sh3add:
158 ; RV64I:       # %bb.0:
159 ; RV64I-NEXT:    slli a0, a0, 3
160 ; RV64I-NEXT:    add a0, a1, a0
161 ; RV64I-NEXT:    ld a0, 0(a0)
162 ; RV64I-NEXT:    ret
164 ; RV64ZBA-LABEL: sh3add:
165 ; RV64ZBA:       # %bb.0:
166 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
167 ; RV64ZBA-NEXT:    ld a0, 0(a0)
168 ; RV64ZBA-NEXT:    ret
169   %3 = getelementptr inbounds i64, ptr %1, i64 %0
170   %4 = load i64, ptr %3
171   ret i64 %4
174 define signext i16 @sh1adduw(i32 signext %0, ptr %1) {
175 ; RV64I-LABEL: sh1adduw:
176 ; RV64I:       # %bb.0:
177 ; RV64I-NEXT:    slli a0, a0, 32
178 ; RV64I-NEXT:    srli a0, a0, 31
179 ; RV64I-NEXT:    add a0, a1, a0
180 ; RV64I-NEXT:    lh a0, 0(a0)
181 ; RV64I-NEXT:    ret
183 ; RV64ZBA-LABEL: sh1adduw:
184 ; RV64ZBA:       # %bb.0:
185 ; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
186 ; RV64ZBA-NEXT:    lh a0, 0(a0)
187 ; RV64ZBA-NEXT:    ret
188   %3 = zext i32 %0 to i64
189   %4 = getelementptr inbounds i16, ptr %1, i64 %3
190   %5 = load i16, ptr %4
191   ret i16 %5
194 define i64 @sh1adduw_2(i64 %0, i64 %1) {
195 ; RV64I-LABEL: sh1adduw_2:
196 ; RV64I:       # %bb.0:
197 ; RV64I-NEXT:    slli a0, a0, 32
198 ; RV64I-NEXT:    srli a0, a0, 31
199 ; RV64I-NEXT:    add a0, a0, a1
200 ; RV64I-NEXT:    ret
202 ; RV64ZBA-LABEL: sh1adduw_2:
203 ; RV64ZBA:       # %bb.0:
204 ; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
205 ; RV64ZBA-NEXT:    ret
206   %3 = shl i64 %0, 1
207   %4 = and i64 %3, 8589934590
208   %5 = add i64 %4, %1
209   ret i64 %5
212 define signext i32 @sh2adduw(i32 signext %0, ptr %1) {
213 ; RV64I-LABEL: sh2adduw:
214 ; RV64I:       # %bb.0:
215 ; RV64I-NEXT:    slli a0, a0, 32
216 ; RV64I-NEXT:    srli a0, a0, 30
217 ; RV64I-NEXT:    add a0, a1, a0
218 ; RV64I-NEXT:    lw a0, 0(a0)
219 ; RV64I-NEXT:    ret
221 ; RV64ZBA-LABEL: sh2adduw:
222 ; RV64ZBA:       # %bb.0:
223 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
224 ; RV64ZBA-NEXT:    lw a0, 0(a0)
225 ; RV64ZBA-NEXT:    ret
226   %3 = zext i32 %0 to i64
227   %4 = getelementptr inbounds i32, ptr %1, i64 %3
228   %5 = load i32, ptr %4
229   ret i32 %5
232 define i64 @sh2adduw_2(i64 %0, i64 %1) {
233 ; RV64I-LABEL: sh2adduw_2:
234 ; RV64I:       # %bb.0:
235 ; RV64I-NEXT:    slli a0, a0, 32
236 ; RV64I-NEXT:    srli a0, a0, 30
237 ; RV64I-NEXT:    add a0, a0, a1
238 ; RV64I-NEXT:    ret
240 ; RV64ZBA-LABEL: sh2adduw_2:
241 ; RV64ZBA:       # %bb.0:
242 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
243 ; RV64ZBA-NEXT:    ret
244   %3 = shl i64 %0, 2
245   %4 = and i64 %3, 17179869180
246   %5 = add i64 %4, %1
247   ret i64 %5
250 define i64 @sh3adduw(i32 signext %0, ptr %1) {
251 ; RV64I-LABEL: sh3adduw:
252 ; RV64I:       # %bb.0:
253 ; RV64I-NEXT:    slli a0, a0, 32
254 ; RV64I-NEXT:    srli a0, a0, 29
255 ; RV64I-NEXT:    add a0, a1, a0
256 ; RV64I-NEXT:    ld a0, 0(a0)
257 ; RV64I-NEXT:    ret
259 ; RV64ZBA-LABEL: sh3adduw:
260 ; RV64ZBA:       # %bb.0:
261 ; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
262 ; RV64ZBA-NEXT:    ld a0, 0(a0)
263 ; RV64ZBA-NEXT:    ret
264   %3 = zext i32 %0 to i64
265   %4 = getelementptr inbounds i64, ptr %1, i64 %3
266   %5 = load i64, ptr %4
267   ret i64 %5
270 define i64 @sh3adduw_2(i64 %0, i64 %1) {
271 ; RV64I-LABEL: sh3adduw_2:
272 ; RV64I:       # %bb.0:
273 ; RV64I-NEXT:    slli a0, a0, 32
274 ; RV64I-NEXT:    srli a0, a0, 29
275 ; RV64I-NEXT:    add a0, a0, a1
276 ; RV64I-NEXT:    ret
278 ; RV64ZBA-LABEL: sh3adduw_2:
279 ; RV64ZBA:       # %bb.0:
280 ; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
281 ; RV64ZBA-NEXT:    ret
282   %3 = shl i64 %0, 3
283   %4 = and i64 %3, 34359738360
284   %5 = add i64 %4, %1
285   ret i64 %5
288 ; Type legalization inserts a sext_inreg after the first add. That add will be
289 ; selected as sh2add which does not sign extend. SimplifyDemandedBits is unable
290 ; to remove the sext_inreg because it has multiple uses. The ashr will use the
291 ; sext_inreg to become sraiw. This leaves the sext_inreg only used by the shl.
292 ; If the shl is selected as sllw, we don't need the sext_inreg.
293 define i64 @sh2add_extra_sext(i32 %x, i32 %y, i32 %z) {
294 ; RV64I-LABEL: sh2add_extra_sext:
295 ; RV64I:       # %bb.0:
296 ; RV64I-NEXT:    slli a0, a0, 2
297 ; RV64I-NEXT:    add a0, a0, a1
298 ; RV64I-NEXT:    slli a1, a0, 32
299 ; RV64I-NEXT:    srli a1, a1, 32
300 ; RV64I-NEXT:    sllw a1, a2, a1
301 ; RV64I-NEXT:    sraiw a0, a0, 2
302 ; RV64I-NEXT:    mul a0, a1, a0
303 ; RV64I-NEXT:    ret
305 ; RV64ZBA-LABEL: sh2add_extra_sext:
306 ; RV64ZBA:       # %bb.0:
307 ; RV64ZBA-NEXT:    slli a0, a0, 2
308 ; RV64ZBA-NEXT:    add a0, a0, a1
309 ; RV64ZBA-NEXT:    zext.w a1, a0
310 ; RV64ZBA-NEXT:    sllw a1, a2, a1
311 ; RV64ZBA-NEXT:    sraiw a0, a0, 2
312 ; RV64ZBA-NEXT:    mul a0, a1, a0
313 ; RV64ZBA-NEXT:    ret
314   %a = shl i32 %x, 2
315   %b = add i32 %a, %y
316   %c = shl i32 %z, %b
317   %d = ashr i32 %b, 2
318   %e = sext i32 %c to i64
319   %f = sext i32 %d to i64
320   %g = mul i64 %e, %f
321   ret i64 %g
324 define i64 @addmul6(i64 %a, i64 %b) {
325 ; RV64I-LABEL: addmul6:
326 ; RV64I:       # %bb.0:
327 ; RV64I-NEXT:    li a2, 6
328 ; RV64I-NEXT:    mul a0, a0, a2
329 ; RV64I-NEXT:    add a0, a0, a1
330 ; RV64I-NEXT:    ret
332 ; RV64ZBA-LABEL: addmul6:
333 ; RV64ZBA:       # %bb.0:
334 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
335 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
336 ; RV64ZBA-NEXT:    ret
337   %c = mul i64 %a, 6
338   %d = add i64 %c, %b
339   ret i64 %d
342 define i64 @addmul10(i64 %a, i64 %b) {
343 ; RV64I-LABEL: addmul10:
344 ; RV64I:       # %bb.0:
345 ; RV64I-NEXT:    li a2, 10
346 ; RV64I-NEXT:    mul a0, a0, a2
347 ; RV64I-NEXT:    add a0, a0, a1
348 ; RV64I-NEXT:    ret
350 ; RV64ZBA-LABEL: addmul10:
351 ; RV64ZBA:       # %bb.0:
352 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
353 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
354 ; RV64ZBA-NEXT:    ret
355   %c = mul i64 %a, 10
356   %d = add i64 %c, %b
357   ret i64 %d
360 define i64 @addmul12(i64 %a, i64 %b) {
361 ; RV64I-LABEL: addmul12:
362 ; RV64I:       # %bb.0:
363 ; RV64I-NEXT:    li a2, 12
364 ; RV64I-NEXT:    mul a0, a0, a2
365 ; RV64I-NEXT:    add a0, a0, a1
366 ; RV64I-NEXT:    ret
368 ; RV64ZBA-LABEL: addmul12:
369 ; RV64ZBA:       # %bb.0:
370 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
371 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
372 ; RV64ZBA-NEXT:    ret
373   %c = mul i64 %a, 12
374   %d = add i64 %c, %b
375   ret i64 %d
378 define i64 @addmul18(i64 %a, i64 %b) {
379 ; RV64I-LABEL: addmul18:
380 ; RV64I:       # %bb.0:
381 ; RV64I-NEXT:    li a2, 18
382 ; RV64I-NEXT:    mul a0, a0, a2
383 ; RV64I-NEXT:    add a0, a0, a1
384 ; RV64I-NEXT:    ret
386 ; RV64ZBA-LABEL: addmul18:
387 ; RV64ZBA:       # %bb.0:
388 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
389 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
390 ; RV64ZBA-NEXT:    ret
391   %c = mul i64 %a, 18
392   %d = add i64 %c, %b
393   ret i64 %d
396 define i64 @addmul20(i64 %a, i64 %b) {
397 ; RV64I-LABEL: addmul20:
398 ; RV64I:       # %bb.0:
399 ; RV64I-NEXT:    li a2, 20
400 ; RV64I-NEXT:    mul a0, a0, a2
401 ; RV64I-NEXT:    add a0, a0, a1
402 ; RV64I-NEXT:    ret
404 ; RV64ZBA-LABEL: addmul20:
405 ; RV64ZBA:       # %bb.0:
406 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
407 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
408 ; RV64ZBA-NEXT:    ret
409   %c = mul i64 %a, 20
410   %d = add i64 %c, %b
411   ret i64 %d
414 define i64 @addmul24(i64 %a, i64 %b) {
415 ; RV64I-LABEL: addmul24:
416 ; RV64I:       # %bb.0:
417 ; RV64I-NEXT:    li a2, 24
418 ; RV64I-NEXT:    mul a0, a0, a2
419 ; RV64I-NEXT:    add a0, a0, a1
420 ; RV64I-NEXT:    ret
422 ; RV64ZBA-LABEL: addmul24:
423 ; RV64ZBA:       # %bb.0:
424 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
425 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
426 ; RV64ZBA-NEXT:    ret
427   %c = mul i64 %a, 24
428   %d = add i64 %c, %b
429   ret i64 %d
432 define i64 @addmul36(i64 %a, i64 %b) {
433 ; RV64I-LABEL: addmul36:
434 ; RV64I:       # %bb.0:
435 ; RV64I-NEXT:    li a2, 36
436 ; RV64I-NEXT:    mul a0, a0, a2
437 ; RV64I-NEXT:    add a0, a0, a1
438 ; RV64I-NEXT:    ret
440 ; RV64ZBA-LABEL: addmul36:
441 ; RV64ZBA:       # %bb.0:
442 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
443 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
444 ; RV64ZBA-NEXT:    ret
445   %c = mul i64 %a, 36
446   %d = add i64 %c, %b
447   ret i64 %d
450 define i64 @addmul40(i64 %a, i64 %b) {
451 ; RV64I-LABEL: addmul40:
452 ; RV64I:       # %bb.0:
453 ; RV64I-NEXT:    li a2, 40
454 ; RV64I-NEXT:    mul a0, a0, a2
455 ; RV64I-NEXT:    add a0, a0, a1
456 ; RV64I-NEXT:    ret
458 ; RV64ZBA-LABEL: addmul40:
459 ; RV64ZBA:       # %bb.0:
460 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
461 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
462 ; RV64ZBA-NEXT:    ret
463   %c = mul i64 %a, 40
464   %d = add i64 %c, %b
465   ret i64 %d
468 define i64 @addmul72(i64 %a, i64 %b) {
469 ; RV64I-LABEL: addmul72:
470 ; RV64I:       # %bb.0:
471 ; RV64I-NEXT:    li a2, 72
472 ; RV64I-NEXT:    mul a0, a0, a2
473 ; RV64I-NEXT:    add a0, a0, a1
474 ; RV64I-NEXT:    ret
476 ; RV64ZBA-LABEL: addmul72:
477 ; RV64ZBA:       # %bb.0:
478 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
479 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
480 ; RV64ZBA-NEXT:    ret
481   %c = mul i64 %a, 72
482   %d = add i64 %c, %b
483   ret i64 %d
486 define i64 @mul96(i64 %a) {
487 ; RV64I-LABEL: mul96:
488 ; RV64I:       # %bb.0:
489 ; RV64I-NEXT:    li a1, 96
490 ; RV64I-NEXT:    mul a0, a0, a1
491 ; RV64I-NEXT:    ret
493 ; RV64ZBA-LABEL: mul96:
494 ; RV64ZBA:       # %bb.0:
495 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
496 ; RV64ZBA-NEXT:    slli a0, a0, 5
497 ; RV64ZBA-NEXT:    ret
498   %c = mul i64 %a, 96
499   ret i64 %c
502 define i64 @mul160(i64 %a) {
503 ; RV64I-LABEL: mul160:
504 ; RV64I:       # %bb.0:
505 ; RV64I-NEXT:    li a1, 160
506 ; RV64I-NEXT:    mul a0, a0, a1
507 ; RV64I-NEXT:    ret
509 ; RV64ZBA-LABEL: mul160:
510 ; RV64ZBA:       # %bb.0:
511 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
512 ; RV64ZBA-NEXT:    slli a0, a0, 5
513 ; RV64ZBA-NEXT:    ret
514   %c = mul i64 %a, 160
515   ret i64 %c
518 define i64 @mul288(i64 %a) {
519 ; RV64I-LABEL: mul288:
520 ; RV64I:       # %bb.0:
521 ; RV64I-NEXT:    li a1, 288
522 ; RV64I-NEXT:    mul a0, a0, a1
523 ; RV64I-NEXT:    ret
525 ; RV64ZBA-LABEL: mul288:
526 ; RV64ZBA:       # %bb.0:
527 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
528 ; RV64ZBA-NEXT:    slli a0, a0, 5
529 ; RV64ZBA-NEXT:    ret
530   %c = mul i64 %a, 288
531   ret i64 %c
534 define i64 @zext_mul96(i32 signext %a) {
535 ; RV64I-LABEL: zext_mul96:
536 ; RV64I:       # %bb.0:
537 ; RV64I-NEXT:    li a1, 3
538 ; RV64I-NEXT:    slli a1, a1, 37
539 ; RV64I-NEXT:    slli a0, a0, 32
540 ; RV64I-NEXT:    mulhu a0, a0, a1
541 ; RV64I-NEXT:    ret
543 ; RV64ZBA-LABEL: zext_mul96:
544 ; RV64ZBA:       # %bb.0:
545 ; RV64ZBA-NEXT:    slli.uw a0, a0, 5
546 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
547 ; RV64ZBA-NEXT:    ret
548   %b = zext i32 %a to i64
549   %c = mul i64 %b, 96
550   ret i64 %c
553 define i64 @zext_mul160(i32 signext %a) {
554 ; RV64I-LABEL: zext_mul160:
555 ; RV64I:       # %bb.0:
556 ; RV64I-NEXT:    li a1, 5
557 ; RV64I-NEXT:    slli a1, a1, 37
558 ; RV64I-NEXT:    slli a0, a0, 32
559 ; RV64I-NEXT:    mulhu a0, a0, a1
560 ; RV64I-NEXT:    ret
562 ; RV64ZBA-LABEL: zext_mul160:
563 ; RV64ZBA:       # %bb.0:
564 ; RV64ZBA-NEXT:    slli.uw a0, a0, 5
565 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
566 ; RV64ZBA-NEXT:    ret
567   %b = zext i32 %a to i64
568   %c = mul i64 %b, 160
569   ret i64 %c
572 define i64 @zext_mul288(i32 signext %a) {
573 ; RV64I-LABEL: zext_mul288:
574 ; RV64I:       # %bb.0:
575 ; RV64I-NEXT:    li a1, 9
576 ; RV64I-NEXT:    slli a1, a1, 37
577 ; RV64I-NEXT:    slli a0, a0, 32
578 ; RV64I-NEXT:    mulhu a0, a0, a1
579 ; RV64I-NEXT:    ret
581 ; RV64ZBA-LABEL: zext_mul288:
582 ; RV64ZBA:       # %bb.0:
583 ; RV64ZBA-NEXT:    slli.uw a0, a0, 5
584 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
585 ; RV64ZBA-NEXT:    ret
586   %b = zext i32 %a to i64
587   %c = mul i64 %b, 288
588   ret i64 %c
591 ; We can't use slli.uw becaues the shift amount is more than 31.
592 ; FIXME: The zext.w is unneeded.
593 define i64 @zext_mul12884901888(i32 signext %a) {
594 ; RV64I-LABEL: zext_mul12884901888:
595 ; RV64I:       # %bb.0:
596 ; RV64I-NEXT:    slli a0, a0, 32
597 ; RV64I-NEXT:    srli a0, a0, 32
598 ; RV64I-NEXT:    li a1, 3
599 ; RV64I-NEXT:    slli a1, a1, 32
600 ; RV64I-NEXT:    mul a0, a0, a1
601 ; RV64I-NEXT:    ret
603 ; RV64ZBA-LABEL: zext_mul12884901888:
604 ; RV64ZBA:       # %bb.0:
605 ; RV64ZBA-NEXT:    andi a0, a0, -1
606 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
607 ; RV64ZBA-NEXT:    slli a0, a0, 32
608 ; RV64ZBA-NEXT:    ret
609   %b = zext i32 %a to i64
610   %c = mul i64 %b, 12884901888
611   ret i64 %c
614 ; We can't use slli.uw becaues the shift amount is more than 31.
615 ; FIXME: The zext.w is unneeded.
616 define i64 @zext_mul21474836480(i32 signext %a) {
617 ; RV64I-LABEL: zext_mul21474836480:
618 ; RV64I:       # %bb.0:
619 ; RV64I-NEXT:    slli a0, a0, 32
620 ; RV64I-NEXT:    srli a0, a0, 32
621 ; RV64I-NEXT:    li a1, 5
622 ; RV64I-NEXT:    slli a1, a1, 32
623 ; RV64I-NEXT:    mul a0, a0, a1
624 ; RV64I-NEXT:    ret
626 ; RV64ZBA-LABEL: zext_mul21474836480:
627 ; RV64ZBA:       # %bb.0:
628 ; RV64ZBA-NEXT:    andi a0, a0, -1
629 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
630 ; RV64ZBA-NEXT:    slli a0, a0, 32
631 ; RV64ZBA-NEXT:    ret
632   %b = zext i32 %a to i64
633   %c = mul i64 %b, 21474836480
634   ret i64 %c
637 ; We can't use slli.uw becaues the shift amount is more than 31.
638 ; FIXME: The zext.w is unneeded.
639 define i64 @zext_mul38654705664(i32 signext %a) {
640 ; RV64I-LABEL: zext_mul38654705664:
641 ; RV64I:       # %bb.0:
642 ; RV64I-NEXT:    slli a0, a0, 32
643 ; RV64I-NEXT:    srli a0, a0, 32
644 ; RV64I-NEXT:    li a1, 9
645 ; RV64I-NEXT:    slli a1, a1, 32
646 ; RV64I-NEXT:    mul a0, a0, a1
647 ; RV64I-NEXT:    ret
649 ; RV64ZBA-LABEL: zext_mul38654705664:
650 ; RV64ZBA:       # %bb.0:
651 ; RV64ZBA-NEXT:    andi a0, a0, -1
652 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
653 ; RV64ZBA-NEXT:    slli a0, a0, 32
654 ; RV64ZBA-NEXT:    ret
655   %b = zext i32 %a to i64
656   %c = mul i64 %b, 38654705664
657   ret i64 %c
660 define i64 @sh1add_imm(i64 %0) {
661 ; CHECK-LABEL: sh1add_imm:
662 ; CHECK:       # %bb.0:
663 ; CHECK-NEXT:    slli a0, a0, 1
664 ; CHECK-NEXT:    addi a0, a0, 5
665 ; CHECK-NEXT:    ret
666   %a = shl i64 %0, 1
667   %b = add i64 %a, 5
668   ret i64 %b
671 define i64 @sh2add_imm(i64 %0) {
672 ; CHECK-LABEL: sh2add_imm:
673 ; CHECK:       # %bb.0:
674 ; CHECK-NEXT:    slli a0, a0, 2
675 ; CHECK-NEXT:    addi a0, a0, -6
676 ; CHECK-NEXT:    ret
677   %a = shl i64 %0, 2
678   %b = add i64 %a, -6
679   ret i64 %b
682 define i64 @sh3add_imm(i64 %0) {
683 ; CHECK-LABEL: sh3add_imm:
684 ; CHECK:       # %bb.0:
685 ; CHECK-NEXT:    slli a0, a0, 3
686 ; CHECK-NEXT:    addi a0, a0, 7
687 ; CHECK-NEXT:    ret
688   %a = shl i64 %0, 3
689   %b = add i64 %a, 7
690   ret i64 %b
693 define i64 @sh1adduw_imm(i32 signext %0) {
694 ; RV64I-LABEL: sh1adduw_imm:
695 ; RV64I:       # %bb.0:
696 ; RV64I-NEXT:    slli a0, a0, 32
697 ; RV64I-NEXT:    srli a0, a0, 31
698 ; RV64I-NEXT:    addi a0, a0, 11
699 ; RV64I-NEXT:    ret
701 ; RV64ZBA-LABEL: sh1adduw_imm:
702 ; RV64ZBA:       # %bb.0:
703 ; RV64ZBA-NEXT:    slli.uw a0, a0, 1
704 ; RV64ZBA-NEXT:    addi a0, a0, 11
705 ; RV64ZBA-NEXT:    ret
706   %a = zext i32 %0 to i64
707   %b = shl i64 %a, 1
708   %c = add i64 %b, 11
709   ret i64 %c
712 define i64 @sh2adduw_imm(i32 signext %0) {
713 ; RV64I-LABEL: sh2adduw_imm:
714 ; RV64I:       # %bb.0:
715 ; RV64I-NEXT:    slli a0, a0, 32
716 ; RV64I-NEXT:    srli a0, a0, 30
717 ; RV64I-NEXT:    addi a0, a0, -12
718 ; RV64I-NEXT:    ret
720 ; RV64ZBA-LABEL: sh2adduw_imm:
721 ; RV64ZBA:       # %bb.0:
722 ; RV64ZBA-NEXT:    slli.uw a0, a0, 2
723 ; RV64ZBA-NEXT:    addi a0, a0, -12
724 ; RV64ZBA-NEXT:    ret
725   %a = zext i32 %0 to i64
726   %b = shl i64 %a, 2
727   %c = add i64 %b, -12
728   ret i64 %c
731 define i64 @sh3adduw_imm(i32 signext %0) {
732 ; RV64I-LABEL: sh3adduw_imm:
733 ; RV64I:       # %bb.0:
734 ; RV64I-NEXT:    slli a0, a0, 32
735 ; RV64I-NEXT:    srli a0, a0, 29
736 ; RV64I-NEXT:    addi a0, a0, 13
737 ; RV64I-NEXT:    ret
739 ; RV64ZBA-LABEL: sh3adduw_imm:
740 ; RV64ZBA:       # %bb.0:
741 ; RV64ZBA-NEXT:    slli.uw a0, a0, 3
742 ; RV64ZBA-NEXT:    addi a0, a0, 13
743 ; RV64ZBA-NEXT:    ret
744   %a = zext i32 %0 to i64
745   %b = shl i64 %a, 3
746   %c = add i64 %b, 13
747   ret i64 %c
750 define i64 @adduw_imm(i32 signext %0) nounwind {
751 ; RV64I-LABEL: adduw_imm:
752 ; RV64I:       # %bb.0:
753 ; RV64I-NEXT:    slli a0, a0, 32
754 ; RV64I-NEXT:    srli a0, a0, 32
755 ; RV64I-NEXT:    addi a0, a0, 5
756 ; RV64I-NEXT:    ret
758 ; RV64ZBA-LABEL: adduw_imm:
759 ; RV64ZBA:       # %bb.0:
760 ; RV64ZBA-NEXT:    zext.w a0, a0
761 ; RV64ZBA-NEXT:    addi a0, a0, 5
762 ; RV64ZBA-NEXT:    ret
763   %a = zext i32 %0 to i64
764   %b = add i64 %a, 5
765   ret i64 %b
768 define i64 @mul258(i64 %a) {
769 ; CHECK-LABEL: mul258:
770 ; CHECK:       # %bb.0:
771 ; CHECK-NEXT:    li a1, 258
772 ; CHECK-NEXT:    mul a0, a0, a1
773 ; CHECK-NEXT:    ret
774   %c = mul i64 %a, 258
775   ret i64 %c
778 define i64 @mul260(i64 %a) {
779 ; CHECK-LABEL: mul260:
780 ; CHECK:       # %bb.0:
781 ; CHECK-NEXT:    li a1, 260
782 ; CHECK-NEXT:    mul a0, a0, a1
783 ; CHECK-NEXT:    ret
784   %c = mul i64 %a, 260
785   ret i64 %c
788 define i64 @mul264(i64 %a) {
789 ; CHECK-LABEL: mul264:
790 ; CHECK:       # %bb.0:
791 ; CHECK-NEXT:    li a1, 264
792 ; CHECK-NEXT:    mul a0, a0, a1
793 ; CHECK-NEXT:    ret
794   %c = mul i64 %a, 264
795   ret i64 %c
798 define i64 @imm_zextw() nounwind {
799 ; RV64I-LABEL: imm_zextw:
800 ; RV64I:       # %bb.0:
801 ; RV64I-NEXT:    li a0, 1
802 ; RV64I-NEXT:    slli a0, a0, 32
803 ; RV64I-NEXT:    addi a0, a0, -2
804 ; RV64I-NEXT:    ret
806 ; RV64ZBA-LABEL: imm_zextw:
807 ; RV64ZBA:       # %bb.0:
808 ; RV64ZBA-NEXT:    li a0, -2
809 ; RV64ZBA-NEXT:    zext.w a0, a0
810 ; RV64ZBA-NEXT:    ret
811   ret i64 4294967294 ; -2 in 32 bits.
814 define i64 @mul11(i64 %a) {
815 ; RV64I-LABEL: mul11:
816 ; RV64I:       # %bb.0:
817 ; RV64I-NEXT:    li a1, 11
818 ; RV64I-NEXT:    mul a0, a0, a1
819 ; RV64I-NEXT:    ret
821 ; RV64ZBA-LABEL: mul11:
822 ; RV64ZBA:       # %bb.0:
823 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
824 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
825 ; RV64ZBA-NEXT:    ret
826   %c = mul i64 %a, 11
827   ret i64 %c
830 define i64 @mul19(i64 %a) {
831 ; RV64I-LABEL: mul19:
832 ; RV64I:       # %bb.0:
833 ; RV64I-NEXT:    li a1, 19
834 ; RV64I-NEXT:    mul a0, a0, a1
835 ; RV64I-NEXT:    ret
837 ; RV64ZBA-LABEL: mul19:
838 ; RV64ZBA:       # %bb.0:
839 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
840 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
841 ; RV64ZBA-NEXT:    ret
842   %c = mul i64 %a, 19
843   ret i64 %c
846 define i64 @mul13(i64 %a) {
847 ; RV64I-LABEL: mul13:
848 ; RV64I:       # %bb.0:
849 ; RV64I-NEXT:    li a1, 13
850 ; RV64I-NEXT:    mul a0, a0, a1
851 ; RV64I-NEXT:    ret
853 ; RV64ZBA-LABEL: mul13:
854 ; RV64ZBA:       # %bb.0:
855 ; RV64ZBA-NEXT:    sh1add a1, a0, a0
856 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
857 ; RV64ZBA-NEXT:    ret
858   %c = mul i64 %a, 13
859   ret i64 %c
862 define i64 @mul21(i64 %a) {
863 ; RV64I-LABEL: mul21:
864 ; RV64I:       # %bb.0:
865 ; RV64I-NEXT:    li a1, 21
866 ; RV64I-NEXT:    mul a0, a0, a1
867 ; RV64I-NEXT:    ret
869 ; RV64ZBA-LABEL: mul21:
870 ; RV64ZBA:       # %bb.0:
871 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
872 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
873 ; RV64ZBA-NEXT:    ret
874   %c = mul i64 %a, 21
875   ret i64 %c
878 define i64 @mul37(i64 %a) {
879 ; RV64I-LABEL: mul37:
880 ; RV64I:       # %bb.0:
881 ; RV64I-NEXT:    li a1, 37
882 ; RV64I-NEXT:    mul a0, a0, a1
883 ; RV64I-NEXT:    ret
885 ; RV64ZBA-LABEL: mul37:
886 ; RV64ZBA:       # %bb.0:
887 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
888 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
889 ; RV64ZBA-NEXT:    ret
890   %c = mul i64 %a, 37
891   ret i64 %c
894 define i64 @mul25(i64 %a) {
895 ; RV64I-LABEL: mul25:
896 ; RV64I:       # %bb.0:
897 ; RV64I-NEXT:    li a1, 25
898 ; RV64I-NEXT:    mul a0, a0, a1
899 ; RV64I-NEXT:    ret
901 ; RV64ZBA-LABEL: mul25:
902 ; RV64ZBA:       # %bb.0:
903 ; RV64ZBA-NEXT:    sh1add a1, a0, a0
904 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
905 ; RV64ZBA-NEXT:    ret
906   %c = mul i64 %a, 25
907   ret i64 %c
910 define i64 @mul41(i64 %a) {
911 ; RV64I-LABEL: mul41:
912 ; RV64I:       # %bb.0:
913 ; RV64I-NEXT:    li a1, 41
914 ; RV64I-NEXT:    mul a0, a0, a1
915 ; RV64I-NEXT:    ret
917 ; RV64ZBA-LABEL: mul41:
918 ; RV64ZBA:       # %bb.0:
919 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
920 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
921 ; RV64ZBA-NEXT:    ret
922   %c = mul i64 %a, 41
923   ret i64 %c
926 define i64 @mul73(i64 %a) {
927 ; RV64I-LABEL: mul73:
928 ; RV64I:       # %bb.0:
929 ; RV64I-NEXT:    li a1, 73
930 ; RV64I-NEXT:    mul a0, a0, a1
931 ; RV64I-NEXT:    ret
933 ; RV64ZBA-LABEL: mul73:
934 ; RV64ZBA:       # %bb.0:
935 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
936 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
937 ; RV64ZBA-NEXT:    ret
938   %c = mul i64 %a, 73
939   ret i64 %c
942 define i64 @mul27(i64 %a) {
943 ; RV64I-LABEL: mul27:
944 ; RV64I:       # %bb.0:
945 ; RV64I-NEXT:    li a1, 27
946 ; RV64I-NEXT:    mul a0, a0, a1
947 ; RV64I-NEXT:    ret
949 ; RV64ZBA-LABEL: mul27:
950 ; RV64ZBA:       # %bb.0:
951 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
952 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
953 ; RV64ZBA-NEXT:    ret
954   %c = mul i64 %a, 27
955   ret i64 %c
958 define i64 @mul45(i64 %a) {
959 ; RV64I-LABEL: mul45:
960 ; RV64I:       # %bb.0:
961 ; RV64I-NEXT:    li a1, 45
962 ; RV64I-NEXT:    mul a0, a0, a1
963 ; RV64I-NEXT:    ret
965 ; RV64ZBA-LABEL: mul45:
966 ; RV64ZBA:       # %bb.0:
967 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
968 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
969 ; RV64ZBA-NEXT:    ret
970   %c = mul i64 %a, 45
971   ret i64 %c
974 define i64 @mul81(i64 %a) {
975 ; RV64I-LABEL: mul81:
976 ; RV64I:       # %bb.0:
977 ; RV64I-NEXT:    li a1, 81
978 ; RV64I-NEXT:    mul a0, a0, a1
979 ; RV64I-NEXT:    ret
981 ; RV64ZBA-LABEL: mul81:
982 ; RV64ZBA:       # %bb.0:
983 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
984 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
985 ; RV64ZBA-NEXT:    ret
986   %c = mul i64 %a, 81
987   ret i64 %c
990 define i64 @mul4098(i64 %a) {
991 ; RV64I-LABEL: mul4098:
992 ; RV64I:       # %bb.0:
993 ; RV64I-NEXT:    slli a1, a0, 1
994 ; RV64I-NEXT:    slli a0, a0, 12
995 ; RV64I-NEXT:    add a0, a0, a1
996 ; RV64I-NEXT:    ret
998 ; RV64ZBA-LABEL: mul4098:
999 ; RV64ZBA:       # %bb.0:
1000 ; RV64ZBA-NEXT:    slli a1, a0, 12
1001 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
1002 ; RV64ZBA-NEXT:    ret
1003   %c = mul i64 %a, 4098
1004   ret i64 %c
1007 define i64 @mul4100(i64 %a) {
1008 ; RV64I-LABEL: mul4100:
1009 ; RV64I:       # %bb.0:
1010 ; RV64I-NEXT:    slli a1, a0, 2
1011 ; RV64I-NEXT:    slli a0, a0, 12
1012 ; RV64I-NEXT:    add a0, a0, a1
1013 ; RV64I-NEXT:    ret
1015 ; RV64ZBA-LABEL: mul4100:
1016 ; RV64ZBA:       # %bb.0:
1017 ; RV64ZBA-NEXT:    slli a1, a0, 12
1018 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
1019 ; RV64ZBA-NEXT:    ret
1020   %c = mul i64 %a, 4100
1021   ret i64 %c
1024 define i64 @mul4104(i64 %a) {
1025 ; RV64I-LABEL: mul4104:
1026 ; RV64I:       # %bb.0:
1027 ; RV64I-NEXT:    slli a1, a0, 3
1028 ; RV64I-NEXT:    slli a0, a0, 12
1029 ; RV64I-NEXT:    add a0, a0, a1
1030 ; RV64I-NEXT:    ret
1032 ; RV64ZBA-LABEL: mul4104:
1033 ; RV64ZBA:       # %bb.0:
1034 ; RV64ZBA-NEXT:    slli a1, a0, 12
1035 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
1036 ; RV64ZBA-NEXT:    ret
1037   %c = mul i64 %a, 4104
1038   ret i64 %c
1041 define signext i32 @mulw192(i32 signext %a) {
1042 ; CHECK-LABEL: mulw192:
1043 ; CHECK:       # %bb.0:
1044 ; CHECK-NEXT:    li a1, 192
1045 ; CHECK-NEXT:    mulw a0, a0, a1
1046 ; CHECK-NEXT:    ret
1047   %c = mul i32 %a, 192
1048   ret i32 %c
1051 define signext i32 @mulw320(i32 signext %a) {
1052 ; CHECK-LABEL: mulw320:
1053 ; CHECK:       # %bb.0:
1054 ; CHECK-NEXT:    li a1, 320
1055 ; CHECK-NEXT:    mulw a0, a0, a1
1056 ; CHECK-NEXT:    ret
1057   %c = mul i32 %a, 320
1058   ret i32 %c
1061 define signext i32 @mulw576(i32 signext %a) {
1062 ; CHECK-LABEL: mulw576:
1063 ; CHECK:       # %bb.0:
1064 ; CHECK-NEXT:    li a1, 576
1065 ; CHECK-NEXT:    mulw a0, a0, a1
1066 ; CHECK-NEXT:    ret
1067   %c = mul i32 %a, 576
1068   ret i32 %c
1071 define i64 @add4104(i64 %a) {
1072 ; RV64I-LABEL: add4104:
1073 ; RV64I:       # %bb.0:
1074 ; RV64I-NEXT:    lui a1, 1
1075 ; RV64I-NEXT:    addiw a1, a1, 8
1076 ; RV64I-NEXT:    add a0, a0, a1
1077 ; RV64I-NEXT:    ret
1079 ; RV64ZBA-LABEL: add4104:
1080 ; RV64ZBA:       # %bb.0:
1081 ; RV64ZBA-NEXT:    li a1, 1026
1082 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1083 ; RV64ZBA-NEXT:    ret
1084   %c = add i64 %a, 4104
1085   ret i64 %c
1088 define i64 @add8208(i64 %a) {
1089 ; RV64I-LABEL: add8208:
1090 ; RV64I:       # %bb.0:
1091 ; RV64I-NEXT:    lui a1, 2
1092 ; RV64I-NEXT:    addiw a1, a1, 16
1093 ; RV64I-NEXT:    add a0, a0, a1
1094 ; RV64I-NEXT:    ret
1096 ; RV64ZBA-LABEL: add8208:
1097 ; RV64ZBA:       # %bb.0:
1098 ; RV64ZBA-NEXT:    li a1, 1026
1099 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1100 ; RV64ZBA-NEXT:    ret
1101   %c = add i64 %a, 8208
1102   ret i64 %c
1105 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1106 define signext i32 @add8192_i32(i32 signext %a) {
1107 ; CHECK-LABEL: add8192_i32:
1108 ; CHECK:       # %bb.0:
1109 ; CHECK-NEXT:    lui a1, 2
1110 ; CHECK-NEXT:    addw a0, a0, a1
1111 ; CHECK-NEXT:    ret
1112   %c = add i32 %a, 8192
1113   ret i32 %c
1116 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1117 define i64 @add8192(i64 %a) {
1118 ; CHECK-LABEL: add8192:
1119 ; CHECK:       # %bb.0:
1120 ; CHECK-NEXT:    lui a1, 2
1121 ; CHECK-NEXT:    add a0, a0, a1
1122 ; CHECK-NEXT:    ret
1123   %c = add i64 %a, 8192
1124   ret i64 %c
1127 define signext i32 @addshl32_5_6(i32 signext %a, i32 signext %b) {
1128 ; RV64I-LABEL: addshl32_5_6:
1129 ; RV64I:       # %bb.0:
1130 ; RV64I-NEXT:    slli a0, a0, 5
1131 ; RV64I-NEXT:    slli a1, a1, 6
1132 ; RV64I-NEXT:    addw a0, a0, a1
1133 ; RV64I-NEXT:    ret
1135 ; RV64ZBA-LABEL: addshl32_5_6:
1136 ; RV64ZBA:       # %bb.0:
1137 ; RV64ZBA-NEXT:    slli a1, a1, 1
1138 ; RV64ZBA-NEXT:    add a0, a1, a0
1139 ; RV64ZBA-NEXT:    slliw a0, a0, 5
1140 ; RV64ZBA-NEXT:    ret
1141   %c = shl i32 %a, 5
1142   %d = shl i32 %b, 6
1143   %e = add i32 %c, %d
1144   ret i32 %e
1147 define i64 @addshl64_5_6(i64 %a, i64 %b) {
1148 ; RV64I-LABEL: addshl64_5_6:
1149 ; RV64I:       # %bb.0:
1150 ; RV64I-NEXT:    slli a0, a0, 5
1151 ; RV64I-NEXT:    slli a1, a1, 6
1152 ; RV64I-NEXT:    add a0, a0, a1
1153 ; RV64I-NEXT:    ret
1155 ; RV64ZBA-LABEL: addshl64_5_6:
1156 ; RV64ZBA:       # %bb.0:
1157 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1158 ; RV64ZBA-NEXT:    slli a0, a0, 5
1159 ; RV64ZBA-NEXT:    ret
1160   %c = shl i64 %a, 5
1161   %d = shl i64 %b, 6
1162   %e = add i64 %c, %d
1163   ret i64 %e
1166 define signext i32 @addshl32_5_7(i32 signext %a, i32 signext %b) {
1167 ; RV64I-LABEL: addshl32_5_7:
1168 ; RV64I:       # %bb.0:
1169 ; RV64I-NEXT:    slli a0, a0, 5
1170 ; RV64I-NEXT:    slli a1, a1, 7
1171 ; RV64I-NEXT:    addw a0, a0, a1
1172 ; RV64I-NEXT:    ret
1174 ; RV64ZBA-LABEL: addshl32_5_7:
1175 ; RV64ZBA:       # %bb.0:
1176 ; RV64ZBA-NEXT:    slli a1, a1, 2
1177 ; RV64ZBA-NEXT:    add a0, a1, a0
1178 ; RV64ZBA-NEXT:    slliw a0, a0, 5
1179 ; RV64ZBA-NEXT:    ret
1180   %c = shl i32 %a, 5
1181   %d = shl i32 %b, 7
1182   %e = add i32 %c, %d
1183   ret i32 %e
1186 define i64 @addshl64_5_7(i64 %a, i64 %b) {
1187 ; RV64I-LABEL: addshl64_5_7:
1188 ; RV64I:       # %bb.0:
1189 ; RV64I-NEXT:    slli a0, a0, 5
1190 ; RV64I-NEXT:    slli a1, a1, 7
1191 ; RV64I-NEXT:    add a0, a0, a1
1192 ; RV64I-NEXT:    ret
1194 ; RV64ZBA-LABEL: addshl64_5_7:
1195 ; RV64ZBA:       # %bb.0:
1196 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1197 ; RV64ZBA-NEXT:    slli a0, a0, 5
1198 ; RV64ZBA-NEXT:    ret
1199   %c = shl i64 %a, 5
1200   %d = shl i64 %b, 7
1201   %e = add i64 %c, %d
1202   ret i64 %e
1205 define signext i32 @addshl32_5_8(i32 signext %a, i32 signext %b) {
1206 ; RV64I-LABEL: addshl32_5_8:
1207 ; RV64I:       # %bb.0:
1208 ; RV64I-NEXT:    slli a0, a0, 5
1209 ; RV64I-NEXT:    slli a1, a1, 8
1210 ; RV64I-NEXT:    addw a0, a0, a1
1211 ; RV64I-NEXT:    ret
1213 ; RV64ZBA-LABEL: addshl32_5_8:
1214 ; RV64ZBA:       # %bb.0:
1215 ; RV64ZBA-NEXT:    slli a1, a1, 3
1216 ; RV64ZBA-NEXT:    add a0, a1, a0
1217 ; RV64ZBA-NEXT:    slliw a0, a0, 5
1218 ; RV64ZBA-NEXT:    ret
1219   %c = shl i32 %a, 5
1220   %d = shl i32 %b, 8
1221   %e = add i32 %c, %d
1222   ret i32 %e
1225 define i64 @addshl64_5_8(i64 %a, i64 %b) {
1226 ; RV64I-LABEL: addshl64_5_8:
1227 ; RV64I:       # %bb.0:
1228 ; RV64I-NEXT:    slli a0, a0, 5
1229 ; RV64I-NEXT:    slli a1, a1, 8
1230 ; RV64I-NEXT:    add a0, a0, a1
1231 ; RV64I-NEXT:    ret
1233 ; RV64ZBA-LABEL: addshl64_5_8:
1234 ; RV64ZBA:       # %bb.0:
1235 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1236 ; RV64ZBA-NEXT:    slli a0, a0, 5
1237 ; RV64ZBA-NEXT:    ret
1238   %c = shl i64 %a, 5
1239   %d = shl i64 %b, 8
1240   %e = add i64 %c, %d
1241   ret i64 %e
1244 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1245 ; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
1246 define zeroext i32 @sext_ashr_zext_i8(i8 %a) nounwind {
1247 ; RV64I-LABEL: sext_ashr_zext_i8:
1248 ; RV64I:       # %bb.0:
1249 ; RV64I-NEXT:    slli a0, a0, 24
1250 ; RV64I-NEXT:    sraiw a0, a0, 31
1251 ; RV64I-NEXT:    slli a0, a0, 32
1252 ; RV64I-NEXT:    srli a0, a0, 32
1253 ; RV64I-NEXT:    ret
1255 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i8:
1256 ; RV64ZBANOZBB:       # %bb.0:
1257 ; RV64ZBANOZBB-NEXT:    slli a0, a0, 24
1258 ; RV64ZBANOZBB-NEXT:    sraiw a0, a0, 31
1259 ; RV64ZBANOZBB-NEXT:    zext.w a0, a0
1260 ; RV64ZBANOZBB-NEXT:    ret
1262 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i8:
1263 ; RV64ZBAZBB:       # %bb.0:
1264 ; RV64ZBAZBB-NEXT:    sext.b a0, a0
1265 ; RV64ZBAZBB-NEXT:    sraiw a0, a0, 9
1266 ; RV64ZBAZBB-NEXT:    zext.w a0, a0
1267 ; RV64ZBAZBB-NEXT:    ret
1268   %ext = sext i8 %a to i32
1269   %1 = ashr i32 %ext, 9
1270   ret i32 %1
1273 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1274 ; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
1275 define zeroext i32 @sext_ashr_zext_i16(i16 %a) nounwind {
1276 ; RV64I-LABEL: sext_ashr_zext_i16:
1277 ; RV64I:       # %bb.0:
1278 ; RV64I-NEXT:    slli a0, a0, 16
1279 ; RV64I-NEXT:    sraiw a0, a0, 25
1280 ; RV64I-NEXT:    slli a0, a0, 32
1281 ; RV64I-NEXT:    srli a0, a0, 32
1282 ; RV64I-NEXT:    ret
1284 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i16:
1285 ; RV64ZBANOZBB:       # %bb.0:
1286 ; RV64ZBANOZBB-NEXT:    slli a0, a0, 16
1287 ; RV64ZBANOZBB-NEXT:    sraiw a0, a0, 25
1288 ; RV64ZBANOZBB-NEXT:    zext.w a0, a0
1289 ; RV64ZBANOZBB-NEXT:    ret
1291 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i16:
1292 ; RV64ZBAZBB:       # %bb.0:
1293 ; RV64ZBAZBB-NEXT:    slli a0, a0, 48
1294 ; RV64ZBAZBB-NEXT:    srai a0, a0, 57
1295 ; RV64ZBAZBB-NEXT:    zext.w a0, a0
1296 ; RV64ZBAZBB-NEXT:    ret
1297   %ext = sext i16 %a to i32
1298   %1 = ashr i32 %ext, 9
1299   ret i32 %1
1302 ; This the IR you get from InstCombine if take the difference of 2 pointers and
1303 ; cast is to unsigned before using as an index.
1304 define signext i16 @sh1adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1305 ; RV64I-LABEL: sh1adduw_ptrdiff:
1306 ; RV64I:       # %bb.0:
1307 ; RV64I-NEXT:    li a2, 1
1308 ; RV64I-NEXT:    slli a2, a2, 33
1309 ; RV64I-NEXT:    addi a2, a2, -2
1310 ; RV64I-NEXT:    and a0, a0, a2
1311 ; RV64I-NEXT:    add a0, a1, a0
1312 ; RV64I-NEXT:    lh a0, 0(a0)
1313 ; RV64I-NEXT:    ret
1315 ; RV64ZBA-LABEL: sh1adduw_ptrdiff:
1316 ; RV64ZBA:       # %bb.0:
1317 ; RV64ZBA-NEXT:    srli a0, a0, 1
1318 ; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
1319 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1320 ; RV64ZBA-NEXT:    ret
1321   %ptrdiff = lshr exact i64 %diff, 1
1322   %cast = and i64 %ptrdiff, 4294967295
1323   %ptr = getelementptr inbounds i16, ptr %baseptr, i64 %cast
1324   %res = load i16, ptr %ptr
1325   ret i16 %res
1328 define signext i32 @sh2adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1329 ; RV64I-LABEL: sh2adduw_ptrdiff:
1330 ; RV64I:       # %bb.0:
1331 ; RV64I-NEXT:    li a2, 1
1332 ; RV64I-NEXT:    slli a2, a2, 34
1333 ; RV64I-NEXT:    addi a2, a2, -4
1334 ; RV64I-NEXT:    and a0, a0, a2
1335 ; RV64I-NEXT:    add a0, a1, a0
1336 ; RV64I-NEXT:    lw a0, 0(a0)
1337 ; RV64I-NEXT:    ret
1339 ; RV64ZBA-LABEL: sh2adduw_ptrdiff:
1340 ; RV64ZBA:       # %bb.0:
1341 ; RV64ZBA-NEXT:    srli a0, a0, 2
1342 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
1343 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1344 ; RV64ZBA-NEXT:    ret
1345   %ptrdiff = lshr exact i64 %diff, 2
1346   %cast = and i64 %ptrdiff, 4294967295
1347   %ptr = getelementptr inbounds i32, ptr %baseptr, i64 %cast
1348   %res = load i32, ptr %ptr
1349   ret i32 %res
1352 define i64 @sh3adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1353 ; RV64I-LABEL: sh3adduw_ptrdiff:
1354 ; RV64I:       # %bb.0:
1355 ; RV64I-NEXT:    li a2, 1
1356 ; RV64I-NEXT:    slli a2, a2, 35
1357 ; RV64I-NEXT:    addi a2, a2, -8
1358 ; RV64I-NEXT:    and a0, a0, a2
1359 ; RV64I-NEXT:    add a0, a1, a0
1360 ; RV64I-NEXT:    ld a0, 0(a0)
1361 ; RV64I-NEXT:    ret
1363 ; RV64ZBA-LABEL: sh3adduw_ptrdiff:
1364 ; RV64ZBA:       # %bb.0:
1365 ; RV64ZBA-NEXT:    srli a0, a0, 3
1366 ; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
1367 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1368 ; RV64ZBA-NEXT:    ret
1369   %ptrdiff = lshr exact i64 %diff, 3
1370   %cast = and i64 %ptrdiff, 4294967295
1371   %ptr = getelementptr inbounds i64, ptr %baseptr, i64 %cast
1372   %res = load i64, ptr %ptr
1373   ret i64 %res
1376 define signext i16 @srliw_1_sh1add(ptr %0, i32 signext %1) {
1377 ; RV64I-LABEL: srliw_1_sh1add:
1378 ; RV64I:       # %bb.0:
1379 ; RV64I-NEXT:    srliw a1, a1, 1
1380 ; RV64I-NEXT:    slli a1, a1, 1
1381 ; RV64I-NEXT:    add a0, a0, a1
1382 ; RV64I-NEXT:    lh a0, 0(a0)
1383 ; RV64I-NEXT:    ret
1385 ; RV64ZBA-LABEL: srliw_1_sh1add:
1386 ; RV64ZBA:       # %bb.0:
1387 ; RV64ZBA-NEXT:    srliw a1, a1, 1
1388 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1389 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1390 ; RV64ZBA-NEXT:    ret
1391   %3 = lshr i32 %1, 1
1392   %4 = zext i32 %3 to i64
1393   %5 = getelementptr inbounds i16, ptr %0, i64 %4
1394   %6 = load i16, ptr %5, align 2
1395   ret i16 %6
1398 define i128 @slliuw_ptrdiff(i64 %diff, ptr %baseptr) {
1399 ; RV64I-LABEL: slliuw_ptrdiff:
1400 ; RV64I:       # %bb.0:
1401 ; RV64I-NEXT:    li a2, 1
1402 ; RV64I-NEXT:    slli a2, a2, 36
1403 ; RV64I-NEXT:    addi a2, a2, -16
1404 ; RV64I-NEXT:    and a0, a0, a2
1405 ; RV64I-NEXT:    add a1, a1, a0
1406 ; RV64I-NEXT:    ld a0, 0(a1)
1407 ; RV64I-NEXT:    ld a1, 8(a1)
1408 ; RV64I-NEXT:    ret
1410 ; RV64ZBA-LABEL: slliuw_ptrdiff:
1411 ; RV64ZBA:       # %bb.0:
1412 ; RV64ZBA-NEXT:    srli a0, a0, 4
1413 ; RV64ZBA-NEXT:    slli.uw a0, a0, 4
1414 ; RV64ZBA-NEXT:    add a1, a1, a0
1415 ; RV64ZBA-NEXT:    ld a0, 0(a1)
1416 ; RV64ZBA-NEXT:    ld a1, 8(a1)
1417 ; RV64ZBA-NEXT:    ret
1418   %ptrdiff = lshr exact i64 %diff, 4
1419   %cast = and i64 %ptrdiff, 4294967295
1420   %ptr = getelementptr inbounds i128, ptr %baseptr, i64 %cast
1421   %res = load i128, ptr %ptr
1422   ret i128 %res
1425 define signext i32 @srliw_2_sh2add(ptr %0, i32 signext %1) {
1426 ; RV64I-LABEL: srliw_2_sh2add:
1427 ; RV64I:       # %bb.0:
1428 ; RV64I-NEXT:    srliw a1, a1, 2
1429 ; RV64I-NEXT:    slli a1, a1, 2
1430 ; RV64I-NEXT:    add a0, a0, a1
1431 ; RV64I-NEXT:    lw a0, 0(a0)
1432 ; RV64I-NEXT:    ret
1434 ; RV64ZBA-LABEL: srliw_2_sh2add:
1435 ; RV64ZBA:       # %bb.0:
1436 ; RV64ZBA-NEXT:    srliw a1, a1, 2
1437 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1438 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1439 ; RV64ZBA-NEXT:    ret
1440   %3 = lshr i32 %1, 2
1441   %4 = zext i32 %3 to i64
1442   %5 = getelementptr inbounds i32, ptr %0, i64 %4
1443   %6 = load i32, ptr %5, align 4
1444   ret i32 %6
1447 define i64 @srliw_3_sh3add(ptr %0, i32 signext %1) {
1448 ; RV64I-LABEL: srliw_3_sh3add:
1449 ; RV64I:       # %bb.0:
1450 ; RV64I-NEXT:    srliw a1, a1, 3
1451 ; RV64I-NEXT:    slli a1, a1, 3
1452 ; RV64I-NEXT:    add a0, a0, a1
1453 ; RV64I-NEXT:    ld a0, 0(a0)
1454 ; RV64I-NEXT:    ret
1456 ; RV64ZBA-LABEL: srliw_3_sh3add:
1457 ; RV64ZBA:       # %bb.0:
1458 ; RV64ZBA-NEXT:    srliw a1, a1, 3
1459 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1460 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1461 ; RV64ZBA-NEXT:    ret
1462   %3 = lshr i32 %1, 3
1463   %4 = zext i32 %3 to i64
1464   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1465   %6 = load i64, ptr %5, align 8
1466   ret i64 %6
1469 define signext i32 @srliw_1_sh2add(ptr %0, i32 signext %1) {
1470 ; RV64I-LABEL: srliw_1_sh2add:
1471 ; RV64I:       # %bb.0:
1472 ; RV64I-NEXT:    srliw a1, a1, 1
1473 ; RV64I-NEXT:    slli a1, a1, 32
1474 ; RV64I-NEXT:    srli a1, a1, 32
1475 ; RV64I-NEXT:    slli a1, a1, 2
1476 ; RV64I-NEXT:    add a0, a0, a1
1477 ; RV64I-NEXT:    lw a0, 0(a0)
1478 ; RV64I-NEXT:    ret
1480 ; RV64ZBA-LABEL: srliw_1_sh2add:
1481 ; RV64ZBA:       # %bb.0:
1482 ; RV64ZBA-NEXT:    srliw a1, a1, 1
1483 ; RV64ZBA-NEXT:    zext.w a1, a1
1484 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1485 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1486 ; RV64ZBA-NEXT:    ret
1487   %3 = lshr i32 %1, 1
1488   %4 = zext i32 %3 to i64
1489   %5 = getelementptr inbounds i32, ptr %0, i64 %4
1490   %6 = load i32, ptr %5, align 4
1491   ret i32 %6
1494 define i64 @srliw_1_sh3add(ptr %0, i32 signext %1) {
1495 ; RV64I-LABEL: srliw_1_sh3add:
1496 ; RV64I:       # %bb.0:
1497 ; RV64I-NEXT:    srliw a1, a1, 1
1498 ; RV64I-NEXT:    slli a1, a1, 32
1499 ; RV64I-NEXT:    srli a1, a1, 32
1500 ; RV64I-NEXT:    slli a1, a1, 3
1501 ; RV64I-NEXT:    add a0, a0, a1
1502 ; RV64I-NEXT:    ld a0, 0(a0)
1503 ; RV64I-NEXT:    ret
1505 ; RV64ZBA-LABEL: srliw_1_sh3add:
1506 ; RV64ZBA:       # %bb.0:
1507 ; RV64ZBA-NEXT:    srliw a1, a1, 1
1508 ; RV64ZBA-NEXT:    zext.w a1, a1
1509 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1510 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1511 ; RV64ZBA-NEXT:    ret
1512   %3 = lshr i32 %1, 1
1513   %4 = zext i32 %3 to i64
1514   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1515   %6 = load i64, ptr %5, align 8
1516   ret i64 %6
1519 define i64 @srliw_2_sh3add(ptr %0, i32 signext %1) {
1520 ; RV64I-LABEL: srliw_2_sh3add:
1521 ; RV64I:       # %bb.0:
1522 ; RV64I-NEXT:    srliw a1, a1, 2
1523 ; RV64I-NEXT:    slli a1, a1, 32
1524 ; RV64I-NEXT:    srli a1, a1, 32
1525 ; RV64I-NEXT:    slli a1, a1, 3
1526 ; RV64I-NEXT:    add a0, a0, a1
1527 ; RV64I-NEXT:    ld a0, 0(a0)
1528 ; RV64I-NEXT:    ret
1530 ; RV64ZBA-LABEL: srliw_2_sh3add:
1531 ; RV64ZBA:       # %bb.0:
1532 ; RV64ZBA-NEXT:    srliw a1, a1, 2
1533 ; RV64ZBA-NEXT:    zext.w a1, a1
1534 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1535 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1536 ; RV64ZBA-NEXT:    ret
1537   %3 = lshr i32 %1, 2
1538   %4 = zext i32 %3 to i64
1539   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1540   %6 = load i64, ptr %5, align 8
1541   ret i64 %6
1544 define signext i16 @srliw_2_sh1add(ptr %0, i32 signext %1) {
1545 ; RV64I-LABEL: srliw_2_sh1add:
1546 ; RV64I:       # %bb.0:
1547 ; RV64I-NEXT:    srliw a1, a1, 2
1548 ; RV64I-NEXT:    slli a1, a1, 32
1549 ; RV64I-NEXT:    srli a1, a1, 32
1550 ; RV64I-NEXT:    slli a1, a1, 1
1551 ; RV64I-NEXT:    add a0, a0, a1
1552 ; RV64I-NEXT:    lh a0, 0(a0)
1553 ; RV64I-NEXT:    ret
1555 ; RV64ZBA-LABEL: srliw_2_sh1add:
1556 ; RV64ZBA:       # %bb.0:
1557 ; RV64ZBA-NEXT:    srliw a1, a1, 2
1558 ; RV64ZBA-NEXT:    zext.w a1, a1
1559 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1560 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1561 ; RV64ZBA-NEXT:    ret
1562   %3 = lshr i32 %1, 2
1563   %4 = zext i32 %3 to i64
1564   %5 = getelementptr inbounds i16, ptr %0, i64 %4
1565   %6 = load i16, ptr %5, align 2
1566   ret i16 %6
1570 define signext i32 @srliw_3_sh2add(ptr %0, i32 signext %1) {
1571 ; RV64I-LABEL: srliw_3_sh2add:
1572 ; RV64I:       # %bb.0:
1573 ; RV64I-NEXT:    srliw a1, a1, 3
1574 ; RV64I-NEXT:    slli a1, a1, 32
1575 ; RV64I-NEXT:    srli a1, a1, 32
1576 ; RV64I-NEXT:    slli a1, a1, 2
1577 ; RV64I-NEXT:    add a0, a0, a1
1578 ; RV64I-NEXT:    lw a0, 0(a0)
1579 ; RV64I-NEXT:    ret
1581 ; RV64ZBA-LABEL: srliw_3_sh2add:
1582 ; RV64ZBA:       # %bb.0:
1583 ; RV64ZBA-NEXT:    srliw a1, a1, 3
1584 ; RV64ZBA-NEXT:    zext.w a1, a1
1585 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1586 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1587 ; RV64ZBA-NEXT:    ret
1588   %3 = lshr i32 %1, 3
1589   %4 = zext i32 %3 to i64
1590   %5 = getelementptr inbounds i32, ptr %0, i64 %4
1591   %6 = load i32, ptr %5, align 4
1592   ret i32 %6
1595 define i64 @srliw_4_sh3add(ptr %0, i32 signext %1) {
1596 ; RV64I-LABEL: srliw_4_sh3add:
1597 ; RV64I:       # %bb.0:
1598 ; RV64I-NEXT:    srliw a1, a1, 4
1599 ; RV64I-NEXT:    slli a1, a1, 32
1600 ; RV64I-NEXT:    srli a1, a1, 32
1601 ; RV64I-NEXT:    slli a1, a1, 3
1602 ; RV64I-NEXT:    add a0, a0, a1
1603 ; RV64I-NEXT:    ld a0, 0(a0)
1604 ; RV64I-NEXT:    ret
1606 ; RV64ZBA-LABEL: srliw_4_sh3add:
1607 ; RV64ZBA:       # %bb.0:
1608 ; RV64ZBA-NEXT:    srliw a1, a1, 4
1609 ; RV64ZBA-NEXT:    zext.w a1, a1
1610 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1611 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1612 ; RV64ZBA-NEXT:    ret
1613   %3 = lshr i32 %1, 4
1614   %4 = zext i32 %3 to i64
1615   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1616   %6 = load i64, ptr %5, align 8
1617   ret i64 %6
1620 define signext i32 @srli_1_sh2add(ptr %0, i64 %1) {
1621 ; RV64I-LABEL: srli_1_sh2add:
1622 ; RV64I:       # %bb.0:
1623 ; RV64I-NEXT:    slli a1, a1, 1
1624 ; RV64I-NEXT:    andi a1, a1, -4
1625 ; RV64I-NEXT:    add a0, a0, a1
1626 ; RV64I-NEXT:    lw a0, 0(a0)
1627 ; RV64I-NEXT:    ret
1629 ; RV64ZBA-LABEL: srli_1_sh2add:
1630 ; RV64ZBA:       # %bb.0:
1631 ; RV64ZBA-NEXT:    srli a1, a1, 1
1632 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1633 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1634 ; RV64ZBA-NEXT:    ret
1635   %3 = lshr i64 %1, 1
1636   %4 = getelementptr inbounds i32, ptr %0, i64 %3
1637   %5 = load i32, ptr %4, align 4
1638   ret i32 %5
1641 define i64 @srli_2_sh3add(ptr %0, i64 %1) {
1642 ; RV64I-LABEL: srli_2_sh3add:
1643 ; RV64I:       # %bb.0:
1644 ; RV64I-NEXT:    slli a1, a1, 1
1645 ; RV64I-NEXT:    andi a1, a1, -8
1646 ; RV64I-NEXT:    add a0, a0, a1
1647 ; RV64I-NEXT:    ld a0, 0(a0)
1648 ; RV64I-NEXT:    ret
1650 ; RV64ZBA-LABEL: srli_2_sh3add:
1651 ; RV64ZBA:       # %bb.0:
1652 ; RV64ZBA-NEXT:    srli a1, a1, 2
1653 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1654 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1655 ; RV64ZBA-NEXT:    ret
1656   %3 = lshr i64 %1, 2
1657   %4 = getelementptr inbounds i64, ptr %0, i64 %3
1658   %5 = load i64, ptr %4, align 8
1659   ret i64 %5
1662 define signext i16 @srli_2_sh1add(ptr %0, i64 %1) {
1663 ; RV64I-LABEL: srli_2_sh1add:
1664 ; RV64I:       # %bb.0:
1665 ; RV64I-NEXT:    srli a1, a1, 1
1666 ; RV64I-NEXT:    andi a1, a1, -2
1667 ; RV64I-NEXT:    add a0, a0, a1
1668 ; RV64I-NEXT:    lh a0, 0(a0)
1669 ; RV64I-NEXT:    ret
1671 ; RV64ZBA-LABEL: srli_2_sh1add:
1672 ; RV64ZBA:       # %bb.0:
1673 ; RV64ZBA-NEXT:    srli a1, a1, 2
1674 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1675 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1676 ; RV64ZBA-NEXT:    ret
1677   %3 = lshr i64 %1, 2
1678   %4 = getelementptr inbounds i16, ptr %0, i64 %3
1679   %5 = load i16, ptr %4, align 2
1680   ret i16 %5
1683 define signext i32 @srli_3_sh2add(ptr %0, i64 %1) {
1684 ; RV64I-LABEL: srli_3_sh2add:
1685 ; RV64I:       # %bb.0:
1686 ; RV64I-NEXT:    srli a1, a1, 1
1687 ; RV64I-NEXT:    andi a1, a1, -4
1688 ; RV64I-NEXT:    add a0, a0, a1
1689 ; RV64I-NEXT:    lw a0, 0(a0)
1690 ; RV64I-NEXT:    ret
1692 ; RV64ZBA-LABEL: srli_3_sh2add:
1693 ; RV64ZBA:       # %bb.0:
1694 ; RV64ZBA-NEXT:    srli a1, a1, 3
1695 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1696 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1697 ; RV64ZBA-NEXT:    ret
1698   %3 = lshr i64 %1, 3
1699   %4 = getelementptr inbounds i32, ptr %0, i64 %3
1700   %5 = load i32, ptr %4, align 4
1701   ret i32 %5
1704 define i64 @srli_4_sh3add(ptr %0, i64 %1) {
1705 ; RV64I-LABEL: srli_4_sh3add:
1706 ; RV64I:       # %bb.0:
1707 ; RV64I-NEXT:    srli a1, a1, 1
1708 ; RV64I-NEXT:    andi a1, a1, -8
1709 ; RV64I-NEXT:    add a0, a0, a1
1710 ; RV64I-NEXT:    ld a0, 0(a0)
1711 ; RV64I-NEXT:    ret
1713 ; RV64ZBA-LABEL: srli_4_sh3add:
1714 ; RV64ZBA:       # %bb.0:
1715 ; RV64ZBA-NEXT:    srli a1, a1, 4
1716 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1717 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1718 ; RV64ZBA-NEXT:    ret
1719   %3 = lshr i64 %1, 4
1720   %4 = getelementptr inbounds i64, ptr %0, i64 %3
1721   %5 = load i64, ptr %4, align 8
1722   ret i64 %5
1725 define signext i16 @shl_2_sh1add(ptr %0, i32 signext %1) {
1726 ; RV64I-LABEL: shl_2_sh1add:
1727 ; RV64I:       # %bb.0:
1728 ; RV64I-NEXT:    slli a1, a1, 2
1729 ; RV64I-NEXT:    slli a1, a1, 32
1730 ; RV64I-NEXT:    srli a1, a1, 32
1731 ; RV64I-NEXT:    slli a1, a1, 1
1732 ; RV64I-NEXT:    add a0, a0, a1
1733 ; RV64I-NEXT:    lh a0, 0(a0)
1734 ; RV64I-NEXT:    ret
1736 ; RV64ZBA-LABEL: shl_2_sh1add:
1737 ; RV64ZBA:       # %bb.0:
1738 ; RV64ZBA-NEXT:    slli a1, a1, 2
1739 ; RV64ZBA-NEXT:    zext.w a1, a1
1740 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1741 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1742 ; RV64ZBA-NEXT:    ret
1743   %3 = shl i32 %1, 2
1744   %4 = zext i32 %3 to i64
1745   %5 = getelementptr inbounds i16, ptr %0, i64 %4
1746   %6 = load i16, ptr %5, align 2
1747   ret i16 %6
1750 define signext i32 @shl_16_sh2add(ptr %0, i32 signext %1) {
1751 ; RV64I-LABEL: shl_16_sh2add:
1752 ; RV64I:       # %bb.0:
1753 ; RV64I-NEXT:    slli a1, a1, 16
1754 ; RV64I-NEXT:    slli a1, a1, 32
1755 ; RV64I-NEXT:    srli a1, a1, 32
1756 ; RV64I-NEXT:    slli a1, a1, 2
1757 ; RV64I-NEXT:    add a0, a0, a1
1758 ; RV64I-NEXT:    lw a0, 0(a0)
1759 ; RV64I-NEXT:    ret
1761 ; RV64ZBA-LABEL: shl_16_sh2add:
1762 ; RV64ZBA:       # %bb.0:
1763 ; RV64ZBA-NEXT:    slli a1, a1, 16
1764 ; RV64ZBA-NEXT:    zext.w a1, a1
1765 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1766 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1767 ; RV64ZBA-NEXT:    ret
1768   %3 = shl i32 %1, 16
1769   %4 = zext i32 %3 to i64
1770   %5 = getelementptr inbounds i32, ptr %0, i64 %4
1771   %6 = load i32, ptr %5, align 4
1772   ret i32 %6
1775 define i64 @shl_31_sh3add(ptr %0, i32 signext %1) {
1776 ; RV64I-LABEL: shl_31_sh3add:
1777 ; RV64I:       # %bb.0:
1778 ; RV64I-NEXT:    slli a1, a1, 31
1779 ; RV64I-NEXT:    slli a1, a1, 32
1780 ; RV64I-NEXT:    srli a1, a1, 32
1781 ; RV64I-NEXT:    slli a1, a1, 3
1782 ; RV64I-NEXT:    add a0, a0, a1
1783 ; RV64I-NEXT:    ld a0, 0(a0)
1784 ; RV64I-NEXT:    ret
1786 ; RV64ZBA-LABEL: shl_31_sh3add:
1787 ; RV64ZBA:       # %bb.0:
1788 ; RV64ZBA-NEXT:    slli a1, a1, 31
1789 ; RV64ZBA-NEXT:    zext.w a1, a1
1790 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1791 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1792 ; RV64ZBA-NEXT:    ret
1793   %3 = shl i32 %1, 31
1794   %4 = zext i32 %3 to i64
1795   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1796   %6 = load i64, ptr %5, align 8
1797   ret i64 %6