Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / CodeGen / RISCV / rv64-legal-i32 / rv64zba.ll
blob06bebb29a04b92770837aa0d78d84c7b721f0f18
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 i128 @slliuw_3(i32 signext %0, ptr %1) {
49 ; RV64I-LABEL: slliuw_3:
50 ; RV64I:       # %bb.0:
51 ; RV64I-NEXT:    addi a0, a0, 1
52 ; RV64I-NEXT:    slli a0, a0, 32
53 ; RV64I-NEXT:    srli a0, a0, 28
54 ; RV64I-NEXT:    add a1, a1, a0
55 ; RV64I-NEXT:    ld a0, 0(a1)
56 ; RV64I-NEXT:    ld a1, 8(a1)
57 ; RV64I-NEXT:    ret
59 ; RV64ZBA-LABEL: slliuw_3:
60 ; RV64ZBA:       # %bb.0:
61 ; RV64ZBA-NEXT:    addi a0, a0, 1
62 ; RV64ZBA-NEXT:    slli.uw a0, a0, 4
63 ; RV64ZBA-NEXT:    add a1, a1, a0
64 ; RV64ZBA-NEXT:    ld a0, 0(a1)
65 ; RV64ZBA-NEXT:    ld a1, 8(a1)
66 ; RV64ZBA-NEXT:    ret
67   %add = add i32 %0, 1
68   %3 = zext i32 %add to i64
69   %4 = getelementptr inbounds i128, ptr %1, i64 %3
70   %5 = load i128, ptr %4
71   ret i128 %5
74 define i64 @adduw(i64 %a, i64 %b) nounwind {
75 ; RV64I-LABEL: adduw:
76 ; RV64I:       # %bb.0:
77 ; RV64I-NEXT:    slli a1, a1, 32
78 ; RV64I-NEXT:    srli a1, a1, 32
79 ; RV64I-NEXT:    add a0, a1, a0
80 ; RV64I-NEXT:    ret
82 ; RV64ZBA-LABEL: adduw:
83 ; RV64ZBA:       # %bb.0:
84 ; RV64ZBA-NEXT:    add.uw a0, a1, a0
85 ; RV64ZBA-NEXT:    ret
86   %and = and i64 %b, 4294967295
87   %add = add i64 %and, %a
88   ret i64 %add
91 define signext i8 @adduw_2(i32 signext %0, ptr %1) {
92 ; RV64I-LABEL: adduw_2:
93 ; RV64I:       # %bb.0:
94 ; RV64I-NEXT:    slli a0, a0, 32
95 ; RV64I-NEXT:    srli a0, a0, 32
96 ; RV64I-NEXT:    add a0, a1, a0
97 ; RV64I-NEXT:    lb a0, 0(a0)
98 ; RV64I-NEXT:    ret
100 ; RV64ZBA-LABEL: adduw_2:
101 ; RV64ZBA:       # %bb.0:
102 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
103 ; RV64ZBA-NEXT:    lb a0, 0(a0)
104 ; RV64ZBA-NEXT:    ret
105   %3 = zext i32 %0 to i64
106   %4 = getelementptr inbounds i8, ptr %1, i64 %3
107   %5 = load i8, ptr %4
108   ret i8 %5
111 define signext i8 @adduw_3(i32 signext %0, ptr %1) {
112 ; RV64I-LABEL: adduw_3:
113 ; RV64I:       # %bb.0:
114 ; RV64I-NEXT:    addi a0, a0, 1
115 ; RV64I-NEXT:    slli a0, a0, 32
116 ; RV64I-NEXT:    srli a0, a0, 32
117 ; RV64I-NEXT:    add a0, a1, a0
118 ; RV64I-NEXT:    lb a0, 0(a0)
119 ; RV64I-NEXT:    ret
121 ; RV64ZBA-LABEL: adduw_3:
122 ; RV64ZBA:       # %bb.0:
123 ; RV64ZBA-NEXT:    addi a0, a0, 1
124 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
125 ; RV64ZBA-NEXT:    lb a0, 0(a0)
126 ; RV64ZBA-NEXT:    ret
127   %add = add i32 %0, 1
128   %3 = zext i32 %add to i64
129   %4 = getelementptr inbounds i8, ptr %1, i64 %3
130   %5 = load i8, ptr %4
131   ret i8 %5
134 define i64 @zextw_i64(i64 %a) nounwind {
135 ; RV64I-LABEL: zextw_i64:
136 ; RV64I:       # %bb.0:
137 ; RV64I-NEXT:    slli a0, a0, 32
138 ; RV64I-NEXT:    srli a0, a0, 32
139 ; RV64I-NEXT:    ret
141 ; RV64ZBA-LABEL: zextw_i64:
142 ; RV64ZBA:       # %bb.0:
143 ; RV64ZBA-NEXT:    zext.w a0, a0
144 ; RV64ZBA-NEXT:    ret
145   %and = and i64 %a, 4294967295
146   ret i64 %and
149 ; This makes sure targetShrinkDemandedConstant changes the and immmediate to
150 ; allow zext.w or slli+srli.
151 define i64 @zextw_demandedbits_i64(i64 %0) {
152 ; RV64I-LABEL: zextw_demandedbits_i64:
153 ; RV64I:       # %bb.0:
154 ; RV64I-NEXT:    ori a0, a0, 1
155 ; RV64I-NEXT:    slli a0, a0, 32
156 ; RV64I-NEXT:    srli a0, a0, 32
157 ; RV64I-NEXT:    ret
159 ; RV64ZBA-LABEL: zextw_demandedbits_i64:
160 ; RV64ZBA:       # %bb.0:
161 ; RV64ZBA-NEXT:    ori a0, a0, 1
162 ; RV64ZBA-NEXT:    zext.w a0, a0
163 ; RV64ZBA-NEXT:    ret
164   %2 = and i64 %0, 4294967294
165   %3 = or i64 %2, 1
166   ret i64 %3
169 define signext i16 @sh1add(i64 %0, ptr %1) {
170 ; RV64I-LABEL: sh1add:
171 ; RV64I:       # %bb.0:
172 ; RV64I-NEXT:    slli a0, a0, 1
173 ; RV64I-NEXT:    add a0, a1, a0
174 ; RV64I-NEXT:    lh a0, 0(a0)
175 ; RV64I-NEXT:    ret
177 ; RV64ZBA-LABEL: sh1add:
178 ; RV64ZBA:       # %bb.0:
179 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
180 ; RV64ZBA-NEXT:    lh a0, 0(a0)
181 ; RV64ZBA-NEXT:    ret
182   %3 = getelementptr inbounds i16, ptr %1, i64 %0
183   %4 = load i16, ptr %3
184   ret i16 %4
187 define signext i32 @sh2add(i64 %0, ptr %1) {
188 ; RV64I-LABEL: sh2add:
189 ; RV64I:       # %bb.0:
190 ; RV64I-NEXT:    slli a0, a0, 2
191 ; RV64I-NEXT:    add a0, a1, a0
192 ; RV64I-NEXT:    lw a0, 0(a0)
193 ; RV64I-NEXT:    ret
195 ; RV64ZBA-LABEL: sh2add:
196 ; RV64ZBA:       # %bb.0:
197 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
198 ; RV64ZBA-NEXT:    lw a0, 0(a0)
199 ; RV64ZBA-NEXT:    ret
200   %3 = getelementptr inbounds i32, ptr %1, i64 %0
201   %4 = load i32, ptr %3
202   ret i32 %4
205 define i64 @sh3add(i64 %0, ptr %1) {
206 ; RV64I-LABEL: sh3add:
207 ; RV64I:       # %bb.0:
208 ; RV64I-NEXT:    slli a0, a0, 3
209 ; RV64I-NEXT:    add a0, a1, a0
210 ; RV64I-NEXT:    ld a0, 0(a0)
211 ; RV64I-NEXT:    ret
213 ; RV64ZBA-LABEL: sh3add:
214 ; RV64ZBA:       # %bb.0:
215 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
216 ; RV64ZBA-NEXT:    ld a0, 0(a0)
217 ; RV64ZBA-NEXT:    ret
218   %3 = getelementptr inbounds i64, ptr %1, i64 %0
219   %4 = load i64, ptr %3
220   ret i64 %4
223 define signext i16 @sh1adduw(i32 signext %0, ptr %1) {
224 ; RV64I-LABEL: sh1adduw:
225 ; RV64I:       # %bb.0:
226 ; RV64I-NEXT:    slli a0, a0, 32
227 ; RV64I-NEXT:    srli a0, a0, 31
228 ; RV64I-NEXT:    add a0, a1, a0
229 ; RV64I-NEXT:    lh a0, 0(a0)
230 ; RV64I-NEXT:    ret
232 ; RV64ZBA-LABEL: sh1adduw:
233 ; RV64ZBA:       # %bb.0:
234 ; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
235 ; RV64ZBA-NEXT:    lh a0, 0(a0)
236 ; RV64ZBA-NEXT:    ret
237   %3 = zext i32 %0 to i64
238   %4 = getelementptr inbounds i16, ptr %1, i64 %3
239   %5 = load i16, ptr %4
240   ret i16 %5
243 define i64 @sh1adduw_2(i64 %0, i64 %1) {
244 ; RV64I-LABEL: sh1adduw_2:
245 ; RV64I:       # %bb.0:
246 ; RV64I-NEXT:    slli a0, a0, 32
247 ; RV64I-NEXT:    srli a0, a0, 31
248 ; RV64I-NEXT:    add a0, a0, a1
249 ; RV64I-NEXT:    ret
251 ; RV64ZBA-LABEL: sh1adduw_2:
252 ; RV64ZBA:       # %bb.0:
253 ; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
254 ; RV64ZBA-NEXT:    ret
255   %3 = shl i64 %0, 1
256   %4 = and i64 %3, 8589934590
257   %5 = add i64 %4, %1
258   ret i64 %5
261 define signext i32 @sh2adduw(i32 signext %0, ptr %1) {
262 ; RV64I-LABEL: sh2adduw:
263 ; RV64I:       # %bb.0:
264 ; RV64I-NEXT:    slli a0, a0, 32
265 ; RV64I-NEXT:    srli a0, a0, 30
266 ; RV64I-NEXT:    add a0, a1, a0
267 ; RV64I-NEXT:    lw a0, 0(a0)
268 ; RV64I-NEXT:    ret
270 ; RV64ZBA-LABEL: sh2adduw:
271 ; RV64ZBA:       # %bb.0:
272 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
273 ; RV64ZBA-NEXT:    lw a0, 0(a0)
274 ; RV64ZBA-NEXT:    ret
275   %3 = zext i32 %0 to i64
276   %4 = getelementptr inbounds i32, ptr %1, i64 %3
277   %5 = load i32, ptr %4
278   ret i32 %5
281 define i64 @sh2adduw_2(i64 %0, i64 %1) {
282 ; RV64I-LABEL: sh2adduw_2:
283 ; RV64I:       # %bb.0:
284 ; RV64I-NEXT:    slli a0, a0, 32
285 ; RV64I-NEXT:    srli a0, a0, 30
286 ; RV64I-NEXT:    add a0, a0, a1
287 ; RV64I-NEXT:    ret
289 ; RV64ZBA-LABEL: sh2adduw_2:
290 ; RV64ZBA:       # %bb.0:
291 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
292 ; RV64ZBA-NEXT:    ret
293   %3 = shl i64 %0, 2
294   %4 = and i64 %3, 17179869180
295   %5 = add i64 %4, %1
296   ret i64 %5
299 define i64 @sh3adduw(i32 signext %0, ptr %1) {
300 ; RV64I-LABEL: sh3adduw:
301 ; RV64I:       # %bb.0:
302 ; RV64I-NEXT:    slli a0, a0, 32
303 ; RV64I-NEXT:    srli a0, a0, 29
304 ; RV64I-NEXT:    add a0, a1, a0
305 ; RV64I-NEXT:    ld a0, 0(a0)
306 ; RV64I-NEXT:    ret
308 ; RV64ZBA-LABEL: sh3adduw:
309 ; RV64ZBA:       # %bb.0:
310 ; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
311 ; RV64ZBA-NEXT:    ld a0, 0(a0)
312 ; RV64ZBA-NEXT:    ret
313   %3 = zext i32 %0 to i64
314   %4 = getelementptr inbounds i64, ptr %1, i64 %3
315   %5 = load i64, ptr %4
316   ret i64 %5
319 define i64 @sh3adduw_2(i64 %0, i64 %1) {
320 ; RV64I-LABEL: sh3adduw_2:
321 ; RV64I:       # %bb.0:
322 ; RV64I-NEXT:    slli a0, a0, 32
323 ; RV64I-NEXT:    srli a0, a0, 29
324 ; RV64I-NEXT:    add a0, a0, a1
325 ; RV64I-NEXT:    ret
327 ; RV64ZBA-LABEL: sh3adduw_2:
328 ; RV64ZBA:       # %bb.0:
329 ; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
330 ; RV64ZBA-NEXT:    ret
331   %3 = shl i64 %0, 3
332   %4 = and i64 %3, 34359738360
333   %5 = add i64 %4, %1
334   ret i64 %5
337 ; Type legalization inserts a sext_inreg after the first add. That add will be
338 ; selected as sh2add which does not sign extend. SimplifyDemandedBits is unable
339 ; to remove the sext_inreg because it has multiple uses. The ashr will use the
340 ; sext_inreg to become sraiw. This leaves the sext_inreg only used by the shl.
341 ; If the shl is selected as sllw, we don't need the sext_inreg.
342 define i64 @sh2add_extra_sext(i32 %x, i32 %y, i32 %z) {
343 ; RV64I-LABEL: sh2add_extra_sext:
344 ; RV64I:       # %bb.0:
345 ; RV64I-NEXT:    slli a0, a0, 2
346 ; RV64I-NEXT:    add a0, a0, a1
347 ; RV64I-NEXT:    sllw a1, a2, a0
348 ; RV64I-NEXT:    sraiw a0, a0, 2
349 ; RV64I-NEXT:    mul a0, a1, a0
350 ; RV64I-NEXT:    ret
352 ; RV64ZBA-LABEL: sh2add_extra_sext:
353 ; RV64ZBA:       # %bb.0:
354 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
355 ; RV64ZBA-NEXT:    sllw a1, a2, a0
356 ; RV64ZBA-NEXT:    sraiw a0, a0, 2
357 ; RV64ZBA-NEXT:    mul a0, a1, a0
358 ; RV64ZBA-NEXT:    ret
359   %a = shl i32 %x, 2
360   %b = add i32 %a, %y
361   %c = shl i32 %z, %b
362   %d = ashr i32 %b, 2
363   %e = sext i32 %c to i64
364   %f = sext i32 %d to i64
365   %g = mul i64 %e, %f
366   ret i64 %g
369 define i64 @addmul6(i64 %a, i64 %b) {
370 ; RV64I-LABEL: addmul6:
371 ; RV64I:       # %bb.0:
372 ; RV64I-NEXT:    li a2, 6
373 ; RV64I-NEXT:    mul a0, a0, a2
374 ; RV64I-NEXT:    add a0, a0, a1
375 ; RV64I-NEXT:    ret
377 ; RV64ZBA-LABEL: addmul6:
378 ; RV64ZBA:       # %bb.0:
379 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
380 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
381 ; RV64ZBA-NEXT:    ret
382   %c = mul i64 %a, 6
383   %d = add i64 %c, %b
384   ret i64 %d
387 define i64 @addmul10(i64 %a, i64 %b) {
388 ; RV64I-LABEL: addmul10:
389 ; RV64I:       # %bb.0:
390 ; RV64I-NEXT:    li a2, 10
391 ; RV64I-NEXT:    mul a0, a0, a2
392 ; RV64I-NEXT:    add a0, a0, a1
393 ; RV64I-NEXT:    ret
395 ; RV64ZBA-LABEL: addmul10:
396 ; RV64ZBA:       # %bb.0:
397 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
398 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
399 ; RV64ZBA-NEXT:    ret
400   %c = mul i64 %a, 10
401   %d = add i64 %c, %b
402   ret i64 %d
405 define i64 @addmul12(i64 %a, i64 %b) {
406 ; RV64I-LABEL: addmul12:
407 ; RV64I:       # %bb.0:
408 ; RV64I-NEXT:    li a2, 12
409 ; RV64I-NEXT:    mul a0, a0, a2
410 ; RV64I-NEXT:    add a0, a0, a1
411 ; RV64I-NEXT:    ret
413 ; RV64ZBA-LABEL: addmul12:
414 ; RV64ZBA:       # %bb.0:
415 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
416 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
417 ; RV64ZBA-NEXT:    ret
418   %c = mul i64 %a, 12
419   %d = add i64 %c, %b
420   ret i64 %d
423 define i64 @addmul18(i64 %a, i64 %b) {
424 ; RV64I-LABEL: addmul18:
425 ; RV64I:       # %bb.0:
426 ; RV64I-NEXT:    li a2, 18
427 ; RV64I-NEXT:    mul a0, a0, a2
428 ; RV64I-NEXT:    add a0, a0, a1
429 ; RV64I-NEXT:    ret
431 ; RV64ZBA-LABEL: addmul18:
432 ; RV64ZBA:       # %bb.0:
433 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
434 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
435 ; RV64ZBA-NEXT:    ret
436   %c = mul i64 %a, 18
437   %d = add i64 %c, %b
438   ret i64 %d
441 define i64 @addmul20(i64 %a, i64 %b) {
442 ; RV64I-LABEL: addmul20:
443 ; RV64I:       # %bb.0:
444 ; RV64I-NEXT:    li a2, 20
445 ; RV64I-NEXT:    mul a0, a0, a2
446 ; RV64I-NEXT:    add a0, a0, a1
447 ; RV64I-NEXT:    ret
449 ; RV64ZBA-LABEL: addmul20:
450 ; RV64ZBA:       # %bb.0:
451 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
452 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
453 ; RV64ZBA-NEXT:    ret
454   %c = mul i64 %a, 20
455   %d = add i64 %c, %b
456   ret i64 %d
459 define i64 @addmul24(i64 %a, i64 %b) {
460 ; RV64I-LABEL: addmul24:
461 ; RV64I:       # %bb.0:
462 ; RV64I-NEXT:    li a2, 24
463 ; RV64I-NEXT:    mul a0, a0, a2
464 ; RV64I-NEXT:    add a0, a0, a1
465 ; RV64I-NEXT:    ret
467 ; RV64ZBA-LABEL: addmul24:
468 ; RV64ZBA:       # %bb.0:
469 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
470 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
471 ; RV64ZBA-NEXT:    ret
472   %c = mul i64 %a, 24
473   %d = add i64 %c, %b
474   ret i64 %d
477 define i64 @addmul36(i64 %a, i64 %b) {
478 ; RV64I-LABEL: addmul36:
479 ; RV64I:       # %bb.0:
480 ; RV64I-NEXT:    li a2, 36
481 ; RV64I-NEXT:    mul a0, a0, a2
482 ; RV64I-NEXT:    add a0, a0, a1
483 ; RV64I-NEXT:    ret
485 ; RV64ZBA-LABEL: addmul36:
486 ; RV64ZBA:       # %bb.0:
487 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
488 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
489 ; RV64ZBA-NEXT:    ret
490   %c = mul i64 %a, 36
491   %d = add i64 %c, %b
492   ret i64 %d
495 define i64 @addmul40(i64 %a, i64 %b) {
496 ; RV64I-LABEL: addmul40:
497 ; RV64I:       # %bb.0:
498 ; RV64I-NEXT:    li a2, 40
499 ; RV64I-NEXT:    mul a0, a0, a2
500 ; RV64I-NEXT:    add a0, a0, a1
501 ; RV64I-NEXT:    ret
503 ; RV64ZBA-LABEL: addmul40:
504 ; RV64ZBA:       # %bb.0:
505 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
506 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
507 ; RV64ZBA-NEXT:    ret
508   %c = mul i64 %a, 40
509   %d = add i64 %c, %b
510   ret i64 %d
513 define i64 @addmul72(i64 %a, i64 %b) {
514 ; RV64I-LABEL: addmul72:
515 ; RV64I:       # %bb.0:
516 ; RV64I-NEXT:    li a2, 72
517 ; RV64I-NEXT:    mul a0, a0, a2
518 ; RV64I-NEXT:    add a0, a0, a1
519 ; RV64I-NEXT:    ret
521 ; RV64ZBA-LABEL: addmul72:
522 ; RV64ZBA:       # %bb.0:
523 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
524 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
525 ; RV64ZBA-NEXT:    ret
526   %c = mul i64 %a, 72
527   %d = add i64 %c, %b
528   ret i64 %d
531 define i64 @mul96(i64 %a) {
532 ; RV64I-LABEL: mul96:
533 ; RV64I:       # %bb.0:
534 ; RV64I-NEXT:    li a1, 96
535 ; RV64I-NEXT:    mul a0, a0, a1
536 ; RV64I-NEXT:    ret
538 ; RV64ZBA-LABEL: mul96:
539 ; RV64ZBA:       # %bb.0:
540 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
541 ; RV64ZBA-NEXT:    slli a0, a0, 5
542 ; RV64ZBA-NEXT:    ret
543   %c = mul i64 %a, 96
544   ret i64 %c
547 define i64 @mul160(i64 %a) {
548 ; RV64I-LABEL: mul160:
549 ; RV64I:       # %bb.0:
550 ; RV64I-NEXT:    li a1, 160
551 ; RV64I-NEXT:    mul a0, a0, a1
552 ; RV64I-NEXT:    ret
554 ; RV64ZBA-LABEL: mul160:
555 ; RV64ZBA:       # %bb.0:
556 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
557 ; RV64ZBA-NEXT:    slli a0, a0, 5
558 ; RV64ZBA-NEXT:    ret
559   %c = mul i64 %a, 160
560   ret i64 %c
563 define i64 @mul288(i64 %a) {
564 ; RV64I-LABEL: mul288:
565 ; RV64I:       # %bb.0:
566 ; RV64I-NEXT:    li a1, 288
567 ; RV64I-NEXT:    mul a0, a0, a1
568 ; RV64I-NEXT:    ret
570 ; RV64ZBA-LABEL: mul288:
571 ; RV64ZBA:       # %bb.0:
572 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
573 ; RV64ZBA-NEXT:    slli a0, a0, 5
574 ; RV64ZBA-NEXT:    ret
575   %c = mul i64 %a, 288
576   ret i64 %c
579 define i64 @zext_mul96(i32 signext %a) {
580 ; RV64I-LABEL: zext_mul96:
581 ; RV64I:       # %bb.0:
582 ; RV64I-NEXT:    li a1, 3
583 ; RV64I-NEXT:    slli a1, a1, 37
584 ; RV64I-NEXT:    slli a0, a0, 32
585 ; RV64I-NEXT:    mulhu a0, a0, a1
586 ; RV64I-NEXT:    ret
588 ; RV64ZBA-LABEL: zext_mul96:
589 ; RV64ZBA:       # %bb.0:
590 ; RV64ZBA-NEXT:    slli.uw a0, a0, 5
591 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
592 ; RV64ZBA-NEXT:    ret
593   %b = zext i32 %a to i64
594   %c = mul i64 %b, 96
595   ret i64 %c
598 define i64 @zext_mul160(i32 signext %a) {
599 ; RV64I-LABEL: zext_mul160:
600 ; RV64I:       # %bb.0:
601 ; RV64I-NEXT:    li a1, 5
602 ; RV64I-NEXT:    slli a1, a1, 37
603 ; RV64I-NEXT:    slli a0, a0, 32
604 ; RV64I-NEXT:    mulhu a0, a0, a1
605 ; RV64I-NEXT:    ret
607 ; RV64ZBA-LABEL: zext_mul160:
608 ; RV64ZBA:       # %bb.0:
609 ; RV64ZBA-NEXT:    slli.uw a0, a0, 5
610 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
611 ; RV64ZBA-NEXT:    ret
612   %b = zext i32 %a to i64
613   %c = mul i64 %b, 160
614   ret i64 %c
617 define i64 @zext_mul288(i32 signext %a) {
618 ; RV64I-LABEL: zext_mul288:
619 ; RV64I:       # %bb.0:
620 ; RV64I-NEXT:    li a1, 9
621 ; RV64I-NEXT:    slli a1, a1, 37
622 ; RV64I-NEXT:    slli a0, a0, 32
623 ; RV64I-NEXT:    mulhu a0, a0, a1
624 ; RV64I-NEXT:    ret
626 ; RV64ZBA-LABEL: zext_mul288:
627 ; RV64ZBA:       # %bb.0:
628 ; RV64ZBA-NEXT:    slli.uw a0, a0, 5
629 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
630 ; RV64ZBA-NEXT:    ret
631   %b = zext i32 %a to i64
632   %c = mul i64 %b, 288
633   ret i64 %c
636 ; We can't use slli.uw becaues the shift amount is more than 31.
637 ; FIXME: The zext.w is unneeded.
638 define i64 @zext_mul12884901888(i32 signext %a) {
639 ; RV64I-LABEL: zext_mul12884901888:
640 ; RV64I:       # %bb.0:
641 ; RV64I-NEXT:    slli a0, a0, 32
642 ; RV64I-NEXT:    srli a0, a0, 32
643 ; RV64I-NEXT:    li a1, 3
644 ; RV64I-NEXT:    slli a1, a1, 32
645 ; RV64I-NEXT:    mul a0, a0, a1
646 ; RV64I-NEXT:    ret
648 ; RV64ZBA-LABEL: zext_mul12884901888:
649 ; RV64ZBA:       # %bb.0:
650 ; RV64ZBA-NEXT:    andi a0, a0, -1
651 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
652 ; RV64ZBA-NEXT:    slli a0, a0, 32
653 ; RV64ZBA-NEXT:    ret
654   %b = zext i32 %a to i64
655   %c = mul i64 %b, 12884901888
656   ret i64 %c
659 ; We can't use slli.uw becaues the shift amount is more than 31.
660 ; FIXME: The zext.w is unneeded.
661 define i64 @zext_mul21474836480(i32 signext %a) {
662 ; RV64I-LABEL: zext_mul21474836480:
663 ; RV64I:       # %bb.0:
664 ; RV64I-NEXT:    slli a0, a0, 32
665 ; RV64I-NEXT:    srli a0, a0, 32
666 ; RV64I-NEXT:    li a1, 5
667 ; RV64I-NEXT:    slli a1, a1, 32
668 ; RV64I-NEXT:    mul a0, a0, a1
669 ; RV64I-NEXT:    ret
671 ; RV64ZBA-LABEL: zext_mul21474836480:
672 ; RV64ZBA:       # %bb.0:
673 ; RV64ZBA-NEXT:    andi a0, a0, -1
674 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
675 ; RV64ZBA-NEXT:    slli a0, a0, 32
676 ; RV64ZBA-NEXT:    ret
677   %b = zext i32 %a to i64
678   %c = mul i64 %b, 21474836480
679   ret i64 %c
682 ; We can't use slli.uw becaues the shift amount is more than 31.
683 ; FIXME: The zext.w is unneeded.
684 define i64 @zext_mul38654705664(i32 signext %a) {
685 ; RV64I-LABEL: zext_mul38654705664:
686 ; RV64I:       # %bb.0:
687 ; RV64I-NEXT:    slli a0, a0, 32
688 ; RV64I-NEXT:    srli a0, a0, 32
689 ; RV64I-NEXT:    li a1, 9
690 ; RV64I-NEXT:    slli a1, a1, 32
691 ; RV64I-NEXT:    mul a0, a0, a1
692 ; RV64I-NEXT:    ret
694 ; RV64ZBA-LABEL: zext_mul38654705664:
695 ; RV64ZBA:       # %bb.0:
696 ; RV64ZBA-NEXT:    andi a0, a0, -1
697 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
698 ; RV64ZBA-NEXT:    slli a0, a0, 32
699 ; RV64ZBA-NEXT:    ret
700   %b = zext i32 %a to i64
701   %c = mul i64 %b, 38654705664
702   ret i64 %c
705 define i64 @sh1add_imm(i64 %0) {
706 ; CHECK-LABEL: sh1add_imm:
707 ; CHECK:       # %bb.0:
708 ; CHECK-NEXT:    slli a0, a0, 1
709 ; CHECK-NEXT:    addi a0, a0, 5
710 ; CHECK-NEXT:    ret
711   %a = shl i64 %0, 1
712   %b = add i64 %a, 5
713   ret i64 %b
716 define i64 @sh2add_imm(i64 %0) {
717 ; CHECK-LABEL: sh2add_imm:
718 ; CHECK:       # %bb.0:
719 ; CHECK-NEXT:    slli a0, a0, 2
720 ; CHECK-NEXT:    addi a0, a0, -6
721 ; CHECK-NEXT:    ret
722   %a = shl i64 %0, 2
723   %b = add i64 %a, -6
724   ret i64 %b
727 define i64 @sh3add_imm(i64 %0) {
728 ; CHECK-LABEL: sh3add_imm:
729 ; CHECK:       # %bb.0:
730 ; CHECK-NEXT:    slli a0, a0, 3
731 ; CHECK-NEXT:    addi a0, a0, 7
732 ; CHECK-NEXT:    ret
733   %a = shl i64 %0, 3
734   %b = add i64 %a, 7
735   ret i64 %b
738 define i64 @sh1adduw_imm(i32 signext %0) {
739 ; RV64I-LABEL: sh1adduw_imm:
740 ; RV64I:       # %bb.0:
741 ; RV64I-NEXT:    slli a0, a0, 32
742 ; RV64I-NEXT:    srli a0, a0, 31
743 ; RV64I-NEXT:    addi a0, a0, 11
744 ; RV64I-NEXT:    ret
746 ; RV64ZBA-LABEL: sh1adduw_imm:
747 ; RV64ZBA:       # %bb.0:
748 ; RV64ZBA-NEXT:    slli.uw a0, a0, 1
749 ; RV64ZBA-NEXT:    addi a0, a0, 11
750 ; RV64ZBA-NEXT:    ret
751   %a = zext i32 %0 to i64
752   %b = shl i64 %a, 1
753   %c = add i64 %b, 11
754   ret i64 %c
757 define i64 @sh2adduw_imm(i32 signext %0) {
758 ; RV64I-LABEL: sh2adduw_imm:
759 ; RV64I:       # %bb.0:
760 ; RV64I-NEXT:    slli a0, a0, 32
761 ; RV64I-NEXT:    srli a0, a0, 30
762 ; RV64I-NEXT:    addi a0, a0, -12
763 ; RV64I-NEXT:    ret
765 ; RV64ZBA-LABEL: sh2adduw_imm:
766 ; RV64ZBA:       # %bb.0:
767 ; RV64ZBA-NEXT:    slli.uw a0, a0, 2
768 ; RV64ZBA-NEXT:    addi a0, a0, -12
769 ; RV64ZBA-NEXT:    ret
770   %a = zext i32 %0 to i64
771   %b = shl i64 %a, 2
772   %c = add i64 %b, -12
773   ret i64 %c
776 define i64 @sh3adduw_imm(i32 signext %0) {
777 ; RV64I-LABEL: sh3adduw_imm:
778 ; RV64I:       # %bb.0:
779 ; RV64I-NEXT:    slli a0, a0, 32
780 ; RV64I-NEXT:    srli a0, a0, 29
781 ; RV64I-NEXT:    addi a0, a0, 13
782 ; RV64I-NEXT:    ret
784 ; RV64ZBA-LABEL: sh3adduw_imm:
785 ; RV64ZBA:       # %bb.0:
786 ; RV64ZBA-NEXT:    slli.uw a0, a0, 3
787 ; RV64ZBA-NEXT:    addi a0, a0, 13
788 ; RV64ZBA-NEXT:    ret
789   %a = zext i32 %0 to i64
790   %b = shl i64 %a, 3
791   %c = add i64 %b, 13
792   ret i64 %c
795 define i64 @adduw_imm(i32 signext %0) nounwind {
796 ; RV64I-LABEL: adduw_imm:
797 ; RV64I:       # %bb.0:
798 ; RV64I-NEXT:    slli a0, a0, 32
799 ; RV64I-NEXT:    srli a0, a0, 32
800 ; RV64I-NEXT:    addi a0, a0, 5
801 ; RV64I-NEXT:    ret
803 ; RV64ZBA-LABEL: adduw_imm:
804 ; RV64ZBA:       # %bb.0:
805 ; RV64ZBA-NEXT:    zext.w a0, a0
806 ; RV64ZBA-NEXT:    addi a0, a0, 5
807 ; RV64ZBA-NEXT:    ret
808   %a = zext i32 %0 to i64
809   %b = add i64 %a, 5
810   ret i64 %b
813 define i64 @mul258(i64 %a) {
814 ; CHECK-LABEL: mul258:
815 ; CHECK:       # %bb.0:
816 ; CHECK-NEXT:    li a1, 258
817 ; CHECK-NEXT:    mul a0, a0, a1
818 ; CHECK-NEXT:    ret
819   %c = mul i64 %a, 258
820   ret i64 %c
823 define i64 @mul260(i64 %a) {
824 ; CHECK-LABEL: mul260:
825 ; CHECK:       # %bb.0:
826 ; CHECK-NEXT:    li a1, 260
827 ; CHECK-NEXT:    mul a0, a0, a1
828 ; CHECK-NEXT:    ret
829   %c = mul i64 %a, 260
830   ret i64 %c
833 define i64 @mul264(i64 %a) {
834 ; CHECK-LABEL: mul264:
835 ; CHECK:       # %bb.0:
836 ; CHECK-NEXT:    li a1, 264
837 ; CHECK-NEXT:    mul a0, a0, a1
838 ; CHECK-NEXT:    ret
839   %c = mul i64 %a, 264
840   ret i64 %c
843 define i64 @imm_zextw() nounwind {
844 ; RV64I-LABEL: imm_zextw:
845 ; RV64I:       # %bb.0:
846 ; RV64I-NEXT:    li a0, 1
847 ; RV64I-NEXT:    slli a0, a0, 32
848 ; RV64I-NEXT:    addi a0, a0, -2
849 ; RV64I-NEXT:    ret
851 ; RV64ZBA-LABEL: imm_zextw:
852 ; RV64ZBA:       # %bb.0:
853 ; RV64ZBA-NEXT:    li a0, -2
854 ; RV64ZBA-NEXT:    zext.w a0, a0
855 ; RV64ZBA-NEXT:    ret
856   ret i64 4294967294 ; -2 in 32 bits.
859 define i64 @mul11(i64 %a) {
860 ; RV64I-LABEL: mul11:
861 ; RV64I:       # %bb.0:
862 ; RV64I-NEXT:    li a1, 11
863 ; RV64I-NEXT:    mul a0, a0, a1
864 ; RV64I-NEXT:    ret
866 ; RV64ZBA-LABEL: mul11:
867 ; RV64ZBA:       # %bb.0:
868 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
869 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
870 ; RV64ZBA-NEXT:    ret
871   %c = mul i64 %a, 11
872   ret i64 %c
875 define i64 @mul19(i64 %a) {
876 ; RV64I-LABEL: mul19:
877 ; RV64I:       # %bb.0:
878 ; RV64I-NEXT:    li a1, 19
879 ; RV64I-NEXT:    mul a0, a0, a1
880 ; RV64I-NEXT:    ret
882 ; RV64ZBA-LABEL: mul19:
883 ; RV64ZBA:       # %bb.0:
884 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
885 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
886 ; RV64ZBA-NEXT:    ret
887   %c = mul i64 %a, 19
888   ret i64 %c
891 define i64 @mul13(i64 %a) {
892 ; RV64I-LABEL: mul13:
893 ; RV64I:       # %bb.0:
894 ; RV64I-NEXT:    li a1, 13
895 ; RV64I-NEXT:    mul a0, a0, a1
896 ; RV64I-NEXT:    ret
898 ; RV64ZBA-LABEL: mul13:
899 ; RV64ZBA:       # %bb.0:
900 ; RV64ZBA-NEXT:    sh1add a1, a0, a0
901 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
902 ; RV64ZBA-NEXT:    ret
903   %c = mul i64 %a, 13
904   ret i64 %c
907 define i64 @mul21(i64 %a) {
908 ; RV64I-LABEL: mul21:
909 ; RV64I:       # %bb.0:
910 ; RV64I-NEXT:    li a1, 21
911 ; RV64I-NEXT:    mul a0, a0, a1
912 ; RV64I-NEXT:    ret
914 ; RV64ZBA-LABEL: mul21:
915 ; RV64ZBA:       # %bb.0:
916 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
917 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
918 ; RV64ZBA-NEXT:    ret
919   %c = mul i64 %a, 21
920   ret i64 %c
923 define i64 @mul37(i64 %a) {
924 ; RV64I-LABEL: mul37:
925 ; RV64I:       # %bb.0:
926 ; RV64I-NEXT:    li a1, 37
927 ; RV64I-NEXT:    mul a0, a0, a1
928 ; RV64I-NEXT:    ret
930 ; RV64ZBA-LABEL: mul37:
931 ; RV64ZBA:       # %bb.0:
932 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
933 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
934 ; RV64ZBA-NEXT:    ret
935   %c = mul i64 %a, 37
936   ret i64 %c
939 define i64 @mul25(i64 %a) {
940 ; RV64I-LABEL: mul25:
941 ; RV64I:       # %bb.0:
942 ; RV64I-NEXT:    li a1, 25
943 ; RV64I-NEXT:    mul a0, a0, a1
944 ; RV64I-NEXT:    ret
946 ; RV64ZBA-LABEL: mul25:
947 ; RV64ZBA:       # %bb.0:
948 ; RV64ZBA-NEXT:    sh1add a1, a0, a0
949 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
950 ; RV64ZBA-NEXT:    ret
951   %c = mul i64 %a, 25
952   ret i64 %c
955 define i64 @mul41(i64 %a) {
956 ; RV64I-LABEL: mul41:
957 ; RV64I:       # %bb.0:
958 ; RV64I-NEXT:    li a1, 41
959 ; RV64I-NEXT:    mul a0, a0, a1
960 ; RV64I-NEXT:    ret
962 ; RV64ZBA-LABEL: mul41:
963 ; RV64ZBA:       # %bb.0:
964 ; RV64ZBA-NEXT:    sh2add a1, a0, a0
965 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
966 ; RV64ZBA-NEXT:    ret
967   %c = mul i64 %a, 41
968   ret i64 %c
971 define i64 @mul73(i64 %a) {
972 ; RV64I-LABEL: mul73:
973 ; RV64I:       # %bb.0:
974 ; RV64I-NEXT:    li a1, 73
975 ; RV64I-NEXT:    mul a0, a0, a1
976 ; RV64I-NEXT:    ret
978 ; RV64ZBA-LABEL: mul73:
979 ; RV64ZBA:       # %bb.0:
980 ; RV64ZBA-NEXT:    sh3add a1, a0, a0
981 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
982 ; RV64ZBA-NEXT:    ret
983   %c = mul i64 %a, 73
984   ret i64 %c
987 define i64 @mul27(i64 %a) {
988 ; RV64I-LABEL: mul27:
989 ; RV64I:       # %bb.0:
990 ; RV64I-NEXT:    li a1, 27
991 ; RV64I-NEXT:    mul a0, a0, a1
992 ; RV64I-NEXT:    ret
994 ; RV64ZBA-LABEL: mul27:
995 ; RV64ZBA:       # %bb.0:
996 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
997 ; RV64ZBA-NEXT:    sh1add a0, a0, a0
998 ; RV64ZBA-NEXT:    ret
999   %c = mul i64 %a, 27
1000   ret i64 %c
1003 define i64 @mul45(i64 %a) {
1004 ; RV64I-LABEL: mul45:
1005 ; RV64I:       # %bb.0:
1006 ; RV64I-NEXT:    li a1, 45
1007 ; RV64I-NEXT:    mul a0, a0, a1
1008 ; RV64I-NEXT:    ret
1010 ; RV64ZBA-LABEL: mul45:
1011 ; RV64ZBA:       # %bb.0:
1012 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
1013 ; RV64ZBA-NEXT:    sh2add a0, a0, a0
1014 ; RV64ZBA-NEXT:    ret
1015   %c = mul i64 %a, 45
1016   ret i64 %c
1019 define i64 @mul81(i64 %a) {
1020 ; RV64I-LABEL: mul81:
1021 ; RV64I:       # %bb.0:
1022 ; RV64I-NEXT:    li a1, 81
1023 ; RV64I-NEXT:    mul a0, a0, a1
1024 ; RV64I-NEXT:    ret
1026 ; RV64ZBA-LABEL: mul81:
1027 ; RV64ZBA:       # %bb.0:
1028 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
1029 ; RV64ZBA-NEXT:    sh3add a0, a0, a0
1030 ; RV64ZBA-NEXT:    ret
1031   %c = mul i64 %a, 81
1032   ret i64 %c
1035 define i64 @mul4098(i64 %a) {
1036 ; RV64I-LABEL: mul4098:
1037 ; RV64I:       # %bb.0:
1038 ; RV64I-NEXT:    slli a1, a0, 1
1039 ; RV64I-NEXT:    slli a0, a0, 12
1040 ; RV64I-NEXT:    add a0, a0, a1
1041 ; RV64I-NEXT:    ret
1043 ; RV64ZBA-LABEL: mul4098:
1044 ; RV64ZBA:       # %bb.0:
1045 ; RV64ZBA-NEXT:    slli a1, a0, 12
1046 ; RV64ZBA-NEXT:    sh1add a0, a0, a1
1047 ; RV64ZBA-NEXT:    ret
1048   %c = mul i64 %a, 4098
1049   ret i64 %c
1052 define i64 @mul4100(i64 %a) {
1053 ; RV64I-LABEL: mul4100:
1054 ; RV64I:       # %bb.0:
1055 ; RV64I-NEXT:    slli a1, a0, 2
1056 ; RV64I-NEXT:    slli a0, a0, 12
1057 ; RV64I-NEXT:    add a0, a0, a1
1058 ; RV64I-NEXT:    ret
1060 ; RV64ZBA-LABEL: mul4100:
1061 ; RV64ZBA:       # %bb.0:
1062 ; RV64ZBA-NEXT:    slli a1, a0, 12
1063 ; RV64ZBA-NEXT:    sh2add a0, a0, a1
1064 ; RV64ZBA-NEXT:    ret
1065   %c = mul i64 %a, 4100
1066   ret i64 %c
1069 define i64 @mul4104(i64 %a) {
1070 ; RV64I-LABEL: mul4104:
1071 ; RV64I:       # %bb.0:
1072 ; RV64I-NEXT:    slli a1, a0, 3
1073 ; RV64I-NEXT:    slli a0, a0, 12
1074 ; RV64I-NEXT:    add a0, a0, a1
1075 ; RV64I-NEXT:    ret
1077 ; RV64ZBA-LABEL: mul4104:
1078 ; RV64ZBA:       # %bb.0:
1079 ; RV64ZBA-NEXT:    slli a1, a0, 12
1080 ; RV64ZBA-NEXT:    sh3add a0, a0, a1
1081 ; RV64ZBA-NEXT:    ret
1082   %c = mul i64 %a, 4104
1083   ret i64 %c
1086 define signext i32 @mulw192(i32 signext %a) {
1087 ; CHECK-LABEL: mulw192:
1088 ; CHECK:       # %bb.0:
1089 ; CHECK-NEXT:    li a1, 192
1090 ; CHECK-NEXT:    mulw a0, a0, a1
1091 ; CHECK-NEXT:    ret
1092   %c = mul i32 %a, 192
1093   ret i32 %c
1096 define signext i32 @mulw320(i32 signext %a) {
1097 ; CHECK-LABEL: mulw320:
1098 ; CHECK:       # %bb.0:
1099 ; CHECK-NEXT:    li a1, 320
1100 ; CHECK-NEXT:    mulw a0, a0, a1
1101 ; CHECK-NEXT:    ret
1102   %c = mul i32 %a, 320
1103   ret i32 %c
1106 define signext i32 @mulw576(i32 signext %a) {
1107 ; CHECK-LABEL: mulw576:
1108 ; CHECK:       # %bb.0:
1109 ; CHECK-NEXT:    li a1, 576
1110 ; CHECK-NEXT:    mulw a0, a0, a1
1111 ; CHECK-NEXT:    ret
1112   %c = mul i32 %a, 576
1113   ret i32 %c
1116 define i64 @add4104(i64 %a) {
1117 ; RV64I-LABEL: add4104:
1118 ; RV64I:       # %bb.0:
1119 ; RV64I-NEXT:    lui a1, 1
1120 ; RV64I-NEXT:    addiw a1, a1, 8
1121 ; RV64I-NEXT:    add a0, a0, a1
1122 ; RV64I-NEXT:    ret
1124 ; RV64ZBA-LABEL: add4104:
1125 ; RV64ZBA:       # %bb.0:
1126 ; RV64ZBA-NEXT:    li a1, 1026
1127 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1128 ; RV64ZBA-NEXT:    ret
1129   %c = add i64 %a, 4104
1130   ret i64 %c
1133 define i64 @add8208(i64 %a) {
1134 ; RV64I-LABEL: add8208:
1135 ; RV64I:       # %bb.0:
1136 ; RV64I-NEXT:    lui a1, 2
1137 ; RV64I-NEXT:    addiw a1, a1, 16
1138 ; RV64I-NEXT:    add a0, a0, a1
1139 ; RV64I-NEXT:    ret
1141 ; RV64ZBA-LABEL: add8208:
1142 ; RV64ZBA:       # %bb.0:
1143 ; RV64ZBA-NEXT:    li a1, 1026
1144 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1145 ; RV64ZBA-NEXT:    ret
1146   %c = add i64 %a, 8208
1147   ret i64 %c
1150 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1151 define signext i32 @add8192_i32(i32 signext %a) {
1152 ; CHECK-LABEL: add8192_i32:
1153 ; CHECK:       # %bb.0:
1154 ; CHECK-NEXT:    lui a1, 2
1155 ; CHECK-NEXT:    addw a0, a0, a1
1156 ; CHECK-NEXT:    ret
1157   %c = add i32 %a, 8192
1158   ret i32 %c
1161 ; Make sure we prefer LUI for the 8192 instead of using sh3add.
1162 define i64 @add8192(i64 %a) {
1163 ; CHECK-LABEL: add8192:
1164 ; CHECK:       # %bb.0:
1165 ; CHECK-NEXT:    lui a1, 2
1166 ; CHECK-NEXT:    add a0, a0, a1
1167 ; CHECK-NEXT:    ret
1168   %c = add i64 %a, 8192
1169   ret i64 %c
1172 define signext i32 @addshl32_5_6(i32 signext %a, i32 signext %b) {
1173 ; RV64I-LABEL: addshl32_5_6:
1174 ; RV64I:       # %bb.0:
1175 ; RV64I-NEXT:    slli a0, a0, 5
1176 ; RV64I-NEXT:    slli a1, a1, 6
1177 ; RV64I-NEXT:    addw a0, a0, a1
1178 ; RV64I-NEXT:    ret
1180 ; RV64ZBA-LABEL: addshl32_5_6:
1181 ; RV64ZBA:       # %bb.0:
1182 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1183 ; RV64ZBA-NEXT:    slliw a0, a0, 5
1184 ; RV64ZBA-NEXT:    ret
1185   %c = shl i32 %a, 5
1186   %d = shl i32 %b, 6
1187   %e = add i32 %c, %d
1188   ret i32 %e
1191 define i64 @addshl64_5_6(i64 %a, i64 %b) {
1192 ; RV64I-LABEL: addshl64_5_6:
1193 ; RV64I:       # %bb.0:
1194 ; RV64I-NEXT:    slli a0, a0, 5
1195 ; RV64I-NEXT:    slli a1, a1, 6
1196 ; RV64I-NEXT:    add a0, a0, a1
1197 ; RV64I-NEXT:    ret
1199 ; RV64ZBA-LABEL: addshl64_5_6:
1200 ; RV64ZBA:       # %bb.0:
1201 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1202 ; RV64ZBA-NEXT:    slli a0, a0, 5
1203 ; RV64ZBA-NEXT:    ret
1204   %c = shl i64 %a, 5
1205   %d = shl i64 %b, 6
1206   %e = add i64 %c, %d
1207   ret i64 %e
1210 define signext i32 @addshl32_5_7(i32 signext %a, i32 signext %b) {
1211 ; RV64I-LABEL: addshl32_5_7:
1212 ; RV64I:       # %bb.0:
1213 ; RV64I-NEXT:    slli a0, a0, 5
1214 ; RV64I-NEXT:    slli a1, a1, 7
1215 ; RV64I-NEXT:    addw a0, a0, a1
1216 ; RV64I-NEXT:    ret
1218 ; RV64ZBA-LABEL: addshl32_5_7:
1219 ; RV64ZBA:       # %bb.0:
1220 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1221 ; RV64ZBA-NEXT:    slliw a0, a0, 5
1222 ; RV64ZBA-NEXT:    ret
1223   %c = shl i32 %a, 5
1224   %d = shl i32 %b, 7
1225   %e = add i32 %c, %d
1226   ret i32 %e
1229 define i64 @addshl64_5_7(i64 %a, i64 %b) {
1230 ; RV64I-LABEL: addshl64_5_7:
1231 ; RV64I:       # %bb.0:
1232 ; RV64I-NEXT:    slli a0, a0, 5
1233 ; RV64I-NEXT:    slli a1, a1, 7
1234 ; RV64I-NEXT:    add a0, a0, a1
1235 ; RV64I-NEXT:    ret
1237 ; RV64ZBA-LABEL: addshl64_5_7:
1238 ; RV64ZBA:       # %bb.0:
1239 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1240 ; RV64ZBA-NEXT:    slli a0, a0, 5
1241 ; RV64ZBA-NEXT:    ret
1242   %c = shl i64 %a, 5
1243   %d = shl i64 %b, 7
1244   %e = add i64 %c, %d
1245   ret i64 %e
1248 define signext i32 @addshl32_5_8(i32 signext %a, i32 signext %b) {
1249 ; RV64I-LABEL: addshl32_5_8:
1250 ; RV64I:       # %bb.0:
1251 ; RV64I-NEXT:    slli a0, a0, 5
1252 ; RV64I-NEXT:    slli a1, a1, 8
1253 ; RV64I-NEXT:    addw a0, a0, a1
1254 ; RV64I-NEXT:    ret
1256 ; RV64ZBA-LABEL: addshl32_5_8:
1257 ; RV64ZBA:       # %bb.0:
1258 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1259 ; RV64ZBA-NEXT:    slliw a0, a0, 5
1260 ; RV64ZBA-NEXT:    ret
1261   %c = shl i32 %a, 5
1262   %d = shl i32 %b, 8
1263   %e = add i32 %c, %d
1264   ret i32 %e
1267 define i64 @addshl64_5_8(i64 %a, i64 %b) {
1268 ; RV64I-LABEL: addshl64_5_8:
1269 ; RV64I:       # %bb.0:
1270 ; RV64I-NEXT:    slli a0, a0, 5
1271 ; RV64I-NEXT:    slli a1, a1, 8
1272 ; RV64I-NEXT:    add a0, a0, a1
1273 ; RV64I-NEXT:    ret
1275 ; RV64ZBA-LABEL: addshl64_5_8:
1276 ; RV64ZBA:       # %bb.0:
1277 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1278 ; RV64ZBA-NEXT:    slli a0, a0, 5
1279 ; RV64ZBA-NEXT:    ret
1280   %c = shl i64 %a, 5
1281   %d = shl i64 %b, 8
1282   %e = add i64 %c, %d
1283   ret i64 %e
1286 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1287 ; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
1288 define zeroext i32 @sext_ashr_zext_i8(i8 %a) nounwind {
1289 ; RV64I-LABEL: sext_ashr_zext_i8:
1290 ; RV64I:       # %bb.0:
1291 ; RV64I-NEXT:    slli a0, a0, 24
1292 ; RV64I-NEXT:    sraiw a0, a0, 31
1293 ; RV64I-NEXT:    slli a0, a0, 32
1294 ; RV64I-NEXT:    srli a0, a0, 32
1295 ; RV64I-NEXT:    ret
1297 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i8:
1298 ; RV64ZBANOZBB:       # %bb.0:
1299 ; RV64ZBANOZBB-NEXT:    slli a0, a0, 24
1300 ; RV64ZBANOZBB-NEXT:    sraiw a0, a0, 31
1301 ; RV64ZBANOZBB-NEXT:    zext.w a0, a0
1302 ; RV64ZBANOZBB-NEXT:    ret
1304 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i8:
1305 ; RV64ZBAZBB:       # %bb.0:
1306 ; RV64ZBAZBB-NEXT:    sext.b a0, a0
1307 ; RV64ZBAZBB-NEXT:    sraiw a0, a0, 9
1308 ; RV64ZBAZBB-NEXT:    zext.w a0, a0
1309 ; RV64ZBAZBB-NEXT:    ret
1310   %ext = sext i8 %a to i32
1311   %1 = ashr i32 %ext, 9
1312   ret i32 %1
1315 ; Make sure we use sext.h+slli+srli for Zba+Zbb.
1316 ; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
1317 define zeroext i32 @sext_ashr_zext_i16(i16 %a) nounwind {
1318 ; RV64I-LABEL: sext_ashr_zext_i16:
1319 ; RV64I:       # %bb.0:
1320 ; RV64I-NEXT:    slli a0, a0, 16
1321 ; RV64I-NEXT:    sraiw a0, a0, 25
1322 ; RV64I-NEXT:    slli a0, a0, 32
1323 ; RV64I-NEXT:    srli a0, a0, 32
1324 ; RV64I-NEXT:    ret
1326 ; RV64ZBANOZBB-LABEL: sext_ashr_zext_i16:
1327 ; RV64ZBANOZBB:       # %bb.0:
1328 ; RV64ZBANOZBB-NEXT:    slli a0, a0, 16
1329 ; RV64ZBANOZBB-NEXT:    sraiw a0, a0, 25
1330 ; RV64ZBANOZBB-NEXT:    zext.w a0, a0
1331 ; RV64ZBANOZBB-NEXT:    ret
1333 ; RV64ZBAZBB-LABEL: sext_ashr_zext_i16:
1334 ; RV64ZBAZBB:       # %bb.0:
1335 ; RV64ZBAZBB-NEXT:    slli a0, a0, 48
1336 ; RV64ZBAZBB-NEXT:    srai a0, a0, 57
1337 ; RV64ZBAZBB-NEXT:    zext.w a0, a0
1338 ; RV64ZBAZBB-NEXT:    ret
1339   %ext = sext i16 %a to i32
1340   %1 = ashr i32 %ext, 9
1341   ret i32 %1
1344 ; This the IR you get from InstCombine if take the difference of 2 pointers and
1345 ; cast is to unsigned before using as an index.
1346 define signext i16 @sh1adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1347 ; RV64I-LABEL: sh1adduw_ptrdiff:
1348 ; RV64I:       # %bb.0:
1349 ; RV64I-NEXT:    li a2, 1
1350 ; RV64I-NEXT:    slli a2, a2, 33
1351 ; RV64I-NEXT:    addi a2, a2, -2
1352 ; RV64I-NEXT:    and a0, a0, a2
1353 ; RV64I-NEXT:    add a0, a1, a0
1354 ; RV64I-NEXT:    lh a0, 0(a0)
1355 ; RV64I-NEXT:    ret
1357 ; RV64ZBA-LABEL: sh1adduw_ptrdiff:
1358 ; RV64ZBA:       # %bb.0:
1359 ; RV64ZBA-NEXT:    srli a0, a0, 1
1360 ; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
1361 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1362 ; RV64ZBA-NEXT:    ret
1363   %ptrdiff = lshr exact i64 %diff, 1
1364   %cast = and i64 %ptrdiff, 4294967295
1365   %ptr = getelementptr inbounds i16, ptr %baseptr, i64 %cast
1366   %res = load i16, ptr %ptr
1367   ret i16 %res
1370 define signext i32 @sh2adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1371 ; RV64I-LABEL: sh2adduw_ptrdiff:
1372 ; RV64I:       # %bb.0:
1373 ; RV64I-NEXT:    li a2, 1
1374 ; RV64I-NEXT:    slli a2, a2, 34
1375 ; RV64I-NEXT:    addi a2, a2, -4
1376 ; RV64I-NEXT:    and a0, a0, a2
1377 ; RV64I-NEXT:    add a0, a1, a0
1378 ; RV64I-NEXT:    lw a0, 0(a0)
1379 ; RV64I-NEXT:    ret
1381 ; RV64ZBA-LABEL: sh2adduw_ptrdiff:
1382 ; RV64ZBA:       # %bb.0:
1383 ; RV64ZBA-NEXT:    srli a0, a0, 2
1384 ; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
1385 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1386 ; RV64ZBA-NEXT:    ret
1387   %ptrdiff = lshr exact i64 %diff, 2
1388   %cast = and i64 %ptrdiff, 4294967295
1389   %ptr = getelementptr inbounds i32, ptr %baseptr, i64 %cast
1390   %res = load i32, ptr %ptr
1391   ret i32 %res
1394 define i64 @sh3adduw_ptrdiff(i64 %diff, ptr %baseptr) {
1395 ; RV64I-LABEL: sh3adduw_ptrdiff:
1396 ; RV64I:       # %bb.0:
1397 ; RV64I-NEXT:    li a2, 1
1398 ; RV64I-NEXT:    slli a2, a2, 35
1399 ; RV64I-NEXT:    addi a2, a2, -8
1400 ; RV64I-NEXT:    and a0, a0, a2
1401 ; RV64I-NEXT:    add a0, a1, a0
1402 ; RV64I-NEXT:    ld a0, 0(a0)
1403 ; RV64I-NEXT:    ret
1405 ; RV64ZBA-LABEL: sh3adduw_ptrdiff:
1406 ; RV64ZBA:       # %bb.0:
1407 ; RV64ZBA-NEXT:    srli a0, a0, 3
1408 ; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
1409 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1410 ; RV64ZBA-NEXT:    ret
1411   %ptrdiff = lshr exact i64 %diff, 3
1412   %cast = and i64 %ptrdiff, 4294967295
1413   %ptr = getelementptr inbounds i64, ptr %baseptr, i64 %cast
1414   %res = load i64, ptr %ptr
1415   ret i64 %res
1418 define signext i16 @srliw_1_sh1add(ptr %0, i32 signext %1) {
1419 ; RV64I-LABEL: srliw_1_sh1add:
1420 ; RV64I:       # %bb.0:
1421 ; RV64I-NEXT:    srliw a1, a1, 1
1422 ; RV64I-NEXT:    slli a1, a1, 1
1423 ; RV64I-NEXT:    add a0, a0, a1
1424 ; RV64I-NEXT:    lh a0, 0(a0)
1425 ; RV64I-NEXT:    ret
1427 ; RV64ZBA-LABEL: srliw_1_sh1add:
1428 ; RV64ZBA:       # %bb.0:
1429 ; RV64ZBA-NEXT:    srliw a1, a1, 1
1430 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1431 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1432 ; RV64ZBA-NEXT:    ret
1433   %3 = lshr i32 %1, 1
1434   %4 = zext i32 %3 to i64
1435   %5 = getelementptr inbounds i16, ptr %0, i64 %4
1436   %6 = load i16, ptr %5, align 2
1437   ret i16 %6
1440 define i128 @slliuw_ptrdiff(i64 %diff, ptr %baseptr) {
1441 ; RV64I-LABEL: slliuw_ptrdiff:
1442 ; RV64I:       # %bb.0:
1443 ; RV64I-NEXT:    li a2, 1
1444 ; RV64I-NEXT:    slli a2, a2, 36
1445 ; RV64I-NEXT:    addi a2, a2, -16
1446 ; RV64I-NEXT:    and a0, a0, a2
1447 ; RV64I-NEXT:    add a1, a1, a0
1448 ; RV64I-NEXT:    ld a0, 0(a1)
1449 ; RV64I-NEXT:    ld a1, 8(a1)
1450 ; RV64I-NEXT:    ret
1452 ; RV64ZBA-LABEL: slliuw_ptrdiff:
1453 ; RV64ZBA:       # %bb.0:
1454 ; RV64ZBA-NEXT:    srli a0, a0, 4
1455 ; RV64ZBA-NEXT:    slli.uw a0, a0, 4
1456 ; RV64ZBA-NEXT:    add a1, a1, a0
1457 ; RV64ZBA-NEXT:    ld a0, 0(a1)
1458 ; RV64ZBA-NEXT:    ld a1, 8(a1)
1459 ; RV64ZBA-NEXT:    ret
1460   %ptrdiff = lshr exact i64 %diff, 4
1461   %cast = and i64 %ptrdiff, 4294967295
1462   %ptr = getelementptr inbounds i128, ptr %baseptr, i64 %cast
1463   %res = load i128, ptr %ptr
1464   ret i128 %res
1467 define signext i32 @srliw_2_sh2add(ptr %0, i32 signext %1) {
1468 ; RV64I-LABEL: srliw_2_sh2add:
1469 ; RV64I:       # %bb.0:
1470 ; RV64I-NEXT:    srliw a1, a1, 2
1471 ; RV64I-NEXT:    slli a1, a1, 2
1472 ; RV64I-NEXT:    add a0, a0, a1
1473 ; RV64I-NEXT:    lw a0, 0(a0)
1474 ; RV64I-NEXT:    ret
1476 ; RV64ZBA-LABEL: srliw_2_sh2add:
1477 ; RV64ZBA:       # %bb.0:
1478 ; RV64ZBA-NEXT:    srliw a1, a1, 2
1479 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1480 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1481 ; RV64ZBA-NEXT:    ret
1482   %3 = lshr i32 %1, 2
1483   %4 = zext i32 %3 to i64
1484   %5 = getelementptr inbounds i32, ptr %0, i64 %4
1485   %6 = load i32, ptr %5, align 4
1486   ret i32 %6
1489 define i64 @srliw_3_sh3add(ptr %0, i32 signext %1) {
1490 ; RV64I-LABEL: srliw_3_sh3add:
1491 ; RV64I:       # %bb.0:
1492 ; RV64I-NEXT:    srliw a1, a1, 3
1493 ; RV64I-NEXT:    slli a1, a1, 3
1494 ; RV64I-NEXT:    add a0, a0, a1
1495 ; RV64I-NEXT:    ld a0, 0(a0)
1496 ; RV64I-NEXT:    ret
1498 ; RV64ZBA-LABEL: srliw_3_sh3add:
1499 ; RV64ZBA:       # %bb.0:
1500 ; RV64ZBA-NEXT:    srliw a1, a1, 3
1501 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1502 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1503 ; RV64ZBA-NEXT:    ret
1504   %3 = lshr i32 %1, 3
1505   %4 = zext i32 %3 to i64
1506   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1507   %6 = load i64, ptr %5, align 8
1508   ret i64 %6
1511 define signext i32 @srliw_1_sh2add(ptr %0, i32 signext %1) {
1512 ; RV64I-LABEL: srliw_1_sh2add:
1513 ; RV64I:       # %bb.0:
1514 ; RV64I-NEXT:    srliw a1, a1, 1
1515 ; RV64I-NEXT:    slli a1, a1, 32
1516 ; RV64I-NEXT:    srli a1, a1, 30
1517 ; RV64I-NEXT:    add a0, a0, a1
1518 ; RV64I-NEXT:    lw a0, 0(a0)
1519 ; RV64I-NEXT:    ret
1521 ; RV64ZBA-LABEL: srliw_1_sh2add:
1522 ; RV64ZBA:       # %bb.0:
1523 ; RV64ZBA-NEXT:    srliw a1, a1, 1
1524 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1525 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1526 ; RV64ZBA-NEXT:    ret
1527   %3 = lshr i32 %1, 1
1528   %4 = zext i32 %3 to i64
1529   %5 = getelementptr inbounds i32, ptr %0, i64 %4
1530   %6 = load i32, ptr %5, align 4
1531   ret i32 %6
1534 define i64 @srliw_1_sh3add(ptr %0, i32 signext %1) {
1535 ; RV64I-LABEL: srliw_1_sh3add:
1536 ; RV64I:       # %bb.0:
1537 ; RV64I-NEXT:    srliw a1, a1, 1
1538 ; RV64I-NEXT:    slli a1, a1, 32
1539 ; RV64I-NEXT:    srli a1, a1, 29
1540 ; RV64I-NEXT:    add a0, a0, a1
1541 ; RV64I-NEXT:    ld a0, 0(a0)
1542 ; RV64I-NEXT:    ret
1544 ; RV64ZBA-LABEL: srliw_1_sh3add:
1545 ; RV64ZBA:       # %bb.0:
1546 ; RV64ZBA-NEXT:    srliw a1, a1, 1
1547 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1548 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1549 ; RV64ZBA-NEXT:    ret
1550   %3 = lshr i32 %1, 1
1551   %4 = zext i32 %3 to i64
1552   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1553   %6 = load i64, ptr %5, align 8
1554   ret i64 %6
1557 define i64 @srliw_2_sh3add(ptr %0, i32 signext %1) {
1558 ; RV64I-LABEL: srliw_2_sh3add:
1559 ; RV64I:       # %bb.0:
1560 ; RV64I-NEXT:    srliw a1, a1, 2
1561 ; RV64I-NEXT:    slli a1, a1, 32
1562 ; RV64I-NEXT:    srli a1, a1, 29
1563 ; RV64I-NEXT:    add a0, a0, a1
1564 ; RV64I-NEXT:    ld a0, 0(a0)
1565 ; RV64I-NEXT:    ret
1567 ; RV64ZBA-LABEL: srliw_2_sh3add:
1568 ; RV64ZBA:       # %bb.0:
1569 ; RV64ZBA-NEXT:    srliw a1, a1, 2
1570 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1571 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1572 ; RV64ZBA-NEXT:    ret
1573   %3 = lshr i32 %1, 2
1574   %4 = zext i32 %3 to i64
1575   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1576   %6 = load i64, ptr %5, align 8
1577   ret i64 %6
1580 define signext i16 @srliw_2_sh1add(ptr %0, i32 signext %1) {
1581 ; RV64I-LABEL: srliw_2_sh1add:
1582 ; RV64I:       # %bb.0:
1583 ; RV64I-NEXT:    srliw a1, a1, 2
1584 ; RV64I-NEXT:    slli a1, a1, 32
1585 ; RV64I-NEXT:    srli a1, a1, 31
1586 ; RV64I-NEXT:    add a0, a0, a1
1587 ; RV64I-NEXT:    lh a0, 0(a0)
1588 ; RV64I-NEXT:    ret
1590 ; RV64ZBA-LABEL: srliw_2_sh1add:
1591 ; RV64ZBA:       # %bb.0:
1592 ; RV64ZBA-NEXT:    srliw a1, a1, 2
1593 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1594 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1595 ; RV64ZBA-NEXT:    ret
1596   %3 = lshr i32 %1, 2
1597   %4 = zext i32 %3 to i64
1598   %5 = getelementptr inbounds i16, ptr %0, i64 %4
1599   %6 = load i16, ptr %5, align 2
1600   ret i16 %6
1604 define signext i32 @srliw_3_sh2add(ptr %0, i32 signext %1) {
1605 ; RV64I-LABEL: srliw_3_sh2add:
1606 ; RV64I:       # %bb.0:
1607 ; RV64I-NEXT:    srliw a1, a1, 3
1608 ; RV64I-NEXT:    slli a1, a1, 32
1609 ; RV64I-NEXT:    srli a1, a1, 30
1610 ; RV64I-NEXT:    add a0, a0, a1
1611 ; RV64I-NEXT:    lw a0, 0(a0)
1612 ; RV64I-NEXT:    ret
1614 ; RV64ZBA-LABEL: srliw_3_sh2add:
1615 ; RV64ZBA:       # %bb.0:
1616 ; RV64ZBA-NEXT:    srliw a1, a1, 3
1617 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1618 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1619 ; RV64ZBA-NEXT:    ret
1620   %3 = lshr i32 %1, 3
1621   %4 = zext i32 %3 to i64
1622   %5 = getelementptr inbounds i32, ptr %0, i64 %4
1623   %6 = load i32, ptr %5, align 4
1624   ret i32 %6
1627 define i64 @srliw_4_sh3add(ptr %0, i32 signext %1) {
1628 ; RV64I-LABEL: srliw_4_sh3add:
1629 ; RV64I:       # %bb.0:
1630 ; RV64I-NEXT:    srliw a1, a1, 4
1631 ; RV64I-NEXT:    slli a1, a1, 32
1632 ; RV64I-NEXT:    srli a1, a1, 29
1633 ; RV64I-NEXT:    add a0, a0, a1
1634 ; RV64I-NEXT:    ld a0, 0(a0)
1635 ; RV64I-NEXT:    ret
1637 ; RV64ZBA-LABEL: srliw_4_sh3add:
1638 ; RV64ZBA:       # %bb.0:
1639 ; RV64ZBA-NEXT:    srliw a1, a1, 4
1640 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1641 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1642 ; RV64ZBA-NEXT:    ret
1643   %3 = lshr i32 %1, 4
1644   %4 = zext i32 %3 to i64
1645   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1646   %6 = load i64, ptr %5, align 8
1647   ret i64 %6
1650 define signext i32 @srli_1_sh2add(ptr %0, i64 %1) {
1651 ; RV64I-LABEL: srli_1_sh2add:
1652 ; RV64I:       # %bb.0:
1653 ; RV64I-NEXT:    slli a1, a1, 1
1654 ; RV64I-NEXT:    andi a1, a1, -4
1655 ; RV64I-NEXT:    add a0, a0, a1
1656 ; RV64I-NEXT:    lw a0, 0(a0)
1657 ; RV64I-NEXT:    ret
1659 ; RV64ZBA-LABEL: srli_1_sh2add:
1660 ; RV64ZBA:       # %bb.0:
1661 ; RV64ZBA-NEXT:    srli a1, a1, 1
1662 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1663 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1664 ; RV64ZBA-NEXT:    ret
1665   %3 = lshr i64 %1, 1
1666   %4 = getelementptr inbounds i32, ptr %0, i64 %3
1667   %5 = load i32, ptr %4, align 4
1668   ret i32 %5
1671 define i64 @srli_2_sh3add(ptr %0, i64 %1) {
1672 ; RV64I-LABEL: srli_2_sh3add:
1673 ; RV64I:       # %bb.0:
1674 ; RV64I-NEXT:    slli a1, a1, 1
1675 ; RV64I-NEXT:    andi a1, a1, -8
1676 ; RV64I-NEXT:    add a0, a0, a1
1677 ; RV64I-NEXT:    ld a0, 0(a0)
1678 ; RV64I-NEXT:    ret
1680 ; RV64ZBA-LABEL: srli_2_sh3add:
1681 ; RV64ZBA:       # %bb.0:
1682 ; RV64ZBA-NEXT:    srli a1, a1, 2
1683 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1684 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1685 ; RV64ZBA-NEXT:    ret
1686   %3 = lshr i64 %1, 2
1687   %4 = getelementptr inbounds i64, ptr %0, i64 %3
1688   %5 = load i64, ptr %4, align 8
1689   ret i64 %5
1692 define signext i16 @srli_2_sh1add(ptr %0, i64 %1) {
1693 ; RV64I-LABEL: srli_2_sh1add:
1694 ; RV64I:       # %bb.0:
1695 ; RV64I-NEXT:    srli a1, a1, 1
1696 ; RV64I-NEXT:    andi a1, a1, -2
1697 ; RV64I-NEXT:    add a0, a0, a1
1698 ; RV64I-NEXT:    lh a0, 0(a0)
1699 ; RV64I-NEXT:    ret
1701 ; RV64ZBA-LABEL: srli_2_sh1add:
1702 ; RV64ZBA:       # %bb.0:
1703 ; RV64ZBA-NEXT:    srli a1, a1, 2
1704 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1705 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1706 ; RV64ZBA-NEXT:    ret
1707   %3 = lshr i64 %1, 2
1708   %4 = getelementptr inbounds i16, ptr %0, i64 %3
1709   %5 = load i16, ptr %4, align 2
1710   ret i16 %5
1713 define signext i32 @srli_3_sh2add(ptr %0, i64 %1) {
1714 ; RV64I-LABEL: srli_3_sh2add:
1715 ; RV64I:       # %bb.0:
1716 ; RV64I-NEXT:    srli a1, a1, 1
1717 ; RV64I-NEXT:    andi a1, a1, -4
1718 ; RV64I-NEXT:    add a0, a0, a1
1719 ; RV64I-NEXT:    lw a0, 0(a0)
1720 ; RV64I-NEXT:    ret
1722 ; RV64ZBA-LABEL: srli_3_sh2add:
1723 ; RV64ZBA:       # %bb.0:
1724 ; RV64ZBA-NEXT:    srli a1, a1, 3
1725 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1726 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1727 ; RV64ZBA-NEXT:    ret
1728   %3 = lshr i64 %1, 3
1729   %4 = getelementptr inbounds i32, ptr %0, i64 %3
1730   %5 = load i32, ptr %4, align 4
1731   ret i32 %5
1734 define i64 @srli_4_sh3add(ptr %0, i64 %1) {
1735 ; RV64I-LABEL: srli_4_sh3add:
1736 ; RV64I:       # %bb.0:
1737 ; RV64I-NEXT:    srli a1, a1, 1
1738 ; RV64I-NEXT:    andi a1, a1, -8
1739 ; RV64I-NEXT:    add a0, a0, a1
1740 ; RV64I-NEXT:    ld a0, 0(a0)
1741 ; RV64I-NEXT:    ret
1743 ; RV64ZBA-LABEL: srli_4_sh3add:
1744 ; RV64ZBA:       # %bb.0:
1745 ; RV64ZBA-NEXT:    srli a1, a1, 4
1746 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1747 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1748 ; RV64ZBA-NEXT:    ret
1749   %3 = lshr i64 %1, 4
1750   %4 = getelementptr inbounds i64, ptr %0, i64 %3
1751   %5 = load i64, ptr %4, align 8
1752   ret i64 %5
1755 define signext i16 @shl_2_sh1add(ptr %0, i32 signext %1) {
1756 ; RV64I-LABEL: shl_2_sh1add:
1757 ; RV64I:       # %bb.0:
1758 ; RV64I-NEXT:    slli a1, a1, 2
1759 ; RV64I-NEXT:    slli a1, a1, 32
1760 ; RV64I-NEXT:    srli a1, a1, 31
1761 ; RV64I-NEXT:    add a0, a0, a1
1762 ; RV64I-NEXT:    lh a0, 0(a0)
1763 ; RV64I-NEXT:    ret
1765 ; RV64ZBA-LABEL: shl_2_sh1add:
1766 ; RV64ZBA:       # %bb.0:
1767 ; RV64ZBA-NEXT:    slli a1, a1, 2
1768 ; RV64ZBA-NEXT:    zext.w a1, a1
1769 ; RV64ZBA-NEXT:    sh1add a0, a1, a0
1770 ; RV64ZBA-NEXT:    lh a0, 0(a0)
1771 ; RV64ZBA-NEXT:    ret
1772   %3 = shl i32 %1, 2
1773   %4 = zext i32 %3 to i64
1774   %5 = getelementptr inbounds i16, ptr %0, i64 %4
1775   %6 = load i16, ptr %5, align 2
1776   ret i16 %6
1779 define signext i32 @shl_16_sh2add(ptr %0, i32 signext %1) {
1780 ; RV64I-LABEL: shl_16_sh2add:
1781 ; RV64I:       # %bb.0:
1782 ; RV64I-NEXT:    slli a1, a1, 16
1783 ; RV64I-NEXT:    slli a1, a1, 32
1784 ; RV64I-NEXT:    srli a1, a1, 30
1785 ; RV64I-NEXT:    add a0, a0, a1
1786 ; RV64I-NEXT:    lw a0, 0(a0)
1787 ; RV64I-NEXT:    ret
1789 ; RV64ZBA-LABEL: shl_16_sh2add:
1790 ; RV64ZBA:       # %bb.0:
1791 ; RV64ZBA-NEXT:    slli a1, a1, 16
1792 ; RV64ZBA-NEXT:    zext.w a1, a1
1793 ; RV64ZBA-NEXT:    sh2add a0, a1, a0
1794 ; RV64ZBA-NEXT:    lw a0, 0(a0)
1795 ; RV64ZBA-NEXT:    ret
1796   %3 = shl i32 %1, 16
1797   %4 = zext i32 %3 to i64
1798   %5 = getelementptr inbounds i32, ptr %0, i64 %4
1799   %6 = load i32, ptr %5, align 4
1800   ret i32 %6
1803 define i64 @shl_31_sh3add(ptr %0, i32 signext %1) {
1804 ; RV64I-LABEL: shl_31_sh3add:
1805 ; RV64I:       # %bb.0:
1806 ; RV64I-NEXT:    slli a1, a1, 31
1807 ; RV64I-NEXT:    slli a1, a1, 32
1808 ; RV64I-NEXT:    srli a1, a1, 29
1809 ; RV64I-NEXT:    add a0, a0, a1
1810 ; RV64I-NEXT:    ld a0, 0(a0)
1811 ; RV64I-NEXT:    ret
1813 ; RV64ZBA-LABEL: shl_31_sh3add:
1814 ; RV64ZBA:       # %bb.0:
1815 ; RV64ZBA-NEXT:    slli a1, a1, 31
1816 ; RV64ZBA-NEXT:    zext.w a1, a1
1817 ; RV64ZBA-NEXT:    sh3add a0, a1, a0
1818 ; RV64ZBA-NEXT:    ld a0, 0(a0)
1819 ; RV64ZBA-NEXT:    ret
1820   %3 = shl i32 %1, 31
1821   %4 = zext i32 %3 to i64
1822   %5 = getelementptr inbounds i64, ptr %0, i64 %4
1823   %6 = load i64, ptr %5, align 8
1824   ret i64 %6
1827 define i64 @pack_i64(i64 %a, i64 %b) nounwind {
1828 ; RV64I-LABEL: pack_i64:
1829 ; RV64I:       # %bb.0:
1830 ; RV64I-NEXT:    slli a0, a0, 32
1831 ; RV64I-NEXT:    srli a0, a0, 32
1832 ; RV64I-NEXT:    slli a1, a1, 32
1833 ; RV64I-NEXT:    or a0, a1, a0
1834 ; RV64I-NEXT:    ret
1836 ; RV64ZBA-LABEL: pack_i64:
1837 ; RV64ZBA:       # %bb.0:
1838 ; RV64ZBA-NEXT:    slli a1, a1, 32
1839 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
1840 ; RV64ZBA-NEXT:    ret
1841   %shl = and i64 %a, 4294967295
1842   %shl1 = shl i64 %b, 32
1843   %or = or i64 %shl1, %shl
1844   ret i64 %or
1847 define i64 @pack_i64_2(i32 signext %a, i32 signext %b) nounwind {
1848 ; RV64I-LABEL: pack_i64_2:
1849 ; RV64I:       # %bb.0:
1850 ; RV64I-NEXT:    slli a0, a0, 32
1851 ; RV64I-NEXT:    srli a0, a0, 32
1852 ; RV64I-NEXT:    slli a1, a1, 32
1853 ; RV64I-NEXT:    or a0, a1, a0
1854 ; RV64I-NEXT:    ret
1856 ; RV64ZBA-LABEL: pack_i64_2:
1857 ; RV64ZBA:       # %bb.0:
1858 ; RV64ZBA-NEXT:    slli a1, a1, 32
1859 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
1860 ; RV64ZBA-NEXT:    ret
1861   %zexta = zext i32 %a to i64
1862   %zextb = zext i32 %b to i64
1863   %shl1 = shl i64 %zextb, 32
1864   %or = or i64 %shl1, %zexta
1865   ret i64 %or
1868 define i64 @pack_i64_3(i32 signext %a, i32 signext %b) nounwind {
1869 ; RV64I-LABEL: pack_i64_3:
1870 ; RV64I:       # %bb.0:
1871 ; RV64I-NEXT:    addi a0, a0, 1
1872 ; RV64I-NEXT:    addi a1, a1, 1
1873 ; RV64I-NEXT:    slli a0, a0, 32
1874 ; RV64I-NEXT:    srli a0, a0, 32
1875 ; RV64I-NEXT:    slli a1, a1, 32
1876 ; RV64I-NEXT:    or a0, a1, a0
1877 ; RV64I-NEXT:    ret
1879 ; RV64ZBA-LABEL: pack_i64_3:
1880 ; RV64ZBA:       # %bb.0:
1881 ; RV64ZBA-NEXT:    addi a0, a0, 1
1882 ; RV64ZBA-NEXT:    addi a1, a1, 1
1883 ; RV64ZBA-NEXT:    slli a1, a1, 32
1884 ; RV64ZBA-NEXT:    add.uw a0, a0, a1
1885 ; RV64ZBA-NEXT:    ret
1886   %adda = add i32 %a, 1
1887   %addb = add i32 %b, 1
1888   %zexta = zext i32 %adda to i64
1889   %zextb = zext i32 %addb to i64
1890   %shl1 = shl i64 %zextb, 32
1891   %or = or i64 %shl1, %zexta
1892   ret i64 %or