xref: /llvm-project/llvm/test/CodeGen/RISCV/GlobalISel/rv64zba.ll (revision 537e0e1ff639ed4f8fa4dadbc84f4a6a12e1d20a)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv64 -global-isel -mattr=+m -verify-machineinstrs < %s \
3; RUN:   | FileCheck %s -check-prefixes=CHECK,RV64I
4; RUN: llc -mtriple=riscv64 -global-isel -mattr=+m,+zba -verify-machineinstrs < %s \
5; RUN:   | FileCheck %s -check-prefixes=CHECK,RV64ZBA,RV64ZBANOZBB
6; RUN: llc -mtriple=riscv64 -global-isel -mattr=+m,+zba,+zbb -verify-machineinstrs < %s \
7; RUN:   | FileCheck %s -check-prefixes=CHECK,RV64ZBA,RV64ZBAZBB
8
9define i64 @slliuw(i64 %a) nounwind {
10; RV64I-LABEL: slliuw:
11; RV64I:       # %bb.0:
12; RV64I-NEXT:    li a1, 1
13; RV64I-NEXT:    slli a1, a1, 33
14; RV64I-NEXT:    addi a1, a1, -2
15; RV64I-NEXT:    slli a0, a0, 1
16; RV64I-NEXT:    and a0, a0, a1
17; RV64I-NEXT:    ret
18;
19; RV64ZBA-LABEL: slliuw:
20; RV64ZBA:       # %bb.0:
21; RV64ZBA-NEXT:    slli a0, a0, 1
22; RV64ZBA-NEXT:    srli a0, a0, 1
23; RV64ZBA-NEXT:    slli.uw a0, a0, 1
24; RV64ZBA-NEXT:    ret
25  %conv1 = shl i64 %a, 1
26  %shl = and i64 %conv1, 8589934590
27  ret i64 %shl
28}
29
30define i128 @slliuw_2(i32 signext %0, ptr %1) {
31; RV64I-LABEL: slliuw_2:
32; RV64I:       # %bb.0:
33; RV64I-NEXT:    slli a0, a0, 32
34; RV64I-NEXT:    srli a0, a0, 28
35; RV64I-NEXT:    add a1, a1, a0
36; RV64I-NEXT:    ld a0, 0(a1)
37; RV64I-NEXT:    ld a1, 8(a1)
38; RV64I-NEXT:    ret
39;
40; RV64ZBA-LABEL: slliuw_2:
41; RV64ZBA:       # %bb.0:
42; RV64ZBA-NEXT:    slli.uw a0, a0, 4
43; RV64ZBA-NEXT:    add a1, a1, a0
44; RV64ZBA-NEXT:    ld a0, 0(a1)
45; RV64ZBA-NEXT:    ld a1, 8(a1)
46; RV64ZBA-NEXT:    ret
47  %3 = zext i32 %0 to i64
48  %4 = getelementptr inbounds i128, ptr %1, i64 %3
49  %5 = load i128, ptr %4
50  ret i128 %5
51}
52
53define i64 @adduw(i64 %a, i64 %b) nounwind {
54; RV64I-LABEL: adduw:
55; RV64I:       # %bb.0:
56; RV64I-NEXT:    slli a1, a1, 32
57; RV64I-NEXT:    srli a1, a1, 32
58; RV64I-NEXT:    add a0, a1, a0
59; RV64I-NEXT:    ret
60;
61; RV64ZBA-LABEL: adduw:
62; RV64ZBA:       # %bb.0:
63; RV64ZBA-NEXT:    add.uw a0, a1, a0
64; RV64ZBA-NEXT:    ret
65  %and = and i64 %b, 4294967295
66  %add = add i64 %and, %a
67  ret i64 %add
68}
69
70define signext i8 @adduw_2(i32 signext %0, ptr %1) {
71; RV64I-LABEL: adduw_2:
72; RV64I:       # %bb.0:
73; RV64I-NEXT:    slli a0, a0, 32
74; RV64I-NEXT:    srli a0, a0, 32
75; RV64I-NEXT:    add a0, a1, a0
76; RV64I-NEXT:    lb a0, 0(a0)
77; RV64I-NEXT:    ret
78;
79; RV64ZBA-LABEL: adduw_2:
80; RV64ZBA:       # %bb.0:
81; RV64ZBA-NEXT:    add.uw a0, a0, a1
82; RV64ZBA-NEXT:    lb a0, 0(a0)
83; RV64ZBA-NEXT:    ret
84  %3 = zext i32 %0 to i64
85  %4 = getelementptr inbounds i8, ptr %1, i64 %3
86  %5 = load i8, ptr %4
87  ret i8 %5
88}
89
90define i64 @zextw_i64(i64 %a) nounwind {
91; RV64I-LABEL: zextw_i64:
92; RV64I:       # %bb.0:
93; RV64I-NEXT:    slli a0, a0, 32
94; RV64I-NEXT:    srli a0, a0, 32
95; RV64I-NEXT:    ret
96;
97; RV64ZBA-LABEL: zextw_i64:
98; RV64ZBA:       # %bb.0:
99; RV64ZBA-NEXT:    zext.w a0, a0
100; RV64ZBA-NEXT:    ret
101  %and = and i64 %a, 4294967295
102  ret i64 %and
103}
104
105; This makes sure targetShrinkDemandedConstant changes the and immmediate to
106; allow zext.w or slli+srli.
107define i64 @zextw_demandedbits_i64(i64 %0) {
108; CHECK-LABEL: zextw_demandedbits_i64:
109; CHECK:       # %bb.0:
110; CHECK-NEXT:    srliw a0, a0, 1
111; CHECK-NEXT:    slli a0, a0, 1
112; CHECK-NEXT:    ori a0, a0, 1
113; CHECK-NEXT:    ret
114  %2 = and i64 %0, 4294967294
115  %3 = or i64 %2, 1
116  ret i64 %3
117}
118
119define signext i16 @sh1add(i64 %0, ptr %1) {
120; RV64I-LABEL: sh1add:
121; RV64I:       # %bb.0:
122; RV64I-NEXT:    slli a0, a0, 1
123; RV64I-NEXT:    add a0, a1, a0
124; RV64I-NEXT:    lh a0, 0(a0)
125; RV64I-NEXT:    ret
126;
127; RV64ZBA-LABEL: sh1add:
128; RV64ZBA:       # %bb.0:
129; RV64ZBA-NEXT:    sh1add a0, a0, a1
130; RV64ZBA-NEXT:    lh a0, 0(a0)
131; RV64ZBA-NEXT:    ret
132  %3 = getelementptr inbounds i16, ptr %1, i64 %0
133  %4 = load i16, ptr %3
134  ret i16 %4
135}
136
137define signext i32 @sh2add(i64 %0, ptr %1) {
138; RV64I-LABEL: sh2add:
139; RV64I:       # %bb.0:
140; RV64I-NEXT:    slli a0, a0, 2
141; RV64I-NEXT:    add a0, a1, a0
142; RV64I-NEXT:    lw a0, 0(a0)
143; RV64I-NEXT:    ret
144;
145; RV64ZBA-LABEL: sh2add:
146; RV64ZBA:       # %bb.0:
147; RV64ZBA-NEXT:    sh2add a0, a0, a1
148; RV64ZBA-NEXT:    lw a0, 0(a0)
149; RV64ZBA-NEXT:    ret
150  %3 = getelementptr inbounds i32, ptr %1, i64 %0
151  %4 = load i32, ptr %3
152  ret i32 %4
153}
154
155define i64 @sh3add(i64 %0, ptr %1) {
156; RV64I-LABEL: sh3add:
157; RV64I:       # %bb.0:
158; RV64I-NEXT:    slli a0, a0, 3
159; RV64I-NEXT:    add a0, a1, a0
160; RV64I-NEXT:    ld a0, 0(a0)
161; RV64I-NEXT:    ret
162;
163; RV64ZBA-LABEL: sh3add:
164; RV64ZBA:       # %bb.0:
165; RV64ZBA-NEXT:    sh3add a0, a0, a1
166; RV64ZBA-NEXT:    ld a0, 0(a0)
167; RV64ZBA-NEXT:    ret
168  %3 = getelementptr inbounds i64, ptr %1, i64 %0
169  %4 = load i64, ptr %3
170  ret i64 %4
171}
172
173define signext i16 @sh1adduw(i32 signext %0, ptr %1) {
174; RV64I-LABEL: sh1adduw:
175; RV64I:       # %bb.0:
176; RV64I-NEXT:    slli a0, a0, 32
177; RV64I-NEXT:    srli a0, a0, 31
178; RV64I-NEXT:    add a0, a1, a0
179; RV64I-NEXT:    lh a0, 0(a0)
180; RV64I-NEXT:    ret
181;
182; RV64ZBA-LABEL: sh1adduw:
183; RV64ZBA:       # %bb.0:
184; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
185; RV64ZBA-NEXT:    lh a0, 0(a0)
186; RV64ZBA-NEXT:    ret
187  %3 = zext i32 %0 to i64
188  %4 = getelementptr inbounds i16, ptr %1, i64 %3
189  %5 = load i16, ptr %4
190  ret i16 %5
191}
192
193define i64 @sh1adduw_2(i64 %0, i64 %1) {
194; RV64I-LABEL: sh1adduw_2:
195; RV64I:       # %bb.0:
196; RV64I-NEXT:    li a2, 1
197; RV64I-NEXT:    slli a2, a2, 33
198; RV64I-NEXT:    addi a2, a2, -2
199; RV64I-NEXT:    slli a0, a0, 1
200; RV64I-NEXT:    and a0, a0, a2
201; RV64I-NEXT:    add a0, a0, a1
202; RV64I-NEXT:    ret
203;
204; RV64ZBA-LABEL: sh1adduw_2:
205; RV64ZBA:       # %bb.0:
206; RV64ZBA-NEXT:    slli a0, a0, 1
207; RV64ZBA-NEXT:    srli a0, a0, 1
208; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
209; RV64ZBA-NEXT:    ret
210  %3 = shl i64 %0, 1
211  %4 = and i64 %3, 8589934590
212  %5 = add i64 %4, %1
213  ret i64 %5
214}
215
216define i64 @sh1adduw_3(i64 %0, i64 %1) {
217; RV64I-LABEL: sh1adduw_3:
218; RV64I:       # %bb.0:
219; RV64I-NEXT:    li a2, 1
220; RV64I-NEXT:    slli a2, a2, 33
221; RV64I-NEXT:    addi a2, a2, -2
222; RV64I-NEXT:    slli a0, a0, 1
223; RV64I-NEXT:    and a0, a0, a2
224; RV64I-NEXT:    or a0, a0, a1
225; RV64I-NEXT:    ret
226;
227; RV64ZBA-LABEL: sh1adduw_3:
228; RV64ZBA:       # %bb.0:
229; RV64ZBA-NEXT:    slli a0, a0, 1
230; RV64ZBA-NEXT:    srli a0, a0, 1
231; RV64ZBA-NEXT:    slli.uw a0, a0, 1
232; RV64ZBA-NEXT:    or a0, a0, a1
233; RV64ZBA-NEXT:    ret
234  %3 = shl i64 %0, 1
235  %4 = and i64 %3, 8589934590
236  %5 = or disjoint i64 %4, %1
237  ret i64 %5
238}
239
240define signext i32 @sh2adduw(i32 signext %0, ptr %1) {
241; RV64I-LABEL: sh2adduw:
242; RV64I:       # %bb.0:
243; RV64I-NEXT:    slli a0, a0, 32
244; RV64I-NEXT:    srli a0, a0, 30
245; RV64I-NEXT:    add a0, a1, a0
246; RV64I-NEXT:    lw a0, 0(a0)
247; RV64I-NEXT:    ret
248;
249; RV64ZBA-LABEL: sh2adduw:
250; RV64ZBA:       # %bb.0:
251; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
252; RV64ZBA-NEXT:    lw a0, 0(a0)
253; RV64ZBA-NEXT:    ret
254  %3 = zext i32 %0 to i64
255  %4 = getelementptr inbounds i32, ptr %1, i64 %3
256  %5 = load i32, ptr %4
257  ret i32 %5
258}
259
260define i64 @sh2adduw_2(i64 %0, i64 %1) {
261; RV64I-LABEL: sh2adduw_2:
262; RV64I:       # %bb.0:
263; RV64I-NEXT:    li a2, 1
264; RV64I-NEXT:    slli a2, a2, 34
265; RV64I-NEXT:    addi a2, a2, -4
266; RV64I-NEXT:    slli a0, a0, 2
267; RV64I-NEXT:    and a0, a0, a2
268; RV64I-NEXT:    add a0, a0, a1
269; RV64I-NEXT:    ret
270;
271; RV64ZBA-LABEL: sh2adduw_2:
272; RV64ZBA:       # %bb.0:
273; RV64ZBA-NEXT:    slli a0, a0, 2
274; RV64ZBA-NEXT:    srli a0, a0, 2
275; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
276; RV64ZBA-NEXT:    ret
277  %3 = shl i64 %0, 2
278  %4 = and i64 %3, 17179869180
279  %5 = add i64 %4, %1
280  ret i64 %5
281}
282
283define i64 @sh2adduw_3(i64 %0, i64 %1) {
284; RV64I-LABEL: sh2adduw_3:
285; RV64I:       # %bb.0:
286; RV64I-NEXT:    li a2, 1
287; RV64I-NEXT:    slli a2, a2, 34
288; RV64I-NEXT:    addi a2, a2, -4
289; RV64I-NEXT:    slli a0, a0, 2
290; RV64I-NEXT:    and a0, a0, a2
291; RV64I-NEXT:    or a0, a0, a1
292; RV64I-NEXT:    ret
293;
294; RV64ZBA-LABEL: sh2adduw_3:
295; RV64ZBA:       # %bb.0:
296; RV64ZBA-NEXT:    slli a0, a0, 2
297; RV64ZBA-NEXT:    srli a0, a0, 2
298; RV64ZBA-NEXT:    slli.uw a0, a0, 2
299; RV64ZBA-NEXT:    or a0, a0, a1
300; RV64ZBA-NEXT:    ret
301  %3 = shl i64 %0, 2
302  %4 = and i64 %3, 17179869180
303  %5 = or disjoint i64 %4, %1
304  ret i64 %5
305}
306
307define i64 @sh3adduw(i32 signext %0, ptr %1) {
308; RV64I-LABEL: sh3adduw:
309; RV64I:       # %bb.0:
310; RV64I-NEXT:    slli a0, a0, 32
311; RV64I-NEXT:    srli a0, a0, 29
312; RV64I-NEXT:    add a0, a1, a0
313; RV64I-NEXT:    ld a0, 0(a0)
314; RV64I-NEXT:    ret
315;
316; RV64ZBA-LABEL: sh3adduw:
317; RV64ZBA:       # %bb.0:
318; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
319; RV64ZBA-NEXT:    ld a0, 0(a0)
320; RV64ZBA-NEXT:    ret
321  %3 = zext i32 %0 to i64
322  %4 = getelementptr inbounds i64, ptr %1, i64 %3
323  %5 = load i64, ptr %4
324  ret i64 %5
325}
326
327define i64 @sh3adduw_2(i64 %0, i64 %1) {
328; RV64I-LABEL: sh3adduw_2:
329; RV64I:       # %bb.0:
330; RV64I-NEXT:    li a2, 1
331; RV64I-NEXT:    slli a2, a2, 35
332; RV64I-NEXT:    addi a2, a2, -8
333; RV64I-NEXT:    slli a0, a0, 3
334; RV64I-NEXT:    and a0, a0, a2
335; RV64I-NEXT:    add a0, a0, a1
336; RV64I-NEXT:    ret
337;
338; RV64ZBA-LABEL: sh3adduw_2:
339; RV64ZBA:       # %bb.0:
340; RV64ZBA-NEXT:    slli a0, a0, 3
341; RV64ZBA-NEXT:    srli a0, a0, 3
342; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
343; RV64ZBA-NEXT:    ret
344  %3 = shl i64 %0, 3
345  %4 = and i64 %3, 34359738360
346  %5 = add i64 %4, %1
347  ret i64 %5
348}
349
350define i64 @sh3adduw_3(i64 %0, i64 %1) {
351; RV64I-LABEL: sh3adduw_3:
352; RV64I:       # %bb.0:
353; RV64I-NEXT:    li a2, 1
354; RV64I-NEXT:    slli a2, a2, 35
355; RV64I-NEXT:    addi a2, a2, -8
356; RV64I-NEXT:    slli a0, a0, 3
357; RV64I-NEXT:    and a0, a0, a2
358; RV64I-NEXT:    or a0, a0, a1
359; RV64I-NEXT:    ret
360;
361; RV64ZBA-LABEL: sh3adduw_3:
362; RV64ZBA:       # %bb.0:
363; RV64ZBA-NEXT:    slli a0, a0, 3
364; RV64ZBA-NEXT:    srli a0, a0, 3
365; RV64ZBA-NEXT:    slli.uw a0, a0, 3
366; RV64ZBA-NEXT:    or a0, a0, a1
367; RV64ZBA-NEXT:    ret
368  %3 = shl i64 %0, 3
369  %4 = and i64 %3, 34359738360
370  %5 = or disjoint i64 %4, %1
371  ret i64 %5
372}
373
374; Make sure we use sext.h+slli+srli for Zba+Zbb.
375; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
376define zeroext i32 @sext_ashr_zext_i8(i8 %a) nounwind {
377; RV64I-LABEL: sext_ashr_zext_i8:
378; RV64I:       # %bb.0:
379; RV64I-NEXT:    slli a0, a0, 56
380; RV64I-NEXT:    srai a0, a0, 63
381; RV64I-NEXT:    slli a0, a0, 32
382; RV64I-NEXT:    srli a0, a0, 32
383; RV64I-NEXT:    ret
384;
385; RV64ZBANOZBB-LABEL: sext_ashr_zext_i8:
386; RV64ZBANOZBB:       # %bb.0:
387; RV64ZBANOZBB-NEXT:    slli a0, a0, 56
388; RV64ZBANOZBB-NEXT:    srai a0, a0, 63
389; RV64ZBANOZBB-NEXT:    zext.w a0, a0
390; RV64ZBANOZBB-NEXT:    ret
391;
392; RV64ZBAZBB-LABEL: sext_ashr_zext_i8:
393; RV64ZBAZBB:       # %bb.0:
394; RV64ZBAZBB-NEXT:    sext.b a0, a0
395; RV64ZBAZBB-NEXT:    srai a0, a0, 9
396; RV64ZBAZBB-NEXT:    zext.w a0, a0
397; RV64ZBAZBB-NEXT:    ret
398  %ext = sext i8 %a to i32
399  %1 = ashr i32 %ext, 9
400  ret i32 %1
401}
402
403define i64 @sh6_sh3_add1(i64 noundef %x, i64 noundef %y, i64 noundef %z) {
404; RV64I-LABEL: sh6_sh3_add1:
405; RV64I:       # %bb.0: # %entry
406; RV64I-NEXT:    slli a2, a2, 3
407; RV64I-NEXT:    slli a1, a1, 6
408; RV64I-NEXT:    add a1, a1, a2
409; RV64I-NEXT:    add a0, a1, a0
410; RV64I-NEXT:    ret
411;
412; RV64ZBA-LABEL: sh6_sh3_add1:
413; RV64ZBA:       # %bb.0: # %entry
414; RV64ZBA-NEXT:    slli a1, a1, 6
415; RV64ZBA-NEXT:    sh3add a1, a2, a1
416; RV64ZBA-NEXT:    add a0, a1, a0
417; RV64ZBA-NEXT:    ret
418entry:
419  %shl = shl i64 %z, 3
420  %shl1 = shl i64 %y, 6
421  %add = add nsw i64 %shl1, %shl
422  %add2 = add nsw i64 %add, %x
423  ret i64 %add2
424}
425
426define i64 @sh6_sh3_add2(i64 noundef %x, i64 noundef %y, i64 noundef %z) {
427; RV64I-LABEL: sh6_sh3_add2:
428; RV64I:       # %bb.0: # %entry
429; RV64I-NEXT:    slli a2, a2, 3
430; RV64I-NEXT:    slli a1, a1, 6
431; RV64I-NEXT:    add a0, a1, a0
432; RV64I-NEXT:    add a0, a0, a2
433; RV64I-NEXT:    ret
434;
435; RV64ZBA-LABEL: sh6_sh3_add2:
436; RV64ZBA:       # %bb.0: # %entry
437; RV64ZBA-NEXT:    sh3add a1, a1, a2
438; RV64ZBA-NEXT:    sh3add a0, a1, a0
439; RV64ZBA-NEXT:    ret
440entry:
441  %shl = shl i64 %z, 3
442  %shl1 = shl i64 %y, 6
443  %add = add nsw i64 %shl1, %x
444  %add2 = add nsw i64 %add, %shl
445  ret i64 %add2
446}
447
448define i64 @sh6_sh3_add3(i64 noundef %x, i64 noundef %y, i64 noundef %z) {
449; RV64I-LABEL: sh6_sh3_add3:
450; RV64I:       # %bb.0: # %entry
451; RV64I-NEXT:    slli a2, a2, 3
452; RV64I-NEXT:    slli a1, a1, 6
453; RV64I-NEXT:    add a1, a1, a2
454; RV64I-NEXT:    add a0, a0, a1
455; RV64I-NEXT:    ret
456;
457; RV64ZBA-LABEL: sh6_sh3_add3:
458; RV64ZBA:       # %bb.0: # %entry
459; RV64ZBA-NEXT:    slli a1, a1, 6
460; RV64ZBA-NEXT:    sh3add a1, a2, a1
461; RV64ZBA-NEXT:    add a0, a0, a1
462; RV64ZBA-NEXT:    ret
463entry:
464  %shl = shl i64 %z, 3
465  %shl1 = shl i64 %y, 6
466  %add = add nsw i64 %shl1, %shl
467  %add2 = add nsw i64 %x, %add
468  ret i64 %add2
469}
470
471define i64 @sh6_sh3_add4(i64 noundef %x, i64 noundef %y, i64 noundef %z) {
472; RV64I-LABEL: sh6_sh3_add4:
473; RV64I:       # %bb.0: # %entry
474; RV64I-NEXT:    slli a2, a2, 3
475; RV64I-NEXT:    slli a1, a1, 6
476; RV64I-NEXT:    add a0, a0, a2
477; RV64I-NEXT:    add a0, a0, a1
478; RV64I-NEXT:    ret
479;
480; RV64ZBA-LABEL: sh6_sh3_add4:
481; RV64ZBA:       # %bb.0: # %entry
482; RV64ZBA-NEXT:    slli a1, a1, 6
483; RV64ZBA-NEXT:    sh3add a0, a2, a0
484; RV64ZBA-NEXT:    add a0, a0, a1
485; RV64ZBA-NEXT:    ret
486entry:
487  %shl = shl i64 %z, 3
488  %shl1 = shl i64 %y, 6
489  %add = add nsw i64 %x, %shl
490  %add2 = add nsw i64 %add, %shl1
491  ret i64 %add2
492}
493
494; Make sure we use sext.h+slli+srli for Zba+Zbb.
495; FIXME: The RV64I and Zba only cases can be done with only 3 shifts.
496define zeroext i32 @sext_ashr_zext_i16(i16 %a) nounwind {
497; RV64I-LABEL: sext_ashr_zext_i16:
498; RV64I:       # %bb.0:
499; RV64I-NEXT:    slli a0, a0, 48
500; RV64I-NEXT:    srai a0, a0, 57
501; RV64I-NEXT:    slli a0, a0, 32
502; RV64I-NEXT:    srli a0, a0, 32
503; RV64I-NEXT:    ret
504;
505; RV64ZBANOZBB-LABEL: sext_ashr_zext_i16:
506; RV64ZBANOZBB:       # %bb.0:
507; RV64ZBANOZBB-NEXT:    slli a0, a0, 48
508; RV64ZBANOZBB-NEXT:    srai a0, a0, 57
509; RV64ZBANOZBB-NEXT:    zext.w a0, a0
510; RV64ZBANOZBB-NEXT:    ret
511;
512; RV64ZBAZBB-LABEL: sext_ashr_zext_i16:
513; RV64ZBAZBB:       # %bb.0:
514; RV64ZBAZBB-NEXT:    sext.h a0, a0
515; RV64ZBAZBB-NEXT:    srai a0, a0, 9
516; RV64ZBAZBB-NEXT:    zext.w a0, a0
517; RV64ZBAZBB-NEXT:    ret
518  %ext = sext i16 %a to i32
519  %1 = ashr i32 %ext, 9
520  ret i32 %1
521}
522
523; This the IR you get from InstCombine if take the difference of 2 pointers and
524; cast is to unsigned before using as an index.
525define signext i16 @sh1adduw_ptrdiff(i64 %diff, ptr %baseptr) {
526; RV64I-LABEL: sh1adduw_ptrdiff:
527; RV64I:       # %bb.0:
528; RV64I-NEXT:    srli a0, a0, 1
529; RV64I-NEXT:    slli a0, a0, 32
530; RV64I-NEXT:    srli a0, a0, 31
531; RV64I-NEXT:    add a0, a1, a0
532; RV64I-NEXT:    lh a0, 0(a0)
533; RV64I-NEXT:    ret
534;
535; RV64ZBA-LABEL: sh1adduw_ptrdiff:
536; RV64ZBA:       # %bb.0:
537; RV64ZBA-NEXT:    srli a0, a0, 1
538; RV64ZBA-NEXT:    sh1add.uw a0, a0, a1
539; RV64ZBA-NEXT:    lh a0, 0(a0)
540; RV64ZBA-NEXT:    ret
541  %ptrdiff = lshr exact i64 %diff, 1
542  %cast = and i64 %ptrdiff, 4294967295
543  %ptr = getelementptr inbounds i16, ptr %baseptr, i64 %cast
544  %res = load i16, ptr %ptr
545  ret i16 %res
546}
547
548define signext i32 @sh2adduw_ptrdiff(i64 %diff, ptr %baseptr) {
549; RV64I-LABEL: sh2adduw_ptrdiff:
550; RV64I:       # %bb.0:
551; RV64I-NEXT:    srli a0, a0, 2
552; RV64I-NEXT:    slli a0, a0, 32
553; RV64I-NEXT:    srli a0, a0, 30
554; RV64I-NEXT:    add a0, a1, a0
555; RV64I-NEXT:    lw a0, 0(a0)
556; RV64I-NEXT:    ret
557;
558; RV64ZBA-LABEL: sh2adduw_ptrdiff:
559; RV64ZBA:       # %bb.0:
560; RV64ZBA-NEXT:    srli a0, a0, 2
561; RV64ZBA-NEXT:    sh2add.uw a0, a0, a1
562; RV64ZBA-NEXT:    lw a0, 0(a0)
563; RV64ZBA-NEXT:    ret
564  %ptrdiff = lshr exact i64 %diff, 2
565  %cast = and i64 %ptrdiff, 4294967295
566  %ptr = getelementptr inbounds i32, ptr %baseptr, i64 %cast
567  %res = load i32, ptr %ptr
568  ret i32 %res
569}
570
571define i64 @sh3adduw_ptrdiff(i64 %diff, ptr %baseptr) {
572; RV64I-LABEL: sh3adduw_ptrdiff:
573; RV64I:       # %bb.0:
574; RV64I-NEXT:    srli a0, a0, 3
575; RV64I-NEXT:    slli a0, a0, 32
576; RV64I-NEXT:    srli a0, a0, 29
577; RV64I-NEXT:    add a0, a1, a0
578; RV64I-NEXT:    ld a0, 0(a0)
579; RV64I-NEXT:    ret
580;
581; RV64ZBA-LABEL: sh3adduw_ptrdiff:
582; RV64ZBA:       # %bb.0:
583; RV64ZBA-NEXT:    srli a0, a0, 3
584; RV64ZBA-NEXT:    sh3add.uw a0, a0, a1
585; RV64ZBA-NEXT:    ld a0, 0(a0)
586; RV64ZBA-NEXT:    ret
587  %ptrdiff = lshr exact i64 %diff, 3
588  %cast = and i64 %ptrdiff, 4294967295
589  %ptr = getelementptr inbounds i64, ptr %baseptr, i64 %cast
590  %res = load i64, ptr %ptr
591  ret i64 %res
592}
593
594define signext i16 @srliw_1_sh1add(ptr %0, i32 signext %1) {
595; RV64I-LABEL: srliw_1_sh1add:
596; RV64I:       # %bb.0:
597; RV64I-NEXT:    srliw a1, a1, 1
598; RV64I-NEXT:    slli a1, a1, 1
599; RV64I-NEXT:    add a0, a0, a1
600; RV64I-NEXT:    lh a0, 0(a0)
601; RV64I-NEXT:    ret
602;
603; RV64ZBA-LABEL: srliw_1_sh1add:
604; RV64ZBA:       # %bb.0:
605; RV64ZBA-NEXT:    srliw a1, a1, 1
606; RV64ZBA-NEXT:    sh1add a0, a1, a0
607; RV64ZBA-NEXT:    lh a0, 0(a0)
608; RV64ZBA-NEXT:    ret
609  %3 = lshr i32 %1, 1
610  %4 = zext i32 %3 to i64
611  %5 = getelementptr inbounds i16, ptr %0, i64 %4
612  %6 = load i16, ptr %5, align 2
613  ret i16 %6
614}
615
616define i128 @slliuw_ptrdiff(i64 %diff, ptr %baseptr) {
617; RV64I-LABEL: slliuw_ptrdiff:
618; RV64I:       # %bb.0:
619; RV64I-NEXT:    srli a0, a0, 4
620; RV64I-NEXT:    slli a0, a0, 32
621; RV64I-NEXT:    srli a0, a0, 28
622; RV64I-NEXT:    add a1, a1, a0
623; RV64I-NEXT:    ld a0, 0(a1)
624; RV64I-NEXT:    ld a1, 8(a1)
625; RV64I-NEXT:    ret
626;
627; RV64ZBA-LABEL: slliuw_ptrdiff:
628; RV64ZBA:       # %bb.0:
629; RV64ZBA-NEXT:    srli a0, a0, 4
630; RV64ZBA-NEXT:    slli.uw a0, a0, 4
631; RV64ZBA-NEXT:    add a1, a1, a0
632; RV64ZBA-NEXT:    ld a0, 0(a1)
633; RV64ZBA-NEXT:    ld a1, 8(a1)
634; RV64ZBA-NEXT:    ret
635  %ptrdiff = lshr exact i64 %diff, 4
636  %cast = and i64 %ptrdiff, 4294967295
637  %ptr = getelementptr inbounds i128, ptr %baseptr, i64 %cast
638  %res = load i128, ptr %ptr
639  ret i128 %res
640}
641
642define signext i32 @srliw_2_sh2add(ptr %0, i32 signext %1) {
643; RV64I-LABEL: srliw_2_sh2add:
644; RV64I:       # %bb.0:
645; RV64I-NEXT:    srliw a1, a1, 2
646; RV64I-NEXT:    slli a1, a1, 2
647; RV64I-NEXT:    add a0, a0, a1
648; RV64I-NEXT:    lw a0, 0(a0)
649; RV64I-NEXT:    ret
650;
651; RV64ZBA-LABEL: srliw_2_sh2add:
652; RV64ZBA:       # %bb.0:
653; RV64ZBA-NEXT:    srliw a1, a1, 2
654; RV64ZBA-NEXT:    sh2add a0, a1, a0
655; RV64ZBA-NEXT:    lw a0, 0(a0)
656; RV64ZBA-NEXT:    ret
657  %3 = lshr i32 %1, 2
658  %4 = zext i32 %3 to i64
659  %5 = getelementptr inbounds i32, ptr %0, i64 %4
660  %6 = load i32, ptr %5, align 4
661  ret i32 %6
662}
663
664define i64 @srliw_3_sh3add(ptr %0, i32 signext %1) {
665; RV64I-LABEL: srliw_3_sh3add:
666; RV64I:       # %bb.0:
667; RV64I-NEXT:    srliw a1, a1, 3
668; RV64I-NEXT:    slli a1, a1, 3
669; RV64I-NEXT:    add a0, a0, a1
670; RV64I-NEXT:    ld a0, 0(a0)
671; RV64I-NEXT:    ret
672;
673; RV64ZBA-LABEL: srliw_3_sh3add:
674; RV64ZBA:       # %bb.0:
675; RV64ZBA-NEXT:    srliw a1, a1, 3
676; RV64ZBA-NEXT:    sh3add a0, a1, a0
677; RV64ZBA-NEXT:    ld a0, 0(a0)
678; RV64ZBA-NEXT:    ret
679  %3 = lshr i32 %1, 3
680  %4 = zext i32 %3 to i64
681  %5 = getelementptr inbounds i64, ptr %0, i64 %4
682  %6 = load i64, ptr %5, align 8
683  ret i64 %6
684}
685
686define signext i32 @srliw_1_sh2add(ptr %0, i32 signext %1) {
687; RV64I-LABEL: srliw_1_sh2add:
688; RV64I:       # %bb.0:
689; RV64I-NEXT:    srliw a1, a1, 1
690; RV64I-NEXT:    slli a1, a1, 2
691; RV64I-NEXT:    add a0, a0, a1
692; RV64I-NEXT:    lw a0, 0(a0)
693; RV64I-NEXT:    ret
694;
695; RV64ZBA-LABEL: srliw_1_sh2add:
696; RV64ZBA:       # %bb.0:
697; RV64ZBA-NEXT:    srliw a1, a1, 1
698; RV64ZBA-NEXT:    sh2add a0, a1, a0
699; RV64ZBA-NEXT:    lw a0, 0(a0)
700; RV64ZBA-NEXT:    ret
701  %3 = lshr i32 %1, 1
702  %4 = zext i32 %3 to i64
703  %5 = getelementptr inbounds i32, ptr %0, i64 %4
704  %6 = load i32, ptr %5, align 4
705  ret i32 %6
706}
707
708define i64 @srliw_1_sh3add(ptr %0, i32 signext %1) {
709; RV64I-LABEL: srliw_1_sh3add:
710; RV64I:       # %bb.0:
711; RV64I-NEXT:    srliw a1, a1, 1
712; RV64I-NEXT:    slli a1, a1, 3
713; RV64I-NEXT:    add a0, a0, a1
714; RV64I-NEXT:    ld a0, 0(a0)
715; RV64I-NEXT:    ret
716;
717; RV64ZBA-LABEL: srliw_1_sh3add:
718; RV64ZBA:       # %bb.0:
719; RV64ZBA-NEXT:    srliw a1, a1, 1
720; RV64ZBA-NEXT:    sh3add a0, a1, a0
721; RV64ZBA-NEXT:    ld a0, 0(a0)
722; RV64ZBA-NEXT:    ret
723  %3 = lshr i32 %1, 1
724  %4 = zext i32 %3 to i64
725  %5 = getelementptr inbounds i64, ptr %0, i64 %4
726  %6 = load i64, ptr %5, align 8
727  ret i64 %6
728}
729
730define i64 @srliw_2_sh3add(ptr %0, i32 signext %1) {
731; RV64I-LABEL: srliw_2_sh3add:
732; RV64I:       # %bb.0:
733; RV64I-NEXT:    srliw a1, a1, 2
734; RV64I-NEXT:    slli a1, a1, 3
735; RV64I-NEXT:    add a0, a0, a1
736; RV64I-NEXT:    ld a0, 0(a0)
737; RV64I-NEXT:    ret
738;
739; RV64ZBA-LABEL: srliw_2_sh3add:
740; RV64ZBA:       # %bb.0:
741; RV64ZBA-NEXT:    srliw a1, a1, 2
742; RV64ZBA-NEXT:    sh3add a0, a1, a0
743; RV64ZBA-NEXT:    ld a0, 0(a0)
744; RV64ZBA-NEXT:    ret
745  %3 = lshr i32 %1, 2
746  %4 = zext i32 %3 to i64
747  %5 = getelementptr inbounds i64, ptr %0, i64 %4
748  %6 = load i64, ptr %5, align 8
749  ret i64 %6
750}
751
752define signext i16 @srliw_2_sh1add(ptr %0, i32 signext %1) {
753; RV64I-LABEL: srliw_2_sh1add:
754; RV64I:       # %bb.0:
755; RV64I-NEXT:    srliw a1, a1, 2
756; RV64I-NEXT:    slli a1, a1, 1
757; RV64I-NEXT:    add a0, a0, a1
758; RV64I-NEXT:    lh a0, 0(a0)
759; RV64I-NEXT:    ret
760;
761; RV64ZBA-LABEL: srliw_2_sh1add:
762; RV64ZBA:       # %bb.0:
763; RV64ZBA-NEXT:    srliw a1, a1, 2
764; RV64ZBA-NEXT:    sh1add a0, a1, a0
765; RV64ZBA-NEXT:    lh a0, 0(a0)
766; RV64ZBA-NEXT:    ret
767  %3 = lshr i32 %1, 2
768  %4 = zext i32 %3 to i64
769  %5 = getelementptr inbounds i16, ptr %0, i64 %4
770  %6 = load i16, ptr %5, align 2
771  ret i16 %6
772}
773
774
775define signext i32 @srliw_3_sh2add(ptr %0, i32 signext %1) {
776; RV64I-LABEL: srliw_3_sh2add:
777; RV64I:       # %bb.0:
778; RV64I-NEXT:    srliw a1, a1, 3
779; RV64I-NEXT:    slli a1, a1, 2
780; RV64I-NEXT:    add a0, a0, a1
781; RV64I-NEXT:    lw a0, 0(a0)
782; RV64I-NEXT:    ret
783;
784; RV64ZBA-LABEL: srliw_3_sh2add:
785; RV64ZBA:       # %bb.0:
786; RV64ZBA-NEXT:    srliw a1, a1, 3
787; RV64ZBA-NEXT:    sh2add a0, a1, a0
788; RV64ZBA-NEXT:    lw a0, 0(a0)
789; RV64ZBA-NEXT:    ret
790  %3 = lshr i32 %1, 3
791  %4 = zext i32 %3 to i64
792  %5 = getelementptr inbounds i32, ptr %0, i64 %4
793  %6 = load i32, ptr %5, align 4
794  ret i32 %6
795}
796
797define i64 @srliw_4_sh3add(ptr %0, i32 signext %1) {
798; RV64I-LABEL: srliw_4_sh3add:
799; RV64I:       # %bb.0:
800; RV64I-NEXT:    srliw a1, a1, 4
801; RV64I-NEXT:    slli a1, a1, 3
802; RV64I-NEXT:    add a0, a0, a1
803; RV64I-NEXT:    ld a0, 0(a0)
804; RV64I-NEXT:    ret
805;
806; RV64ZBA-LABEL: srliw_4_sh3add:
807; RV64ZBA:       # %bb.0:
808; RV64ZBA-NEXT:    srliw a1, a1, 4
809; RV64ZBA-NEXT:    sh3add a0, a1, a0
810; RV64ZBA-NEXT:    ld a0, 0(a0)
811; RV64ZBA-NEXT:    ret
812  %3 = lshr i32 %1, 4
813  %4 = zext i32 %3 to i64
814  %5 = getelementptr inbounds i64, ptr %0, i64 %4
815  %6 = load i64, ptr %5, align 8
816  ret i64 %6
817}
818
819define signext i32 @srli_1_sh2add(ptr %0, i64 %1) {
820; RV64I-LABEL: srli_1_sh2add:
821; RV64I:       # %bb.0:
822; RV64I-NEXT:    srli a1, a1, 1
823; RV64I-NEXT:    slli a1, a1, 2
824; RV64I-NEXT:    add a0, a0, a1
825; RV64I-NEXT:    lw a0, 0(a0)
826; RV64I-NEXT:    ret
827;
828; RV64ZBA-LABEL: srli_1_sh2add:
829; RV64ZBA:       # %bb.0:
830; RV64ZBA-NEXT:    srli a1, a1, 1
831; RV64ZBA-NEXT:    sh2add a0, a1, a0
832; RV64ZBA-NEXT:    lw a0, 0(a0)
833; RV64ZBA-NEXT:    ret
834  %3 = lshr i64 %1, 1
835  %4 = getelementptr inbounds i32, ptr %0, i64 %3
836  %5 = load i32, ptr %4, align 4
837  ret i32 %5
838}
839
840define i64 @srli_2_sh3add(ptr %0, i64 %1) {
841; RV64I-LABEL: srli_2_sh3add:
842; RV64I:       # %bb.0:
843; RV64I-NEXT:    srli a1, a1, 2
844; RV64I-NEXT:    slli a1, a1, 3
845; RV64I-NEXT:    add a0, a0, a1
846; RV64I-NEXT:    ld a0, 0(a0)
847; RV64I-NEXT:    ret
848;
849; RV64ZBA-LABEL: srli_2_sh3add:
850; RV64ZBA:       # %bb.0:
851; RV64ZBA-NEXT:    srli a1, a1, 2
852; RV64ZBA-NEXT:    sh3add a0, a1, a0
853; RV64ZBA-NEXT:    ld a0, 0(a0)
854; RV64ZBA-NEXT:    ret
855  %3 = lshr i64 %1, 2
856  %4 = getelementptr inbounds i64, ptr %0, i64 %3
857  %5 = load i64, ptr %4, align 8
858  ret i64 %5
859}
860
861define signext i16 @srli_2_sh1add(ptr %0, i64 %1) {
862; RV64I-LABEL: srli_2_sh1add:
863; RV64I:       # %bb.0:
864; RV64I-NEXT:    srli a1, a1, 2
865; RV64I-NEXT:    slli a1, a1, 1
866; RV64I-NEXT:    add a0, a0, a1
867; RV64I-NEXT:    lh a0, 0(a0)
868; RV64I-NEXT:    ret
869;
870; RV64ZBA-LABEL: srli_2_sh1add:
871; RV64ZBA:       # %bb.0:
872; RV64ZBA-NEXT:    srli a1, a1, 2
873; RV64ZBA-NEXT:    sh1add a0, a1, a0
874; RV64ZBA-NEXT:    lh a0, 0(a0)
875; RV64ZBA-NEXT:    ret
876  %3 = lshr i64 %1, 2
877  %4 = getelementptr inbounds i16, ptr %0, i64 %3
878  %5 = load i16, ptr %4, align 2
879  ret i16 %5
880}
881
882define signext i32 @srli_3_sh2add(ptr %0, i64 %1) {
883; RV64I-LABEL: srli_3_sh2add:
884; RV64I:       # %bb.0:
885; RV64I-NEXT:    srli a1, a1, 3
886; RV64I-NEXT:    slli a1, a1, 2
887; RV64I-NEXT:    add a0, a0, a1
888; RV64I-NEXT:    lw a0, 0(a0)
889; RV64I-NEXT:    ret
890;
891; RV64ZBA-LABEL: srli_3_sh2add:
892; RV64ZBA:       # %bb.0:
893; RV64ZBA-NEXT:    srli a1, a1, 3
894; RV64ZBA-NEXT:    sh2add a0, a1, a0
895; RV64ZBA-NEXT:    lw a0, 0(a0)
896; RV64ZBA-NEXT:    ret
897  %3 = lshr i64 %1, 3
898  %4 = getelementptr inbounds i32, ptr %0, i64 %3
899  %5 = load i32, ptr %4, align 4
900  ret i32 %5
901}
902
903define i64 @srli_4_sh3add(ptr %0, i64 %1) {
904; RV64I-LABEL: srli_4_sh3add:
905; RV64I:       # %bb.0:
906; RV64I-NEXT:    srli a1, a1, 4
907; RV64I-NEXT:    slli a1, a1, 3
908; RV64I-NEXT:    add a0, a0, a1
909; RV64I-NEXT:    ld a0, 0(a0)
910; RV64I-NEXT:    ret
911;
912; RV64ZBA-LABEL: srli_4_sh3add:
913; RV64ZBA:       # %bb.0:
914; RV64ZBA-NEXT:    srli a1, a1, 4
915; RV64ZBA-NEXT:    sh3add a0, a1, a0
916; RV64ZBA-NEXT:    ld a0, 0(a0)
917; RV64ZBA-NEXT:    ret
918  %3 = lshr i64 %1, 4
919  %4 = getelementptr inbounds i64, ptr %0, i64 %3
920  %5 = load i64, ptr %4, align 8
921  ret i64 %5
922}
923
924define signext i16 @shl_2_sh1adduw(ptr %0, i32 signext %1) {
925; RV64I-LABEL: shl_2_sh1adduw:
926; RV64I:       # %bb.0:
927; RV64I-NEXT:    slli a1, a1, 2
928; RV64I-NEXT:    slli a1, a1, 32
929; RV64I-NEXT:    srli a1, a1, 31
930; RV64I-NEXT:    add a0, a0, a1
931; RV64I-NEXT:    lh a0, 0(a0)
932; RV64I-NEXT:    ret
933;
934; RV64ZBA-LABEL: shl_2_sh1adduw:
935; RV64ZBA:       # %bb.0:
936; RV64ZBA-NEXT:    slli a1, a1, 2
937; RV64ZBA-NEXT:    sh1add.uw a0, a1, a0
938; RV64ZBA-NEXT:    lh a0, 0(a0)
939; RV64ZBA-NEXT:    ret
940  %3 = shl i32 %1, 2
941  %4 = zext i32 %3 to i64
942  %5 = getelementptr inbounds i16, ptr %0, i64 %4
943  %6 = load i16, ptr %5, align 2
944  ret i16 %6
945}
946
947define signext i32 @shl_16_sh2adduw(ptr %0, i32 signext %1) {
948; RV64I-LABEL: shl_16_sh2adduw:
949; RV64I:       # %bb.0:
950; RV64I-NEXT:    slli a1, a1, 16
951; RV64I-NEXT:    slli a1, a1, 32
952; RV64I-NEXT:    srli a1, a1, 30
953; RV64I-NEXT:    add a0, a0, a1
954; RV64I-NEXT:    lw a0, 0(a0)
955; RV64I-NEXT:    ret
956;
957; RV64ZBA-LABEL: shl_16_sh2adduw:
958; RV64ZBA:       # %bb.0:
959; RV64ZBA-NEXT:    slli a1, a1, 16
960; RV64ZBA-NEXT:    sh2add.uw a0, a1, a0
961; RV64ZBA-NEXT:    lw a0, 0(a0)
962; RV64ZBA-NEXT:    ret
963  %3 = shl i32 %1, 16
964  %4 = zext i32 %3 to i64
965  %5 = getelementptr inbounds i32, ptr %0, i64 %4
966  %6 = load i32, ptr %5, align 4
967  ret i32 %6
968}
969
970define i64 @shl_31_sh3adduw(ptr %0, i32 signext %1) {
971; RV64I-LABEL: shl_31_sh3adduw:
972; RV64I:       # %bb.0:
973; RV64I-NEXT:    slli a1, a1, 31
974; RV64I-NEXT:    slli a1, a1, 32
975; RV64I-NEXT:    srli a1, a1, 29
976; RV64I-NEXT:    add a0, a0, a1
977; RV64I-NEXT:    ld a0, 0(a0)
978; RV64I-NEXT:    ret
979;
980; RV64ZBA-LABEL: shl_31_sh3adduw:
981; RV64ZBA:       # %bb.0:
982; RV64ZBA-NEXT:    slli a1, a1, 31
983; RV64ZBA-NEXT:    sh3add.uw a0, a1, a0
984; RV64ZBA-NEXT:    ld a0, 0(a0)
985; RV64ZBA-NEXT:    ret
986  %3 = shl i32 %1, 31
987  %4 = zext i32 %3 to i64
988  %5 = getelementptr inbounds i64, ptr %0, i64 %4
989  %6 = load i64, ptr %5, align 8
990  ret i64 %6
991}
992
993define i64 @pack_i64(i64 %a, i64 %b) nounwind {
994; RV64I-LABEL: pack_i64:
995; RV64I:       # %bb.0:
996; RV64I-NEXT:    slli a0, a0, 32
997; RV64I-NEXT:    srli a0, a0, 32
998; RV64I-NEXT:    slli a1, a1, 32
999; RV64I-NEXT:    or a0, a1, a0
1000; RV64I-NEXT:    ret
1001;
1002; RV64ZBA-LABEL: pack_i64:
1003; RV64ZBA:       # %bb.0:
1004; RV64ZBA-NEXT:    zext.w a0, a0
1005; RV64ZBA-NEXT:    slli a1, a1, 32
1006; RV64ZBA-NEXT:    or a0, a1, a0
1007; RV64ZBA-NEXT:    ret
1008  %shl = and i64 %a, 4294967295
1009  %shl1 = shl i64 %b, 32
1010  %or = or i64 %shl1, %shl
1011  ret i64 %or
1012}
1013
1014define i64 @pack_i64_2(i32 signext %a, i32 signext %b) nounwind {
1015; RV64I-LABEL: pack_i64_2:
1016; RV64I:       # %bb.0:
1017; RV64I-NEXT:    slli a0, a0, 32
1018; RV64I-NEXT:    slli a1, a1, 32
1019; RV64I-NEXT:    srli a0, a0, 32
1020; RV64I-NEXT:    srli a1, a1, 32
1021; RV64I-NEXT:    slli a1, a1, 32
1022; RV64I-NEXT:    or a0, a1, a0
1023; RV64I-NEXT:    ret
1024;
1025; RV64ZBA-LABEL: pack_i64_2:
1026; RV64ZBA:       # %bb.0:
1027; RV64ZBA-NEXT:    zext.w a0, a0
1028; RV64ZBA-NEXT:    zext.w a1, a1
1029; RV64ZBA-NEXT:    slli a1, a1, 32
1030; RV64ZBA-NEXT:    or a0, a1, a0
1031; RV64ZBA-NEXT:    ret
1032  %zexta = zext i32 %a to i64
1033  %zextb = zext i32 %b to i64
1034  %shl1 = shl i64 %zextb, 32
1035  %or = or i64 %shl1, %zexta
1036  ret i64 %or
1037}
1038
1039define i64 @pack_i64_disjoint(i64 %a, i64 %b) nounwind {
1040; RV64I-LABEL: pack_i64_disjoint:
1041; RV64I:       # %bb.0:
1042; RV64I-NEXT:    slli a0, a0, 32
1043; RV64I-NEXT:    srli a0, a0, 32
1044; RV64I-NEXT:    or a0, a1, a0
1045; RV64I-NEXT:    ret
1046;
1047; RV64ZBA-LABEL: pack_i64_disjoint:
1048; RV64ZBA:       # %bb.0:
1049; RV64ZBA-NEXT:    zext.w a0, a0
1050; RV64ZBA-NEXT:    or a0, a1, a0
1051; RV64ZBA-NEXT:    ret
1052  %shl = and i64 %a, 4294967295
1053  %or = or disjoint i64 %b, %shl
1054  ret i64 %or
1055}
1056
1057define i64 @pack_i64_disjoint_2(i32 signext %a, i64 %b) nounwind {
1058; RV64I-LABEL: pack_i64_disjoint_2:
1059; RV64I:       # %bb.0:
1060; RV64I-NEXT:    slli a0, a0, 32
1061; RV64I-NEXT:    srli a0, a0, 32
1062; RV64I-NEXT:    or a0, a1, a0
1063; RV64I-NEXT:    ret
1064;
1065; RV64ZBA-LABEL: pack_i64_disjoint_2:
1066; RV64ZBA:       # %bb.0:
1067; RV64ZBA-NEXT:    zext.w a0, a0
1068; RV64ZBA-NEXT:    or a0, a1, a0
1069; RV64ZBA-NEXT:    ret
1070  %zexta = zext i32 %a to i64
1071  %or = or disjoint i64 %b, %zexta
1072  ret i64 %or
1073}
1074
1075define i8 @array_index_sh1_sh0(ptr %p, i64 %idx1, i64 %idx2) {
1076; RV64I-LABEL: array_index_sh1_sh0:
1077; RV64I:       # %bb.0:
1078; RV64I-NEXT:    slli a1, a1, 1
1079; RV64I-NEXT:    add a0, a0, a2
1080; RV64I-NEXT:    add a0, a0, a1
1081; RV64I-NEXT:    lbu a0, 0(a0)
1082; RV64I-NEXT:    ret
1083;
1084; RV64ZBA-LABEL: array_index_sh1_sh0:
1085; RV64ZBA:       # %bb.0:
1086; RV64ZBA-NEXT:    sh1add a0, a1, a0
1087; RV64ZBA-NEXT:    add a0, a0, a2
1088; RV64ZBA-NEXT:    lbu a0, 0(a0)
1089; RV64ZBA-NEXT:    ret
1090  %a = getelementptr inbounds [2 x i8], ptr %p, i64 %idx1, i64 %idx2
1091  %b = load i8, ptr %a, align 1
1092  ret i8 %b
1093}
1094
1095define i16 @array_index_sh1_sh1(ptr %p, i64 %idx1, i64 %idx2) {
1096; RV64I-LABEL: array_index_sh1_sh1:
1097; RV64I:       # %bb.0:
1098; RV64I-NEXT:    slli a1, a1, 2
1099; RV64I-NEXT:    add a0, a0, a1
1100; RV64I-NEXT:    slli a2, a2, 1
1101; RV64I-NEXT:    add a0, a0, a2
1102; RV64I-NEXT:    lh a0, 0(a0)
1103; RV64I-NEXT:    ret
1104;
1105; RV64ZBA-LABEL: array_index_sh1_sh1:
1106; RV64ZBA:       # %bb.0:
1107; RV64ZBA-NEXT:    sh2add a0, a1, a0
1108; RV64ZBA-NEXT:    sh1add a0, a2, a0
1109; RV64ZBA-NEXT:    lh a0, 0(a0)
1110; RV64ZBA-NEXT:    ret
1111  %a = getelementptr inbounds [2 x i16], ptr %p, i64 %idx1, i64 %idx2
1112  %b = load i16, ptr %a, align 2
1113  ret i16 %b
1114}
1115
1116define i32 @array_index_sh1_sh2(ptr %p, i64 %idx1, i64 %idx2) {
1117; RV64I-LABEL: array_index_sh1_sh2:
1118; RV64I:       # %bb.0:
1119; RV64I-NEXT:    slli a1, a1, 3
1120; RV64I-NEXT:    add a0, a0, a1
1121; RV64I-NEXT:    slli a2, a2, 2
1122; RV64I-NEXT:    add a0, a0, a2
1123; RV64I-NEXT:    lw a0, 0(a0)
1124; RV64I-NEXT:    ret
1125;
1126; RV64ZBA-LABEL: array_index_sh1_sh2:
1127; RV64ZBA:       # %bb.0:
1128; RV64ZBA-NEXT:    sh3add a0, a1, a0
1129; RV64ZBA-NEXT:    sh2add a0, a2, a0
1130; RV64ZBA-NEXT:    lw a0, 0(a0)
1131; RV64ZBA-NEXT:    ret
1132  %a = getelementptr inbounds [2 x i32], ptr %p, i64 %idx1, i64 %idx2
1133  %b = load i32, ptr %a, align 4
1134  ret i32 %b
1135}
1136
1137define i64 @array_index_sh1_sh3(ptr %p, i64 %idx1, i64 %idx2) {
1138; RV64I-LABEL: array_index_sh1_sh3:
1139; RV64I:       # %bb.0:
1140; RV64I-NEXT:    slli a1, a1, 4
1141; RV64I-NEXT:    add a0, a0, a1
1142; RV64I-NEXT:    slli a2, a2, 3
1143; RV64I-NEXT:    add a0, a0, a2
1144; RV64I-NEXT:    ld a0, 0(a0)
1145; RV64I-NEXT:    ret
1146;
1147; RV64ZBA-LABEL: array_index_sh1_sh3:
1148; RV64ZBA:       # %bb.0:
1149; RV64ZBA-NEXT:    sh1add a1, a1, a2
1150; RV64ZBA-NEXT:    sh3add a0, a1, a0
1151; RV64ZBA-NEXT:    ld a0, 0(a0)
1152; RV64ZBA-NEXT:    ret
1153  %a = getelementptr inbounds [2 x i64], ptr %p, i64 %idx1, i64 %idx2
1154  %b = load i64, ptr %a, align 8
1155  ret i64 %b
1156}
1157
1158define i8 @array_index_sh2_sh0(ptr %p, i64 %idx1, i64 %idx2) {
1159; RV64I-LABEL: array_index_sh2_sh0:
1160; RV64I:       # %bb.0:
1161; RV64I-NEXT:    slli a1, a1, 2
1162; RV64I-NEXT:    add a0, a0, a2
1163; RV64I-NEXT:    add a0, a0, a1
1164; RV64I-NEXT:    lbu a0, 0(a0)
1165; RV64I-NEXT:    ret
1166;
1167; RV64ZBA-LABEL: array_index_sh2_sh0:
1168; RV64ZBA:       # %bb.0:
1169; RV64ZBA-NEXT:    sh2add a0, a1, a0
1170; RV64ZBA-NEXT:    add a0, a0, a2
1171; RV64ZBA-NEXT:    lbu a0, 0(a0)
1172; RV64ZBA-NEXT:    ret
1173  %a = getelementptr inbounds [4 x i8], ptr %p, i64 %idx1, i64 %idx2
1174  %b = load i8, ptr %a, align 1
1175  ret i8 %b
1176}
1177
1178define i16 @array_index_sh2_sh1(ptr %p, i64 %idx1, i64 %idx2) {
1179; RV64I-LABEL: array_index_sh2_sh1:
1180; RV64I:       # %bb.0:
1181; RV64I-NEXT:    slli a1, a1, 3
1182; RV64I-NEXT:    add a0, a0, a1
1183; RV64I-NEXT:    slli a2, a2, 1
1184; RV64I-NEXT:    add a0, a0, a2
1185; RV64I-NEXT:    lh a0, 0(a0)
1186; RV64I-NEXT:    ret
1187;
1188; RV64ZBA-LABEL: array_index_sh2_sh1:
1189; RV64ZBA:       # %bb.0:
1190; RV64ZBA-NEXT:    sh3add a0, a1, a0
1191; RV64ZBA-NEXT:    sh1add a0, a2, a0
1192; RV64ZBA-NEXT:    lh a0, 0(a0)
1193; RV64ZBA-NEXT:    ret
1194  %a = getelementptr inbounds [4 x i16], ptr %p, i64 %idx1, i64 %idx2
1195  %b = load i16, ptr %a, align 2
1196  ret i16 %b
1197}
1198
1199define i32 @array_index_sh2_sh2(ptr %p, i64 %idx1, i64 %idx2) {
1200; RV64I-LABEL: array_index_sh2_sh2:
1201; RV64I:       # %bb.0:
1202; RV64I-NEXT:    slli a1, a1, 4
1203; RV64I-NEXT:    add a0, a0, a1
1204; RV64I-NEXT:    slli a2, a2, 2
1205; RV64I-NEXT:    add a0, a0, a2
1206; RV64I-NEXT:    lw a0, 0(a0)
1207; RV64I-NEXT:    ret
1208;
1209; RV64ZBA-LABEL: array_index_sh2_sh2:
1210; RV64ZBA:       # %bb.0:
1211; RV64ZBA-NEXT:    sh2add a1, a1, a2
1212; RV64ZBA-NEXT:    sh2add a0, a1, a0
1213; RV64ZBA-NEXT:    lw a0, 0(a0)
1214; RV64ZBA-NEXT:    ret
1215  %a = getelementptr inbounds [4 x i32], ptr %p, i64 %idx1, i64 %idx2
1216  %b = load i32, ptr %a, align 4
1217  ret i32 %b
1218}
1219
1220define i64 @array_index_sh2_sh3(ptr %p, i64 %idx1, i64 %idx2) {
1221; RV64I-LABEL: array_index_sh2_sh3:
1222; RV64I:       # %bb.0:
1223; RV64I-NEXT:    slli a1, a1, 5
1224; RV64I-NEXT:    add a0, a0, a1
1225; RV64I-NEXT:    slli a2, a2, 3
1226; RV64I-NEXT:    add a0, a0, a2
1227; RV64I-NEXT:    ld a0, 0(a0)
1228; RV64I-NEXT:    ret
1229;
1230; RV64ZBA-LABEL: array_index_sh2_sh3:
1231; RV64ZBA:       # %bb.0:
1232; RV64ZBA-NEXT:    sh2add a1, a1, a2
1233; RV64ZBA-NEXT:    sh3add a0, a1, a0
1234; RV64ZBA-NEXT:    ld a0, 0(a0)
1235; RV64ZBA-NEXT:    ret
1236  %a = getelementptr inbounds [4 x i64], ptr %p, i64 %idx1, i64 %idx2
1237  %b = load i64, ptr %a, align 8
1238  ret i64 %b
1239}
1240
1241define i8 @array_index_sh3_sh0(ptr %p, i64 %idx1, i64 %idx2) {
1242; RV64I-LABEL: array_index_sh3_sh0:
1243; RV64I:       # %bb.0:
1244; RV64I-NEXT:    slli a1, a1, 3
1245; RV64I-NEXT:    add a0, a0, a2
1246; RV64I-NEXT:    add a0, a0, a1
1247; RV64I-NEXT:    lbu a0, 0(a0)
1248; RV64I-NEXT:    ret
1249;
1250; RV64ZBA-LABEL: array_index_sh3_sh0:
1251; RV64ZBA:       # %bb.0:
1252; RV64ZBA-NEXT:    sh3add a0, a1, a0
1253; RV64ZBA-NEXT:    add a0, a0, a2
1254; RV64ZBA-NEXT:    lbu a0, 0(a0)
1255; RV64ZBA-NEXT:    ret
1256  %a = getelementptr inbounds [8 x i8], ptr %p, i64 %idx1, i64 %idx2
1257  %b = load i8, ptr %a, align 1
1258  ret i8 %b
1259}
1260
1261define i16 @array_index_sh3_sh1(ptr %p, i64 %idx1, i64 %idx2) {
1262; RV64I-LABEL: array_index_sh3_sh1:
1263; RV64I:       # %bb.0:
1264; RV64I-NEXT:    slli a1, a1, 4
1265; RV64I-NEXT:    add a0, a0, a1
1266; RV64I-NEXT:    slli a2, a2, 1
1267; RV64I-NEXT:    add a0, a0, a2
1268; RV64I-NEXT:    lh a0, 0(a0)
1269; RV64I-NEXT:    ret
1270;
1271; RV64ZBA-LABEL: array_index_sh3_sh1:
1272; RV64ZBA:       # %bb.0:
1273; RV64ZBA-NEXT:    sh3add a1, a1, a2
1274; RV64ZBA-NEXT:    sh1add a0, a1, a0
1275; RV64ZBA-NEXT:    lh a0, 0(a0)
1276; RV64ZBA-NEXT:    ret
1277  %a = getelementptr inbounds [8 x i16], ptr %p, i64 %idx1, i64 %idx2
1278  %b = load i16, ptr %a, align 2
1279  ret i16 %b
1280}
1281
1282define i32 @array_index_sh3_sh2(ptr %p, i64 %idx1, i64 %idx2) {
1283; RV64I-LABEL: array_index_sh3_sh2:
1284; RV64I:       # %bb.0:
1285; RV64I-NEXT:    slli a1, a1, 5
1286; RV64I-NEXT:    add a0, a0, a1
1287; RV64I-NEXT:    slli a2, a2, 2
1288; RV64I-NEXT:    add a0, a0, a2
1289; RV64I-NEXT:    lw a0, 0(a0)
1290; RV64I-NEXT:    ret
1291;
1292; RV64ZBA-LABEL: array_index_sh3_sh2:
1293; RV64ZBA:       # %bb.0:
1294; RV64ZBA-NEXT:    sh3add a1, a1, a2
1295; RV64ZBA-NEXT:    sh2add a0, a1, a0
1296; RV64ZBA-NEXT:    lw a0, 0(a0)
1297; RV64ZBA-NEXT:    ret
1298  %a = getelementptr inbounds [8 x i32], ptr %p, i64 %idx1, i64 %idx2
1299  %b = load i32, ptr %a, align 4
1300  ret i32 %b
1301}
1302
1303define i64 @array_index_sh3_sh3(ptr %p, i64 %idx1, i64 %idx2) {
1304; RV64I-LABEL: array_index_sh3_sh3:
1305; RV64I:       # %bb.0:
1306; RV64I-NEXT:    slli a1, a1, 6
1307; RV64I-NEXT:    add a0, a0, a1
1308; RV64I-NEXT:    slli a2, a2, 3
1309; RV64I-NEXT:    add a0, a0, a2
1310; RV64I-NEXT:    ld a0, 0(a0)
1311; RV64I-NEXT:    ret
1312;
1313; RV64ZBA-LABEL: array_index_sh3_sh3:
1314; RV64ZBA:       # %bb.0:
1315; RV64ZBA-NEXT:    sh3add a1, a1, a2
1316; RV64ZBA-NEXT:    sh3add a0, a1, a0
1317; RV64ZBA-NEXT:    ld a0, 0(a0)
1318; RV64ZBA-NEXT:    ret
1319  %a = getelementptr inbounds [8 x i64], ptr %p, i64 %idx1, i64 %idx2
1320  %b = load i64, ptr %a, align 8
1321  ret i64 %b
1322}
1323
1324; Similar to above, but with a lshr on one of the indices. This requires
1325; special handling during isel to form a shift pair.
1326define i64 @array_index_lshr_sh3_sh3(ptr %p, i64 %idx1, i64 %idx2) {
1327; RV64I-LABEL: array_index_lshr_sh3_sh3:
1328; RV64I:       # %bb.0:
1329; RV64I-NEXT:    srli a1, a1, 58
1330; RV64I-NEXT:    slli a2, a2, 3
1331; RV64I-NEXT:    slli a1, a1, 6
1332; RV64I-NEXT:    add a0, a0, a2
1333; RV64I-NEXT:    add a0, a0, a1
1334; RV64I-NEXT:    ld a0, 0(a0)
1335; RV64I-NEXT:    ret
1336;
1337; RV64ZBA-LABEL: array_index_lshr_sh3_sh3:
1338; RV64ZBA:       # %bb.0:
1339; RV64ZBA-NEXT:    srli a1, a1, 58
1340; RV64ZBA-NEXT:    sh3add a1, a1, a2
1341; RV64ZBA-NEXT:    sh3add a0, a1, a0
1342; RV64ZBA-NEXT:    ld a0, 0(a0)
1343; RV64ZBA-NEXT:    ret
1344  %shr = lshr i64 %idx1, 58
1345  %a = getelementptr inbounds [8 x i64], ptr %p, i64 %shr, i64 %idx2
1346  %b = load i64, ptr %a, align 8
1347  ret i64 %b
1348}
1349
1350define i8 @array_index_sh4_sh0(ptr %p, i64 %idx1, i64 %idx2) {
1351; CHECK-LABEL: array_index_sh4_sh0:
1352; CHECK:       # %bb.0:
1353; CHECK-NEXT:    slli a1, a1, 4
1354; CHECK-NEXT:    add a0, a0, a2
1355; CHECK-NEXT:    add a0, a0, a1
1356; CHECK-NEXT:    lbu a0, 0(a0)
1357; CHECK-NEXT:    ret
1358  %a = getelementptr inbounds [16 x i8], ptr %p, i64 %idx1, i64 %idx2
1359  %b = load i8, ptr %a, align 1
1360  ret i8 %b
1361}
1362
1363define i16 @array_index_sh4_sh1(ptr %p, i64 %idx1, i64 %idx2) {
1364; RV64I-LABEL: array_index_sh4_sh1:
1365; RV64I:       # %bb.0:
1366; RV64I-NEXT:    slli a1, a1, 5
1367; RV64I-NEXT:    add a0, a0, a1
1368; RV64I-NEXT:    slli a2, a2, 1
1369; RV64I-NEXT:    add a0, a0, a2
1370; RV64I-NEXT:    lh a0, 0(a0)
1371; RV64I-NEXT:    ret
1372;
1373; RV64ZBA-LABEL: array_index_sh4_sh1:
1374; RV64ZBA:       # %bb.0:
1375; RV64ZBA-NEXT:    slli a1, a1, 5
1376; RV64ZBA-NEXT:    add a0, a0, a1
1377; RV64ZBA-NEXT:    sh1add a0, a2, a0
1378; RV64ZBA-NEXT:    lh a0, 0(a0)
1379; RV64ZBA-NEXT:    ret
1380  %a = getelementptr inbounds [16 x i16], ptr %p, i64 %idx1, i64 %idx2
1381  %b = load i16, ptr %a, align 2
1382  ret i16 %b
1383}
1384
1385define i32 @array_index_sh4_sh2(ptr %p, i64 %idx1, i64 %idx2) {
1386; RV64I-LABEL: array_index_sh4_sh2:
1387; RV64I:       # %bb.0:
1388; RV64I-NEXT:    slli a1, a1, 6
1389; RV64I-NEXT:    add a0, a0, a1
1390; RV64I-NEXT:    slli a2, a2, 2
1391; RV64I-NEXT:    add a0, a0, a2
1392; RV64I-NEXT:    lw a0, 0(a0)
1393; RV64I-NEXT:    ret
1394;
1395; RV64ZBA-LABEL: array_index_sh4_sh2:
1396; RV64ZBA:       # %bb.0:
1397; RV64ZBA-NEXT:    slli a1, a1, 6
1398; RV64ZBA-NEXT:    add a0, a0, a1
1399; RV64ZBA-NEXT:    sh2add a0, a2, a0
1400; RV64ZBA-NEXT:    lw a0, 0(a0)
1401; RV64ZBA-NEXT:    ret
1402  %a = getelementptr inbounds [16 x i32], ptr %p, i64 %idx1, i64 %idx2
1403  %b = load i32, ptr %a, align 4
1404  ret i32 %b
1405}
1406
1407define i64 @array_index_sh4_sh3(ptr %p, i64 %idx1, i64 %idx2) {
1408; RV64I-LABEL: array_index_sh4_sh3:
1409; RV64I:       # %bb.0:
1410; RV64I-NEXT:    slli a1, a1, 7
1411; RV64I-NEXT:    add a0, a0, a1
1412; RV64I-NEXT:    slli a2, a2, 3
1413; RV64I-NEXT:    add a0, a0, a2
1414; RV64I-NEXT:    ld a0, 0(a0)
1415; RV64I-NEXT:    ret
1416;
1417; RV64ZBA-LABEL: array_index_sh4_sh3:
1418; RV64ZBA:       # %bb.0:
1419; RV64ZBA-NEXT:    slli a1, a1, 7
1420; RV64ZBA-NEXT:    add a0, a0, a1
1421; RV64ZBA-NEXT:    sh3add a0, a2, a0
1422; RV64ZBA-NEXT:    ld a0, 0(a0)
1423; RV64ZBA-NEXT:    ret
1424  %a = getelementptr inbounds [16 x i64], ptr %p, i64 %idx1, i64 %idx2
1425  %b = load i64, ptr %a, align 8
1426  ret i64 %b
1427}
1428
1429define ptr @gep_lshr_i32(ptr %0, i64 %1) {
1430; RV64I-LABEL: gep_lshr_i32:
1431; RV64I:       # %bb.0: # %entry
1432; RV64I-NEXT:    srli a1, a1, 2
1433; RV64I-NEXT:    slli a1, a1, 32
1434; RV64I-NEXT:    srli a1, a1, 32
1435; RV64I-NEXT:    li a2, 80
1436; RV64I-NEXT:    mul a1, a1, a2
1437; RV64I-NEXT:    add a0, a0, a1
1438; RV64I-NEXT:    ret
1439;
1440; RV64ZBA-LABEL: gep_lshr_i32:
1441; RV64ZBA:       # %bb.0: # %entry
1442; RV64ZBA-NEXT:    srli a1, a1, 2
1443; RV64ZBA-NEXT:    zext.w a1, a1
1444; RV64ZBA-NEXT:    li a2, 80
1445; RV64ZBA-NEXT:    mul a1, a1, a2
1446; RV64ZBA-NEXT:    add a0, a0, a1
1447; RV64ZBA-NEXT:    ret
1448entry:
1449  %2 = lshr exact i64 %1, 2
1450  %3 = and i64 %2, 4294967295
1451  %5 = getelementptr [80 x i8], ptr %0, i64 %3
1452  ret ptr %5
1453}
1454
1455define i64 @srli_slliuw(i64 %1) {
1456; RV64I-LABEL: srli_slliuw:
1457; RV64I:       # %bb.0: # %entry
1458; RV64I-NEXT:    srli a0, a0, 2
1459; RV64I-NEXT:    slli a0, a0, 32
1460; RV64I-NEXT:    srli a0, a0, 28
1461; RV64I-NEXT:    ret
1462;
1463; RV64ZBA-LABEL: srli_slliuw:
1464; RV64ZBA:       # %bb.0: # %entry
1465; RV64ZBA-NEXT:    srli a0, a0, 2
1466; RV64ZBA-NEXT:    slli.uw a0, a0, 4
1467; RV64ZBA-NEXT:    ret
1468entry:
1469  %2 = lshr exact i64 %1, 2
1470  %3 = and i64 %2, 4294967295
1471  %4 = shl i64 %3, 4
1472  ret i64 %4
1473}
1474
1475define i64 @srli_slliuw_canonical(i64 %0) {
1476; RV64I-LABEL: srli_slliuw_canonical:
1477; RV64I:       # %bb.0: # %entry
1478; RV64I-NEXT:    li a1, 1
1479; RV64I-NEXT:    slli a1, a1, 36
1480; RV64I-NEXT:    addi a1, a1, -16
1481; RV64I-NEXT:    slli a0, a0, 2
1482; RV64I-NEXT:    and a0, a0, a1
1483; RV64I-NEXT:    ret
1484;
1485; RV64ZBA-LABEL: srli_slliuw_canonical:
1486; RV64ZBA:       # %bb.0: # %entry
1487; RV64ZBA-NEXT:    slli a0, a0, 2
1488; RV64ZBA-NEXT:    srli a0, a0, 4
1489; RV64ZBA-NEXT:    slli.uw a0, a0, 4
1490; RV64ZBA-NEXT:    ret
1491entry:
1492  %1 = shl i64 %0, 2
1493  %2 = and i64 %1, 68719476720
1494  ret i64 %2
1495}
1496
1497; Make sure we don't accidentally use slli.uw with a shift of 32.
1498define i64 @srli_slliuw_negative_test(i64 %0) {
1499; CHECK-LABEL: srli_slliuw_negative_test:
1500; CHECK:       # %bb.0: # %entry
1501; CHECK-NEXT:    srli a0, a0, 6
1502; CHECK-NEXT:    slli a0, a0, 32
1503; CHECK-NEXT:    ret
1504entry:
1505  %1 = lshr i64 %0, 6
1506  %2 = shl i64 %1, 32
1507  ret i64 %2
1508}
1509
1510define i64 @srli_slli_i16(i64 %1) {
1511; RV64I-LABEL: srli_slli_i16:
1512; RV64I:       # %bb.0: # %entry
1513; RV64I-NEXT:    srli a0, a0, 2
1514; RV64I-NEXT:    slli a0, a0, 48
1515; RV64I-NEXT:    srli a0, a0, 48
1516; RV64I-NEXT:    slli a0, a0, 4
1517; RV64I-NEXT:    ret
1518;
1519; RV64ZBANOZBB-LABEL: srli_slli_i16:
1520; RV64ZBANOZBB:       # %bb.0: # %entry
1521; RV64ZBANOZBB-NEXT:    srli a0, a0, 2
1522; RV64ZBANOZBB-NEXT:    slli a0, a0, 48
1523; RV64ZBANOZBB-NEXT:    srli a0, a0, 48
1524; RV64ZBANOZBB-NEXT:    slli a0, a0, 4
1525; RV64ZBANOZBB-NEXT:    ret
1526;
1527; RV64ZBAZBB-LABEL: srli_slli_i16:
1528; RV64ZBAZBB:       # %bb.0: # %entry
1529; RV64ZBAZBB-NEXT:    srli a0, a0, 2
1530; RV64ZBAZBB-NEXT:    zext.h a0, a0
1531; RV64ZBAZBB-NEXT:    slli a0, a0, 4
1532; RV64ZBAZBB-NEXT:    ret
1533entry:
1534  %2 = lshr exact i64 %1, 2
1535  %3 = and i64 %2, 65535
1536  %4 = shl i64 %3, 4
1537  ret i64 %4
1538}
1539
1540define i64 @srli_slliuw_2(i64 %1) {
1541; RV64I-LABEL: srli_slliuw_2:
1542; RV64I:       # %bb.0: # %entry
1543; RV64I-NEXT:    srli a0, a0, 18
1544; RV64I-NEXT:    slli a0, a0, 32
1545; RV64I-NEXT:    srli a0, a0, 29
1546; RV64I-NEXT:    ret
1547;
1548; RV64ZBA-LABEL: srli_slliuw_2:
1549; RV64ZBA:       # %bb.0: # %entry
1550; RV64ZBA-NEXT:    srli a0, a0, 18
1551; RV64ZBA-NEXT:    slli.uw a0, a0, 3
1552; RV64ZBA-NEXT:    ret
1553entry:
1554  %2 = lshr i64 %1, 18
1555  %3 = and i64 %2, 4294967295
1556  %4 = shl i64 %3, 3
1557  ret i64 %4
1558}
1559
1560define i64 @srli_slliuw_canonical_2(i64 %0) {
1561; RV64I-LABEL: srli_slliuw_canonical_2:
1562; RV64I:       # %bb.0: # %entry
1563; RV64I-NEXT:    li a1, 1
1564; RV64I-NEXT:    slli a1, a1, 35
1565; RV64I-NEXT:    addi a1, a1, -8
1566; RV64I-NEXT:    srli a0, a0, 15
1567; RV64I-NEXT:    and a0, a0, a1
1568; RV64I-NEXT:    ret
1569;
1570; RV64ZBA-LABEL: srli_slliuw_canonical_2:
1571; RV64ZBA:       # %bb.0: # %entry
1572; RV64ZBA-NEXT:    srli a0, a0, 15
1573; RV64ZBA-NEXT:    srli a0, a0, 3
1574; RV64ZBA-NEXT:    slli.uw a0, a0, 3
1575; RV64ZBA-NEXT:    ret
1576entry:
1577  %1 = lshr i64 %0, 15
1578  %2 = and i64 %1, 34359738360
1579  ret i64 %2
1580}
1581
1582define ptr @srai_srli_sh3add(ptr %0, i64 %1) nounwind {
1583; RV64I-LABEL: srai_srli_sh3add:
1584; RV64I:       # %bb.0: # %entry
1585; RV64I-NEXT:    srai a1, a1, 32
1586; RV64I-NEXT:    srli a1, a1, 6
1587; RV64I-NEXT:    slli a1, a1, 3
1588; RV64I-NEXT:    add a0, a0, a1
1589; RV64I-NEXT:    ret
1590;
1591; RV64ZBA-LABEL: srai_srli_sh3add:
1592; RV64ZBA:       # %bb.0: # %entry
1593; RV64ZBA-NEXT:    srai a1, a1, 32
1594; RV64ZBA-NEXT:    srli a1, a1, 6
1595; RV64ZBA-NEXT:    sh3add a0, a1, a0
1596; RV64ZBA-NEXT:    ret
1597entry:
1598  %2 = ashr i64 %1, 32
1599  %3 = lshr i64 %2, 6
1600  %4 = getelementptr i64, ptr %0, i64 %3
1601  ret ptr %4
1602}
1603
1604define ptr @srai_srli_slli(ptr %0, i64 %1) nounwind {
1605; CHECK-LABEL: srai_srli_slli:
1606; CHECK:       # %bb.0: # %entry
1607; CHECK-NEXT:    srai a1, a1, 32
1608; CHECK-NEXT:    srli a1, a1, 6
1609; CHECK-NEXT:    slli a1, a1, 4
1610; CHECK-NEXT:    add a0, a0, a1
1611; CHECK-NEXT:    ret
1612entry:
1613  %2 = ashr i64 %1, 32
1614  %3 = lshr i64 %2, 6
1615  %4 = getelementptr i128, ptr %0, i64 %3
1616  ret ptr %4
1617}
1618
1619; Negative to make sure the peephole added for srai_srli_slli and
1620; srai_srli_sh3add doesn't break this.
1621define i64 @srai_andi(i64 %x) nounwind {
1622; CHECK-LABEL: srai_andi:
1623; CHECK:       # %bb.0: # %entry
1624; CHECK-NEXT:    srai a0, a0, 8
1625; CHECK-NEXT:    andi a0, a0, -8
1626; CHECK-NEXT:    ret
1627entry:
1628  %y = ashr i64 %x, 8
1629  %z = and i64 %y, -8
1630  ret i64 %z
1631}
1632
1633; Negative to make sure the peephole added for srai_srli_slli and
1634; srai_srli_sh3add doesn't break this.
1635define i64 @srai_lui_and(i64 %x) nounwind {
1636; CHECK-LABEL: srai_lui_and:
1637; CHECK:       # %bb.0: # %entry
1638; CHECK-NEXT:    lui a1, 1048574
1639; CHECK-NEXT:    srai a0, a0, 8
1640; CHECK-NEXT:    and a0, a0, a1
1641; CHECK-NEXT:    ret
1642entry:
1643  %y = ashr i64 %x, 8
1644  %z = and i64 %y, -8192
1645  ret i64 %z
1646}
1647
1648define i64 @add_u32simm32_zextw(i64 %x) nounwind {
1649; RV64I-LABEL: add_u32simm32_zextw:
1650; RV64I:       # %bb.0: # %entry
1651; RV64I-NEXT:    li a1, 1
1652; RV64I-NEXT:    slli a1, a1, 32
1653; RV64I-NEXT:    addi a1, a1, -2
1654; RV64I-NEXT:    add a0, a0, a1
1655; RV64I-NEXT:    addi a1, a1, 1
1656; RV64I-NEXT:    and a0, a0, a1
1657; RV64I-NEXT:    ret
1658;
1659; RV64ZBA-LABEL: add_u32simm32_zextw:
1660; RV64ZBA:       # %bb.0: # %entry
1661; RV64ZBA-NEXT:    li a1, -2
1662; RV64ZBA-NEXT:    zext.w a1, a1
1663; RV64ZBA-NEXT:    add a0, a0, a1
1664; RV64ZBA-NEXT:    zext.w a0, a0
1665; RV64ZBA-NEXT:    ret
1666entry:
1667  %add = add i64 %x, 4294967294
1668  %and = and i64 %add, 4294967295
1669  ret i64 %and
1670}
1671