Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / CodeGen / RISCV / rv64zba.ll
blob9b472523875e792255999585ae7f7955f19d02e9
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
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:    sllw a1, a2, a0
299 ; RV64I-NEXT:    sraiw a0, a0, 2
300 ; RV64I-NEXT:    mul a0, a1, a0
301 ; RV64I-NEXT:    ret
303 ; RV64ZBA-LABEL: sh2add_extra_sext:
304 ; RV64ZBA:       # %bb.0:
305 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
306 ; RV64ZBA-NEXT:    sllw a1, a2, a0
307 ; RV64ZBA-NEXT:    sraiw a0, a0, 2
308 ; RV64ZBA-NEXT:    mul a0, a1, a0
309 ; RV64ZBA-NEXT:    ret
310   %a = shl i32 %x, 2
311   %b = add i32 %a, %y
312   %c = shl i32 %z, %b
313   %d = ashr i32 %b, 2
314   %e = sext i32 %c to i64
315   %f = sext i32 %d to i64
316   %g = mul i64 %e, %f
317   ret i64 %g
320 define i64 @addmul6(i64 %a, i64 %b) {
321 ; RV64I-LABEL: addmul6:
322 ; RV64I:       # %bb.0:
323 ; RV64I-NEXT:    li a2, 6
324 ; RV64I-NEXT:    mul a0, a0, a2
325 ; RV64I-NEXT:    add a0, a0, a1
326 ; RV64I-NEXT:    ret
328 ; RV64ZBA-LABEL: addmul6:
329 ; RV64ZBA:       # %bb.0:
330 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
331 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
332 ; RV64ZBA-NEXT:    ret
333   %c = mul i64 %a, 6
334   %d = add i64 %c, %b
335   ret i64 %d
338 define i64 @addmul10(i64 %a, i64 %b) {
339 ; RV64I-LABEL: addmul10:
340 ; RV64I:       # %bb.0:
341 ; RV64I-NEXT:    li a2, 10
342 ; RV64I-NEXT:    mul a0, a0, a2
343 ; RV64I-NEXT:    add a0, a0, a1
344 ; RV64I-NEXT:    ret
346 ; RV64ZBA-LABEL: addmul10:
347 ; RV64ZBA:       # %bb.0:
348 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
349 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
350 ; RV64ZBA-NEXT:    ret
351   %c = mul i64 %a, 10
352   %d = add i64 %c, %b
353   ret i64 %d
356 define i64 @addmul12(i64 %a, i64 %b) {
357 ; RV64I-LABEL: addmul12:
358 ; RV64I:       # %bb.0:
359 ; RV64I-NEXT:    li a2, 12
360 ; RV64I-NEXT:    mul a0, a0, a2
361 ; RV64I-NEXT:    add a0, a0, a1
362 ; RV64I-NEXT:    ret
364 ; RV64ZBA-LABEL: addmul12:
365 ; RV64ZBA:       # %bb.0:
366 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
367 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
368 ; RV64ZBA-NEXT:    ret
369   %c = mul i64 %a, 12
370   %d = add i64 %c, %b
371   ret i64 %d
374 define i64 @addmul18(i64 %a, i64 %b) {
375 ; RV64I-LABEL: addmul18:
376 ; RV64I:       # %bb.0:
377 ; RV64I-NEXT:    li a2, 18
378 ; RV64I-NEXT:    mul a0, a0, a2
379 ; RV64I-NEXT:    add a0, a0, a1
380 ; RV64I-NEXT:    ret
382 ; RV64ZBA-LABEL: addmul18:
383 ; RV64ZBA:       # %bb.0:
384 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
385 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
386 ; RV64ZBA-NEXT:    ret
387   %c = mul i64 %a, 18
388   %d = add i64 %c, %b
389   ret i64 %d
392 define i64 @addmul20(i64 %a, i64 %b) {
393 ; RV64I-LABEL: addmul20:
394 ; RV64I:       # %bb.0:
395 ; RV64I-NEXT:    li a2, 20
396 ; RV64I-NEXT:    mul a0, a0, a2
397 ; RV64I-NEXT:    add a0, a0, a1
398 ; RV64I-NEXT:    ret
400 ; RV64ZBA-LABEL: addmul20:
401 ; RV64ZBA:       # %bb.0:
402 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
403 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
404 ; RV64ZBA-NEXT:    ret
405   %c = mul i64 %a, 20
406   %d = add i64 %c, %b
407   ret i64 %d
410 define i64 @addmul24(i64 %a, i64 %b) {
411 ; RV64I-LABEL: addmul24:
412 ; RV64I:       # %bb.0:
413 ; RV64I-NEXT:    li a2, 24
414 ; RV64I-NEXT:    mul a0, a0, a2
415 ; RV64I-NEXT:    add a0, a0, a1
416 ; RV64I-NEXT:    ret
418 ; RV64ZBA-LABEL: addmul24:
419 ; RV64ZBA:       # %bb.0:
420 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
421 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
422 ; RV64ZBA-NEXT:    ret
423   %c = mul i64 %a, 24
424   %d = add i64 %c, %b
425   ret i64 %d
428 define i64 @addmul36(i64 %a, i64 %b) {
429 ; RV64I-LABEL: addmul36:
430 ; RV64I:       # %bb.0:
431 ; RV64I-NEXT:    li a2, 36
432 ; RV64I-NEXT:    mul a0, a0, a2
433 ; RV64I-NEXT:    add a0, a0, a1
434 ; RV64I-NEXT:    ret
436 ; RV64ZBA-LABEL: addmul36:
437 ; RV64ZBA:       # %bb.0:
438 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
439 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
440 ; RV64ZBA-NEXT:    ret
441   %c = mul i64 %a, 36
442   %d = add i64 %c, %b
443   ret i64 %d
446 define i64 @addmul40(i64 %a, i64 %b) {
447 ; RV64I-LABEL: addmul40:
448 ; RV64I:       # %bb.0:
449 ; RV64I-NEXT:    li a2, 40
450 ; RV64I-NEXT:    mul a0, a0, a2
451 ; RV64I-NEXT:    add a0, a0, a1
452 ; RV64I-NEXT:    ret
454 ; RV64ZBA-LABEL: addmul40:
455 ; RV64ZBA:       # %bb.0:
456 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
457 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
458 ; RV64ZBA-NEXT:    ret
459   %c = mul i64 %a, 40
460   %d = add i64 %c, %b
461   ret i64 %d
464 define i64 @addmul72(i64 %a, i64 %b) {
465 ; RV64I-LABEL: addmul72:
466 ; RV64I:       # %bb.0:
467 ; RV64I-NEXT:    li a2, 72
468 ; RV64I-NEXT:    mul a0, a0, a2
469 ; RV64I-NEXT:    add a0, a0, a1
470 ; RV64I-NEXT:    ret
472 ; RV64ZBA-LABEL: addmul72:
473 ; RV64ZBA:       # %bb.0:
474 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
475 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
476 ; RV64ZBA-NEXT:    ret
477   %c = mul i64 %a, 72
478   %d = add i64 %c, %b
479   ret i64 %d
482 define i64 @mul96(i64 %a) {
483 ; RV64I-LABEL: mul96:
484 ; RV64I:       # %bb.0:
485 ; RV64I-NEXT:    li a1, 96
486 ; RV64I-NEXT:    mul a0, a0, a1
487 ; RV64I-NEXT:    ret
489 ; RV64ZBA-LABEL: mul96:
490 ; RV64ZBA:       # %bb.0:
491 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
492 ; RV64ZBA-NEXT:    slli a0, a0, 5
493 ; RV64ZBA-NEXT:    ret
494   %c = mul i64 %a, 96
495   ret i64 %c
498 define i64 @mul160(i64 %a) {
499 ; RV64I-LABEL: mul160:
500 ; RV64I:       # %bb.0:
501 ; RV64I-NEXT:    li a1, 160
502 ; RV64I-NEXT:    mul a0, a0, a1
503 ; RV64I-NEXT:    ret
505 ; RV64ZBA-LABEL: mul160:
506 ; RV64ZBA:       # %bb.0:
507 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
508 ; RV64ZBA-NEXT:    slli a0, a0, 5
509 ; RV64ZBA-NEXT:    ret
510   %c = mul i64 %a, 160
511   ret i64 %c
514 define i64 @mul288(i64 %a) {
515 ; RV64I-LABEL: mul288:
516 ; RV64I:       # %bb.0:
517 ; RV64I-NEXT:    li a1, 288
518 ; RV64I-NEXT:    mul a0, a0, a1
519 ; RV64I-NEXT:    ret
521 ; RV64ZBA-LABEL: mul288:
522 ; RV64ZBA:       # %bb.0:
523 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
524 ; RV64ZBA-NEXT:    slli a0, a0, 5
525 ; RV64ZBA-NEXT:    ret
526   %c = mul i64 %a, 288
527   ret i64 %c
530 define i64 @zext_mul96(i32 signext %a) {
531 ; RV64I-LABEL: zext_mul96:
532 ; RV64I:       # %bb.0:
533 ; RV64I-NEXT:    li a1, 3
534 ; RV64I-NEXT:    slli a1, a1, 37
535 ; RV64I-NEXT:    slli a0, a0, 32
536 ; RV64I-NEXT:    mulhu a0, a0, a1
537 ; RV64I-NEXT:    ret
539 ; RV64ZBA-LABEL: zext_mul96:
540 ; RV64ZBA:       # %bb.0:
541 ; RV64ZBA-NEXT:    slli.uw a0, a0, 5
542 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
543 ; RV64ZBA-NEXT:    ret
544   %b = zext i32 %a to i64
545   %c = mul i64 %b, 96
546   ret i64 %c
549 define i64 @zext_mul160(i32 signext %a) {
550 ; RV64I-LABEL: zext_mul160:
551 ; RV64I:       # %bb.0:
552 ; RV64I-NEXT:    li a1, 5
553 ; RV64I-NEXT:    slli a1, a1, 37
554 ; RV64I-NEXT:    slli a0, a0, 32
555 ; RV64I-NEXT:    mulhu a0, a0, a1
556 ; RV64I-NEXT:    ret
558 ; RV64ZBA-LABEL: zext_mul160:
559 ; RV64ZBA:       # %bb.0:
560 ; RV64ZBA-NEXT:    slli.uw a0, a0, 5
561 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
562 ; RV64ZBA-NEXT:    ret
563   %b = zext i32 %a to i64
564   %c = mul i64 %b, 160
565   ret i64 %c
568 define i64 @zext_mul288(i32 signext %a) {
569 ; RV64I-LABEL: zext_mul288:
570 ; RV64I:       # %bb.0:
571 ; RV64I-NEXT:    li a1, 9
572 ; RV64I-NEXT:    slli a1, a1, 37
573 ; RV64I-NEXT:    slli a0, a0, 32
574 ; RV64I-NEXT:    mulhu a0, a0, a1
575 ; RV64I-NEXT:    ret
577 ; RV64ZBA-LABEL: zext_mul288:
578 ; RV64ZBA:       # %bb.0:
579 ; RV64ZBA-NEXT:    slli.uw a0, a0, 5
580 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
581 ; RV64ZBA-NEXT:    ret
582   %b = zext i32 %a to i64
583   %c = mul i64 %b, 288
584   ret i64 %c
587 ; We can't use slli.uw becaues the shift amount is more than 31.
588 ; FIXME: The zext.w is unneeded.
589 define i64 @zext_mul12884901888(i32 signext %a) {
590 ; RV64I-LABEL: zext_mul12884901888:
591 ; RV64I:       # %bb.0:
592 ; RV64I-NEXT:    slli a0, a0, 32
593 ; RV64I-NEXT:    srli a0, a0, 32
594 ; RV64I-NEXT:    li a1, 3
595 ; RV64I-NEXT:    slli a1, a1, 32
596 ; RV64I-NEXT:    mul a0, a0, a1
597 ; RV64I-NEXT:    ret
599 ; RV64ZBA-LABEL: zext_mul12884901888:
600 ; RV64ZBA:       # %bb.0:
601 ; RV64ZBA-NEXT:    andi a0, a0, -1
602 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
603 ; RV64ZBA-NEXT:    slli a0, a0, 32
604 ; RV64ZBA-NEXT:    ret
605   %b = zext i32 %a to i64
606   %c = mul i64 %b, 12884901888
607   ret i64 %c
610 ; We can't use slli.uw becaues the shift amount is more than 31.
611 ; FIXME: The zext.w is unneeded.
612 define i64 @zext_mul21474836480(i32 signext %a) {
613 ; RV64I-LABEL: zext_mul21474836480:
614 ; RV64I:       # %bb.0:
615 ; RV64I-NEXT:    slli a0, a0, 32
616 ; RV64I-NEXT:    srli a0, a0, 32
617 ; RV64I-NEXT:    li a1, 5
618 ; RV64I-NEXT:    slli a1, a1, 32
619 ; RV64I-NEXT:    mul a0, a0, a1
620 ; RV64I-NEXT:    ret
622 ; RV64ZBA-LABEL: zext_mul21474836480:
623 ; RV64ZBA:       # %bb.0:
624 ; RV64ZBA-NEXT:    andi a0, a0, -1
625 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
626 ; RV64ZBA-NEXT:    slli a0, a0, 32
627 ; RV64ZBA-NEXT:    ret
628   %b = zext i32 %a to i64
629   %c = mul i64 %b, 21474836480
630   ret i64 %c
633 ; We can't use slli.uw becaues the shift amount is more than 31.
634 ; FIXME: The zext.w is unneeded.
635 define i64 @zext_mul38654705664(i32 signext %a) {
636 ; RV64I-LABEL: zext_mul38654705664:
637 ; RV64I:       # %bb.0:
638 ; RV64I-NEXT:    slli a0, a0, 32
639 ; RV64I-NEXT:    srli a0, a0, 32
640 ; RV64I-NEXT:    li a1, 9
641 ; RV64I-NEXT:    slli a1, a1, 32
642 ; RV64I-NEXT:    mul a0, a0, a1
643 ; RV64I-NEXT:    ret
645 ; RV64ZBA-LABEL: zext_mul38654705664:
646 ; RV64ZBA:       # %bb.0:
647 ; RV64ZBA-NEXT:    andi a0, a0, -1
648 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
649 ; RV64ZBA-NEXT:    slli a0, a0, 32
650 ; RV64ZBA-NEXT:    ret
651   %b = zext i32 %a to i64
652   %c = mul i64 %b, 38654705664
653   ret i64 %c
656 define i64 @sh1add_imm(i64 %0) {
657 ; CHECK-LABEL: sh1add_imm:
658 ; CHECK:       # %bb.0:
659 ; CHECK-NEXT:    slli a0, a0, 1
660 ; CHECK-NEXT:    addi a0, a0, 5
661 ; CHECK-NEXT:    ret
662   %a = shl i64 %0, 1
663   %b = add i64 %a, 5
664   ret i64 %b
667 define i64 @sh2add_imm(i64 %0) {
668 ; CHECK-LABEL: sh2add_imm:
669 ; CHECK:       # %bb.0:
670 ; CHECK-NEXT:    slli a0, a0, 2
671 ; CHECK-NEXT:    addi a0, a0, -6
672 ; CHECK-NEXT:    ret
673   %a = shl i64 %0, 2
674   %b = add i64 %a, -6
675   ret i64 %b
678 define i64 @sh3add_imm(i64 %0) {
679 ; CHECK-LABEL: sh3add_imm:
680 ; CHECK:       # %bb.0:
681 ; CHECK-NEXT:    slli a0, a0, 3
682 ; CHECK-NEXT:    addi a0, a0, 7
683 ; CHECK-NEXT:    ret
684   %a = shl i64 %0, 3
685   %b = add i64 %a, 7
686   ret i64 %b
689 define i64 @sh1adduw_imm(i32 signext %0) {
690 ; RV64I-LABEL: sh1adduw_imm:
691 ; RV64I:       # %bb.0:
692 ; RV64I-NEXT:    slli a0, a0, 32
693 ; RV64I-NEXT:    srli a0, a0, 31
694 ; RV64I-NEXT:    addi a0, a0, 11
695 ; RV64I-NEXT:    ret
697 ; RV64ZBA-LABEL: sh1adduw_imm:
698 ; RV64ZBA:       # %bb.0:
699 ; RV64ZBA-NEXT:    slli.uw a0, a0, 1
700 ; RV64ZBA-NEXT:    addi a0, a0, 11
701 ; RV64ZBA-NEXT:    ret
702   %a = zext i32 %0 to i64
703   %b = shl i64 %a, 1
704   %c = add i64 %b, 11
705   ret i64 %c
708 define i64 @sh2adduw_imm(i32 signext %0) {
709 ; RV64I-LABEL: sh2adduw_imm:
710 ; RV64I:       # %bb.0:
711 ; RV64I-NEXT:    slli a0, a0, 32
712 ; RV64I-NEXT:    srli a0, a0, 30
713 ; RV64I-NEXT:    addi a0, a0, -12
714 ; RV64I-NEXT:    ret
716 ; RV64ZBA-LABEL: sh2adduw_imm:
717 ; RV64ZBA:       # %bb.0:
718 ; RV64ZBA-NEXT:    slli.uw a0, a0, 2
719 ; RV64ZBA-NEXT:    addi a0, a0, -12
720 ; RV64ZBA-NEXT:    ret
721   %a = zext i32 %0 to i64
722   %b = shl i64 %a, 2
723   %c = add i64 %b, -12
724   ret i64 %c
727 define i64 @sh3adduw_imm(i32 signext %0) {
728 ; RV64I-LABEL: sh3adduw_imm:
729 ; RV64I:       # %bb.0:
730 ; RV64I-NEXT:    slli a0, a0, 32
731 ; RV64I-NEXT:    srli a0, a0, 29
732 ; RV64I-NEXT:    addi a0, a0, 13
733 ; RV64I-NEXT:    ret
735 ; RV64ZBA-LABEL: sh3adduw_imm:
736 ; RV64ZBA:       # %bb.0:
737 ; RV64ZBA-NEXT:    slli.uw a0, a0, 3
738 ; RV64ZBA-NEXT:    addi a0, a0, 13
739 ; RV64ZBA-NEXT:    ret
740   %a = zext i32 %0 to i64
741   %b = shl i64 %a, 3
742   %c = add i64 %b, 13
743   ret i64 %c
746 define i64 @adduw_imm(i32 signext %0) nounwind {
747 ; RV64I-LABEL: adduw_imm:
748 ; RV64I:       # %bb.0:
749 ; RV64I-NEXT:    slli a0, a0, 32
750 ; RV64I-NEXT:    srli a0, a0, 32
751 ; RV64I-NEXT:    addi a0, a0, 5
752 ; RV64I-NEXT:    ret
754 ; RV64ZBA-LABEL: adduw_imm:
755 ; RV64ZBA:       # %bb.0:
756 ; RV64ZBA-NEXT:    zext.w a0, a0
757 ; RV64ZBA-NEXT:    addi a0, a0, 5
758 ; RV64ZBA-NEXT:    ret
759   %a = zext i32 %0 to i64
760   %b = add i64 %a, 5
761   ret i64 %b
764 define i64 @mul258(i64 %a) {
765 ; CHECK-LABEL: mul258:
766 ; CHECK:       # %bb.0:
767 ; CHECK-NEXT:    li a1, 258
768 ; CHECK-NEXT:    mul a0, a0, a1
769 ; CHECK-NEXT:    ret
770   %c = mul i64 %a, 258
771   ret i64 %c
774 define i64 @mul260(i64 %a) {
775 ; CHECK-LABEL: mul260:
776 ; CHECK:       # %bb.0:
777 ; CHECK-NEXT:    li a1, 260
778 ; CHECK-NEXT:    mul a0, a0, a1
779 ; CHECK-NEXT:    ret
780   %c = mul i64 %a, 260
781   ret i64 %c
784 define i64 @mul264(i64 %a) {
785 ; CHECK-LABEL: mul264:
786 ; CHECK:       # %bb.0:
787 ; CHECK-NEXT:    li a1, 264
788 ; CHECK-NEXT:    mul a0, a0, a1
789 ; CHECK-NEXT:    ret
790   %c = mul i64 %a, 264
791   ret i64 %c
794 define i64 @imm_zextw() nounwind {
795 ; RV64I-LABEL: imm_zextw:
796 ; RV64I:       # %bb.0:
797 ; RV64I-NEXT:    li a0, 1
798 ; RV64I-NEXT:    slli a0, a0, 32
799 ; RV64I-NEXT:    addi a0, a0, -2
800 ; RV64I-NEXT:    ret
802 ; RV64ZBA-LABEL: imm_zextw:
803 ; RV64ZBA:       # %bb.0:
804 ; RV64ZBA-NEXT:    li a0, -2
805 ; RV64ZBA-NEXT:    zext.w a0, a0
806 ; RV64ZBA-NEXT:    ret
807   ret i64 4294967294 ; -2 in 32 bits.
810 define i64 @mul11(i64 %a) {
811 ; RV64I-LABEL: mul11:
812 ; RV64I:       # %bb.0:
813 ; RV64I-NEXT:    li a1, 11
814 ; RV64I-NEXT:    mul a0, a0, a1
815 ; RV64I-NEXT:    ret
817 ; RV64ZBA-LABEL: mul11:
818 ; RV64ZBA:       # %bb.0:
819 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
820 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
821 ; RV64ZBA-NEXT:    ret
822   %c = mul i64 %a, 11
823   ret i64 %c
826 define i64 @mul19(i64 %a) {
827 ; RV64I-LABEL: mul19:
828 ; RV64I:       # %bb.0:
829 ; RV64I-NEXT:    li a1, 19
830 ; RV64I-NEXT:    mul a0, a0, a1
831 ; RV64I-NEXT:    ret
833 ; RV64ZBA-LABEL: mul19:
834 ; RV64ZBA:       # %bb.0:
835 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
836 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
837 ; RV64ZBA-NEXT:    ret
838   %c = mul i64 %a, 19
839   ret i64 %c
842 define i64 @mul13(i64 %a) {
843 ; RV64I-LABEL: mul13:
844 ; RV64I:       # %bb.0:
845 ; RV64I-NEXT:    li a1, 13
846 ; RV64I-NEXT:    mul a0, a0, a1
847 ; RV64I-NEXT:    ret
849 ; RV64ZBA-LABEL: mul13:
850 ; RV64ZBA:       # %bb.0:
851 ; RV64ZBA-NEXT:    sh1add a1, a0, a0
852 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
853 ; RV64ZBA-NEXT:    ret
854   %c = mul i64 %a, 13
855   ret i64 %c
858 define i64 @mul21(i64 %a) {
859 ; RV64I-LABEL: mul21:
860 ; RV64I:       # %bb.0:
861 ; RV64I-NEXT:    li a1, 21
862 ; RV64I-NEXT:    mul a0, a0, a1
863 ; RV64I-NEXT:    ret
865 ; RV64ZBA-LABEL: mul21:
866 ; RV64ZBA:       # %bb.0:
867 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
868 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
869 ; RV64ZBA-NEXT:    ret
870   %c = mul i64 %a, 21
871   ret i64 %c
874 define i64 @mul37(i64 %a) {
875 ; RV64I-LABEL: mul37:
876 ; RV64I:       # %bb.0:
877 ; RV64I-NEXT:    li a1, 37
878 ; RV64I-NEXT:    mul a0, a0, a1
879 ; RV64I-NEXT:    ret
881 ; RV64ZBA-LABEL: mul37:
882 ; RV64ZBA:       # %bb.0:
883 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
884 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
885 ; RV64ZBA-NEXT:    ret
886   %c = mul i64 %a, 37
887   ret i64 %c
890 define i64 @mul25(i64 %a) {
891 ; RV64I-LABEL: mul25:
892 ; RV64I:       # %bb.0:
893 ; RV64I-NEXT:    li a1, 25
894 ; RV64I-NEXT:    mul a0, a0, a1
895 ; RV64I-NEXT:    ret
897 ; RV64ZBA-LABEL: mul25:
898 ; RV64ZBA:       # %bb.0:
899 ; RV64ZBA-NEXT:    sh1add a1, a0, a0
900 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
901 ; RV64ZBA-NEXT:    ret
902   %c = mul i64 %a, 25
903   ret i64 %c
906 define i64 @mul41(i64 %a) {
907 ; RV64I-LABEL: mul41:
908 ; RV64I:       # %bb.0:
909 ; RV64I-NEXT:    li a1, 41
910 ; RV64I-NEXT:    mul a0, a0, a1
911 ; RV64I-NEXT:    ret
913 ; RV64ZBA-LABEL: mul41:
914 ; RV64ZBA:       # %bb.0:
915 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
916 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
917 ; RV64ZBA-NEXT:    ret
918   %c = mul i64 %a, 41
919   ret i64 %c
922 define i64 @mul73(i64 %a) {
923 ; RV64I-LABEL: mul73:
924 ; RV64I:       # %bb.0:
925 ; RV64I-NEXT:    li a1, 73
926 ; RV64I-NEXT:    mul a0, a0, a1
927 ; RV64I-NEXT:    ret
929 ; RV64ZBA-LABEL: mul73:
930 ; RV64ZBA:       # %bb.0:
931 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
932 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
933 ; RV64ZBA-NEXT:    ret
934   %c = mul i64 %a, 73
935   ret i64 %c
938 define i64 @mul27(i64 %a) {
939 ; RV64I-LABEL: mul27:
940 ; RV64I:       # %bb.0:
941 ; RV64I-NEXT:    li a1, 27
942 ; RV64I-NEXT:    mul a0, a0, a1
943 ; RV64I-NEXT:    ret
945 ; RV64ZBA-LABEL: mul27:
946 ; RV64ZBA:       # %bb.0:
947 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
948 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
949 ; RV64ZBA-NEXT:    ret
950   %c = mul i64 %a, 27
951   ret i64 %c
954 define i64 @mul45(i64 %a) {
955 ; RV64I-LABEL: mul45:
956 ; RV64I:       # %bb.0:
957 ; RV64I-NEXT:    li a1, 45
958 ; RV64I-NEXT:    mul a0, a0, a1
959 ; RV64I-NEXT:    ret
961 ; RV64ZBA-LABEL: mul45:
962 ; RV64ZBA:       # %bb.0:
963 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
964 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
965 ; RV64ZBA-NEXT:    ret
966   %c = mul i64 %a, 45
967   ret i64 %c
970 define i64 @mul81(i64 %a) {
971 ; RV64I-LABEL: mul81:
972 ; RV64I:       # %bb.0:
973 ; RV64I-NEXT:    li a1, 81
974 ; RV64I-NEXT:    mul a0, a0, a1
975 ; RV64I-NEXT:    ret
977 ; RV64ZBA-LABEL: mul81:
978 ; RV64ZBA:       # %bb.0:
979 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
980 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
981 ; RV64ZBA-NEXT:    ret
982   %c = mul i64 %a, 81
983   ret i64 %c
986 define i64 @mul4098(i64 %a) {
987 ; RV64I-LABEL: mul4098:
988 ; RV64I:       # %bb.0:
989 ; RV64I-NEXT:    slli a1, a0, 1
990 ; RV64I-NEXT:    slli a0, a0, 12
991 ; RV64I-NEXT:    add a0, a0, a1
992 ; RV64I-NEXT:    ret
994 ; RV64ZBA-LABEL: mul4098:
995 ; RV64ZBA:       # %bb.0:
996 ; RV64ZBA-NEXT:    slli a1, a0, 12
997 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
998 ; RV64ZBA-NEXT:    ret
999   %c = mul i64 %a, 4098
1000   ret i64 %c
1003 define i64 @mul4100(i64 %a) {
1004 ; RV64I-LABEL: mul4100:
1005 ; RV64I:       # %bb.0:
1006 ; RV64I-NEXT:    slli a1, a0, 2
1007 ; RV64I-NEXT:    slli a0, a0, 12
1008 ; RV64I-NEXT:    add a0, a0, a1
1009 ; RV64I-NEXT:    ret
1011 ; RV64ZBA-LABEL: mul4100:
1012 ; RV64ZBA:       # %bb.0:
1013 ; RV64ZBA-NEXT:    slli a1, a0, 12
1014 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
1015 ; RV64ZBA-NEXT:    ret
1016   %c = mul i64 %a, 4100
1017   ret i64 %c
1020 define i64 @mul4104(i64 %a) {
1021 ; RV64I-LABEL: mul4104:
1022 ; RV64I:       # %bb.0:
1023 ; RV64I-NEXT:    slli a1, a0, 3
1024 ; RV64I-NEXT:    slli a0, a0, 12
1025 ; RV64I-NEXT:    add a0, a0, a1
1026 ; RV64I-NEXT:    ret
1028 ; RV64ZBA-LABEL: mul4104:
1029 ; RV64ZBA:       # %bb.0:
1030 ; RV64ZBA-NEXT:    slli a1, a0, 12
1031 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
1032 ; RV64ZBA-NEXT:    ret
1033   %c = mul i64 %a, 4104
1034   ret i64 %c
1037 define signext i32 @mulw192(i32 signext %a) {
1038 ; RV64I-LABEL: mulw192:
1039 ; RV64I:       # %bb.0:
1040 ; RV64I-NEXT:    li a1, 192
1041 ; RV64I-NEXT:    mulw a0, a0, a1
1042 ; RV64I-NEXT:    ret
1044 ; RV64ZBA-LABEL: mulw192:
1045 ; RV64ZBA:       # %bb.0:
1046 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
1047 ; RV64ZBA-NEXT:    slliw a0, a0, 6
1048 ; RV64ZBA-NEXT:    ret
1049   %c = mul i32 %a, 192
1050   ret i32 %c
1053 define signext i32 @mulw320(i32 signext %a) {
1054 ; RV64I-LABEL: mulw320:
1055 ; RV64I:       # %bb.0:
1056 ; RV64I-NEXT:    li a1, 320
1057 ; RV64I-NEXT:    mulw a0, a0, a1
1058 ; RV64I-NEXT:    ret
1060 ; RV64ZBA-LABEL: mulw320:
1061 ; RV64ZBA:       # %bb.0:
1062 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
1063 ; RV64ZBA-NEXT:    slliw a0, a0, 6
1064 ; RV64ZBA-NEXT:    ret
1065   %c = mul i32 %a, 320
1066   ret i32 %c
1069 define signext i32 @mulw576(i32 signext %a) {
1070 ; RV64I-LABEL: mulw576:
1071 ; RV64I:       # %bb.0:
1072 ; RV64I-NEXT:    li a1, 576
1073 ; RV64I-NEXT:    mulw a0, a0, a1
1074 ; RV64I-NEXT:    ret
1076 ; RV64ZBA-LABEL: mulw576:
1077 ; RV64ZBA:       # %bb.0:
1078 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
1079 ; RV64ZBA-NEXT:    slliw a0, a0, 6
1080 ; RV64ZBA-NEXT:    ret
1081   %c = mul i32 %a, 576
1082   ret i32 %c
1085 define i64 @add4104(i64 %a) {
1086 ; RV64I-LABEL: add4104:
1087 ; RV64I:       # %bb.0:
1088 ; RV64I-NEXT:    lui a1, 1
1089 ; RV64I-NEXT:    addiw a1, a1, 8
1090 ; RV64I-NEXT:    add a0, a0, a1
1091 ; RV64I-NEXT:    ret
1093 ; RV64ZBA-LABEL: add4104:
1094 ; RV64ZBA:       # %bb.0:
1095 ; RV64ZBA-NEXT:    li a1, 1026
1096 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1097 ; RV64ZBA-NEXT:    ret
1098   %c = add i64 %a, 4104
1099   ret i64 %c
1102 define i64 @add8208(i64 %a) {
1103 ; RV64I-LABEL: add8208:
1104 ; RV64I:       # %bb.0:
1105 ; RV64I-NEXT:    lui a1, 2
1106 ; RV64I-NEXT:    addiw a1, a1, 16
1107 ; RV64I-NEXT:    add a0, a0, a1
1108 ; RV64I-NEXT:    ret
1110 ; RV64ZBA-LABEL: add8208:
1111 ; RV64ZBA:       # %bb.0:
1112 ; RV64ZBA-NEXT:    li a1, 1026
1113 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1114 ; RV64ZBA-NEXT:    ret
1115   %c = add i64 %a, 8208
1116   ret i64 %c
1119 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1120 define signext i32 @add8192_i32(i32 signext %a) {
1121 ; CHECK-LABEL: add8192_i32:
1122 ; CHECK:       # %bb.0:
1123 ; CHECK-NEXT:    lui a1, 2
1124 ; CHECK-NEXT:    addw a0, a0, a1
1125 ; CHECK-NEXT:    ret
1126   %c = add i32 %a, 8192
1127   ret i32 %c
1130 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1131 define i64 @add8192(i64 %a) {
1132 ; CHECK-LABEL: add8192:
1133 ; CHECK:       # %bb.0:
1134 ; CHECK-NEXT:    lui a1, 2
1135 ; CHECK-NEXT:    add a0, a0, a1
1136 ; CHECK-NEXT:    ret
1137   %c = add i64 %a, 8192
1138   ret i64 %c
1141 define signext i32 @addshl32_5_6(i32 signext %a, i32 signext %b) {
1142 ; RV64I-LABEL: addshl32_5_6:
1143 ; RV64I:       # %bb.0:
1144 ; RV64I-NEXT:    slli a0, a0, 5
1145 ; RV64I-NEXT:    slli a1, a1, 6
1146 ; RV64I-NEXT:    addw a0, a0, a1
1147 ; RV64I-NEXT:    ret
1149 ; RV64ZBA-LABEL: addshl32_5_6:
1150 ; RV64ZBA:       # %bb.0:
1151 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1152 ; RV64ZBA-NEXT:    slliw a0, a0, 5
1153 ; RV64ZBA-NEXT:    ret
1154   %c = shl i32 %a, 5
1155   %d = shl i32 %b, 6
1156   %e = add i32 %c, %d
1157   ret i32 %e
1160 define i64 @addshl64_5_6(i64 %a, i64 %b) {
1161 ; RV64I-LABEL: addshl64_5_6:
1162 ; RV64I:       # %bb.0:
1163 ; RV64I-NEXT:    slli a0, a0, 5
1164 ; RV64I-NEXT:    slli a1, a1, 6
1165 ; RV64I-NEXT:    add a0, a0, a1
1166 ; RV64I-NEXT:    ret
1168 ; RV64ZBA-LABEL: addshl64_5_6:
1169 ; RV64ZBA:       # %bb.0:
1170 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1171 ; RV64ZBA-NEXT:    slli a0, a0, 5
1172 ; RV64ZBA-NEXT:    ret
1173   %c = shl i64 %a, 5
1174   %d = shl i64 %b, 6
1175   %e = add i64 %c, %d
1176   ret i64 %e
1179 define signext i32 @addshl32_5_7(i32 signext %a, i32 signext %b) {
1180 ; RV64I-LABEL: addshl32_5_7:
1181 ; RV64I:       # %bb.0:
1182 ; RV64I-NEXT:    slli a0, a0, 5
1183 ; RV64I-NEXT:    slli a1, a1, 7
1184 ; RV64I-NEXT:    addw a0, a0, a1
1185 ; RV64I-NEXT:    ret
1187 ; RV64ZBA-LABEL: addshl32_5_7:
1188 ; RV64ZBA:       # %bb.0:
1189 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1190 ; RV64ZBA-NEXT:    slliw a0, a0, 5
1191 ; RV64ZBA-NEXT:    ret
1192   %c = shl i32 %a, 5
1193   %d = shl i32 %b, 7
1194   %e = add i32 %c, %d
1195   ret i32 %e
1198 define i64 @addshl64_5_7(i64 %a, i64 %b) {
1199 ; RV64I-LABEL: addshl64_5_7:
1200 ; RV64I:       # %bb.0:
1201 ; RV64I-NEXT:    slli a0, a0, 5
1202 ; RV64I-NEXT:    slli a1, a1, 7
1203 ; RV64I-NEXT:    add a0, a0, a1
1204 ; RV64I-NEXT:    ret
1206 ; RV64ZBA-LABEL: addshl64_5_7:
1207 ; RV64ZBA:       # %bb.0:
1208 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1209 ; RV64ZBA-NEXT:    slli a0, a0, 5
1210 ; RV64ZBA-NEXT:    ret
1211   %c = shl i64 %a, 5
1212   %d = shl i64 %b, 7
1213   %e = add i64 %c, %d
1214   ret i64 %e
1217 define signext i32 @addshl32_5_8(i32 signext %a, i32 signext %b) {
1218 ; RV64I-LABEL: addshl32_5_8:
1219 ; RV64I:       # %bb.0:
1220 ; RV64I-NEXT:    slli a0, a0, 5
1221 ; RV64I-NEXT:    slli a1, a1, 8
1222 ; RV64I-NEXT:    addw a0, a0, a1
1223 ; RV64I-NEXT:    ret
1225 ; RV64ZBA-LABEL: addshl32_5_8:
1226 ; RV64ZBA:       # %bb.0:
1227 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1228 ; RV64ZBA-NEXT:    slliw a0, a0, 5
1229 ; RV64ZBA-NEXT:    ret
1230   %c = shl i32 %a, 5
1231   %d = shl i32 %b, 8
1232   %e = add i32 %c, %d
1233   ret i32 %e
1236 define i64 @addshl64_5_8(i64 %a, i64 %b) {
1237 ; RV64I-LABEL: addshl64_5_8:
1238 ; RV64I:       # %bb.0:
1239 ; RV64I-NEXT:    slli a0, a0, 5
1240 ; RV64I-NEXT:    slli a1, a1, 8
1241 ; RV64I-NEXT:    add a0, a0, a1
1242 ; RV64I-NEXT:    ret
1244 ; RV64ZBA-LABEL: addshl64_5_8:
1245 ; RV64ZBA:       # %bb.0:
1246 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1247 ; RV64ZBA-NEXT:    slli a0, a0, 5
1248 ; RV64ZBA-NEXT:    ret
1249   %c = shl i64 %a, 5
1250   %d = shl i64 %b, 8
1251   %e = add i64 %c, %d
1252   ret i64 %e
1255 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1256 ; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
1257 define zeroext i32 @sext_ashr_zext_i8(i8 %a) nounwind {
1258 ; RV64I-LABEL: sext_ashr_zext_i8:
1259 ; RV64I:       # %bb.0:
1260 ; RV64I-NEXT:    slli a0, a0, 56
1261 ; RV64I-NEXT:    srai a0, a0, 56
1262 ; RV64I-NEXT:    slli a0, a0, 23
1263 ; RV64I-NEXT:    srli a0, a0, 32
1264 ; RV64I-NEXT:    ret
1266 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i8:
1267 ; RV64ZBANOZBB:       # %bb.0:
1268 ; RV64ZBANOZBB-NEXT:    slli a0, a0, 56
1269 ; RV64ZBANOZBB-NEXT:    srai a0, a0, 56
1270 ; RV64ZBANOZBB-NEXT:    slli a0, a0, 23
1271 ; RV64ZBANOZBB-NEXT:    srli a0, a0, 32
1272 ; RV64ZBANOZBB-NEXT:    ret
1274 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i8:
1275 ; RV64ZBAZBB:       # %bb.0:
1276 ; RV64ZBAZBB-NEXT:    sext.b a0, a0
1277 ; RV64ZBAZBB-NEXT:    slli a0, a0, 23
1278 ; RV64ZBAZBB-NEXT:    srli a0, a0, 32
1279 ; RV64ZBAZBB-NEXT:    ret
1280   %ext = sext i8 %a to i32
1281   %1 = ashr i32 %ext, 9
1282   ret i32 %1
1285 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1286 ; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
1287 define zeroext i32 @sext_ashr_zext_i16(i16 %a) nounwind {
1288 ; RV64I-LABEL: sext_ashr_zext_i16:
1289 ; RV64I:       # %bb.0:
1290 ; RV64I-NEXT:    slli a0, a0, 48
1291 ; RV64I-NEXT:    srai a0, a0, 48
1292 ; RV64I-NEXT:    slli a0, a0, 23
1293 ; RV64I-NEXT:    srli a0, a0, 32
1294 ; RV64I-NEXT:    ret
1296 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i16:
1297 ; RV64ZBANOZBB:       # %bb.0:
1298 ; RV64ZBANOZBB-NEXT:    slli a0, a0, 48
1299 ; RV64ZBANOZBB-NEXT:    srai a0, a0, 48
1300 ; RV64ZBANOZBB-NEXT:    slli a0, a0, 23
1301 ; RV64ZBANOZBB-NEXT:    srli a0, a0, 32
1302 ; RV64ZBANOZBB-NEXT:    ret
1304 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i16:
1305 ; RV64ZBAZBB:       # %bb.0:
1306 ; RV64ZBAZBB-NEXT:    sext.h a0, a0
1307 ; RV64ZBAZBB-NEXT:    slli a0, a0, 23
1308 ; RV64ZBAZBB-NEXT:    srli a0, a0, 32
1309 ; RV64ZBAZBB-NEXT:    ret
1310   %ext = sext i16 %a to i32
1311   %1 = ashr i32 %ext, 9
1312   ret i32 %1
1315 ; This the IR you get from InstCombine if take the difference of 2 pointers and
1316 ; cast is to unsigned before using as an index.
1317 define signext i16 @sh1adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1318 ; RV64I-LABEL: sh1adduw_ptrdiff:
1319 ; RV64I:       # %bb.0:
1320 ; RV64I-NEXT:    li a2, 1
1321 ; RV64I-NEXT:    slli a2, a2, 33
1322 ; RV64I-NEXT:    addi a2, a2, -2
1323 ; RV64I-NEXT:    and a0, a0, a2
1324 ; RV64I-NEXT:    add a0, a1, a0
1325 ; RV64I-NEXT:    lh a0, 0(a0)
1326 ; RV64I-NEXT:    ret
1328 ; RV64ZBA-LABEL: sh1adduw_ptrdiff:
1329 ; RV64ZBA:       # %bb.0:
1330 ; RV64ZBA-NEXT:    srli a0, a0, 1
1331 ; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
1332 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1333 ; RV64ZBA-NEXT:    ret
1334   %ptrdiff = lshr exact i64 %diff, 1
1335   %cast = and i64 %ptrdiff, 4294967295
1336   %ptr = getelementptr inbounds i16, ptr %baseptr, i64 %cast
1337   %res = load i16, ptr %ptr
1338   ret i16 %res
1341 define signext i32 @sh2adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1342 ; RV64I-LABEL: sh2adduw_ptrdiff:
1343 ; RV64I:       # %bb.0:
1344 ; RV64I-NEXT:    li a2, 1
1345 ; RV64I-NEXT:    slli a2, a2, 34
1346 ; RV64I-NEXT:    addi a2, a2, -4
1347 ; RV64I-NEXT:    and a0, a0, a2
1348 ; RV64I-NEXT:    add a0, a1, a0
1349 ; RV64I-NEXT:    lw a0, 0(a0)
1350 ; RV64I-NEXT:    ret
1352 ; RV64ZBA-LABEL: sh2adduw_ptrdiff:
1353 ; RV64ZBA:       # %bb.0:
1354 ; RV64ZBA-NEXT:    srli a0, a0, 2
1355 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
1356 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1357 ; RV64ZBA-NEXT:    ret
1358   %ptrdiff = lshr exact i64 %diff, 2
1359   %cast = and i64 %ptrdiff, 4294967295
1360   %ptr = getelementptr inbounds i32, ptr %baseptr, i64 %cast
1361   %res = load i32, ptr %ptr
1362   ret i32 %res
1365 define i64 @sh3adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1366 ; RV64I-LABEL: sh3adduw_ptrdiff:
1367 ; RV64I:       # %bb.0:
1368 ; RV64I-NEXT:    li a2, 1
1369 ; RV64I-NEXT:    slli a2, a2, 35
1370 ; RV64I-NEXT:    addi a2, a2, -8
1371 ; RV64I-NEXT:    and a0, a0, a2
1372 ; RV64I-NEXT:    add a0, a1, a0
1373 ; RV64I-NEXT:    ld a0, 0(a0)
1374 ; RV64I-NEXT:    ret
1376 ; RV64ZBA-LABEL: sh3adduw_ptrdiff:
1377 ; RV64ZBA:       # %bb.0:
1378 ; RV64ZBA-NEXT:    srli a0, a0, 3
1379 ; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
1380 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1381 ; RV64ZBA-NEXT:    ret
1382   %ptrdiff = lshr exact i64 %diff, 3
1383   %cast = and i64 %ptrdiff, 4294967295
1384   %ptr = getelementptr inbounds i64, ptr %baseptr, i64 %cast
1385   %res = load i64, ptr %ptr
1386   ret i64 %res
1389 define signext i16 @srliw_1_sh1add(ptr %0, i32 signext %1) {
1390 ; RV64I-LABEL: srliw_1_sh1add:
1391 ; RV64I:       # %bb.0:
1392 ; RV64I-NEXT:    srliw a1, a1, 1
1393 ; RV64I-NEXT:    slli a1, a1, 1
1394 ; RV64I-NEXT:    add a0, a0, a1
1395 ; RV64I-NEXT:    lh a0, 0(a0)
1396 ; RV64I-NEXT:    ret
1398 ; RV64ZBA-LABEL: srliw_1_sh1add:
1399 ; RV64ZBA:       # %bb.0:
1400 ; RV64ZBA-NEXT:    srliw a1, a1, 1
1401 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1402 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1403 ; RV64ZBA-NEXT:    ret
1404   %3 = lshr i32 %1, 1
1405   %4 = zext i32 %3 to i64
1406   %5 = getelementptr inbounds i16, ptr %0, i64 %4
1407   %6 = load i16, ptr %5, align 2
1408   ret i16 %6
1411 define i128 @slliuw_ptrdiff(i64 %diff, ptr %baseptr) {
1412 ; RV64I-LABEL: slliuw_ptrdiff:
1413 ; RV64I:       # %bb.0:
1414 ; RV64I-NEXT:    li a2, 1
1415 ; RV64I-NEXT:    slli a2, a2, 36
1416 ; RV64I-NEXT:    addi a2, a2, -16
1417 ; RV64I-NEXT:    and a0, a0, a2
1418 ; RV64I-NEXT:    add a1, a1, a0
1419 ; RV64I-NEXT:    ld a0, 0(a1)
1420 ; RV64I-NEXT:    ld a1, 8(a1)
1421 ; RV64I-NEXT:    ret
1423 ; RV64ZBA-LABEL: slliuw_ptrdiff:
1424 ; RV64ZBA:       # %bb.0:
1425 ; RV64ZBA-NEXT:    srli a0, a0, 4
1426 ; RV64ZBA-NEXT:    slli.uw a0, a0, 4
1427 ; RV64ZBA-NEXT:    add a1, a1, a0
1428 ; RV64ZBA-NEXT:    ld a0, 0(a1)
1429 ; RV64ZBA-NEXT:    ld a1, 8(a1)
1430 ; RV64ZBA-NEXT:    ret
1431   %ptrdiff = lshr exact i64 %diff, 4
1432   %cast = and i64 %ptrdiff, 4294967295
1433   %ptr = getelementptr inbounds i128, ptr %baseptr, i64 %cast
1434   %res = load i128, ptr %ptr
1435   ret i128 %res
1438 define signext i32 @srliw_2_sh2add(ptr %0, i32 signext %1) {
1439 ; RV64I-LABEL: srliw_2_sh2add:
1440 ; RV64I:       # %bb.0:
1441 ; RV64I-NEXT:    srliw a1, a1, 2
1442 ; RV64I-NEXT:    slli a1, a1, 2
1443 ; RV64I-NEXT:    add a0, a0, a1
1444 ; RV64I-NEXT:    lw a0, 0(a0)
1445 ; RV64I-NEXT:    ret
1447 ; RV64ZBA-LABEL: srliw_2_sh2add:
1448 ; RV64ZBA:       # %bb.0:
1449 ; RV64ZBA-NEXT:    srliw a1, a1, 2
1450 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1451 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1452 ; RV64ZBA-NEXT:    ret
1453   %3 = lshr i32 %1, 2
1454   %4 = zext i32 %3 to i64
1455   %5 = getelementptr inbounds i32, ptr %0, i64 %4
1456   %6 = load i32, ptr %5, align 4
1457   ret i32 %6
1460 define i64 @srliw_3_sh3add(ptr %0, i32 signext %1) {
1461 ; RV64I-LABEL: srliw_3_sh3add:
1462 ; RV64I:       # %bb.0:
1463 ; RV64I-NEXT:    srliw a1, a1, 3
1464 ; RV64I-NEXT:    slli a1, a1, 3
1465 ; RV64I-NEXT:    add a0, a0, a1
1466 ; RV64I-NEXT:    ld a0, 0(a0)
1467 ; RV64I-NEXT:    ret
1469 ; RV64ZBA-LABEL: srliw_3_sh3add:
1470 ; RV64ZBA:       # %bb.0:
1471 ; RV64ZBA-NEXT:    srliw a1, a1, 3
1472 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1473 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1474 ; RV64ZBA-NEXT:    ret
1475   %3 = lshr i32 %1, 3
1476   %4 = zext i32 %3 to i64
1477   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1478   %6 = load i64, ptr %5, align 8
1479   ret i64 %6
1482 define signext i32 @srliw_1_sh2add(ptr %0, i32 signext %1) {
1483 ; RV64I-LABEL: srliw_1_sh2add:
1484 ; RV64I:       # %bb.0:
1485 ; RV64I-NEXT:    srliw a1, a1, 1
1486 ; RV64I-NEXT:    slli a1, a1, 2
1487 ; RV64I-NEXT:    add a0, a0, a1
1488 ; RV64I-NEXT:    lw a0, 0(a0)
1489 ; RV64I-NEXT:    ret
1491 ; RV64ZBA-LABEL: srliw_1_sh2add:
1492 ; RV64ZBA:       # %bb.0:
1493 ; RV64ZBA-NEXT:    srliw a1, a1, 1
1494 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1495 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1496 ; RV64ZBA-NEXT:    ret
1497   %3 = lshr i32 %1, 1
1498   %4 = zext i32 %3 to i64
1499   %5 = getelementptr inbounds i32, ptr %0, i64 %4
1500   %6 = load i32, ptr %5, align 4
1501   ret i32 %6
1504 define i64 @srliw_1_sh3add(ptr %0, i32 signext %1) {
1505 ; RV64I-LABEL: srliw_1_sh3add:
1506 ; RV64I:       # %bb.0:
1507 ; RV64I-NEXT:    srliw a1, a1, 1
1508 ; RV64I-NEXT:    slli a1, a1, 3
1509 ; RV64I-NEXT:    add a0, a0, a1
1510 ; RV64I-NEXT:    ld a0, 0(a0)
1511 ; RV64I-NEXT:    ret
1513 ; RV64ZBA-LABEL: srliw_1_sh3add:
1514 ; RV64ZBA:       # %bb.0:
1515 ; RV64ZBA-NEXT:    srliw a1, a1, 1
1516 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1517 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1518 ; RV64ZBA-NEXT:    ret
1519   %3 = lshr i32 %1, 1
1520   %4 = zext i32 %3 to i64
1521   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1522   %6 = load i64, ptr %5, align 8
1523   ret i64 %6
1526 define i64 @srliw_2_sh3add(ptr %0, i32 signext %1) {
1527 ; RV64I-LABEL: srliw_2_sh3add:
1528 ; RV64I:       # %bb.0:
1529 ; RV64I-NEXT:    srliw a1, a1, 2
1530 ; RV64I-NEXT:    slli a1, a1, 3
1531 ; RV64I-NEXT:    add a0, a0, a1
1532 ; RV64I-NEXT:    ld a0, 0(a0)
1533 ; RV64I-NEXT:    ret
1535 ; RV64ZBA-LABEL: srliw_2_sh3add:
1536 ; RV64ZBA:       # %bb.0:
1537 ; RV64ZBA-NEXT:    srliw a1, a1, 2
1538 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1539 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1540 ; RV64ZBA-NEXT:    ret
1541   %3 = lshr i32 %1, 2
1542   %4 = zext i32 %3 to i64
1543   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1544   %6 = load i64, ptr %5, align 8
1545   ret i64 %6
1548 define signext i16 @srliw_2_sh1add(ptr %0, i32 signext %1) {
1549 ; RV64I-LABEL: srliw_2_sh1add:
1550 ; RV64I:       # %bb.0:
1551 ; RV64I-NEXT:    srliw a1, a1, 2
1552 ; RV64I-NEXT:    slli a1, a1, 1
1553 ; RV64I-NEXT:    add a0, a0, a1
1554 ; RV64I-NEXT:    lh a0, 0(a0)
1555 ; RV64I-NEXT:    ret
1557 ; RV64ZBA-LABEL: srliw_2_sh1add:
1558 ; RV64ZBA:       # %bb.0:
1559 ; RV64ZBA-NEXT:    srliw a1, a1, 2
1560 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1561 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1562 ; RV64ZBA-NEXT:    ret
1563   %3 = lshr i32 %1, 2
1564   %4 = zext i32 %3 to i64
1565   %5 = getelementptr inbounds i16, ptr %0, i64 %4
1566   %6 = load i16, ptr %5, align 2
1567   ret i16 %6
1571 define signext i32 @srliw_3_sh2add(ptr %0, i32 signext %1) {
1572 ; RV64I-LABEL: srliw_3_sh2add:
1573 ; RV64I:       # %bb.0:
1574 ; RV64I-NEXT:    srliw a1, a1, 3
1575 ; RV64I-NEXT:    slli a1, a1, 2
1576 ; RV64I-NEXT:    add a0, a0, a1
1577 ; RV64I-NEXT:    lw a0, 0(a0)
1578 ; RV64I-NEXT:    ret
1580 ; RV64ZBA-LABEL: srliw_3_sh2add:
1581 ; RV64ZBA:       # %bb.0:
1582 ; RV64ZBA-NEXT:    srliw a1, a1, 3
1583 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1584 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1585 ; RV64ZBA-NEXT:    ret
1586   %3 = lshr i32 %1, 3
1587   %4 = zext i32 %3 to i64
1588   %5 = getelementptr inbounds i32, ptr %0, i64 %4
1589   %6 = load i32, ptr %5, align 4
1590   ret i32 %6
1593 define i64 @srliw_4_sh3add(ptr %0, i32 signext %1) {
1594 ; RV64I-LABEL: srliw_4_sh3add:
1595 ; RV64I:       # %bb.0:
1596 ; RV64I-NEXT:    srliw a1, a1, 4
1597 ; RV64I-NEXT:    slli a1, a1, 3
1598 ; RV64I-NEXT:    add a0, a0, a1
1599 ; RV64I-NEXT:    ld a0, 0(a0)
1600 ; RV64I-NEXT:    ret
1602 ; RV64ZBA-LABEL: srliw_4_sh3add:
1603 ; RV64ZBA:       # %bb.0:
1604 ; RV64ZBA-NEXT:    srliw a1, a1, 4
1605 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1606 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1607 ; RV64ZBA-NEXT:    ret
1608   %3 = lshr i32 %1, 4
1609   %4 = zext i32 %3 to i64
1610   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1611   %6 = load i64, ptr %5, align 8
1612   ret i64 %6
1615 define signext i32 @srli_1_sh2add(ptr %0, i64 %1) {
1616 ; RV64I-LABEL: srli_1_sh2add:
1617 ; RV64I:       # %bb.0:
1618 ; RV64I-NEXT:    slli a1, a1, 1
1619 ; RV64I-NEXT:    andi a1, a1, -4
1620 ; RV64I-NEXT:    add a0, a0, a1
1621 ; RV64I-NEXT:    lw a0, 0(a0)
1622 ; RV64I-NEXT:    ret
1624 ; RV64ZBA-LABEL: srli_1_sh2add:
1625 ; RV64ZBA:       # %bb.0:
1626 ; RV64ZBA-NEXT:    srli a1, a1, 1
1627 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1628 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1629 ; RV64ZBA-NEXT:    ret
1630   %3 = lshr i64 %1, 1
1631   %4 = getelementptr inbounds i32, ptr %0, i64 %3
1632   %5 = load i32, ptr %4, align 4
1633   ret i32 %5
1636 define i64 @srli_2_sh3add(ptr %0, i64 %1) {
1637 ; RV64I-LABEL: srli_2_sh3add:
1638 ; RV64I:       # %bb.0:
1639 ; RV64I-NEXT:    slli a1, a1, 1
1640 ; RV64I-NEXT:    andi a1, a1, -8
1641 ; RV64I-NEXT:    add a0, a0, a1
1642 ; RV64I-NEXT:    ld a0, 0(a0)
1643 ; RV64I-NEXT:    ret
1645 ; RV64ZBA-LABEL: srli_2_sh3add:
1646 ; RV64ZBA:       # %bb.0:
1647 ; RV64ZBA-NEXT:    srli a1, a1, 2
1648 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1649 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1650 ; RV64ZBA-NEXT:    ret
1651   %3 = lshr i64 %1, 2
1652   %4 = getelementptr inbounds i64, ptr %0, i64 %3
1653   %5 = load i64, ptr %4, align 8
1654   ret i64 %5
1657 define signext i16 @srli_2_sh1add(ptr %0, i64 %1) {
1658 ; RV64I-LABEL: srli_2_sh1add:
1659 ; RV64I:       # %bb.0:
1660 ; RV64I-NEXT:    srli a1, a1, 1
1661 ; RV64I-NEXT:    andi a1, a1, -2
1662 ; RV64I-NEXT:    add a0, a0, a1
1663 ; RV64I-NEXT:    lh a0, 0(a0)
1664 ; RV64I-NEXT:    ret
1666 ; RV64ZBA-LABEL: srli_2_sh1add:
1667 ; RV64ZBA:       # %bb.0:
1668 ; RV64ZBA-NEXT:    srli a1, a1, 2
1669 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1670 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1671 ; RV64ZBA-NEXT:    ret
1672   %3 = lshr i64 %1, 2
1673   %4 = getelementptr inbounds i16, ptr %0, i64 %3
1674   %5 = load i16, ptr %4, align 2
1675   ret i16 %5
1678 define signext i32 @srli_3_sh2add(ptr %0, i64 %1) {
1679 ; RV64I-LABEL: srli_3_sh2add:
1680 ; RV64I:       # %bb.0:
1681 ; RV64I-NEXT:    srli a1, a1, 1
1682 ; RV64I-NEXT:    andi a1, a1, -4
1683 ; RV64I-NEXT:    add a0, a0, a1
1684 ; RV64I-NEXT:    lw a0, 0(a0)
1685 ; RV64I-NEXT:    ret
1687 ; RV64ZBA-LABEL: srli_3_sh2add:
1688 ; RV64ZBA:       # %bb.0:
1689 ; RV64ZBA-NEXT:    srli a1, a1, 3
1690 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1691 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1692 ; RV64ZBA-NEXT:    ret
1693   %3 = lshr i64 %1, 3
1694   %4 = getelementptr inbounds i32, ptr %0, i64 %3
1695   %5 = load i32, ptr %4, align 4
1696   ret i32 %5
1699 define i64 @srli_4_sh3add(ptr %0, i64 %1) {
1700 ; RV64I-LABEL: srli_4_sh3add:
1701 ; RV64I:       # %bb.0:
1702 ; RV64I-NEXT:    srli a1, a1, 1
1703 ; RV64I-NEXT:    andi a1, a1, -8
1704 ; RV64I-NEXT:    add a0, a0, a1
1705 ; RV64I-NEXT:    ld a0, 0(a0)
1706 ; RV64I-NEXT:    ret
1708 ; RV64ZBA-LABEL: srli_4_sh3add:
1709 ; RV64ZBA:       # %bb.0:
1710 ; RV64ZBA-NEXT:    srli a1, a1, 4
1711 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1712 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1713 ; RV64ZBA-NEXT:    ret
1714   %3 = lshr i64 %1, 4
1715   %4 = getelementptr inbounds i64, ptr %0, i64 %3
1716   %5 = load i64, ptr %4, align 8
1717   ret i64 %5
1720 define signext i16 @shl_2_sh1add(ptr %0, i32 signext %1) {
1721 ; RV64I-LABEL: shl_2_sh1add:
1722 ; RV64I:       # %bb.0:
1723 ; RV64I-NEXT:    slli a1, a1, 34
1724 ; RV64I-NEXT:    srli a1, a1, 31
1725 ; RV64I-NEXT:    add a0, a0, a1
1726 ; RV64I-NEXT:    lh a0, 0(a0)
1727 ; RV64I-NEXT:    ret
1729 ; RV64ZBA-LABEL: shl_2_sh1add:
1730 ; RV64ZBA:       # %bb.0:
1731 ; RV64ZBA-NEXT:    slli a1, a1, 2
1732 ; RV64ZBA-NEXT:    sh1add.uw a0, a1, a0
1733 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1734 ; RV64ZBA-NEXT:    ret
1735   %3 = shl i32 %1, 2
1736   %4 = zext i32 %3 to i64
1737   %5 = getelementptr inbounds i16, ptr %0, i64 %4
1738   %6 = load i16, ptr %5, align 2
1739   ret i16 %6
1742 define signext i32 @shl_16_sh2add(ptr %0, i32 signext %1) {
1743 ; RV64I-LABEL: shl_16_sh2add:
1744 ; RV64I:       # %bb.0:
1745 ; RV64I-NEXT:    slli a1, a1, 48
1746 ; RV64I-NEXT:    srli a1, a1, 30
1747 ; RV64I-NEXT:    add a0, a0, a1
1748 ; RV64I-NEXT:    lw a0, 0(a0)
1749 ; RV64I-NEXT:    ret
1751 ; RV64ZBA-LABEL: shl_16_sh2add:
1752 ; RV64ZBA:       # %bb.0:
1753 ; RV64ZBA-NEXT:    slli a1, a1, 16
1754 ; RV64ZBA-NEXT:    sh2add.uw a0, a1, a0
1755 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1756 ; RV64ZBA-NEXT:    ret
1757   %3 = shl i32 %1, 16
1758   %4 = zext i32 %3 to i64
1759   %5 = getelementptr inbounds i32, ptr %0, i64 %4
1760   %6 = load i32, ptr %5, align 4
1761   ret i32 %6
1764 define i64 @shl_31_sh3add(ptr %0, i32 signext %1) {
1765 ; RV64I-LABEL: shl_31_sh3add:
1766 ; RV64I:       # %bb.0:
1767 ; RV64I-NEXT:    slli a1, a1, 63
1768 ; RV64I-NEXT:    srli a1, a1, 29
1769 ; RV64I-NEXT:    add a0, a0, a1
1770 ; RV64I-NEXT:    ld a0, 0(a0)
1771 ; RV64I-NEXT:    ret
1773 ; RV64ZBA-LABEL: shl_31_sh3add:
1774 ; RV64ZBA:       # %bb.0:
1775 ; RV64ZBA-NEXT:    slli a1, a1, 31
1776 ; RV64ZBA-NEXT:    sh3add.uw a0, a1, a0
1777 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1778 ; RV64ZBA-NEXT:    ret
1779   %3 = shl i32 %1, 31
1780   %4 = zext i32 %3 to i64
1781   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1782   %6 = load i64, ptr %5, align 8
1783   ret i64 %6
1786 define i64 @pack_i64(i64 %a, i64 %b) nounwind {
1787 ; RV64I-LABEL: pack_i64:
1788 ; RV64I:       # %bb.0:
1789 ; RV64I-NEXT:    slli a0, a0, 32
1790 ; RV64I-NEXT:    srli a0, a0, 32
1791 ; RV64I-NEXT:    slli a1, a1, 32
1792 ; RV64I-NEXT:    or a0, a1, a0
1793 ; RV64I-NEXT:    ret
1795 ; RV64ZBA-LABEL: pack_i64:
1796 ; RV64ZBA:       # %bb.0:
1797 ; RV64ZBA-NEXT:    slli a1, a1, 32
1798 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
1799 ; RV64ZBA-NEXT:    ret
1800   %shl = and i64 %a, 4294967295
1801   %shl1 = shl i64 %b, 32
1802   %or = or i64 %shl1, %shl
1803   ret i64 %or
1806 define i64 @pack_i64_2(i32 signext %a, i32 signext %b) nounwind {
1807 ; RV64I-LABEL: pack_i64_2:
1808 ; RV64I:       # %bb.0:
1809 ; RV64I-NEXT:    slli a0, a0, 32
1810 ; RV64I-NEXT:    srli a0, a0, 32
1811 ; RV64I-NEXT:    slli a1, a1, 32
1812 ; RV64I-NEXT:    or a0, a1, a0
1813 ; RV64I-NEXT:    ret
1815 ; RV64ZBA-LABEL: pack_i64_2:
1816 ; RV64ZBA:       # %bb.0:
1817 ; RV64ZBA-NEXT:    slli a1, a1, 32
1818 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
1819 ; RV64ZBA-NEXT:    ret
1820   %zexta = zext i32 %a to i64
1821   %zextb = zext i32 %b to i64
1822   %shl1 = shl i64 %zextb, 32
1823   %or = or i64 %shl1, %zexta
1824   ret i64 %or