xref: /llvm-project/llvm/test/CodeGen/RISCV/rotl-rotr.ll (revision 9122c5235ec85ce0c0ad337e862b006e7b349d84)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3; RUN:   | FileCheck %s -check-prefix=RV32I
4; RUN: llc -mtriple=riscv64 -verify-machineinstrs -enable-legalize-types-checking < %s \
5; RUN:   | FileCheck %s -check-prefix=RV64I
6; RUN: llc -mtriple=riscv32 -mattr=+zbb -verify-machineinstrs < %s \
7; RUN:   | FileCheck %s -check-prefix=RV32ZBB
8; RUN: llc -mtriple=riscv64 -mattr=+zbb -verify-machineinstrs < %s \
9; RUN:   | FileCheck %s -check-prefix=RV64ZBB
10; RUN: llc -mtriple=riscv32 -mattr=+xtheadbb -verify-machineinstrs < %s \
11; RUN:   | FileCheck %s -check-prefix=RV32XTHEADBB
12; RUN: llc -mtriple=riscv64 -mattr=+xtheadbb -verify-machineinstrs < %s \
13; RUN:   | FileCheck %s -check-prefix=RV64XTHEADBB
14
15; NOTE: -enable-legalize-types-checking is on one command line due to a previous
16; assertion failure on an expensive checks build for @rotr_32_mask_multiple.
17
18; These IR sequences are idioms for rotates. If rotate instructions are
19; supported, they will be turned into ISD::ROTL or ISD::ROTR.
20
21define i32 @rotl_32(i32 %x, i32 %y) nounwind {
22; RV32I-LABEL: rotl_32:
23; RV32I:       # %bb.0:
24; RV32I-NEXT:    neg a2, a1
25; RV32I-NEXT:    sll a1, a0, a1
26; RV32I-NEXT:    srl a0, a0, a2
27; RV32I-NEXT:    or a0, a1, a0
28; RV32I-NEXT:    ret
29;
30; RV64I-LABEL: rotl_32:
31; RV64I:       # %bb.0:
32; RV64I-NEXT:    negw a2, a1
33; RV64I-NEXT:    sllw a1, a0, a1
34; RV64I-NEXT:    srlw a0, a0, a2
35; RV64I-NEXT:    or a0, a1, a0
36; RV64I-NEXT:    ret
37;
38; RV32ZBB-LABEL: rotl_32:
39; RV32ZBB:       # %bb.0:
40; RV32ZBB-NEXT:    rol a0, a0, a1
41; RV32ZBB-NEXT:    ret
42;
43; RV64ZBB-LABEL: rotl_32:
44; RV64ZBB:       # %bb.0:
45; RV64ZBB-NEXT:    rolw a0, a0, a1
46; RV64ZBB-NEXT:    ret
47;
48; RV32XTHEADBB-LABEL: rotl_32:
49; RV32XTHEADBB:       # %bb.0:
50; RV32XTHEADBB-NEXT:    sll a2, a0, a1
51; RV32XTHEADBB-NEXT:    neg a1, a1
52; RV32XTHEADBB-NEXT:    srl a0, a0, a1
53; RV32XTHEADBB-NEXT:    or a0, a2, a0
54; RV32XTHEADBB-NEXT:    ret
55;
56; RV64XTHEADBB-LABEL: rotl_32:
57; RV64XTHEADBB:       # %bb.0:
58; RV64XTHEADBB-NEXT:    sllw a2, a0, a1
59; RV64XTHEADBB-NEXT:    negw a1, a1
60; RV64XTHEADBB-NEXT:    srlw a0, a0, a1
61; RV64XTHEADBB-NEXT:    or a0, a2, a0
62; RV64XTHEADBB-NEXT:    ret
63  %z = sub i32 32, %y
64  %b = shl i32 %x, %y
65  %c = lshr i32 %x, %z
66  %d = or i32 %b, %c
67  ret i32 %d
68}
69
70define i32 @rotr_32(i32 %x, i32 %y) nounwind {
71; RV32I-LABEL: rotr_32:
72; RV32I:       # %bb.0:
73; RV32I-NEXT:    neg a2, a1
74; RV32I-NEXT:    srl a1, a0, a1
75; RV32I-NEXT:    sll a0, a0, a2
76; RV32I-NEXT:    or a0, a1, a0
77; RV32I-NEXT:    ret
78;
79; RV64I-LABEL: rotr_32:
80; RV64I:       # %bb.0:
81; RV64I-NEXT:    negw a2, a1
82; RV64I-NEXT:    srlw a1, a0, a1
83; RV64I-NEXT:    sllw a0, a0, a2
84; RV64I-NEXT:    or a0, a1, a0
85; RV64I-NEXT:    ret
86;
87; RV32ZBB-LABEL: rotr_32:
88; RV32ZBB:       # %bb.0:
89; RV32ZBB-NEXT:    ror a0, a0, a1
90; RV32ZBB-NEXT:    ret
91;
92; RV64ZBB-LABEL: rotr_32:
93; RV64ZBB:       # %bb.0:
94; RV64ZBB-NEXT:    rorw a0, a0, a1
95; RV64ZBB-NEXT:    ret
96;
97; RV32XTHEADBB-LABEL: rotr_32:
98; RV32XTHEADBB:       # %bb.0:
99; RV32XTHEADBB-NEXT:    srl a2, a0, a1
100; RV32XTHEADBB-NEXT:    neg a1, a1
101; RV32XTHEADBB-NEXT:    sll a0, a0, a1
102; RV32XTHEADBB-NEXT:    or a0, a2, a0
103; RV32XTHEADBB-NEXT:    ret
104;
105; RV64XTHEADBB-LABEL: rotr_32:
106; RV64XTHEADBB:       # %bb.0:
107; RV64XTHEADBB-NEXT:    srlw a2, a0, a1
108; RV64XTHEADBB-NEXT:    negw a1, a1
109; RV64XTHEADBB-NEXT:    sllw a0, a0, a1
110; RV64XTHEADBB-NEXT:    or a0, a2, a0
111; RV64XTHEADBB-NEXT:    ret
112  %z = sub i32 32, %y
113  %b = lshr i32 %x, %y
114  %c = shl i32 %x, %z
115  %d = or i32 %b, %c
116  ret i32 %d
117}
118
119define i64 @rotl_64(i64 %x, i64 %y) nounwind {
120; RV32I-LABEL: rotl_64:
121; RV32I:       # %bb.0:
122; RV32I-NEXT:    addi a5, a2, -32
123; RV32I-NEXT:    sll a4, a0, a2
124; RV32I-NEXT:    bltz a5, .LBB2_2
125; RV32I-NEXT:  # %bb.1:
126; RV32I-NEXT:    mv a3, a4
127; RV32I-NEXT:    j .LBB2_3
128; RV32I-NEXT:  .LBB2_2:
129; RV32I-NEXT:    sll a3, a1, a2
130; RV32I-NEXT:    not a6, a2
131; RV32I-NEXT:    srli a7, a0, 1
132; RV32I-NEXT:    srl a6, a7, a6
133; RV32I-NEXT:    or a3, a3, a6
134; RV32I-NEXT:  .LBB2_3:
135; RV32I-NEXT:    srai a5, a5, 31
136; RV32I-NEXT:    neg a7, a2
137; RV32I-NEXT:    li a6, 32
138; RV32I-NEXT:    and a4, a5, a4
139; RV32I-NEXT:    sub a5, a6, a2
140; RV32I-NEXT:    srl a6, a1, a7
141; RV32I-NEXT:    bltz a5, .LBB2_5
142; RV32I-NEXT:  # %bb.4:
143; RV32I-NEXT:    mv a0, a6
144; RV32I-NEXT:    j .LBB2_6
145; RV32I-NEXT:  .LBB2_5:
146; RV32I-NEXT:    srl a0, a0, a7
147; RV32I-NEXT:    li a7, 64
148; RV32I-NEXT:    sub a2, a7, a2
149; RV32I-NEXT:    not a2, a2
150; RV32I-NEXT:    slli a1, a1, 1
151; RV32I-NEXT:    sll a1, a1, a2
152; RV32I-NEXT:    or a0, a0, a1
153; RV32I-NEXT:  .LBB2_6:
154; RV32I-NEXT:    srai a5, a5, 31
155; RV32I-NEXT:    and a1, a5, a6
156; RV32I-NEXT:    or a1, a3, a1
157; RV32I-NEXT:    or a0, a4, a0
158; RV32I-NEXT:    ret
159;
160; RV64I-LABEL: rotl_64:
161; RV64I:       # %bb.0:
162; RV64I-NEXT:    negw a2, a1
163; RV64I-NEXT:    sll a1, a0, a1
164; RV64I-NEXT:    srl a0, a0, a2
165; RV64I-NEXT:    or a0, a1, a0
166; RV64I-NEXT:    ret
167;
168; RV32ZBB-LABEL: rotl_64:
169; RV32ZBB:       # %bb.0:
170; RV32ZBB-NEXT:    addi a5, a2, -32
171; RV32ZBB-NEXT:    sll a4, a0, a2
172; RV32ZBB-NEXT:    bltz a5, .LBB2_2
173; RV32ZBB-NEXT:  # %bb.1:
174; RV32ZBB-NEXT:    mv a3, a4
175; RV32ZBB-NEXT:    j .LBB2_3
176; RV32ZBB-NEXT:  .LBB2_2:
177; RV32ZBB-NEXT:    sll a3, a1, a2
178; RV32ZBB-NEXT:    not a6, a2
179; RV32ZBB-NEXT:    srli a7, a0, 1
180; RV32ZBB-NEXT:    srl a6, a7, a6
181; RV32ZBB-NEXT:    or a3, a3, a6
182; RV32ZBB-NEXT:  .LBB2_3:
183; RV32ZBB-NEXT:    srai a5, a5, 31
184; RV32ZBB-NEXT:    neg a7, a2
185; RV32ZBB-NEXT:    li a6, 32
186; RV32ZBB-NEXT:    and a4, a5, a4
187; RV32ZBB-NEXT:    sub a5, a6, a2
188; RV32ZBB-NEXT:    srl a6, a1, a7
189; RV32ZBB-NEXT:    bltz a5, .LBB2_5
190; RV32ZBB-NEXT:  # %bb.4:
191; RV32ZBB-NEXT:    mv a0, a6
192; RV32ZBB-NEXT:    j .LBB2_6
193; RV32ZBB-NEXT:  .LBB2_5:
194; RV32ZBB-NEXT:    srl a0, a0, a7
195; RV32ZBB-NEXT:    li a7, 64
196; RV32ZBB-NEXT:    sub a2, a7, a2
197; RV32ZBB-NEXT:    not a2, a2
198; RV32ZBB-NEXT:    slli a1, a1, 1
199; RV32ZBB-NEXT:    sll a1, a1, a2
200; RV32ZBB-NEXT:    or a0, a0, a1
201; RV32ZBB-NEXT:  .LBB2_6:
202; RV32ZBB-NEXT:    srai a5, a5, 31
203; RV32ZBB-NEXT:    and a1, a5, a6
204; RV32ZBB-NEXT:    or a1, a3, a1
205; RV32ZBB-NEXT:    or a0, a4, a0
206; RV32ZBB-NEXT:    ret
207;
208; RV64ZBB-LABEL: rotl_64:
209; RV64ZBB:       # %bb.0:
210; RV64ZBB-NEXT:    rol a0, a0, a1
211; RV64ZBB-NEXT:    ret
212;
213; RV32XTHEADBB-LABEL: rotl_64:
214; RV32XTHEADBB:       # %bb.0:
215; RV32XTHEADBB-NEXT:    addi a5, a2, -32
216; RV32XTHEADBB-NEXT:    sll a4, a0, a2
217; RV32XTHEADBB-NEXT:    bltz a5, .LBB2_2
218; RV32XTHEADBB-NEXT:  # %bb.1:
219; RV32XTHEADBB-NEXT:    mv a3, a4
220; RV32XTHEADBB-NEXT:    j .LBB2_3
221; RV32XTHEADBB-NEXT:  .LBB2_2:
222; RV32XTHEADBB-NEXT:    sll a3, a1, a2
223; RV32XTHEADBB-NEXT:    not a6, a2
224; RV32XTHEADBB-NEXT:    srli a7, a0, 1
225; RV32XTHEADBB-NEXT:    srl a6, a7, a6
226; RV32XTHEADBB-NEXT:    or a3, a3, a6
227; RV32XTHEADBB-NEXT:  .LBB2_3:
228; RV32XTHEADBB-NEXT:    srai a5, a5, 31
229; RV32XTHEADBB-NEXT:    neg a7, a2
230; RV32XTHEADBB-NEXT:    li a6, 32
231; RV32XTHEADBB-NEXT:    and a4, a5, a4
232; RV32XTHEADBB-NEXT:    sub a5, a6, a2
233; RV32XTHEADBB-NEXT:    srl a6, a1, a7
234; RV32XTHEADBB-NEXT:    bltz a5, .LBB2_5
235; RV32XTHEADBB-NEXT:  # %bb.4:
236; RV32XTHEADBB-NEXT:    mv a0, a6
237; RV32XTHEADBB-NEXT:    j .LBB2_6
238; RV32XTHEADBB-NEXT:  .LBB2_5:
239; RV32XTHEADBB-NEXT:    srl a0, a0, a7
240; RV32XTHEADBB-NEXT:    li a7, 64
241; RV32XTHEADBB-NEXT:    sub a2, a7, a2
242; RV32XTHEADBB-NEXT:    not a2, a2
243; RV32XTHEADBB-NEXT:    slli a1, a1, 1
244; RV32XTHEADBB-NEXT:    sll a1, a1, a2
245; RV32XTHEADBB-NEXT:    or a0, a0, a1
246; RV32XTHEADBB-NEXT:  .LBB2_6:
247; RV32XTHEADBB-NEXT:    srai a5, a5, 31
248; RV32XTHEADBB-NEXT:    and a1, a5, a6
249; RV32XTHEADBB-NEXT:    or a1, a3, a1
250; RV32XTHEADBB-NEXT:    or a0, a4, a0
251; RV32XTHEADBB-NEXT:    ret
252;
253; RV64XTHEADBB-LABEL: rotl_64:
254; RV64XTHEADBB:       # %bb.0:
255; RV64XTHEADBB-NEXT:    sll a2, a0, a1
256; RV64XTHEADBB-NEXT:    negw a1, a1
257; RV64XTHEADBB-NEXT:    srl a0, a0, a1
258; RV64XTHEADBB-NEXT:    or a0, a2, a0
259; RV64XTHEADBB-NEXT:    ret
260  %z = sub i64 64, %y
261  %b = shl i64 %x, %y
262  %c = lshr i64 %x, %z
263  %d = or i64 %b, %c
264  ret i64 %d
265}
266
267define i64 @rotr_64(i64 %x, i64 %y) nounwind {
268; RV32I-LABEL: rotr_64:
269; RV32I:       # %bb.0:
270; RV32I-NEXT:    addi a5, a2, -32
271; RV32I-NEXT:    srl a4, a1, a2
272; RV32I-NEXT:    bltz a5, .LBB3_2
273; RV32I-NEXT:  # %bb.1:
274; RV32I-NEXT:    mv a3, a4
275; RV32I-NEXT:    j .LBB3_3
276; RV32I-NEXT:  .LBB3_2:
277; RV32I-NEXT:    srl a3, a0, a2
278; RV32I-NEXT:    not a6, a2
279; RV32I-NEXT:    slli a7, a1, 1
280; RV32I-NEXT:    sll a6, a7, a6
281; RV32I-NEXT:    or a3, a3, a6
282; RV32I-NEXT:  .LBB3_3:
283; RV32I-NEXT:    srai a5, a5, 31
284; RV32I-NEXT:    neg a7, a2
285; RV32I-NEXT:    li a6, 32
286; RV32I-NEXT:    and a4, a5, a4
287; RV32I-NEXT:    sub a5, a6, a2
288; RV32I-NEXT:    sll a6, a0, a7
289; RV32I-NEXT:    bltz a5, .LBB3_5
290; RV32I-NEXT:  # %bb.4:
291; RV32I-NEXT:    mv a1, a6
292; RV32I-NEXT:    j .LBB3_6
293; RV32I-NEXT:  .LBB3_5:
294; RV32I-NEXT:    sll a1, a1, a7
295; RV32I-NEXT:    li a7, 64
296; RV32I-NEXT:    sub a2, a7, a2
297; RV32I-NEXT:    not a2, a2
298; RV32I-NEXT:    srli a0, a0, 1
299; RV32I-NEXT:    srl a0, a0, a2
300; RV32I-NEXT:    or a1, a1, a0
301; RV32I-NEXT:  .LBB3_6:
302; RV32I-NEXT:    srai a5, a5, 31
303; RV32I-NEXT:    and a0, a5, a6
304; RV32I-NEXT:    or a0, a3, a0
305; RV32I-NEXT:    or a1, a4, a1
306; RV32I-NEXT:    ret
307;
308; RV64I-LABEL: rotr_64:
309; RV64I:       # %bb.0:
310; RV64I-NEXT:    negw a2, a1
311; RV64I-NEXT:    srl a1, a0, a1
312; RV64I-NEXT:    sll a0, a0, a2
313; RV64I-NEXT:    or a0, a1, a0
314; RV64I-NEXT:    ret
315;
316; RV32ZBB-LABEL: rotr_64:
317; RV32ZBB:       # %bb.0:
318; RV32ZBB-NEXT:    addi a5, a2, -32
319; RV32ZBB-NEXT:    srl a4, a1, a2
320; RV32ZBB-NEXT:    bltz a5, .LBB3_2
321; RV32ZBB-NEXT:  # %bb.1:
322; RV32ZBB-NEXT:    mv a3, a4
323; RV32ZBB-NEXT:    j .LBB3_3
324; RV32ZBB-NEXT:  .LBB3_2:
325; RV32ZBB-NEXT:    srl a3, a0, a2
326; RV32ZBB-NEXT:    not a6, a2
327; RV32ZBB-NEXT:    slli a7, a1, 1
328; RV32ZBB-NEXT:    sll a6, a7, a6
329; RV32ZBB-NEXT:    or a3, a3, a6
330; RV32ZBB-NEXT:  .LBB3_3:
331; RV32ZBB-NEXT:    srai a5, a5, 31
332; RV32ZBB-NEXT:    neg a7, a2
333; RV32ZBB-NEXT:    li a6, 32
334; RV32ZBB-NEXT:    and a4, a5, a4
335; RV32ZBB-NEXT:    sub a5, a6, a2
336; RV32ZBB-NEXT:    sll a6, a0, a7
337; RV32ZBB-NEXT:    bltz a5, .LBB3_5
338; RV32ZBB-NEXT:  # %bb.4:
339; RV32ZBB-NEXT:    mv a1, a6
340; RV32ZBB-NEXT:    j .LBB3_6
341; RV32ZBB-NEXT:  .LBB3_5:
342; RV32ZBB-NEXT:    sll a1, a1, a7
343; RV32ZBB-NEXT:    li a7, 64
344; RV32ZBB-NEXT:    sub a2, a7, a2
345; RV32ZBB-NEXT:    not a2, a2
346; RV32ZBB-NEXT:    srli a0, a0, 1
347; RV32ZBB-NEXT:    srl a0, a0, a2
348; RV32ZBB-NEXT:    or a1, a1, a0
349; RV32ZBB-NEXT:  .LBB3_6:
350; RV32ZBB-NEXT:    srai a5, a5, 31
351; RV32ZBB-NEXT:    and a0, a5, a6
352; RV32ZBB-NEXT:    or a0, a3, a0
353; RV32ZBB-NEXT:    or a1, a4, a1
354; RV32ZBB-NEXT:    ret
355;
356; RV64ZBB-LABEL: rotr_64:
357; RV64ZBB:       # %bb.0:
358; RV64ZBB-NEXT:    ror a0, a0, a1
359; RV64ZBB-NEXT:    ret
360;
361; RV32XTHEADBB-LABEL: rotr_64:
362; RV32XTHEADBB:       # %bb.0:
363; RV32XTHEADBB-NEXT:    addi a5, a2, -32
364; RV32XTHEADBB-NEXT:    srl a4, a1, a2
365; RV32XTHEADBB-NEXT:    bltz a5, .LBB3_2
366; RV32XTHEADBB-NEXT:  # %bb.1:
367; RV32XTHEADBB-NEXT:    mv a3, a4
368; RV32XTHEADBB-NEXT:    j .LBB3_3
369; RV32XTHEADBB-NEXT:  .LBB3_2:
370; RV32XTHEADBB-NEXT:    srl a3, a0, a2
371; RV32XTHEADBB-NEXT:    not a6, a2
372; RV32XTHEADBB-NEXT:    slli a7, a1, 1
373; RV32XTHEADBB-NEXT:    sll a6, a7, a6
374; RV32XTHEADBB-NEXT:    or a3, a3, a6
375; RV32XTHEADBB-NEXT:  .LBB3_3:
376; RV32XTHEADBB-NEXT:    srai a5, a5, 31
377; RV32XTHEADBB-NEXT:    neg a7, a2
378; RV32XTHEADBB-NEXT:    li a6, 32
379; RV32XTHEADBB-NEXT:    and a4, a5, a4
380; RV32XTHEADBB-NEXT:    sub a5, a6, a2
381; RV32XTHEADBB-NEXT:    sll a6, a0, a7
382; RV32XTHEADBB-NEXT:    bltz a5, .LBB3_5
383; RV32XTHEADBB-NEXT:  # %bb.4:
384; RV32XTHEADBB-NEXT:    mv a1, a6
385; RV32XTHEADBB-NEXT:    j .LBB3_6
386; RV32XTHEADBB-NEXT:  .LBB3_5:
387; RV32XTHEADBB-NEXT:    sll a1, a1, a7
388; RV32XTHEADBB-NEXT:    li a7, 64
389; RV32XTHEADBB-NEXT:    sub a2, a7, a2
390; RV32XTHEADBB-NEXT:    not a2, a2
391; RV32XTHEADBB-NEXT:    srli a0, a0, 1
392; RV32XTHEADBB-NEXT:    srl a0, a0, a2
393; RV32XTHEADBB-NEXT:    or a1, a1, a0
394; RV32XTHEADBB-NEXT:  .LBB3_6:
395; RV32XTHEADBB-NEXT:    srai a5, a5, 31
396; RV32XTHEADBB-NEXT:    and a0, a5, a6
397; RV32XTHEADBB-NEXT:    or a0, a3, a0
398; RV32XTHEADBB-NEXT:    or a1, a4, a1
399; RV32XTHEADBB-NEXT:    ret
400;
401; RV64XTHEADBB-LABEL: rotr_64:
402; RV64XTHEADBB:       # %bb.0:
403; RV64XTHEADBB-NEXT:    srl a2, a0, a1
404; RV64XTHEADBB-NEXT:    negw a1, a1
405; RV64XTHEADBB-NEXT:    sll a0, a0, a1
406; RV64XTHEADBB-NEXT:    or a0, a2, a0
407; RV64XTHEADBB-NEXT:    ret
408  %z = sub i64 64, %y
409  %b = lshr i64 %x, %y
410  %c = shl i64 %x, %z
411  %d = or i64 %b, %c
412  ret i64 %d
413}
414
415define i32 @rotl_32_mask(i32 %x, i32 %y) nounwind {
416; RV32I-LABEL: rotl_32_mask:
417; RV32I:       # %bb.0:
418; RV32I-NEXT:    neg a2, a1
419; RV32I-NEXT:    sll a1, a0, a1
420; RV32I-NEXT:    srl a0, a0, a2
421; RV32I-NEXT:    or a0, a1, a0
422; RV32I-NEXT:    ret
423;
424; RV64I-LABEL: rotl_32_mask:
425; RV64I:       # %bb.0:
426; RV64I-NEXT:    negw a2, a1
427; RV64I-NEXT:    sllw a1, a0, a1
428; RV64I-NEXT:    srlw a0, a0, a2
429; RV64I-NEXT:    or a0, a1, a0
430; RV64I-NEXT:    ret
431;
432; RV32ZBB-LABEL: rotl_32_mask:
433; RV32ZBB:       # %bb.0:
434; RV32ZBB-NEXT:    rol a0, a0, a1
435; RV32ZBB-NEXT:    ret
436;
437; RV64ZBB-LABEL: rotl_32_mask:
438; RV64ZBB:       # %bb.0:
439; RV64ZBB-NEXT:    rolw a0, a0, a1
440; RV64ZBB-NEXT:    ret
441;
442; RV32XTHEADBB-LABEL: rotl_32_mask:
443; RV32XTHEADBB:       # %bb.0:
444; RV32XTHEADBB-NEXT:    sll a2, a0, a1
445; RV32XTHEADBB-NEXT:    neg a1, a1
446; RV32XTHEADBB-NEXT:    srl a0, a0, a1
447; RV32XTHEADBB-NEXT:    or a0, a2, a0
448; RV32XTHEADBB-NEXT:    ret
449;
450; RV64XTHEADBB-LABEL: rotl_32_mask:
451; RV64XTHEADBB:       # %bb.0:
452; RV64XTHEADBB-NEXT:    sllw a2, a0, a1
453; RV64XTHEADBB-NEXT:    negw a1, a1
454; RV64XTHEADBB-NEXT:    srlw a0, a0, a1
455; RV64XTHEADBB-NEXT:    or a0, a2, a0
456; RV64XTHEADBB-NEXT:    ret
457  %z = sub i32 0, %y
458  %and = and i32 %z, 31
459  %b = shl i32 %x, %y
460  %c = lshr i32 %x, %and
461  %d = or i32 %b, %c
462  ret i32 %d
463}
464
465define i32 @rotl_32_mask_and_63_and_31(i32 %x, i32 %y) nounwind {
466; RV32I-LABEL: rotl_32_mask_and_63_and_31:
467; RV32I:       # %bb.0:
468; RV32I-NEXT:    sll a2, a0, a1
469; RV32I-NEXT:    neg a1, a1
470; RV32I-NEXT:    srl a0, a0, a1
471; RV32I-NEXT:    or a0, a2, a0
472; RV32I-NEXT:    ret
473;
474; RV64I-LABEL: rotl_32_mask_and_63_and_31:
475; RV64I:       # %bb.0:
476; RV64I-NEXT:    sllw a2, a0, a1
477; RV64I-NEXT:    negw a1, a1
478; RV64I-NEXT:    srlw a0, a0, a1
479; RV64I-NEXT:    or a0, a2, a0
480; RV64I-NEXT:    ret
481;
482; RV32ZBB-LABEL: rotl_32_mask_and_63_and_31:
483; RV32ZBB:       # %bb.0:
484; RV32ZBB-NEXT:    rol a0, a0, a1
485; RV32ZBB-NEXT:    ret
486;
487; RV64ZBB-LABEL: rotl_32_mask_and_63_and_31:
488; RV64ZBB:       # %bb.0:
489; RV64ZBB-NEXT:    rolw a0, a0, a1
490; RV64ZBB-NEXT:    ret
491;
492; RV32XTHEADBB-LABEL: rotl_32_mask_and_63_and_31:
493; RV32XTHEADBB:       # %bb.0:
494; RV32XTHEADBB-NEXT:    sll a2, a0, a1
495; RV32XTHEADBB-NEXT:    neg a1, a1
496; RV32XTHEADBB-NEXT:    srl a0, a0, a1
497; RV32XTHEADBB-NEXT:    or a0, a2, a0
498; RV32XTHEADBB-NEXT:    ret
499;
500; RV64XTHEADBB-LABEL: rotl_32_mask_and_63_and_31:
501; RV64XTHEADBB:       # %bb.0:
502; RV64XTHEADBB-NEXT:    sllw a2, a0, a1
503; RV64XTHEADBB-NEXT:    negw a1, a1
504; RV64XTHEADBB-NEXT:    srlw a0, a0, a1
505; RV64XTHEADBB-NEXT:    or a0, a2, a0
506; RV64XTHEADBB-NEXT:    ret
507  %a = and i32 %y, 63
508  %b = shl i32 %x, %a
509  %c = sub i32 0, %y
510  %d = and i32 %c, 31
511  %e = lshr i32 %x, %d
512  %f = or i32 %b, %e
513  ret i32 %f
514}
515
516define i32 @rotl_32_mask_or_64_or_32(i32 %x, i32 %y) nounwind {
517; RV32I-LABEL: rotl_32_mask_or_64_or_32:
518; RV32I:       # %bb.0:
519; RV32I-NEXT:    li a0, 0
520; RV32I-NEXT:    ret
521;
522; RV64I-LABEL: rotl_32_mask_or_64_or_32:
523; RV64I:       # %bb.0:
524; RV64I-NEXT:    li a0, 0
525; RV64I-NEXT:    ret
526;
527; RV32ZBB-LABEL: rotl_32_mask_or_64_or_32:
528; RV32ZBB:       # %bb.0:
529; RV32ZBB-NEXT:    rol a0, a0, a1
530; RV32ZBB-NEXT:    ret
531;
532; RV64ZBB-LABEL: rotl_32_mask_or_64_or_32:
533; RV64ZBB:       # %bb.0:
534; RV64ZBB-NEXT:    rolw a0, a0, a1
535; RV64ZBB-NEXT:    ret
536;
537; RV32XTHEADBB-LABEL: rotl_32_mask_or_64_or_32:
538; RV32XTHEADBB:       # %bb.0:
539; RV32XTHEADBB-NEXT:    sll a2, a0, a1
540; RV32XTHEADBB-NEXT:    neg a1, a1
541; RV32XTHEADBB-NEXT:    srl a0, a0, a1
542; RV32XTHEADBB-NEXT:    or a0, a2, a0
543; RV32XTHEADBB-NEXT:    ret
544;
545; RV64XTHEADBB-LABEL: rotl_32_mask_or_64_or_32:
546; RV64XTHEADBB:       # %bb.0:
547; RV64XTHEADBB-NEXT:    sllw a2, a0, a1
548; RV64XTHEADBB-NEXT:    negw a1, a1
549; RV64XTHEADBB-NEXT:    srlw a0, a0, a1
550; RV64XTHEADBB-NEXT:    or a0, a2, a0
551; RV64XTHEADBB-NEXT:    ret
552  %a = or i32 %y, 64
553  %b = shl i32 %x, %a
554  %c = sub i32 0, %y
555  %d = or i32 %c, 32
556  %e = lshr i32 %x, %d
557  %f = or i32 %b, %e
558  ret i32 %f
559}
560
561define i32 @rotr_32_mask(i32 %x, i32 %y) nounwind {
562; RV32I-LABEL: rotr_32_mask:
563; RV32I:       # %bb.0:
564; RV32I-NEXT:    neg a2, a1
565; RV32I-NEXT:    srl a1, a0, a1
566; RV32I-NEXT:    sll a0, a0, a2
567; RV32I-NEXT:    or a0, a1, a0
568; RV32I-NEXT:    ret
569;
570; RV64I-LABEL: rotr_32_mask:
571; RV64I:       # %bb.0:
572; RV64I-NEXT:    negw a2, a1
573; RV64I-NEXT:    srlw a1, a0, a1
574; RV64I-NEXT:    sllw a0, a0, a2
575; RV64I-NEXT:    or a0, a1, a0
576; RV64I-NEXT:    ret
577;
578; RV32ZBB-LABEL: rotr_32_mask:
579; RV32ZBB:       # %bb.0:
580; RV32ZBB-NEXT:    ror a0, a0, a1
581; RV32ZBB-NEXT:    ret
582;
583; RV64ZBB-LABEL: rotr_32_mask:
584; RV64ZBB:       # %bb.0:
585; RV64ZBB-NEXT:    rorw a0, a0, a1
586; RV64ZBB-NEXT:    ret
587;
588; RV32XTHEADBB-LABEL: rotr_32_mask:
589; RV32XTHEADBB:       # %bb.0:
590; RV32XTHEADBB-NEXT:    srl a2, a0, a1
591; RV32XTHEADBB-NEXT:    neg a1, a1
592; RV32XTHEADBB-NEXT:    sll a0, a0, a1
593; RV32XTHEADBB-NEXT:    or a0, a2, a0
594; RV32XTHEADBB-NEXT:    ret
595;
596; RV64XTHEADBB-LABEL: rotr_32_mask:
597; RV64XTHEADBB:       # %bb.0:
598; RV64XTHEADBB-NEXT:    srlw a2, a0, a1
599; RV64XTHEADBB-NEXT:    negw a1, a1
600; RV64XTHEADBB-NEXT:    sllw a0, a0, a1
601; RV64XTHEADBB-NEXT:    or a0, a2, a0
602; RV64XTHEADBB-NEXT:    ret
603  %z = sub i32 0, %y
604  %and = and i32 %z, 31
605  %b = lshr i32 %x, %y
606  %c = shl i32 %x, %and
607  %d = or i32 %b, %c
608  ret i32 %d
609}
610
611define i32 @rotr_32_mask_and_63_and_31(i32 %x, i32 %y) nounwind {
612; RV32I-LABEL: rotr_32_mask_and_63_and_31:
613; RV32I:       # %bb.0:
614; RV32I-NEXT:    srl a2, a0, a1
615; RV32I-NEXT:    neg a1, a1
616; RV32I-NEXT:    sll a0, a0, a1
617; RV32I-NEXT:    or a0, a2, a0
618; RV32I-NEXT:    ret
619;
620; RV64I-LABEL: rotr_32_mask_and_63_and_31:
621; RV64I:       # %bb.0:
622; RV64I-NEXT:    srlw a2, a0, a1
623; RV64I-NEXT:    negw a1, a1
624; RV64I-NEXT:    sllw a0, a0, a1
625; RV64I-NEXT:    or a0, a2, a0
626; RV64I-NEXT:    ret
627;
628; RV32ZBB-LABEL: rotr_32_mask_and_63_and_31:
629; RV32ZBB:       # %bb.0:
630; RV32ZBB-NEXT:    ror a0, a0, a1
631; RV32ZBB-NEXT:    ret
632;
633; RV64ZBB-LABEL: rotr_32_mask_and_63_and_31:
634; RV64ZBB:       # %bb.0:
635; RV64ZBB-NEXT:    rorw a0, a0, a1
636; RV64ZBB-NEXT:    ret
637;
638; RV32XTHEADBB-LABEL: rotr_32_mask_and_63_and_31:
639; RV32XTHEADBB:       # %bb.0:
640; RV32XTHEADBB-NEXT:    srl a2, a0, a1
641; RV32XTHEADBB-NEXT:    neg a1, a1
642; RV32XTHEADBB-NEXT:    sll a0, a0, a1
643; RV32XTHEADBB-NEXT:    or a0, a2, a0
644; RV32XTHEADBB-NEXT:    ret
645;
646; RV64XTHEADBB-LABEL: rotr_32_mask_and_63_and_31:
647; RV64XTHEADBB:       # %bb.0:
648; RV64XTHEADBB-NEXT:    srlw a2, a0, a1
649; RV64XTHEADBB-NEXT:    negw a1, a1
650; RV64XTHEADBB-NEXT:    sllw a0, a0, a1
651; RV64XTHEADBB-NEXT:    or a0, a2, a0
652; RV64XTHEADBB-NEXT:    ret
653  %a = and i32 %y, 63
654  %b = lshr i32 %x, %a
655  %c = sub i32 0, %y
656  %d = and i32 %c, 31
657  %e = shl i32 %x, %d
658  %f = or i32 %b, %e
659  ret i32 %f
660}
661
662define i32 @rotr_32_mask_or_64_or_32(i32 %x, i32 %y) nounwind {
663; RV32I-LABEL: rotr_32_mask_or_64_or_32:
664; RV32I:       # %bb.0:
665; RV32I-NEXT:    li a0, 0
666; RV32I-NEXT:    ret
667;
668; RV64I-LABEL: rotr_32_mask_or_64_or_32:
669; RV64I:       # %bb.0:
670; RV64I-NEXT:    li a0, 0
671; RV64I-NEXT:    ret
672;
673; RV32ZBB-LABEL: rotr_32_mask_or_64_or_32:
674; RV32ZBB:       # %bb.0:
675; RV32ZBB-NEXT:    ror a0, a0, a1
676; RV32ZBB-NEXT:    ret
677;
678; RV64ZBB-LABEL: rotr_32_mask_or_64_or_32:
679; RV64ZBB:       # %bb.0:
680; RV64ZBB-NEXT:    rorw a0, a0, a1
681; RV64ZBB-NEXT:    ret
682;
683; RV32XTHEADBB-LABEL: rotr_32_mask_or_64_or_32:
684; RV32XTHEADBB:       # %bb.0:
685; RV32XTHEADBB-NEXT:    srl a2, a0, a1
686; RV32XTHEADBB-NEXT:    neg a1, a1
687; RV32XTHEADBB-NEXT:    sll a0, a0, a1
688; RV32XTHEADBB-NEXT:    or a0, a2, a0
689; RV32XTHEADBB-NEXT:    ret
690;
691; RV64XTHEADBB-LABEL: rotr_32_mask_or_64_or_32:
692; RV64XTHEADBB:       # %bb.0:
693; RV64XTHEADBB-NEXT:    srlw a2, a0, a1
694; RV64XTHEADBB-NEXT:    negw a1, a1
695; RV64XTHEADBB-NEXT:    sllw a0, a0, a1
696; RV64XTHEADBB-NEXT:    or a0, a2, a0
697; RV64XTHEADBB-NEXT:    ret
698  %a = or i32 %y, 64
699  %b = lshr i32 %x, %a
700  %c = sub i32 0, %y
701  %d = or i32 %c, 32
702  %e = shl i32 %x, %d
703  %f = or i32 %b, %e
704  ret i32 %f
705}
706
707define i64 @rotl_64_mask(i64 %x, i64 %y) nounwind {
708; RV32I-LABEL: rotl_64_mask:
709; RV32I:       # %bb.0:
710; RV32I-NEXT:    addi a5, a2, -32
711; RV32I-NEXT:    sll a4, a0, a2
712; RV32I-NEXT:    bltz a5, .LBB10_2
713; RV32I-NEXT:  # %bb.1:
714; RV32I-NEXT:    mv a3, a4
715; RV32I-NEXT:    j .LBB10_3
716; RV32I-NEXT:  .LBB10_2:
717; RV32I-NEXT:    sll a3, a1, a2
718; RV32I-NEXT:    not a6, a2
719; RV32I-NEXT:    srli a7, a0, 1
720; RV32I-NEXT:    srl a6, a7, a6
721; RV32I-NEXT:    or a3, a3, a6
722; RV32I-NEXT:  .LBB10_3:
723; RV32I-NEXT:    srai t0, a5, 31
724; RV32I-NEXT:    neg a5, a2
725; RV32I-NEXT:    andi a7, a5, 63
726; RV32I-NEXT:    addi a6, a7, -32
727; RV32I-NEXT:    and a2, t0, a4
728; RV32I-NEXT:    bltz a6, .LBB10_5
729; RV32I-NEXT:  # %bb.4:
730; RV32I-NEXT:    srl a0, a1, a7
731; RV32I-NEXT:    j .LBB10_6
732; RV32I-NEXT:  .LBB10_5:
733; RV32I-NEXT:    srl a0, a0, a5
734; RV32I-NEXT:    not a4, a7
735; RV32I-NEXT:    slli a7, a1, 1
736; RV32I-NEXT:    sll a4, a7, a4
737; RV32I-NEXT:    or a0, a0, a4
738; RV32I-NEXT:  .LBB10_6:
739; RV32I-NEXT:    srl a1, a1, a5
740; RV32I-NEXT:    srai a4, a6, 31
741; RV32I-NEXT:    and a1, a4, a1
742; RV32I-NEXT:    or a1, a3, a1
743; RV32I-NEXT:    or a0, a2, a0
744; RV32I-NEXT:    ret
745;
746; RV64I-LABEL: rotl_64_mask:
747; RV64I:       # %bb.0:
748; RV64I-NEXT:    negw a2, a1
749; RV64I-NEXT:    sll a1, a0, a1
750; RV64I-NEXT:    srl a0, a0, a2
751; RV64I-NEXT:    or a0, a1, a0
752; RV64I-NEXT:    ret
753;
754; RV32ZBB-LABEL: rotl_64_mask:
755; RV32ZBB:       # %bb.0:
756; RV32ZBB-NEXT:    addi a5, a2, -32
757; RV32ZBB-NEXT:    sll a4, a0, a2
758; RV32ZBB-NEXT:    bltz a5, .LBB10_2
759; RV32ZBB-NEXT:  # %bb.1:
760; RV32ZBB-NEXT:    mv a3, a4
761; RV32ZBB-NEXT:    j .LBB10_3
762; RV32ZBB-NEXT:  .LBB10_2:
763; RV32ZBB-NEXT:    sll a3, a1, a2
764; RV32ZBB-NEXT:    not a6, a2
765; RV32ZBB-NEXT:    srli a7, a0, 1
766; RV32ZBB-NEXT:    srl a6, a7, a6
767; RV32ZBB-NEXT:    or a3, a3, a6
768; RV32ZBB-NEXT:  .LBB10_3:
769; RV32ZBB-NEXT:    srai t0, a5, 31
770; RV32ZBB-NEXT:    neg a5, a2
771; RV32ZBB-NEXT:    andi a7, a5, 63
772; RV32ZBB-NEXT:    addi a6, a7, -32
773; RV32ZBB-NEXT:    and a2, t0, a4
774; RV32ZBB-NEXT:    bltz a6, .LBB10_5
775; RV32ZBB-NEXT:  # %bb.4:
776; RV32ZBB-NEXT:    srl a0, a1, a7
777; RV32ZBB-NEXT:    j .LBB10_6
778; RV32ZBB-NEXT:  .LBB10_5:
779; RV32ZBB-NEXT:    srl a0, a0, a5
780; RV32ZBB-NEXT:    not a4, a7
781; RV32ZBB-NEXT:    slli a7, a1, 1
782; RV32ZBB-NEXT:    sll a4, a7, a4
783; RV32ZBB-NEXT:    or a0, a0, a4
784; RV32ZBB-NEXT:  .LBB10_6:
785; RV32ZBB-NEXT:    srl a1, a1, a5
786; RV32ZBB-NEXT:    srai a4, a6, 31
787; RV32ZBB-NEXT:    and a1, a4, a1
788; RV32ZBB-NEXT:    or a1, a3, a1
789; RV32ZBB-NEXT:    or a0, a2, a0
790; RV32ZBB-NEXT:    ret
791;
792; RV64ZBB-LABEL: rotl_64_mask:
793; RV64ZBB:       # %bb.0:
794; RV64ZBB-NEXT:    rol a0, a0, a1
795; RV64ZBB-NEXT:    ret
796;
797; RV32XTHEADBB-LABEL: rotl_64_mask:
798; RV32XTHEADBB:       # %bb.0:
799; RV32XTHEADBB-NEXT:    addi a5, a2, -32
800; RV32XTHEADBB-NEXT:    sll a4, a0, a2
801; RV32XTHEADBB-NEXT:    bltz a5, .LBB10_2
802; RV32XTHEADBB-NEXT:  # %bb.1:
803; RV32XTHEADBB-NEXT:    mv a3, a4
804; RV32XTHEADBB-NEXT:    j .LBB10_3
805; RV32XTHEADBB-NEXT:  .LBB10_2:
806; RV32XTHEADBB-NEXT:    sll a3, a1, a2
807; RV32XTHEADBB-NEXT:    not a6, a2
808; RV32XTHEADBB-NEXT:    srli a7, a0, 1
809; RV32XTHEADBB-NEXT:    srl a6, a7, a6
810; RV32XTHEADBB-NEXT:    or a3, a3, a6
811; RV32XTHEADBB-NEXT:  .LBB10_3:
812; RV32XTHEADBB-NEXT:    srai t0, a5, 31
813; RV32XTHEADBB-NEXT:    neg a5, a2
814; RV32XTHEADBB-NEXT:    andi a7, a5, 63
815; RV32XTHEADBB-NEXT:    addi a6, a7, -32
816; RV32XTHEADBB-NEXT:    and a2, t0, a4
817; RV32XTHEADBB-NEXT:    bltz a6, .LBB10_5
818; RV32XTHEADBB-NEXT:  # %bb.4:
819; RV32XTHEADBB-NEXT:    srl a0, a1, a7
820; RV32XTHEADBB-NEXT:    j .LBB10_6
821; RV32XTHEADBB-NEXT:  .LBB10_5:
822; RV32XTHEADBB-NEXT:    srl a0, a0, a5
823; RV32XTHEADBB-NEXT:    not a4, a7
824; RV32XTHEADBB-NEXT:    slli a7, a1, 1
825; RV32XTHEADBB-NEXT:    sll a4, a7, a4
826; RV32XTHEADBB-NEXT:    or a0, a0, a4
827; RV32XTHEADBB-NEXT:  .LBB10_6:
828; RV32XTHEADBB-NEXT:    srl a1, a1, a5
829; RV32XTHEADBB-NEXT:    srai a4, a6, 31
830; RV32XTHEADBB-NEXT:    and a1, a4, a1
831; RV32XTHEADBB-NEXT:    or a1, a3, a1
832; RV32XTHEADBB-NEXT:    or a0, a2, a0
833; RV32XTHEADBB-NEXT:    ret
834;
835; RV64XTHEADBB-LABEL: rotl_64_mask:
836; RV64XTHEADBB:       # %bb.0:
837; RV64XTHEADBB-NEXT:    sll a2, a0, a1
838; RV64XTHEADBB-NEXT:    negw a1, a1
839; RV64XTHEADBB-NEXT:    srl a0, a0, a1
840; RV64XTHEADBB-NEXT:    or a0, a2, a0
841; RV64XTHEADBB-NEXT:    ret
842  %z = sub i64 0, %y
843  %and = and i64 %z, 63
844  %b = shl i64 %x, %y
845  %c = lshr i64 %x, %and
846  %d = or i64 %b, %c
847  ret i64 %d
848}
849
850define i64 @rotl_64_mask_and_127_and_63(i64 %x, i64 %y) nounwind {
851; RV32I-LABEL: rotl_64_mask_and_127_and_63:
852; RV32I:       # %bb.0:
853; RV32I-NEXT:    andi a3, a2, 127
854; RV32I-NEXT:    addi a4, a3, -32
855; RV32I-NEXT:    bltz a4, .LBB11_2
856; RV32I-NEXT:  # %bb.1:
857; RV32I-NEXT:    sll a3, a0, a3
858; RV32I-NEXT:    j .LBB11_3
859; RV32I-NEXT:  .LBB11_2:
860; RV32I-NEXT:    sll a5, a1, a2
861; RV32I-NEXT:    srli a6, a0, 1
862; RV32I-NEXT:    not a3, a3
863; RV32I-NEXT:    srl a3, a6, a3
864; RV32I-NEXT:    or a3, a5, a3
865; RV32I-NEXT:  .LBB11_3:
866; RV32I-NEXT:    sll a7, a0, a2
867; RV32I-NEXT:    srai t0, a4, 31
868; RV32I-NEXT:    neg a4, a2
869; RV32I-NEXT:    andi a6, a4, 63
870; RV32I-NEXT:    addi a5, a6, -32
871; RV32I-NEXT:    and a2, t0, a7
872; RV32I-NEXT:    bltz a5, .LBB11_5
873; RV32I-NEXT:  # %bb.4:
874; RV32I-NEXT:    srl a0, a1, a6
875; RV32I-NEXT:    j .LBB11_6
876; RV32I-NEXT:  .LBB11_5:
877; RV32I-NEXT:    srl a0, a0, a4
878; RV32I-NEXT:    not a6, a6
879; RV32I-NEXT:    slli a7, a1, 1
880; RV32I-NEXT:    sll a6, a7, a6
881; RV32I-NEXT:    or a0, a0, a6
882; RV32I-NEXT:  .LBB11_6:
883; RV32I-NEXT:    srl a1, a1, a4
884; RV32I-NEXT:    srai a5, a5, 31
885; RV32I-NEXT:    and a1, a5, a1
886; RV32I-NEXT:    or a1, a3, a1
887; RV32I-NEXT:    or a0, a2, a0
888; RV32I-NEXT:    ret
889;
890; RV64I-LABEL: rotl_64_mask_and_127_and_63:
891; RV64I:       # %bb.0:
892; RV64I-NEXT:    sll a2, a0, a1
893; RV64I-NEXT:    negw a1, a1
894; RV64I-NEXT:    srl a0, a0, a1
895; RV64I-NEXT:    or a0, a2, a0
896; RV64I-NEXT:    ret
897;
898; RV32ZBB-LABEL: rotl_64_mask_and_127_and_63:
899; RV32ZBB:       # %bb.0:
900; RV32ZBB-NEXT:    andi a3, a2, 127
901; RV32ZBB-NEXT:    addi a4, a3, -32
902; RV32ZBB-NEXT:    bltz a4, .LBB11_2
903; RV32ZBB-NEXT:  # %bb.1:
904; RV32ZBB-NEXT:    sll a3, a0, a3
905; RV32ZBB-NEXT:    j .LBB11_3
906; RV32ZBB-NEXT:  .LBB11_2:
907; RV32ZBB-NEXT:    sll a5, a1, a2
908; RV32ZBB-NEXT:    srli a6, a0, 1
909; RV32ZBB-NEXT:    not a3, a3
910; RV32ZBB-NEXT:    srl a3, a6, a3
911; RV32ZBB-NEXT:    or a3, a5, a3
912; RV32ZBB-NEXT:  .LBB11_3:
913; RV32ZBB-NEXT:    sll a7, a0, a2
914; RV32ZBB-NEXT:    srai t0, a4, 31
915; RV32ZBB-NEXT:    neg a4, a2
916; RV32ZBB-NEXT:    andi a6, a4, 63
917; RV32ZBB-NEXT:    addi a5, a6, -32
918; RV32ZBB-NEXT:    and a2, t0, a7
919; RV32ZBB-NEXT:    bltz a5, .LBB11_5
920; RV32ZBB-NEXT:  # %bb.4:
921; RV32ZBB-NEXT:    srl a0, a1, a6
922; RV32ZBB-NEXT:    j .LBB11_6
923; RV32ZBB-NEXT:  .LBB11_5:
924; RV32ZBB-NEXT:    srl a0, a0, a4
925; RV32ZBB-NEXT:    not a6, a6
926; RV32ZBB-NEXT:    slli a7, a1, 1
927; RV32ZBB-NEXT:    sll a6, a7, a6
928; RV32ZBB-NEXT:    or a0, a0, a6
929; RV32ZBB-NEXT:  .LBB11_6:
930; RV32ZBB-NEXT:    srl a1, a1, a4
931; RV32ZBB-NEXT:    srai a5, a5, 31
932; RV32ZBB-NEXT:    and a1, a5, a1
933; RV32ZBB-NEXT:    or a1, a3, a1
934; RV32ZBB-NEXT:    or a0, a2, a0
935; RV32ZBB-NEXT:    ret
936;
937; RV64ZBB-LABEL: rotl_64_mask_and_127_and_63:
938; RV64ZBB:       # %bb.0:
939; RV64ZBB-NEXT:    rol a0, a0, a1
940; RV64ZBB-NEXT:    ret
941;
942; RV32XTHEADBB-LABEL: rotl_64_mask_and_127_and_63:
943; RV32XTHEADBB:       # %bb.0:
944; RV32XTHEADBB-NEXT:    andi a3, a2, 127
945; RV32XTHEADBB-NEXT:    addi a4, a3, -32
946; RV32XTHEADBB-NEXT:    bltz a4, .LBB11_2
947; RV32XTHEADBB-NEXT:  # %bb.1:
948; RV32XTHEADBB-NEXT:    sll a3, a0, a3
949; RV32XTHEADBB-NEXT:    j .LBB11_3
950; RV32XTHEADBB-NEXT:  .LBB11_2:
951; RV32XTHEADBB-NEXT:    sll a5, a1, a2
952; RV32XTHEADBB-NEXT:    srli a6, a0, 1
953; RV32XTHEADBB-NEXT:    not a3, a3
954; RV32XTHEADBB-NEXT:    srl a3, a6, a3
955; RV32XTHEADBB-NEXT:    or a3, a5, a3
956; RV32XTHEADBB-NEXT:  .LBB11_3:
957; RV32XTHEADBB-NEXT:    sll a7, a0, a2
958; RV32XTHEADBB-NEXT:    srai t0, a4, 31
959; RV32XTHEADBB-NEXT:    neg a4, a2
960; RV32XTHEADBB-NEXT:    andi a6, a4, 63
961; RV32XTHEADBB-NEXT:    addi a5, a6, -32
962; RV32XTHEADBB-NEXT:    and a2, t0, a7
963; RV32XTHEADBB-NEXT:    bltz a5, .LBB11_5
964; RV32XTHEADBB-NEXT:  # %bb.4:
965; RV32XTHEADBB-NEXT:    srl a0, a1, a6
966; RV32XTHEADBB-NEXT:    j .LBB11_6
967; RV32XTHEADBB-NEXT:  .LBB11_5:
968; RV32XTHEADBB-NEXT:    srl a0, a0, a4
969; RV32XTHEADBB-NEXT:    not a6, a6
970; RV32XTHEADBB-NEXT:    slli a7, a1, 1
971; RV32XTHEADBB-NEXT:    sll a6, a7, a6
972; RV32XTHEADBB-NEXT:    or a0, a0, a6
973; RV32XTHEADBB-NEXT:  .LBB11_6:
974; RV32XTHEADBB-NEXT:    srl a1, a1, a4
975; RV32XTHEADBB-NEXT:    srai a5, a5, 31
976; RV32XTHEADBB-NEXT:    and a1, a5, a1
977; RV32XTHEADBB-NEXT:    or a1, a3, a1
978; RV32XTHEADBB-NEXT:    or a0, a2, a0
979; RV32XTHEADBB-NEXT:    ret
980;
981; RV64XTHEADBB-LABEL: rotl_64_mask_and_127_and_63:
982; RV64XTHEADBB:       # %bb.0:
983; RV64XTHEADBB-NEXT:    sll a2, a0, a1
984; RV64XTHEADBB-NEXT:    negw a1, a1
985; RV64XTHEADBB-NEXT:    srl a0, a0, a1
986; RV64XTHEADBB-NEXT:    or a0, a2, a0
987; RV64XTHEADBB-NEXT:    ret
988  %a = and i64 %y, 127
989  %b = shl i64 %x, %a
990  %c = sub i64 0, %y
991  %d = and i64 %c, 63
992  %e = lshr i64 %x, %d
993  %f = or i64 %b, %e
994  ret i64 %f
995}
996
997define i64 @rotl_64_mask_or_128_or_64(i64 %x, i64 %y) nounwind {
998; RV32I-LABEL: rotl_64_mask_or_128_or_64:
999; RV32I:       # %bb.0:
1000; RV32I-NEXT:    li a0, 0
1001; RV32I-NEXT:    li a1, 0
1002; RV32I-NEXT:    ret
1003;
1004; RV64I-LABEL: rotl_64_mask_or_128_or_64:
1005; RV64I:       # %bb.0:
1006; RV64I-NEXT:    li a0, 0
1007; RV64I-NEXT:    ret
1008;
1009; RV32ZBB-LABEL: rotl_64_mask_or_128_or_64:
1010; RV32ZBB:       # %bb.0:
1011; RV32ZBB-NEXT:    li a0, 0
1012; RV32ZBB-NEXT:    li a1, 0
1013; RV32ZBB-NEXT:    ret
1014;
1015; RV64ZBB-LABEL: rotl_64_mask_or_128_or_64:
1016; RV64ZBB:       # %bb.0:
1017; RV64ZBB-NEXT:    rol a0, a0, a1
1018; RV64ZBB-NEXT:    ret
1019;
1020; RV32XTHEADBB-LABEL: rotl_64_mask_or_128_or_64:
1021; RV32XTHEADBB:       # %bb.0:
1022; RV32XTHEADBB-NEXT:    li a0, 0
1023; RV32XTHEADBB-NEXT:    li a1, 0
1024; RV32XTHEADBB-NEXT:    ret
1025;
1026; RV64XTHEADBB-LABEL: rotl_64_mask_or_128_or_64:
1027; RV64XTHEADBB:       # %bb.0:
1028; RV64XTHEADBB-NEXT:    sll a2, a0, a1
1029; RV64XTHEADBB-NEXT:    negw a1, a1
1030; RV64XTHEADBB-NEXT:    srl a0, a0, a1
1031; RV64XTHEADBB-NEXT:    or a0, a2, a0
1032; RV64XTHEADBB-NEXT:    ret
1033  %a = or i64 %y, 128
1034  %b = shl i64 %x, %a
1035  %c = sub i64 0, %y
1036  %d = or i64 %c, 64
1037  %e = lshr i64 %x, %d
1038  %f = or i64 %b, %e
1039  ret i64 %f
1040}
1041
1042define i64 @rotr_64_mask(i64 %x, i64 %y) nounwind {
1043; RV32I-LABEL: rotr_64_mask:
1044; RV32I:       # %bb.0:
1045; RV32I-NEXT:    addi a5, a2, -32
1046; RV32I-NEXT:    srl a4, a1, a2
1047; RV32I-NEXT:    bltz a5, .LBB13_2
1048; RV32I-NEXT:  # %bb.1:
1049; RV32I-NEXT:    mv a3, a4
1050; RV32I-NEXT:    j .LBB13_3
1051; RV32I-NEXT:  .LBB13_2:
1052; RV32I-NEXT:    srl a3, a0, a2
1053; RV32I-NEXT:    not a6, a2
1054; RV32I-NEXT:    slli a7, a1, 1
1055; RV32I-NEXT:    sll a6, a7, a6
1056; RV32I-NEXT:    or a3, a3, a6
1057; RV32I-NEXT:  .LBB13_3:
1058; RV32I-NEXT:    srai t0, a5, 31
1059; RV32I-NEXT:    neg a5, a2
1060; RV32I-NEXT:    andi a7, a5, 63
1061; RV32I-NEXT:    addi a6, a7, -32
1062; RV32I-NEXT:    and a2, t0, a4
1063; RV32I-NEXT:    bltz a6, .LBB13_5
1064; RV32I-NEXT:  # %bb.4:
1065; RV32I-NEXT:    sll a1, a0, a7
1066; RV32I-NEXT:    j .LBB13_6
1067; RV32I-NEXT:  .LBB13_5:
1068; RV32I-NEXT:    sll a1, a1, a5
1069; RV32I-NEXT:    not a4, a7
1070; RV32I-NEXT:    srli a7, a0, 1
1071; RV32I-NEXT:    srl a4, a7, a4
1072; RV32I-NEXT:    or a1, a1, a4
1073; RV32I-NEXT:  .LBB13_6:
1074; RV32I-NEXT:    sll a0, a0, a5
1075; RV32I-NEXT:    srai a4, a6, 31
1076; RV32I-NEXT:    and a0, a4, a0
1077; RV32I-NEXT:    or a0, a3, a0
1078; RV32I-NEXT:    or a1, a2, a1
1079; RV32I-NEXT:    ret
1080;
1081; RV64I-LABEL: rotr_64_mask:
1082; RV64I:       # %bb.0:
1083; RV64I-NEXT:    negw a2, a1
1084; RV64I-NEXT:    srl a1, a0, a1
1085; RV64I-NEXT:    sll a0, a0, a2
1086; RV64I-NEXT:    or a0, a1, a0
1087; RV64I-NEXT:    ret
1088;
1089; RV32ZBB-LABEL: rotr_64_mask:
1090; RV32ZBB:       # %bb.0:
1091; RV32ZBB-NEXT:    addi a5, a2, -32
1092; RV32ZBB-NEXT:    srl a4, a1, a2
1093; RV32ZBB-NEXT:    bltz a5, .LBB13_2
1094; RV32ZBB-NEXT:  # %bb.1:
1095; RV32ZBB-NEXT:    mv a3, a4
1096; RV32ZBB-NEXT:    j .LBB13_3
1097; RV32ZBB-NEXT:  .LBB13_2:
1098; RV32ZBB-NEXT:    srl a3, a0, a2
1099; RV32ZBB-NEXT:    not a6, a2
1100; RV32ZBB-NEXT:    slli a7, a1, 1
1101; RV32ZBB-NEXT:    sll a6, a7, a6
1102; RV32ZBB-NEXT:    or a3, a3, a6
1103; RV32ZBB-NEXT:  .LBB13_3:
1104; RV32ZBB-NEXT:    srai t0, a5, 31
1105; RV32ZBB-NEXT:    neg a5, a2
1106; RV32ZBB-NEXT:    andi a7, a5, 63
1107; RV32ZBB-NEXT:    addi a6, a7, -32
1108; RV32ZBB-NEXT:    and a2, t0, a4
1109; RV32ZBB-NEXT:    bltz a6, .LBB13_5
1110; RV32ZBB-NEXT:  # %bb.4:
1111; RV32ZBB-NEXT:    sll a1, a0, a7
1112; RV32ZBB-NEXT:    j .LBB13_6
1113; RV32ZBB-NEXT:  .LBB13_5:
1114; RV32ZBB-NEXT:    sll a1, a1, a5
1115; RV32ZBB-NEXT:    not a4, a7
1116; RV32ZBB-NEXT:    srli a7, a0, 1
1117; RV32ZBB-NEXT:    srl a4, a7, a4
1118; RV32ZBB-NEXT:    or a1, a1, a4
1119; RV32ZBB-NEXT:  .LBB13_6:
1120; RV32ZBB-NEXT:    sll a0, a0, a5
1121; RV32ZBB-NEXT:    srai a4, a6, 31
1122; RV32ZBB-NEXT:    and a0, a4, a0
1123; RV32ZBB-NEXT:    or a0, a3, a0
1124; RV32ZBB-NEXT:    or a1, a2, a1
1125; RV32ZBB-NEXT:    ret
1126;
1127; RV64ZBB-LABEL: rotr_64_mask:
1128; RV64ZBB:       # %bb.0:
1129; RV64ZBB-NEXT:    ror a0, a0, a1
1130; RV64ZBB-NEXT:    ret
1131;
1132; RV32XTHEADBB-LABEL: rotr_64_mask:
1133; RV32XTHEADBB:       # %bb.0:
1134; RV32XTHEADBB-NEXT:    addi a5, a2, -32
1135; RV32XTHEADBB-NEXT:    srl a4, a1, a2
1136; RV32XTHEADBB-NEXT:    bltz a5, .LBB13_2
1137; RV32XTHEADBB-NEXT:  # %bb.1:
1138; RV32XTHEADBB-NEXT:    mv a3, a4
1139; RV32XTHEADBB-NEXT:    j .LBB13_3
1140; RV32XTHEADBB-NEXT:  .LBB13_2:
1141; RV32XTHEADBB-NEXT:    srl a3, a0, a2
1142; RV32XTHEADBB-NEXT:    not a6, a2
1143; RV32XTHEADBB-NEXT:    slli a7, a1, 1
1144; RV32XTHEADBB-NEXT:    sll a6, a7, a6
1145; RV32XTHEADBB-NEXT:    or a3, a3, a6
1146; RV32XTHEADBB-NEXT:  .LBB13_3:
1147; RV32XTHEADBB-NEXT:    srai t0, a5, 31
1148; RV32XTHEADBB-NEXT:    neg a5, a2
1149; RV32XTHEADBB-NEXT:    andi a7, a5, 63
1150; RV32XTHEADBB-NEXT:    addi a6, a7, -32
1151; RV32XTHEADBB-NEXT:    and a2, t0, a4
1152; RV32XTHEADBB-NEXT:    bltz a6, .LBB13_5
1153; RV32XTHEADBB-NEXT:  # %bb.4:
1154; RV32XTHEADBB-NEXT:    sll a1, a0, a7
1155; RV32XTHEADBB-NEXT:    j .LBB13_6
1156; RV32XTHEADBB-NEXT:  .LBB13_5:
1157; RV32XTHEADBB-NEXT:    sll a1, a1, a5
1158; RV32XTHEADBB-NEXT:    not a4, a7
1159; RV32XTHEADBB-NEXT:    srli a7, a0, 1
1160; RV32XTHEADBB-NEXT:    srl a4, a7, a4
1161; RV32XTHEADBB-NEXT:    or a1, a1, a4
1162; RV32XTHEADBB-NEXT:  .LBB13_6:
1163; RV32XTHEADBB-NEXT:    sll a0, a0, a5
1164; RV32XTHEADBB-NEXT:    srai a4, a6, 31
1165; RV32XTHEADBB-NEXT:    and a0, a4, a0
1166; RV32XTHEADBB-NEXT:    or a0, a3, a0
1167; RV32XTHEADBB-NEXT:    or a1, a2, a1
1168; RV32XTHEADBB-NEXT:    ret
1169;
1170; RV64XTHEADBB-LABEL: rotr_64_mask:
1171; RV64XTHEADBB:       # %bb.0:
1172; RV64XTHEADBB-NEXT:    srl a2, a0, a1
1173; RV64XTHEADBB-NEXT:    negw a1, a1
1174; RV64XTHEADBB-NEXT:    sll a0, a0, a1
1175; RV64XTHEADBB-NEXT:    or a0, a2, a0
1176; RV64XTHEADBB-NEXT:    ret
1177  %z = sub i64 0, %y
1178  %and = and i64 %z, 63
1179  %b = lshr i64 %x, %y
1180  %c = shl i64 %x, %and
1181  %d = or i64 %b, %c
1182  ret i64 %d
1183}
1184
1185define i64 @rotr_64_mask_and_127_and_63(i64 %x, i64 %y) nounwind {
1186; RV32I-LABEL: rotr_64_mask_and_127_and_63:
1187; RV32I:       # %bb.0:
1188; RV32I-NEXT:    andi a3, a2, 127
1189; RV32I-NEXT:    addi a4, a3, -32
1190; RV32I-NEXT:    bltz a4, .LBB14_2
1191; RV32I-NEXT:  # %bb.1:
1192; RV32I-NEXT:    srl a3, a1, a3
1193; RV32I-NEXT:    j .LBB14_3
1194; RV32I-NEXT:  .LBB14_2:
1195; RV32I-NEXT:    srl a5, a0, a2
1196; RV32I-NEXT:    slli a6, a1, 1
1197; RV32I-NEXT:    not a3, a3
1198; RV32I-NEXT:    sll a3, a6, a3
1199; RV32I-NEXT:    or a3, a5, a3
1200; RV32I-NEXT:  .LBB14_3:
1201; RV32I-NEXT:    srl a7, a1, a2
1202; RV32I-NEXT:    srai t0, a4, 31
1203; RV32I-NEXT:    neg a4, a2
1204; RV32I-NEXT:    andi a6, a4, 63
1205; RV32I-NEXT:    addi a5, a6, -32
1206; RV32I-NEXT:    and a2, t0, a7
1207; RV32I-NEXT:    bltz a5, .LBB14_5
1208; RV32I-NEXT:  # %bb.4:
1209; RV32I-NEXT:    sll a1, a0, a6
1210; RV32I-NEXT:    j .LBB14_6
1211; RV32I-NEXT:  .LBB14_5:
1212; RV32I-NEXT:    sll a1, a1, a4
1213; RV32I-NEXT:    not a6, a6
1214; RV32I-NEXT:    srli a7, a0, 1
1215; RV32I-NEXT:    srl a6, a7, a6
1216; RV32I-NEXT:    or a1, a1, a6
1217; RV32I-NEXT:  .LBB14_6:
1218; RV32I-NEXT:    sll a0, a0, a4
1219; RV32I-NEXT:    srai a5, a5, 31
1220; RV32I-NEXT:    and a0, a5, a0
1221; RV32I-NEXT:    or a0, a3, a0
1222; RV32I-NEXT:    or a1, a2, a1
1223; RV32I-NEXT:    ret
1224;
1225; RV64I-LABEL: rotr_64_mask_and_127_and_63:
1226; RV64I:       # %bb.0:
1227; RV64I-NEXT:    srl a2, a0, a1
1228; RV64I-NEXT:    negw a1, a1
1229; RV64I-NEXT:    sll a0, a0, a1
1230; RV64I-NEXT:    or a0, a2, a0
1231; RV64I-NEXT:    ret
1232;
1233; RV32ZBB-LABEL: rotr_64_mask_and_127_and_63:
1234; RV32ZBB:       # %bb.0:
1235; RV32ZBB-NEXT:    andi a3, a2, 127
1236; RV32ZBB-NEXT:    addi a4, a3, -32
1237; RV32ZBB-NEXT:    bltz a4, .LBB14_2
1238; RV32ZBB-NEXT:  # %bb.1:
1239; RV32ZBB-NEXT:    srl a3, a1, a3
1240; RV32ZBB-NEXT:    j .LBB14_3
1241; RV32ZBB-NEXT:  .LBB14_2:
1242; RV32ZBB-NEXT:    srl a5, a0, a2
1243; RV32ZBB-NEXT:    slli a6, a1, 1
1244; RV32ZBB-NEXT:    not a3, a3
1245; RV32ZBB-NEXT:    sll a3, a6, a3
1246; RV32ZBB-NEXT:    or a3, a5, a3
1247; RV32ZBB-NEXT:  .LBB14_3:
1248; RV32ZBB-NEXT:    srl a7, a1, a2
1249; RV32ZBB-NEXT:    srai t0, a4, 31
1250; RV32ZBB-NEXT:    neg a4, a2
1251; RV32ZBB-NEXT:    andi a6, a4, 63
1252; RV32ZBB-NEXT:    addi a5, a6, -32
1253; RV32ZBB-NEXT:    and a2, t0, a7
1254; RV32ZBB-NEXT:    bltz a5, .LBB14_5
1255; RV32ZBB-NEXT:  # %bb.4:
1256; RV32ZBB-NEXT:    sll a1, a0, a6
1257; RV32ZBB-NEXT:    j .LBB14_6
1258; RV32ZBB-NEXT:  .LBB14_5:
1259; RV32ZBB-NEXT:    sll a1, a1, a4
1260; RV32ZBB-NEXT:    not a6, a6
1261; RV32ZBB-NEXT:    srli a7, a0, 1
1262; RV32ZBB-NEXT:    srl a6, a7, a6
1263; RV32ZBB-NEXT:    or a1, a1, a6
1264; RV32ZBB-NEXT:  .LBB14_6:
1265; RV32ZBB-NEXT:    sll a0, a0, a4
1266; RV32ZBB-NEXT:    srai a5, a5, 31
1267; RV32ZBB-NEXT:    and a0, a5, a0
1268; RV32ZBB-NEXT:    or a0, a3, a0
1269; RV32ZBB-NEXT:    or a1, a2, a1
1270; RV32ZBB-NEXT:    ret
1271;
1272; RV64ZBB-LABEL: rotr_64_mask_and_127_and_63:
1273; RV64ZBB:       # %bb.0:
1274; RV64ZBB-NEXT:    ror a0, a0, a1
1275; RV64ZBB-NEXT:    ret
1276;
1277; RV32XTHEADBB-LABEL: rotr_64_mask_and_127_and_63:
1278; RV32XTHEADBB:       # %bb.0:
1279; RV32XTHEADBB-NEXT:    andi a3, a2, 127
1280; RV32XTHEADBB-NEXT:    addi a4, a3, -32
1281; RV32XTHEADBB-NEXT:    bltz a4, .LBB14_2
1282; RV32XTHEADBB-NEXT:  # %bb.1:
1283; RV32XTHEADBB-NEXT:    srl a3, a1, a3
1284; RV32XTHEADBB-NEXT:    j .LBB14_3
1285; RV32XTHEADBB-NEXT:  .LBB14_2:
1286; RV32XTHEADBB-NEXT:    srl a5, a0, a2
1287; RV32XTHEADBB-NEXT:    slli a6, a1, 1
1288; RV32XTHEADBB-NEXT:    not a3, a3
1289; RV32XTHEADBB-NEXT:    sll a3, a6, a3
1290; RV32XTHEADBB-NEXT:    or a3, a5, a3
1291; RV32XTHEADBB-NEXT:  .LBB14_3:
1292; RV32XTHEADBB-NEXT:    srl a7, a1, a2
1293; RV32XTHEADBB-NEXT:    srai t0, a4, 31
1294; RV32XTHEADBB-NEXT:    neg a4, a2
1295; RV32XTHEADBB-NEXT:    andi a6, a4, 63
1296; RV32XTHEADBB-NEXT:    addi a5, a6, -32
1297; RV32XTHEADBB-NEXT:    and a2, t0, a7
1298; RV32XTHEADBB-NEXT:    bltz a5, .LBB14_5
1299; RV32XTHEADBB-NEXT:  # %bb.4:
1300; RV32XTHEADBB-NEXT:    sll a1, a0, a6
1301; RV32XTHEADBB-NEXT:    j .LBB14_6
1302; RV32XTHEADBB-NEXT:  .LBB14_5:
1303; RV32XTHEADBB-NEXT:    sll a1, a1, a4
1304; RV32XTHEADBB-NEXT:    not a6, a6
1305; RV32XTHEADBB-NEXT:    srli a7, a0, 1
1306; RV32XTHEADBB-NEXT:    srl a6, a7, a6
1307; RV32XTHEADBB-NEXT:    or a1, a1, a6
1308; RV32XTHEADBB-NEXT:  .LBB14_6:
1309; RV32XTHEADBB-NEXT:    sll a0, a0, a4
1310; RV32XTHEADBB-NEXT:    srai a5, a5, 31
1311; RV32XTHEADBB-NEXT:    and a0, a5, a0
1312; RV32XTHEADBB-NEXT:    or a0, a3, a0
1313; RV32XTHEADBB-NEXT:    or a1, a2, a1
1314; RV32XTHEADBB-NEXT:    ret
1315;
1316; RV64XTHEADBB-LABEL: rotr_64_mask_and_127_and_63:
1317; RV64XTHEADBB:       # %bb.0:
1318; RV64XTHEADBB-NEXT:    srl a2, a0, a1
1319; RV64XTHEADBB-NEXT:    negw a1, a1
1320; RV64XTHEADBB-NEXT:    sll a0, a0, a1
1321; RV64XTHEADBB-NEXT:    or a0, a2, a0
1322; RV64XTHEADBB-NEXT:    ret
1323  %a = and i64 %y, 127
1324  %b = lshr i64 %x, %a
1325  %c = sub i64 0, %y
1326  %d = and i64 %c, 63
1327  %e = shl i64 %x, %d
1328  %f = or i64 %b, %e
1329  ret i64 %f
1330}
1331
1332define i64 @rotr_64_mask_or_128_or_64(i64 %x, i64 %y) nounwind {
1333; RV32I-LABEL: rotr_64_mask_or_128_or_64:
1334; RV32I:       # %bb.0:
1335; RV32I-NEXT:    li a0, 0
1336; RV32I-NEXT:    li a1, 0
1337; RV32I-NEXT:    ret
1338;
1339; RV64I-LABEL: rotr_64_mask_or_128_or_64:
1340; RV64I:       # %bb.0:
1341; RV64I-NEXT:    li a0, 0
1342; RV64I-NEXT:    ret
1343;
1344; RV32ZBB-LABEL: rotr_64_mask_or_128_or_64:
1345; RV32ZBB:       # %bb.0:
1346; RV32ZBB-NEXT:    li a0, 0
1347; RV32ZBB-NEXT:    li a1, 0
1348; RV32ZBB-NEXT:    ret
1349;
1350; RV64ZBB-LABEL: rotr_64_mask_or_128_or_64:
1351; RV64ZBB:       # %bb.0:
1352; RV64ZBB-NEXT:    ror a0, a0, a1
1353; RV64ZBB-NEXT:    ret
1354;
1355; RV32XTHEADBB-LABEL: rotr_64_mask_or_128_or_64:
1356; RV32XTHEADBB:       # %bb.0:
1357; RV32XTHEADBB-NEXT:    li a0, 0
1358; RV32XTHEADBB-NEXT:    li a1, 0
1359; RV32XTHEADBB-NEXT:    ret
1360;
1361; RV64XTHEADBB-LABEL: rotr_64_mask_or_128_or_64:
1362; RV64XTHEADBB:       # %bb.0:
1363; RV64XTHEADBB-NEXT:    srl a2, a0, a1
1364; RV64XTHEADBB-NEXT:    negw a1, a1
1365; RV64XTHEADBB-NEXT:    sll a0, a0, a1
1366; RV64XTHEADBB-NEXT:    or a0, a2, a0
1367; RV64XTHEADBB-NEXT:    ret
1368  %a = or i64 %y, 128
1369  %b = lshr i64 %x, %a
1370  %c = sub i64 0, %y
1371  %d = or i64 %c, 64
1372  %e = shl i64 %x, %d
1373  %f = or i64 %b, %e
1374  ret i64 %f
1375}
1376
1377; Test that we're able to remove a mask on the rotate amount that has more than
1378; one use.
1379define signext i32 @rotl_32_mask_shared(i32 signext %a, i32 signext %b, i32 signext %amt) nounwind {
1380; RV32I-LABEL: rotl_32_mask_shared:
1381; RV32I:       # %bb.0:
1382; RV32I-NEXT:    sll a3, a0, a2
1383; RV32I-NEXT:    neg a4, a2
1384; RV32I-NEXT:    srl a0, a0, a4
1385; RV32I-NEXT:    or a0, a3, a0
1386; RV32I-NEXT:    sll a1, a1, a2
1387; RV32I-NEXT:    add a0, a0, a1
1388; RV32I-NEXT:    ret
1389;
1390; RV64I-LABEL: rotl_32_mask_shared:
1391; RV64I:       # %bb.0:
1392; RV64I-NEXT:    sllw a3, a0, a2
1393; RV64I-NEXT:    negw a4, a2
1394; RV64I-NEXT:    srlw a0, a0, a4
1395; RV64I-NEXT:    or a0, a3, a0
1396; RV64I-NEXT:    sllw a1, a1, a2
1397; RV64I-NEXT:    addw a0, a0, a1
1398; RV64I-NEXT:    ret
1399;
1400; RV32ZBB-LABEL: rotl_32_mask_shared:
1401; RV32ZBB:       # %bb.0:
1402; RV32ZBB-NEXT:    rol a0, a0, a2
1403; RV32ZBB-NEXT:    sll a1, a1, a2
1404; RV32ZBB-NEXT:    add a0, a0, a1
1405; RV32ZBB-NEXT:    ret
1406;
1407; RV64ZBB-LABEL: rotl_32_mask_shared:
1408; RV64ZBB:       # %bb.0:
1409; RV64ZBB-NEXT:    rolw a0, a0, a2
1410; RV64ZBB-NEXT:    sllw a1, a1, a2
1411; RV64ZBB-NEXT:    addw a0, a0, a1
1412; RV64ZBB-NEXT:    ret
1413;
1414; RV32XTHEADBB-LABEL: rotl_32_mask_shared:
1415; RV32XTHEADBB:       # %bb.0:
1416; RV32XTHEADBB-NEXT:    sll a3, a0, a2
1417; RV32XTHEADBB-NEXT:    neg a4, a2
1418; RV32XTHEADBB-NEXT:    srl a0, a0, a4
1419; RV32XTHEADBB-NEXT:    or a0, a3, a0
1420; RV32XTHEADBB-NEXT:    sll a1, a1, a2
1421; RV32XTHEADBB-NEXT:    add a0, a0, a1
1422; RV32XTHEADBB-NEXT:    ret
1423;
1424; RV64XTHEADBB-LABEL: rotl_32_mask_shared:
1425; RV64XTHEADBB:       # %bb.0:
1426; RV64XTHEADBB-NEXT:    sllw a3, a0, a2
1427; RV64XTHEADBB-NEXT:    negw a4, a2
1428; RV64XTHEADBB-NEXT:    srlw a0, a0, a4
1429; RV64XTHEADBB-NEXT:    or a0, a3, a0
1430; RV64XTHEADBB-NEXT:    sllw a1, a1, a2
1431; RV64XTHEADBB-NEXT:    addw a0, a0, a1
1432; RV64XTHEADBB-NEXT:    ret
1433  %maskedamt = and i32 %amt, 31
1434  %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %maskedamt)
1435  %2 = shl i32 %b, %maskedamt
1436  %3 = add i32 %1, %2
1437  ret i32 %3
1438}
1439declare i32 @llvm.fshl.i32(i32, i32, i32)
1440
1441define signext i64 @rotl_64_mask_shared(i64 signext %a, i64 signext %b, i64 signext %amt) nounwind {
1442; RV32I-LABEL: rotl_64_mask_shared:
1443; RV32I:       # %bb.0:
1444; RV32I-NEXT:    slli a5, a4, 26
1445; RV32I-NEXT:    srli t0, a5, 31
1446; RV32I-NEXT:    mv a6, a0
1447; RV32I-NEXT:    bnez t0, .LBB17_2
1448; RV32I-NEXT:  # %bb.1:
1449; RV32I-NEXT:    mv a6, a1
1450; RV32I-NEXT:  .LBB17_2:
1451; RV32I-NEXT:    andi a5, a4, 63
1452; RV32I-NEXT:    sll a7, a6, a4
1453; RV32I-NEXT:    bnez t0, .LBB17_4
1454; RV32I-NEXT:  # %bb.3:
1455; RV32I-NEXT:    mv a1, a0
1456; RV32I-NEXT:  .LBB17_4:
1457; RV32I-NEXT:    srli a0, a1, 1
1458; RV32I-NEXT:    not t0, a4
1459; RV32I-NEXT:    sll t1, a1, a4
1460; RV32I-NEXT:    srli a1, a6, 1
1461; RV32I-NEXT:    srl a6, a0, t0
1462; RV32I-NEXT:    srl t0, a1, t0
1463; RV32I-NEXT:    addi a0, a5, -32
1464; RV32I-NEXT:    or a1, a7, a6
1465; RV32I-NEXT:    or a6, t1, t0
1466; RV32I-NEXT:    bltz a0, .LBB17_6
1467; RV32I-NEXT:  # %bb.5:
1468; RV32I-NEXT:    sll a3, a2, a5
1469; RV32I-NEXT:    j .LBB17_7
1470; RV32I-NEXT:  .LBB17_6:
1471; RV32I-NEXT:    sll a3, a3, a4
1472; RV32I-NEXT:    srli a7, a2, 1
1473; RV32I-NEXT:    not a5, a5
1474; RV32I-NEXT:    srl a5, a7, a5
1475; RV32I-NEXT:    or a3, a3, a5
1476; RV32I-NEXT:  .LBB17_7:
1477; RV32I-NEXT:    sll a2, a2, a4
1478; RV32I-NEXT:    srai a0, a0, 31
1479; RV32I-NEXT:    and a0, a0, a2
1480; RV32I-NEXT:    add a0, a6, a0
1481; RV32I-NEXT:    sltu a2, a0, a6
1482; RV32I-NEXT:    add a1, a1, a3
1483; RV32I-NEXT:    add a1, a1, a2
1484; RV32I-NEXT:    ret
1485;
1486; RV64I-LABEL: rotl_64_mask_shared:
1487; RV64I:       # %bb.0:
1488; RV64I-NEXT:    sll a3, a0, a2
1489; RV64I-NEXT:    negw a4, a2
1490; RV64I-NEXT:    srl a0, a0, a4
1491; RV64I-NEXT:    or a0, a3, a0
1492; RV64I-NEXT:    sll a1, a1, a2
1493; RV64I-NEXT:    add a0, a0, a1
1494; RV64I-NEXT:    ret
1495;
1496; RV32ZBB-LABEL: rotl_64_mask_shared:
1497; RV32ZBB:       # %bb.0:
1498; RV32ZBB-NEXT:    slli a5, a4, 26
1499; RV32ZBB-NEXT:    srli t0, a5, 31
1500; RV32ZBB-NEXT:    mv a6, a0
1501; RV32ZBB-NEXT:    bnez t0, .LBB17_2
1502; RV32ZBB-NEXT:  # %bb.1:
1503; RV32ZBB-NEXT:    mv a6, a1
1504; RV32ZBB-NEXT:  .LBB17_2:
1505; RV32ZBB-NEXT:    andi a5, a4, 63
1506; RV32ZBB-NEXT:    sll a7, a6, a4
1507; RV32ZBB-NEXT:    bnez t0, .LBB17_4
1508; RV32ZBB-NEXT:  # %bb.3:
1509; RV32ZBB-NEXT:    mv a1, a0
1510; RV32ZBB-NEXT:  .LBB17_4:
1511; RV32ZBB-NEXT:    srli a0, a1, 1
1512; RV32ZBB-NEXT:    not t0, a4
1513; RV32ZBB-NEXT:    sll t1, a1, a4
1514; RV32ZBB-NEXT:    srli a1, a6, 1
1515; RV32ZBB-NEXT:    srl a6, a0, t0
1516; RV32ZBB-NEXT:    srl t0, a1, t0
1517; RV32ZBB-NEXT:    addi a0, a5, -32
1518; RV32ZBB-NEXT:    or a1, a7, a6
1519; RV32ZBB-NEXT:    or a6, t1, t0
1520; RV32ZBB-NEXT:    bltz a0, .LBB17_6
1521; RV32ZBB-NEXT:  # %bb.5:
1522; RV32ZBB-NEXT:    sll a3, a2, a5
1523; RV32ZBB-NEXT:    j .LBB17_7
1524; RV32ZBB-NEXT:  .LBB17_6:
1525; RV32ZBB-NEXT:    sll a3, a3, a4
1526; RV32ZBB-NEXT:    srli a7, a2, 1
1527; RV32ZBB-NEXT:    not a5, a5
1528; RV32ZBB-NEXT:    srl a5, a7, a5
1529; RV32ZBB-NEXT:    or a3, a3, a5
1530; RV32ZBB-NEXT:  .LBB17_7:
1531; RV32ZBB-NEXT:    sll a2, a2, a4
1532; RV32ZBB-NEXT:    srai a0, a0, 31
1533; RV32ZBB-NEXT:    and a0, a0, a2
1534; RV32ZBB-NEXT:    add a0, a6, a0
1535; RV32ZBB-NEXT:    sltu a2, a0, a6
1536; RV32ZBB-NEXT:    add a1, a1, a3
1537; RV32ZBB-NEXT:    add a1, a1, a2
1538; RV32ZBB-NEXT:    ret
1539;
1540; RV64ZBB-LABEL: rotl_64_mask_shared:
1541; RV64ZBB:       # %bb.0:
1542; RV64ZBB-NEXT:    rol a0, a0, a2
1543; RV64ZBB-NEXT:    sll a1, a1, a2
1544; RV64ZBB-NEXT:    add a0, a0, a1
1545; RV64ZBB-NEXT:    ret
1546;
1547; RV32XTHEADBB-LABEL: rotl_64_mask_shared:
1548; RV32XTHEADBB:       # %bb.0:
1549; RV32XTHEADBB-NEXT:    th.extu t0, a4, 5, 5
1550; RV32XTHEADBB-NEXT:    mv a6, a0
1551; RV32XTHEADBB-NEXT:    bnez t0, .LBB17_2
1552; RV32XTHEADBB-NEXT:  # %bb.1:
1553; RV32XTHEADBB-NEXT:    mv a6, a1
1554; RV32XTHEADBB-NEXT:  .LBB17_2:
1555; RV32XTHEADBB-NEXT:    andi a5, a4, 63
1556; RV32XTHEADBB-NEXT:    sll a7, a6, a4
1557; RV32XTHEADBB-NEXT:    bnez t0, .LBB17_4
1558; RV32XTHEADBB-NEXT:  # %bb.3:
1559; RV32XTHEADBB-NEXT:    mv a1, a0
1560; RV32XTHEADBB-NEXT:  .LBB17_4:
1561; RV32XTHEADBB-NEXT:    srli a0, a1, 1
1562; RV32XTHEADBB-NEXT:    not t0, a4
1563; RV32XTHEADBB-NEXT:    sll t1, a1, a4
1564; RV32XTHEADBB-NEXT:    srli a1, a6, 1
1565; RV32XTHEADBB-NEXT:    srl a6, a0, t0
1566; RV32XTHEADBB-NEXT:    srl t0, a1, t0
1567; RV32XTHEADBB-NEXT:    addi a0, a5, -32
1568; RV32XTHEADBB-NEXT:    or a1, a7, a6
1569; RV32XTHEADBB-NEXT:    or a6, t1, t0
1570; RV32XTHEADBB-NEXT:    bltz a0, .LBB17_6
1571; RV32XTHEADBB-NEXT:  # %bb.5:
1572; RV32XTHEADBB-NEXT:    sll a3, a2, a5
1573; RV32XTHEADBB-NEXT:    j .LBB17_7
1574; RV32XTHEADBB-NEXT:  .LBB17_6:
1575; RV32XTHEADBB-NEXT:    sll a3, a3, a4
1576; RV32XTHEADBB-NEXT:    srli a7, a2, 1
1577; RV32XTHEADBB-NEXT:    not a5, a5
1578; RV32XTHEADBB-NEXT:    srl a5, a7, a5
1579; RV32XTHEADBB-NEXT:    or a3, a3, a5
1580; RV32XTHEADBB-NEXT:  .LBB17_7:
1581; RV32XTHEADBB-NEXT:    sll a2, a2, a4
1582; RV32XTHEADBB-NEXT:    srai a0, a0, 31
1583; RV32XTHEADBB-NEXT:    and a0, a0, a2
1584; RV32XTHEADBB-NEXT:    add a0, a6, a0
1585; RV32XTHEADBB-NEXT:    sltu a2, a0, a6
1586; RV32XTHEADBB-NEXT:    add a1, a1, a3
1587; RV32XTHEADBB-NEXT:    add a1, a1, a2
1588; RV32XTHEADBB-NEXT:    ret
1589;
1590; RV64XTHEADBB-LABEL: rotl_64_mask_shared:
1591; RV64XTHEADBB:       # %bb.0:
1592; RV64XTHEADBB-NEXT:    sll a3, a0, a2
1593; RV64XTHEADBB-NEXT:    negw a4, a2
1594; RV64XTHEADBB-NEXT:    srl a0, a0, a4
1595; RV64XTHEADBB-NEXT:    or a0, a3, a0
1596; RV64XTHEADBB-NEXT:    sll a1, a1, a2
1597; RV64XTHEADBB-NEXT:    add a0, a0, a1
1598; RV64XTHEADBB-NEXT:    ret
1599  %maskedamt = and i64 %amt, 63
1600  %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %maskedamt)
1601  %2 = shl i64 %b, %maskedamt
1602  %3 = add i64 %1, %2
1603  ret i64 %3
1604}
1605declare i64 @llvm.fshl.i64(i64, i64, i64)
1606
1607define signext i32 @rotr_32_mask_shared(i32 signext %a, i32 signext %b, i32 signext %amt) nounwind {
1608; RV32I-LABEL: rotr_32_mask_shared:
1609; RV32I:       # %bb.0:
1610; RV32I-NEXT:    srl a3, a0, a2
1611; RV32I-NEXT:    neg a4, a2
1612; RV32I-NEXT:    sll a0, a0, a4
1613; RV32I-NEXT:    or a0, a3, a0
1614; RV32I-NEXT:    sll a1, a1, a2
1615; RV32I-NEXT:    add a0, a0, a1
1616; RV32I-NEXT:    ret
1617;
1618; RV64I-LABEL: rotr_32_mask_shared:
1619; RV64I:       # %bb.0:
1620; RV64I-NEXT:    srlw a3, a0, a2
1621; RV64I-NEXT:    negw a4, a2
1622; RV64I-NEXT:    sllw a0, a0, a4
1623; RV64I-NEXT:    or a0, a3, a0
1624; RV64I-NEXT:    sllw a1, a1, a2
1625; RV64I-NEXT:    addw a0, a0, a1
1626; RV64I-NEXT:    ret
1627;
1628; RV32ZBB-LABEL: rotr_32_mask_shared:
1629; RV32ZBB:       # %bb.0:
1630; RV32ZBB-NEXT:    ror a0, a0, a2
1631; RV32ZBB-NEXT:    sll a1, a1, a2
1632; RV32ZBB-NEXT:    add a0, a0, a1
1633; RV32ZBB-NEXT:    ret
1634;
1635; RV64ZBB-LABEL: rotr_32_mask_shared:
1636; RV64ZBB:       # %bb.0:
1637; RV64ZBB-NEXT:    rorw a0, a0, a2
1638; RV64ZBB-NEXT:    sllw a1, a1, a2
1639; RV64ZBB-NEXT:    addw a0, a0, a1
1640; RV64ZBB-NEXT:    ret
1641;
1642; RV32XTHEADBB-LABEL: rotr_32_mask_shared:
1643; RV32XTHEADBB:       # %bb.0:
1644; RV32XTHEADBB-NEXT:    srl a3, a0, a2
1645; RV32XTHEADBB-NEXT:    neg a4, a2
1646; RV32XTHEADBB-NEXT:    sll a0, a0, a4
1647; RV32XTHEADBB-NEXT:    or a0, a3, a0
1648; RV32XTHEADBB-NEXT:    sll a1, a1, a2
1649; RV32XTHEADBB-NEXT:    add a0, a0, a1
1650; RV32XTHEADBB-NEXT:    ret
1651;
1652; RV64XTHEADBB-LABEL: rotr_32_mask_shared:
1653; RV64XTHEADBB:       # %bb.0:
1654; RV64XTHEADBB-NEXT:    srlw a3, a0, a2
1655; RV64XTHEADBB-NEXT:    negw a4, a2
1656; RV64XTHEADBB-NEXT:    sllw a0, a0, a4
1657; RV64XTHEADBB-NEXT:    or a0, a3, a0
1658; RV64XTHEADBB-NEXT:    sllw a1, a1, a2
1659; RV64XTHEADBB-NEXT:    addw a0, a0, a1
1660; RV64XTHEADBB-NEXT:    ret
1661  %maskedamt = and i32 %amt, 31
1662  %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %maskedamt)
1663  %2 = shl i32 %b, %maskedamt
1664  %3 = add i32 %1, %2
1665  ret i32 %3
1666}
1667declare i32 @llvm.fshr.i32(i32, i32, i32)
1668
1669define signext i64 @rotr_64_mask_shared(i64 signext %a, i64 signext %b, i64 signext %amt) nounwind {
1670; RV32I-LABEL: rotr_64_mask_shared:
1671; RV32I:       # %bb.0:
1672; RV32I-NEXT:    andi t0, a4, 32
1673; RV32I-NEXT:    mv a6, a1
1674; RV32I-NEXT:    beqz t0, .LBB19_2
1675; RV32I-NEXT:  # %bb.1:
1676; RV32I-NEXT:    mv a6, a0
1677; RV32I-NEXT:  .LBB19_2:
1678; RV32I-NEXT:    andi a5, a4, 63
1679; RV32I-NEXT:    srl a7, a6, a4
1680; RV32I-NEXT:    beqz t0, .LBB19_4
1681; RV32I-NEXT:  # %bb.3:
1682; RV32I-NEXT:    mv a0, a1
1683; RV32I-NEXT:  .LBB19_4:
1684; RV32I-NEXT:    slli a1, a0, 1
1685; RV32I-NEXT:    not t0, a4
1686; RV32I-NEXT:    srl t1, a0, a4
1687; RV32I-NEXT:    slli a6, a6, 1
1688; RV32I-NEXT:    sll a1, a1, t0
1689; RV32I-NEXT:    sll a6, a6, t0
1690; RV32I-NEXT:    addi a0, a5, -32
1691; RV32I-NEXT:    or a1, a1, a7
1692; RV32I-NEXT:    or a6, a6, t1
1693; RV32I-NEXT:    bltz a0, .LBB19_6
1694; RV32I-NEXT:  # %bb.5:
1695; RV32I-NEXT:    sll a3, a2, a5
1696; RV32I-NEXT:    j .LBB19_7
1697; RV32I-NEXT:  .LBB19_6:
1698; RV32I-NEXT:    sll a3, a3, a4
1699; RV32I-NEXT:    srli a7, a2, 1
1700; RV32I-NEXT:    not a5, a5
1701; RV32I-NEXT:    srl a5, a7, a5
1702; RV32I-NEXT:    or a3, a3, a5
1703; RV32I-NEXT:  .LBB19_7:
1704; RV32I-NEXT:    sll a2, a2, a4
1705; RV32I-NEXT:    srai a0, a0, 31
1706; RV32I-NEXT:    and a0, a0, a2
1707; RV32I-NEXT:    add a0, a6, a0
1708; RV32I-NEXT:    sltu a2, a0, a6
1709; RV32I-NEXT:    add a1, a1, a3
1710; RV32I-NEXT:    add a1, a1, a2
1711; RV32I-NEXT:    ret
1712;
1713; RV64I-LABEL: rotr_64_mask_shared:
1714; RV64I:       # %bb.0:
1715; RV64I-NEXT:    srl a3, a0, a2
1716; RV64I-NEXT:    negw a4, a2
1717; RV64I-NEXT:    sll a0, a0, a4
1718; RV64I-NEXT:    or a0, a3, a0
1719; RV64I-NEXT:    sll a1, a1, a2
1720; RV64I-NEXT:    add a0, a0, a1
1721; RV64I-NEXT:    ret
1722;
1723; RV32ZBB-LABEL: rotr_64_mask_shared:
1724; RV32ZBB:       # %bb.0:
1725; RV32ZBB-NEXT:    andi t0, a4, 32
1726; RV32ZBB-NEXT:    mv a6, a1
1727; RV32ZBB-NEXT:    beqz t0, .LBB19_2
1728; RV32ZBB-NEXT:  # %bb.1:
1729; RV32ZBB-NEXT:    mv a6, a0
1730; RV32ZBB-NEXT:  .LBB19_2:
1731; RV32ZBB-NEXT:    andi a5, a4, 63
1732; RV32ZBB-NEXT:    srl a7, a6, a4
1733; RV32ZBB-NEXT:    beqz t0, .LBB19_4
1734; RV32ZBB-NEXT:  # %bb.3:
1735; RV32ZBB-NEXT:    mv a0, a1
1736; RV32ZBB-NEXT:  .LBB19_4:
1737; RV32ZBB-NEXT:    slli a1, a0, 1
1738; RV32ZBB-NEXT:    not t0, a4
1739; RV32ZBB-NEXT:    srl t1, a0, a4
1740; RV32ZBB-NEXT:    slli a6, a6, 1
1741; RV32ZBB-NEXT:    sll a1, a1, t0
1742; RV32ZBB-NEXT:    sll a6, a6, t0
1743; RV32ZBB-NEXT:    addi a0, a5, -32
1744; RV32ZBB-NEXT:    or a1, a1, a7
1745; RV32ZBB-NEXT:    or a6, a6, t1
1746; RV32ZBB-NEXT:    bltz a0, .LBB19_6
1747; RV32ZBB-NEXT:  # %bb.5:
1748; RV32ZBB-NEXT:    sll a3, a2, a5
1749; RV32ZBB-NEXT:    j .LBB19_7
1750; RV32ZBB-NEXT:  .LBB19_6:
1751; RV32ZBB-NEXT:    sll a3, a3, a4
1752; RV32ZBB-NEXT:    srli a7, a2, 1
1753; RV32ZBB-NEXT:    not a5, a5
1754; RV32ZBB-NEXT:    srl a5, a7, a5
1755; RV32ZBB-NEXT:    or a3, a3, a5
1756; RV32ZBB-NEXT:  .LBB19_7:
1757; RV32ZBB-NEXT:    sll a2, a2, a4
1758; RV32ZBB-NEXT:    srai a0, a0, 31
1759; RV32ZBB-NEXT:    and a0, a0, a2
1760; RV32ZBB-NEXT:    add a0, a6, a0
1761; RV32ZBB-NEXT:    sltu a2, a0, a6
1762; RV32ZBB-NEXT:    add a1, a1, a3
1763; RV32ZBB-NEXT:    add a1, a1, a2
1764; RV32ZBB-NEXT:    ret
1765;
1766; RV64ZBB-LABEL: rotr_64_mask_shared:
1767; RV64ZBB:       # %bb.0:
1768; RV64ZBB-NEXT:    ror a0, a0, a2
1769; RV64ZBB-NEXT:    sll a1, a1, a2
1770; RV64ZBB-NEXT:    add a0, a0, a1
1771; RV64ZBB-NEXT:    ret
1772;
1773; RV32XTHEADBB-LABEL: rotr_64_mask_shared:
1774; RV32XTHEADBB:       # %bb.0:
1775; RV32XTHEADBB-NEXT:    andi t0, a4, 32
1776; RV32XTHEADBB-NEXT:    mv a6, a1
1777; RV32XTHEADBB-NEXT:    beqz t0, .LBB19_2
1778; RV32XTHEADBB-NEXT:  # %bb.1:
1779; RV32XTHEADBB-NEXT:    mv a6, a0
1780; RV32XTHEADBB-NEXT:  .LBB19_2:
1781; RV32XTHEADBB-NEXT:    andi a5, a4, 63
1782; RV32XTHEADBB-NEXT:    srl a7, a6, a4
1783; RV32XTHEADBB-NEXT:    beqz t0, .LBB19_4
1784; RV32XTHEADBB-NEXT:  # %bb.3:
1785; RV32XTHEADBB-NEXT:    mv a0, a1
1786; RV32XTHEADBB-NEXT:  .LBB19_4:
1787; RV32XTHEADBB-NEXT:    slli a1, a0, 1
1788; RV32XTHEADBB-NEXT:    not t0, a4
1789; RV32XTHEADBB-NEXT:    srl t1, a0, a4
1790; RV32XTHEADBB-NEXT:    slli a6, a6, 1
1791; RV32XTHEADBB-NEXT:    sll a1, a1, t0
1792; RV32XTHEADBB-NEXT:    sll a6, a6, t0
1793; RV32XTHEADBB-NEXT:    addi a0, a5, -32
1794; RV32XTHEADBB-NEXT:    or a1, a1, a7
1795; RV32XTHEADBB-NEXT:    or a6, a6, t1
1796; RV32XTHEADBB-NEXT:    bltz a0, .LBB19_6
1797; RV32XTHEADBB-NEXT:  # %bb.5:
1798; RV32XTHEADBB-NEXT:    sll a3, a2, a5
1799; RV32XTHEADBB-NEXT:    j .LBB19_7
1800; RV32XTHEADBB-NEXT:  .LBB19_6:
1801; RV32XTHEADBB-NEXT:    sll a3, a3, a4
1802; RV32XTHEADBB-NEXT:    srli a7, a2, 1
1803; RV32XTHEADBB-NEXT:    not a5, a5
1804; RV32XTHEADBB-NEXT:    srl a5, a7, a5
1805; RV32XTHEADBB-NEXT:    or a3, a3, a5
1806; RV32XTHEADBB-NEXT:  .LBB19_7:
1807; RV32XTHEADBB-NEXT:    sll a2, a2, a4
1808; RV32XTHEADBB-NEXT:    srai a0, a0, 31
1809; RV32XTHEADBB-NEXT:    and a0, a0, a2
1810; RV32XTHEADBB-NEXT:    add a0, a6, a0
1811; RV32XTHEADBB-NEXT:    sltu a2, a0, a6
1812; RV32XTHEADBB-NEXT:    add a1, a1, a3
1813; RV32XTHEADBB-NEXT:    add a1, a1, a2
1814; RV32XTHEADBB-NEXT:    ret
1815;
1816; RV64XTHEADBB-LABEL: rotr_64_mask_shared:
1817; RV64XTHEADBB:       # %bb.0:
1818; RV64XTHEADBB-NEXT:    srl a3, a0, a2
1819; RV64XTHEADBB-NEXT:    negw a4, a2
1820; RV64XTHEADBB-NEXT:    sll a0, a0, a4
1821; RV64XTHEADBB-NEXT:    or a0, a3, a0
1822; RV64XTHEADBB-NEXT:    sll a1, a1, a2
1823; RV64XTHEADBB-NEXT:    add a0, a0, a1
1824; RV64XTHEADBB-NEXT:    ret
1825  %maskedamt = and i64 %amt, 63
1826  %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %maskedamt)
1827  %2 = shl i64 %b, %maskedamt
1828  %3 = add i64 %1, %2
1829  ret i64 %3
1830}
1831declare i64 @llvm.fshr.i64(i64, i64, i64)
1832
1833define signext i32 @rotl_32_mask_multiple(i32 signext %a, i32 signext %b, i32 signext %amt) nounwind {
1834; RV32I-LABEL: rotl_32_mask_multiple:
1835; RV32I:       # %bb.0:
1836; RV32I-NEXT:    sll a3, a0, a2
1837; RV32I-NEXT:    neg a4, a2
1838; RV32I-NEXT:    sll a2, a1, a2
1839; RV32I-NEXT:    srl a0, a0, a4
1840; RV32I-NEXT:    srl a1, a1, a4
1841; RV32I-NEXT:    or a0, a3, a0
1842; RV32I-NEXT:    or a1, a2, a1
1843; RV32I-NEXT:    add a0, a0, a1
1844; RV32I-NEXT:    ret
1845;
1846; RV64I-LABEL: rotl_32_mask_multiple:
1847; RV64I:       # %bb.0:
1848; RV64I-NEXT:    sllw a3, a0, a2
1849; RV64I-NEXT:    negw a4, a2
1850; RV64I-NEXT:    sllw a2, a1, a2
1851; RV64I-NEXT:    srlw a0, a0, a4
1852; RV64I-NEXT:    srlw a1, a1, a4
1853; RV64I-NEXT:    or a0, a3, a0
1854; RV64I-NEXT:    or a1, a2, a1
1855; RV64I-NEXT:    addw a0, a0, a1
1856; RV64I-NEXT:    ret
1857;
1858; RV32ZBB-LABEL: rotl_32_mask_multiple:
1859; RV32ZBB:       # %bb.0:
1860; RV32ZBB-NEXT:    rol a0, a0, a2
1861; RV32ZBB-NEXT:    rol a1, a1, a2
1862; RV32ZBB-NEXT:    add a0, a0, a1
1863; RV32ZBB-NEXT:    ret
1864;
1865; RV64ZBB-LABEL: rotl_32_mask_multiple:
1866; RV64ZBB:       # %bb.0:
1867; RV64ZBB-NEXT:    rolw a0, a0, a2
1868; RV64ZBB-NEXT:    rolw a1, a1, a2
1869; RV64ZBB-NEXT:    addw a0, a0, a1
1870; RV64ZBB-NEXT:    ret
1871;
1872; RV32XTHEADBB-LABEL: rotl_32_mask_multiple:
1873; RV32XTHEADBB:       # %bb.0:
1874; RV32XTHEADBB-NEXT:    sll a3, a0, a2
1875; RV32XTHEADBB-NEXT:    neg a4, a2
1876; RV32XTHEADBB-NEXT:    sll a2, a1, a2
1877; RV32XTHEADBB-NEXT:    srl a0, a0, a4
1878; RV32XTHEADBB-NEXT:    srl a1, a1, a4
1879; RV32XTHEADBB-NEXT:    or a0, a3, a0
1880; RV32XTHEADBB-NEXT:    or a1, a2, a1
1881; RV32XTHEADBB-NEXT:    add a0, a0, a1
1882; RV32XTHEADBB-NEXT:    ret
1883;
1884; RV64XTHEADBB-LABEL: rotl_32_mask_multiple:
1885; RV64XTHEADBB:       # %bb.0:
1886; RV64XTHEADBB-NEXT:    sllw a3, a0, a2
1887; RV64XTHEADBB-NEXT:    negw a4, a2
1888; RV64XTHEADBB-NEXT:    sllw a2, a1, a2
1889; RV64XTHEADBB-NEXT:    srlw a0, a0, a4
1890; RV64XTHEADBB-NEXT:    srlw a1, a1, a4
1891; RV64XTHEADBB-NEXT:    or a0, a3, a0
1892; RV64XTHEADBB-NEXT:    or a1, a2, a1
1893; RV64XTHEADBB-NEXT:    addw a0, a0, a1
1894; RV64XTHEADBB-NEXT:    ret
1895  %maskedamt = and i32 %amt, 31
1896  %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %maskedamt)
1897  %2 = tail call i32 @llvm.fshl.i32(i32 %b, i32 %b, i32 %maskedamt)
1898  %3 = add i32 %1, %2
1899  ret i32 %3
1900}
1901
1902define i64 @rotl_64_mask_multiple(i64 %a, i64 %b, i64 %amt) nounwind {
1903; RV32I-LABEL: rotl_64_mask_multiple:
1904; RV32I:       # %bb.0:
1905; RV32I-NEXT:    slli a5, a4, 26
1906; RV32I-NEXT:    srli a5, a5, 31
1907; RV32I-NEXT:    mv a6, a1
1908; RV32I-NEXT:    bnez a5, .LBB21_2
1909; RV32I-NEXT:  # %bb.1:
1910; RV32I-NEXT:    mv a6, a0
1911; RV32I-NEXT:  .LBB21_2:
1912; RV32I-NEXT:    bnez a5, .LBB21_4
1913; RV32I-NEXT:  # %bb.3:
1914; RV32I-NEXT:    mv a0, a1
1915; RV32I-NEXT:  .LBB21_4:
1916; RV32I-NEXT:    sll a7, a6, a4
1917; RV32I-NEXT:    srli t1, a0, 1
1918; RV32I-NEXT:    not a1, a4
1919; RV32I-NEXT:    sll t0, a0, a4
1920; RV32I-NEXT:    srli a0, a6, 1
1921; RV32I-NEXT:    srl a6, t1, a1
1922; RV32I-NEXT:    srl t1, a0, a1
1923; RV32I-NEXT:    mv a0, a3
1924; RV32I-NEXT:    bnez a5, .LBB21_6
1925; RV32I-NEXT:  # %bb.5:
1926; RV32I-NEXT:    mv a0, a2
1927; RV32I-NEXT:  .LBB21_6:
1928; RV32I-NEXT:    or a6, a7, a6
1929; RV32I-NEXT:    or a7, t0, t1
1930; RV32I-NEXT:    sll t0, a0, a4
1931; RV32I-NEXT:    bnez a5, .LBB21_8
1932; RV32I-NEXT:  # %bb.7:
1933; RV32I-NEXT:    mv a2, a3
1934; RV32I-NEXT:  .LBB21_8:
1935; RV32I-NEXT:    srli a3, a2, 1
1936; RV32I-NEXT:    sll a2, a2, a4
1937; RV32I-NEXT:    srli a0, a0, 1
1938; RV32I-NEXT:    srl a3, a3, a1
1939; RV32I-NEXT:    srl a0, a0, a1
1940; RV32I-NEXT:    or a1, t0, a3
1941; RV32I-NEXT:    or a0, a2, a0
1942; RV32I-NEXT:    add a7, a7, a0
1943; RV32I-NEXT:    add a0, a6, a1
1944; RV32I-NEXT:    sltu a1, a0, a6
1945; RV32I-NEXT:    add a1, a7, a1
1946; RV32I-NEXT:    ret
1947;
1948; RV64I-LABEL: rotl_64_mask_multiple:
1949; RV64I:       # %bb.0:
1950; RV64I-NEXT:    sll a3, a0, a2
1951; RV64I-NEXT:    negw a4, a2
1952; RV64I-NEXT:    sll a2, a1, a2
1953; RV64I-NEXT:    srl a0, a0, a4
1954; RV64I-NEXT:    srl a1, a1, a4
1955; RV64I-NEXT:    or a0, a3, a0
1956; RV64I-NEXT:    or a1, a2, a1
1957; RV64I-NEXT:    add a0, a0, a1
1958; RV64I-NEXT:    ret
1959;
1960; RV32ZBB-LABEL: rotl_64_mask_multiple:
1961; RV32ZBB:       # %bb.0:
1962; RV32ZBB-NEXT:    slli a5, a4, 26
1963; RV32ZBB-NEXT:    srli a5, a5, 31
1964; RV32ZBB-NEXT:    mv a6, a1
1965; RV32ZBB-NEXT:    bnez a5, .LBB21_2
1966; RV32ZBB-NEXT:  # %bb.1:
1967; RV32ZBB-NEXT:    mv a6, a0
1968; RV32ZBB-NEXT:  .LBB21_2:
1969; RV32ZBB-NEXT:    bnez a5, .LBB21_4
1970; RV32ZBB-NEXT:  # %bb.3:
1971; RV32ZBB-NEXT:    mv a0, a1
1972; RV32ZBB-NEXT:  .LBB21_4:
1973; RV32ZBB-NEXT:    sll a7, a6, a4
1974; RV32ZBB-NEXT:    srli t1, a0, 1
1975; RV32ZBB-NEXT:    not a1, a4
1976; RV32ZBB-NEXT:    sll t0, a0, a4
1977; RV32ZBB-NEXT:    srli a0, a6, 1
1978; RV32ZBB-NEXT:    srl a6, t1, a1
1979; RV32ZBB-NEXT:    srl t1, a0, a1
1980; RV32ZBB-NEXT:    mv a0, a3
1981; RV32ZBB-NEXT:    bnez a5, .LBB21_6
1982; RV32ZBB-NEXT:  # %bb.5:
1983; RV32ZBB-NEXT:    mv a0, a2
1984; RV32ZBB-NEXT:  .LBB21_6:
1985; RV32ZBB-NEXT:    or a6, a7, a6
1986; RV32ZBB-NEXT:    or a7, t0, t1
1987; RV32ZBB-NEXT:    sll t0, a0, a4
1988; RV32ZBB-NEXT:    bnez a5, .LBB21_8
1989; RV32ZBB-NEXT:  # %bb.7:
1990; RV32ZBB-NEXT:    mv a2, a3
1991; RV32ZBB-NEXT:  .LBB21_8:
1992; RV32ZBB-NEXT:    srli a3, a2, 1
1993; RV32ZBB-NEXT:    sll a2, a2, a4
1994; RV32ZBB-NEXT:    srli a0, a0, 1
1995; RV32ZBB-NEXT:    srl a3, a3, a1
1996; RV32ZBB-NEXT:    srl a0, a0, a1
1997; RV32ZBB-NEXT:    or a1, t0, a3
1998; RV32ZBB-NEXT:    or a0, a2, a0
1999; RV32ZBB-NEXT:    add a7, a7, a0
2000; RV32ZBB-NEXT:    add a0, a6, a1
2001; RV32ZBB-NEXT:    sltu a1, a0, a6
2002; RV32ZBB-NEXT:    add a1, a7, a1
2003; RV32ZBB-NEXT:    ret
2004;
2005; RV64ZBB-LABEL: rotl_64_mask_multiple:
2006; RV64ZBB:       # %bb.0:
2007; RV64ZBB-NEXT:    rol a0, a0, a2
2008; RV64ZBB-NEXT:    rol a1, a1, a2
2009; RV64ZBB-NEXT:    add a0, a0, a1
2010; RV64ZBB-NEXT:    ret
2011;
2012; RV32XTHEADBB-LABEL: rotl_64_mask_multiple:
2013; RV32XTHEADBB:       # %bb.0:
2014; RV32XTHEADBB-NEXT:    th.extu a5, a4, 5, 5
2015; RV32XTHEADBB-NEXT:    mv a6, a1
2016; RV32XTHEADBB-NEXT:    bnez a5, .LBB21_2
2017; RV32XTHEADBB-NEXT:  # %bb.1:
2018; RV32XTHEADBB-NEXT:    mv a6, a0
2019; RV32XTHEADBB-NEXT:  .LBB21_2:
2020; RV32XTHEADBB-NEXT:    bnez a5, .LBB21_4
2021; RV32XTHEADBB-NEXT:  # %bb.3:
2022; RV32XTHEADBB-NEXT:    mv a0, a1
2023; RV32XTHEADBB-NEXT:  .LBB21_4:
2024; RV32XTHEADBB-NEXT:    sll a7, a6, a4
2025; RV32XTHEADBB-NEXT:    srli t1, a0, 1
2026; RV32XTHEADBB-NEXT:    not a1, a4
2027; RV32XTHEADBB-NEXT:    sll t0, a0, a4
2028; RV32XTHEADBB-NEXT:    srli a0, a6, 1
2029; RV32XTHEADBB-NEXT:    srl a6, t1, a1
2030; RV32XTHEADBB-NEXT:    srl t1, a0, a1
2031; RV32XTHEADBB-NEXT:    mv a0, a3
2032; RV32XTHEADBB-NEXT:    bnez a5, .LBB21_6
2033; RV32XTHEADBB-NEXT:  # %bb.5:
2034; RV32XTHEADBB-NEXT:    mv a0, a2
2035; RV32XTHEADBB-NEXT:  .LBB21_6:
2036; RV32XTHEADBB-NEXT:    or a6, a7, a6
2037; RV32XTHEADBB-NEXT:    or a7, t0, t1
2038; RV32XTHEADBB-NEXT:    sll t0, a0, a4
2039; RV32XTHEADBB-NEXT:    bnez a5, .LBB21_8
2040; RV32XTHEADBB-NEXT:  # %bb.7:
2041; RV32XTHEADBB-NEXT:    mv a2, a3
2042; RV32XTHEADBB-NEXT:  .LBB21_8:
2043; RV32XTHEADBB-NEXT:    srli a3, a2, 1
2044; RV32XTHEADBB-NEXT:    sll a2, a2, a4
2045; RV32XTHEADBB-NEXT:    srli a0, a0, 1
2046; RV32XTHEADBB-NEXT:    srl a3, a3, a1
2047; RV32XTHEADBB-NEXT:    srl a0, a0, a1
2048; RV32XTHEADBB-NEXT:    or a1, t0, a3
2049; RV32XTHEADBB-NEXT:    or a0, a2, a0
2050; RV32XTHEADBB-NEXT:    add a7, a7, a0
2051; RV32XTHEADBB-NEXT:    add a0, a6, a1
2052; RV32XTHEADBB-NEXT:    sltu a1, a0, a6
2053; RV32XTHEADBB-NEXT:    add a1, a7, a1
2054; RV32XTHEADBB-NEXT:    ret
2055;
2056; RV64XTHEADBB-LABEL: rotl_64_mask_multiple:
2057; RV64XTHEADBB:       # %bb.0:
2058; RV64XTHEADBB-NEXT:    sll a3, a0, a2
2059; RV64XTHEADBB-NEXT:    negw a4, a2
2060; RV64XTHEADBB-NEXT:    sll a2, a1, a2
2061; RV64XTHEADBB-NEXT:    srl a0, a0, a4
2062; RV64XTHEADBB-NEXT:    srl a1, a1, a4
2063; RV64XTHEADBB-NEXT:    or a0, a3, a0
2064; RV64XTHEADBB-NEXT:    or a1, a2, a1
2065; RV64XTHEADBB-NEXT:    add a0, a0, a1
2066; RV64XTHEADBB-NEXT:    ret
2067  %maskedamt = and i64 %amt, 63
2068  %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %maskedamt)
2069  %2 = tail call i64 @llvm.fshl.i64(i64 %b, i64 %b, i64 %maskedamt)
2070  %3 = add i64 %1, %2
2071  ret i64 %3
2072}
2073
2074define signext i32 @rotr_32_mask_multiple(i32 signext %a, i32 signext %b, i32 signext %amt) nounwind {
2075; RV32I-LABEL: rotr_32_mask_multiple:
2076; RV32I:       # %bb.0:
2077; RV32I-NEXT:    srl a3, a0, a2
2078; RV32I-NEXT:    neg a4, a2
2079; RV32I-NEXT:    srl a2, a1, a2
2080; RV32I-NEXT:    sll a0, a0, a4
2081; RV32I-NEXT:    sll a1, a1, a4
2082; RV32I-NEXT:    or a0, a3, a0
2083; RV32I-NEXT:    or a1, a2, a1
2084; RV32I-NEXT:    add a0, a0, a1
2085; RV32I-NEXT:    ret
2086;
2087; RV64I-LABEL: rotr_32_mask_multiple:
2088; RV64I:       # %bb.0:
2089; RV64I-NEXT:    srlw a3, a0, a2
2090; RV64I-NEXT:    negw a4, a2
2091; RV64I-NEXT:    srlw a2, a1, a2
2092; RV64I-NEXT:    sllw a0, a0, a4
2093; RV64I-NEXT:    sllw a1, a1, a4
2094; RV64I-NEXT:    or a0, a3, a0
2095; RV64I-NEXT:    or a1, a2, a1
2096; RV64I-NEXT:    addw a0, a0, a1
2097; RV64I-NEXT:    ret
2098;
2099; RV32ZBB-LABEL: rotr_32_mask_multiple:
2100; RV32ZBB:       # %bb.0:
2101; RV32ZBB-NEXT:    ror a0, a0, a2
2102; RV32ZBB-NEXT:    ror a1, a1, a2
2103; RV32ZBB-NEXT:    add a0, a0, a1
2104; RV32ZBB-NEXT:    ret
2105;
2106; RV64ZBB-LABEL: rotr_32_mask_multiple:
2107; RV64ZBB:       # %bb.0:
2108; RV64ZBB-NEXT:    rorw a0, a0, a2
2109; RV64ZBB-NEXT:    rorw a1, a1, a2
2110; RV64ZBB-NEXT:    addw a0, a0, a1
2111; RV64ZBB-NEXT:    ret
2112;
2113; RV32XTHEADBB-LABEL: rotr_32_mask_multiple:
2114; RV32XTHEADBB:       # %bb.0:
2115; RV32XTHEADBB-NEXT:    srl a3, a0, a2
2116; RV32XTHEADBB-NEXT:    neg a4, a2
2117; RV32XTHEADBB-NEXT:    srl a2, a1, a2
2118; RV32XTHEADBB-NEXT:    sll a0, a0, a4
2119; RV32XTHEADBB-NEXT:    sll a1, a1, a4
2120; RV32XTHEADBB-NEXT:    or a0, a3, a0
2121; RV32XTHEADBB-NEXT:    or a1, a2, a1
2122; RV32XTHEADBB-NEXT:    add a0, a0, a1
2123; RV32XTHEADBB-NEXT:    ret
2124;
2125; RV64XTHEADBB-LABEL: rotr_32_mask_multiple:
2126; RV64XTHEADBB:       # %bb.0:
2127; RV64XTHEADBB-NEXT:    srlw a3, a0, a2
2128; RV64XTHEADBB-NEXT:    negw a4, a2
2129; RV64XTHEADBB-NEXT:    srlw a2, a1, a2
2130; RV64XTHEADBB-NEXT:    sllw a0, a0, a4
2131; RV64XTHEADBB-NEXT:    sllw a1, a1, a4
2132; RV64XTHEADBB-NEXT:    or a0, a3, a0
2133; RV64XTHEADBB-NEXT:    or a1, a2, a1
2134; RV64XTHEADBB-NEXT:    addw a0, a0, a1
2135; RV64XTHEADBB-NEXT:    ret
2136  %maskedamt = and i32 %amt, 31
2137  %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %maskedamt)
2138  %2 = tail call i32 @llvm.fshr.i32(i32 %b, i32 %b, i32 %maskedamt)
2139  %3 = add i32 %1, %2
2140  ret i32 %3
2141}
2142
2143define i64 @rotr_64_mask_multiple(i64 %a, i64 %b, i64 %amt) nounwind {
2144; RV32I-LABEL: rotr_64_mask_multiple:
2145; RV32I:       # %bb.0:
2146; RV32I-NEXT:    andi a5, a4, 32
2147; RV32I-NEXT:    mv a6, a0
2148; RV32I-NEXT:    beqz a5, .LBB23_2
2149; RV32I-NEXT:  # %bb.1:
2150; RV32I-NEXT:    mv a6, a1
2151; RV32I-NEXT:  .LBB23_2:
2152; RV32I-NEXT:    beqz a5, .LBB23_4
2153; RV32I-NEXT:  # %bb.3:
2154; RV32I-NEXT:    mv a1, a0
2155; RV32I-NEXT:  .LBB23_4:
2156; RV32I-NEXT:    srl a7, a6, a4
2157; RV32I-NEXT:    slli t1, a1, 1
2158; RV32I-NEXT:    not a0, a4
2159; RV32I-NEXT:    srl t0, a1, a4
2160; RV32I-NEXT:    slli a6, a6, 1
2161; RV32I-NEXT:    sll a1, t1, a0
2162; RV32I-NEXT:    sll t1, a6, a0
2163; RV32I-NEXT:    mv a6, a2
2164; RV32I-NEXT:    beqz a5, .LBB23_6
2165; RV32I-NEXT:  # %bb.5:
2166; RV32I-NEXT:    mv a6, a3
2167; RV32I-NEXT:  .LBB23_6:
2168; RV32I-NEXT:    or a1, a1, a7
2169; RV32I-NEXT:    or a7, t1, t0
2170; RV32I-NEXT:    srl t0, a6, a4
2171; RV32I-NEXT:    beqz a5, .LBB23_8
2172; RV32I-NEXT:  # %bb.7:
2173; RV32I-NEXT:    mv a3, a2
2174; RV32I-NEXT:  .LBB23_8:
2175; RV32I-NEXT:    slli a2, a3, 1
2176; RV32I-NEXT:    srl a3, a3, a4
2177; RV32I-NEXT:    slli a6, a6, 1
2178; RV32I-NEXT:    sll a2, a2, a0
2179; RV32I-NEXT:    sll a0, a6, a0
2180; RV32I-NEXT:    or a2, a2, t0
2181; RV32I-NEXT:    or a0, a0, a3
2182; RV32I-NEXT:    add a7, a7, a0
2183; RV32I-NEXT:    add a0, a1, a2
2184; RV32I-NEXT:    sltu a1, a0, a1
2185; RV32I-NEXT:    add a1, a7, a1
2186; RV32I-NEXT:    ret
2187;
2188; RV64I-LABEL: rotr_64_mask_multiple:
2189; RV64I:       # %bb.0:
2190; RV64I-NEXT:    srl a3, a0, a2
2191; RV64I-NEXT:    negw a4, a2
2192; RV64I-NEXT:    srl a2, a1, a2
2193; RV64I-NEXT:    sll a0, a0, a4
2194; RV64I-NEXT:    sll a1, a1, a4
2195; RV64I-NEXT:    or a0, a3, a0
2196; RV64I-NEXT:    or a1, a2, a1
2197; RV64I-NEXT:    add a0, a0, a1
2198; RV64I-NEXT:    ret
2199;
2200; RV32ZBB-LABEL: rotr_64_mask_multiple:
2201; RV32ZBB:       # %bb.0:
2202; RV32ZBB-NEXT:    andi a5, a4, 32
2203; RV32ZBB-NEXT:    mv a6, a0
2204; RV32ZBB-NEXT:    beqz a5, .LBB23_2
2205; RV32ZBB-NEXT:  # %bb.1:
2206; RV32ZBB-NEXT:    mv a6, a1
2207; RV32ZBB-NEXT:  .LBB23_2:
2208; RV32ZBB-NEXT:    beqz a5, .LBB23_4
2209; RV32ZBB-NEXT:  # %bb.3:
2210; RV32ZBB-NEXT:    mv a1, a0
2211; RV32ZBB-NEXT:  .LBB23_4:
2212; RV32ZBB-NEXT:    srl a7, a6, a4
2213; RV32ZBB-NEXT:    slli t1, a1, 1
2214; RV32ZBB-NEXT:    not a0, a4
2215; RV32ZBB-NEXT:    srl t0, a1, a4
2216; RV32ZBB-NEXT:    slli a6, a6, 1
2217; RV32ZBB-NEXT:    sll a1, t1, a0
2218; RV32ZBB-NEXT:    sll t1, a6, a0
2219; RV32ZBB-NEXT:    mv a6, a2
2220; RV32ZBB-NEXT:    beqz a5, .LBB23_6
2221; RV32ZBB-NEXT:  # %bb.5:
2222; RV32ZBB-NEXT:    mv a6, a3
2223; RV32ZBB-NEXT:  .LBB23_6:
2224; RV32ZBB-NEXT:    or a1, a1, a7
2225; RV32ZBB-NEXT:    or a7, t1, t0
2226; RV32ZBB-NEXT:    srl t0, a6, a4
2227; RV32ZBB-NEXT:    beqz a5, .LBB23_8
2228; RV32ZBB-NEXT:  # %bb.7:
2229; RV32ZBB-NEXT:    mv a3, a2
2230; RV32ZBB-NEXT:  .LBB23_8:
2231; RV32ZBB-NEXT:    slli a2, a3, 1
2232; RV32ZBB-NEXT:    srl a3, a3, a4
2233; RV32ZBB-NEXT:    slli a6, a6, 1
2234; RV32ZBB-NEXT:    sll a2, a2, a0
2235; RV32ZBB-NEXT:    sll a0, a6, a0
2236; RV32ZBB-NEXT:    or a2, a2, t0
2237; RV32ZBB-NEXT:    or a0, a0, a3
2238; RV32ZBB-NEXT:    add a7, a7, a0
2239; RV32ZBB-NEXT:    add a0, a1, a2
2240; RV32ZBB-NEXT:    sltu a1, a0, a1
2241; RV32ZBB-NEXT:    add a1, a7, a1
2242; RV32ZBB-NEXT:    ret
2243;
2244; RV64ZBB-LABEL: rotr_64_mask_multiple:
2245; RV64ZBB:       # %bb.0:
2246; RV64ZBB-NEXT:    ror a0, a0, a2
2247; RV64ZBB-NEXT:    ror a1, a1, a2
2248; RV64ZBB-NEXT:    add a0, a0, a1
2249; RV64ZBB-NEXT:    ret
2250;
2251; RV32XTHEADBB-LABEL: rotr_64_mask_multiple:
2252; RV32XTHEADBB:       # %bb.0:
2253; RV32XTHEADBB-NEXT:    andi a5, a4, 32
2254; RV32XTHEADBB-NEXT:    mv a6, a0
2255; RV32XTHEADBB-NEXT:    beqz a5, .LBB23_2
2256; RV32XTHEADBB-NEXT:  # %bb.1:
2257; RV32XTHEADBB-NEXT:    mv a6, a1
2258; RV32XTHEADBB-NEXT:  .LBB23_2:
2259; RV32XTHEADBB-NEXT:    beqz a5, .LBB23_4
2260; RV32XTHEADBB-NEXT:  # %bb.3:
2261; RV32XTHEADBB-NEXT:    mv a1, a0
2262; RV32XTHEADBB-NEXT:  .LBB23_4:
2263; RV32XTHEADBB-NEXT:    srl a7, a6, a4
2264; RV32XTHEADBB-NEXT:    slli t1, a1, 1
2265; RV32XTHEADBB-NEXT:    not a0, a4
2266; RV32XTHEADBB-NEXT:    srl t0, a1, a4
2267; RV32XTHEADBB-NEXT:    slli a6, a6, 1
2268; RV32XTHEADBB-NEXT:    sll a1, t1, a0
2269; RV32XTHEADBB-NEXT:    sll t1, a6, a0
2270; RV32XTHEADBB-NEXT:    mv a6, a2
2271; RV32XTHEADBB-NEXT:    beqz a5, .LBB23_6
2272; RV32XTHEADBB-NEXT:  # %bb.5:
2273; RV32XTHEADBB-NEXT:    mv a6, a3
2274; RV32XTHEADBB-NEXT:  .LBB23_6:
2275; RV32XTHEADBB-NEXT:    or a1, a1, a7
2276; RV32XTHEADBB-NEXT:    or a7, t1, t0
2277; RV32XTHEADBB-NEXT:    srl t0, a6, a4
2278; RV32XTHEADBB-NEXT:    beqz a5, .LBB23_8
2279; RV32XTHEADBB-NEXT:  # %bb.7:
2280; RV32XTHEADBB-NEXT:    mv a3, a2
2281; RV32XTHEADBB-NEXT:  .LBB23_8:
2282; RV32XTHEADBB-NEXT:    slli a2, a3, 1
2283; RV32XTHEADBB-NEXT:    srl a3, a3, a4
2284; RV32XTHEADBB-NEXT:    slli a6, a6, 1
2285; RV32XTHEADBB-NEXT:    sll a2, a2, a0
2286; RV32XTHEADBB-NEXT:    sll a0, a6, a0
2287; RV32XTHEADBB-NEXT:    or a2, a2, t0
2288; RV32XTHEADBB-NEXT:    or a0, a0, a3
2289; RV32XTHEADBB-NEXT:    add a7, a7, a0
2290; RV32XTHEADBB-NEXT:    add a0, a1, a2
2291; RV32XTHEADBB-NEXT:    sltu a1, a0, a1
2292; RV32XTHEADBB-NEXT:    add a1, a7, a1
2293; RV32XTHEADBB-NEXT:    ret
2294;
2295; RV64XTHEADBB-LABEL: rotr_64_mask_multiple:
2296; RV64XTHEADBB:       # %bb.0:
2297; RV64XTHEADBB-NEXT:    srl a3, a0, a2
2298; RV64XTHEADBB-NEXT:    negw a4, a2
2299; RV64XTHEADBB-NEXT:    srl a2, a1, a2
2300; RV64XTHEADBB-NEXT:    sll a0, a0, a4
2301; RV64XTHEADBB-NEXT:    sll a1, a1, a4
2302; RV64XTHEADBB-NEXT:    or a0, a3, a0
2303; RV64XTHEADBB-NEXT:    or a1, a2, a1
2304; RV64XTHEADBB-NEXT:    add a0, a0, a1
2305; RV64XTHEADBB-NEXT:    ret
2306  %maskedamt = and i64 %amt, 63
2307  %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %maskedamt)
2308  %2 = tail call i64 @llvm.fshr.i64(i64 %b, i64 %b, i64 %maskedamt)
2309  %3 = add i64 %1, %2
2310  ret i64 %3
2311}
2312
2313define i64 @rotl_64_zext(i64 %x, i32 %y) nounwind {
2314; RV32I-LABEL: rotl_64_zext:
2315; RV32I:       # %bb.0:
2316; RV32I-NEXT:    neg a4, a2
2317; RV32I-NEXT:    addi a6, a2, -32
2318; RV32I-NEXT:    sll a5, a0, a2
2319; RV32I-NEXT:    bltz a6, .LBB24_2
2320; RV32I-NEXT:  # %bb.1:
2321; RV32I-NEXT:    mv a3, a5
2322; RV32I-NEXT:    j .LBB24_3
2323; RV32I-NEXT:  .LBB24_2:
2324; RV32I-NEXT:    sll a3, a1, a2
2325; RV32I-NEXT:    not a7, a2
2326; RV32I-NEXT:    srli t0, a0, 1
2327; RV32I-NEXT:    srl a7, t0, a7
2328; RV32I-NEXT:    or a3, a3, a7
2329; RV32I-NEXT:  .LBB24_3:
2330; RV32I-NEXT:    srai a6, a6, 31
2331; RV32I-NEXT:    li a7, 32
2332; RV32I-NEXT:    and a5, a6, a5
2333; RV32I-NEXT:    sub a6, a7, a2
2334; RV32I-NEXT:    srl a7, a1, a4
2335; RV32I-NEXT:    bltz a6, .LBB24_5
2336; RV32I-NEXT:  # %bb.4:
2337; RV32I-NEXT:    mv a0, a7
2338; RV32I-NEXT:    j .LBB24_6
2339; RV32I-NEXT:  .LBB24_5:
2340; RV32I-NEXT:    li t0, 64
2341; RV32I-NEXT:    srl a0, a0, a4
2342; RV32I-NEXT:    sub a2, t0, a2
2343; RV32I-NEXT:    not a2, a2
2344; RV32I-NEXT:    slli a1, a1, 1
2345; RV32I-NEXT:    sll a1, a1, a2
2346; RV32I-NEXT:    or a0, a0, a1
2347; RV32I-NEXT:  .LBB24_6:
2348; RV32I-NEXT:    srai a1, a6, 31
2349; RV32I-NEXT:    and a1, a1, a7
2350; RV32I-NEXT:    or a1, a3, a1
2351; RV32I-NEXT:    or a0, a5, a0
2352; RV32I-NEXT:    ret
2353;
2354; RV64I-LABEL: rotl_64_zext:
2355; RV64I:       # %bb.0:
2356; RV64I-NEXT:    negw a2, a1
2357; RV64I-NEXT:    sll a1, a0, a1
2358; RV64I-NEXT:    srl a0, a0, a2
2359; RV64I-NEXT:    or a0, a1, a0
2360; RV64I-NEXT:    ret
2361;
2362; RV32ZBB-LABEL: rotl_64_zext:
2363; RV32ZBB:       # %bb.0:
2364; RV32ZBB-NEXT:    neg a4, a2
2365; RV32ZBB-NEXT:    addi a6, a2, -32
2366; RV32ZBB-NEXT:    sll a5, a0, a2
2367; RV32ZBB-NEXT:    bltz a6, .LBB24_2
2368; RV32ZBB-NEXT:  # %bb.1:
2369; RV32ZBB-NEXT:    mv a3, a5
2370; RV32ZBB-NEXT:    j .LBB24_3
2371; RV32ZBB-NEXT:  .LBB24_2:
2372; RV32ZBB-NEXT:    sll a3, a1, a2
2373; RV32ZBB-NEXT:    not a7, a2
2374; RV32ZBB-NEXT:    srli t0, a0, 1
2375; RV32ZBB-NEXT:    srl a7, t0, a7
2376; RV32ZBB-NEXT:    or a3, a3, a7
2377; RV32ZBB-NEXT:  .LBB24_3:
2378; RV32ZBB-NEXT:    srai a6, a6, 31
2379; RV32ZBB-NEXT:    li a7, 32
2380; RV32ZBB-NEXT:    and a5, a6, a5
2381; RV32ZBB-NEXT:    sub a6, a7, a2
2382; RV32ZBB-NEXT:    srl a7, a1, a4
2383; RV32ZBB-NEXT:    bltz a6, .LBB24_5
2384; RV32ZBB-NEXT:  # %bb.4:
2385; RV32ZBB-NEXT:    mv a0, a7
2386; RV32ZBB-NEXT:    j .LBB24_6
2387; RV32ZBB-NEXT:  .LBB24_5:
2388; RV32ZBB-NEXT:    li t0, 64
2389; RV32ZBB-NEXT:    srl a0, a0, a4
2390; RV32ZBB-NEXT:    sub a2, t0, a2
2391; RV32ZBB-NEXT:    not a2, a2
2392; RV32ZBB-NEXT:    slli a1, a1, 1
2393; RV32ZBB-NEXT:    sll a1, a1, a2
2394; RV32ZBB-NEXT:    or a0, a0, a1
2395; RV32ZBB-NEXT:  .LBB24_6:
2396; RV32ZBB-NEXT:    srai a1, a6, 31
2397; RV32ZBB-NEXT:    and a1, a1, a7
2398; RV32ZBB-NEXT:    or a1, a3, a1
2399; RV32ZBB-NEXT:    or a0, a5, a0
2400; RV32ZBB-NEXT:    ret
2401;
2402; RV64ZBB-LABEL: rotl_64_zext:
2403; RV64ZBB:       # %bb.0:
2404; RV64ZBB-NEXT:    rol a0, a0, a1
2405; RV64ZBB-NEXT:    ret
2406;
2407; RV32XTHEADBB-LABEL: rotl_64_zext:
2408; RV32XTHEADBB:       # %bb.0:
2409; RV32XTHEADBB-NEXT:    neg a4, a2
2410; RV32XTHEADBB-NEXT:    addi a6, a2, -32
2411; RV32XTHEADBB-NEXT:    sll a5, a0, a2
2412; RV32XTHEADBB-NEXT:    bltz a6, .LBB24_2
2413; RV32XTHEADBB-NEXT:  # %bb.1:
2414; RV32XTHEADBB-NEXT:    mv a3, a5
2415; RV32XTHEADBB-NEXT:    j .LBB24_3
2416; RV32XTHEADBB-NEXT:  .LBB24_2:
2417; RV32XTHEADBB-NEXT:    sll a3, a1, a2
2418; RV32XTHEADBB-NEXT:    not a7, a2
2419; RV32XTHEADBB-NEXT:    srli t0, a0, 1
2420; RV32XTHEADBB-NEXT:    srl a7, t0, a7
2421; RV32XTHEADBB-NEXT:    or a3, a3, a7
2422; RV32XTHEADBB-NEXT:  .LBB24_3:
2423; RV32XTHEADBB-NEXT:    srai a6, a6, 31
2424; RV32XTHEADBB-NEXT:    li a7, 32
2425; RV32XTHEADBB-NEXT:    and a5, a6, a5
2426; RV32XTHEADBB-NEXT:    sub a6, a7, a2
2427; RV32XTHEADBB-NEXT:    srl a7, a1, a4
2428; RV32XTHEADBB-NEXT:    bltz a6, .LBB24_5
2429; RV32XTHEADBB-NEXT:  # %bb.4:
2430; RV32XTHEADBB-NEXT:    mv a0, a7
2431; RV32XTHEADBB-NEXT:    j .LBB24_6
2432; RV32XTHEADBB-NEXT:  .LBB24_5:
2433; RV32XTHEADBB-NEXT:    li t0, 64
2434; RV32XTHEADBB-NEXT:    srl a0, a0, a4
2435; RV32XTHEADBB-NEXT:    sub a2, t0, a2
2436; RV32XTHEADBB-NEXT:    not a2, a2
2437; RV32XTHEADBB-NEXT:    slli a1, a1, 1
2438; RV32XTHEADBB-NEXT:    sll a1, a1, a2
2439; RV32XTHEADBB-NEXT:    or a0, a0, a1
2440; RV32XTHEADBB-NEXT:  .LBB24_6:
2441; RV32XTHEADBB-NEXT:    srai a1, a6, 31
2442; RV32XTHEADBB-NEXT:    and a1, a1, a7
2443; RV32XTHEADBB-NEXT:    or a1, a3, a1
2444; RV32XTHEADBB-NEXT:    or a0, a5, a0
2445; RV32XTHEADBB-NEXT:    ret
2446;
2447; RV64XTHEADBB-LABEL: rotl_64_zext:
2448; RV64XTHEADBB:       # %bb.0:
2449; RV64XTHEADBB-NEXT:    sll a2, a0, a1
2450; RV64XTHEADBB-NEXT:    negw a1, a1
2451; RV64XTHEADBB-NEXT:    srl a0, a0, a1
2452; RV64XTHEADBB-NEXT:    or a0, a2, a0
2453; RV64XTHEADBB-NEXT:    ret
2454  %z = sub i32 64, %y
2455  %zext = zext i32 %z to i64
2456  %zexty = zext i32 %y to i64
2457  %b = shl i64 %x, %zexty
2458  %c = lshr i64 %x, %zext
2459  %d = or i64 %b, %c
2460  ret i64 %d
2461}
2462
2463define i64 @rotr_64_zext(i64 %x, i32 %y) nounwind {
2464; RV32I-LABEL: rotr_64_zext:
2465; RV32I:       # %bb.0:
2466; RV32I-NEXT:    neg a4, a2
2467; RV32I-NEXT:    addi a6, a2, -32
2468; RV32I-NEXT:    srl a5, a1, a2
2469; RV32I-NEXT:    bltz a6, .LBB25_2
2470; RV32I-NEXT:  # %bb.1:
2471; RV32I-NEXT:    mv a3, a5
2472; RV32I-NEXT:    j .LBB25_3
2473; RV32I-NEXT:  .LBB25_2:
2474; RV32I-NEXT:    srl a3, a0, a2
2475; RV32I-NEXT:    not a7, a2
2476; RV32I-NEXT:    slli t0, a1, 1
2477; RV32I-NEXT:    sll a7, t0, a7
2478; RV32I-NEXT:    or a3, a3, a7
2479; RV32I-NEXT:  .LBB25_3:
2480; RV32I-NEXT:    srai a6, a6, 31
2481; RV32I-NEXT:    li a7, 32
2482; RV32I-NEXT:    and a5, a6, a5
2483; RV32I-NEXT:    sub a6, a7, a2
2484; RV32I-NEXT:    sll a7, a0, a4
2485; RV32I-NEXT:    bltz a6, .LBB25_5
2486; RV32I-NEXT:  # %bb.4:
2487; RV32I-NEXT:    mv a1, a7
2488; RV32I-NEXT:    j .LBB25_6
2489; RV32I-NEXT:  .LBB25_5:
2490; RV32I-NEXT:    li t0, 64
2491; RV32I-NEXT:    sll a1, a1, a4
2492; RV32I-NEXT:    sub a2, t0, a2
2493; RV32I-NEXT:    not a2, a2
2494; RV32I-NEXT:    srli a0, a0, 1
2495; RV32I-NEXT:    srl a0, a0, a2
2496; RV32I-NEXT:    or a1, a1, a0
2497; RV32I-NEXT:  .LBB25_6:
2498; RV32I-NEXT:    srai a0, a6, 31
2499; RV32I-NEXT:    and a0, a0, a7
2500; RV32I-NEXT:    or a0, a3, a0
2501; RV32I-NEXT:    or a1, a5, a1
2502; RV32I-NEXT:    ret
2503;
2504; RV64I-LABEL: rotr_64_zext:
2505; RV64I:       # %bb.0:
2506; RV64I-NEXT:    negw a2, a1
2507; RV64I-NEXT:    srl a1, a0, a1
2508; RV64I-NEXT:    sll a0, a0, a2
2509; RV64I-NEXT:    or a0, a1, a0
2510; RV64I-NEXT:    ret
2511;
2512; RV32ZBB-LABEL: rotr_64_zext:
2513; RV32ZBB:       # %bb.0:
2514; RV32ZBB-NEXT:    neg a4, a2
2515; RV32ZBB-NEXT:    addi a6, a2, -32
2516; RV32ZBB-NEXT:    srl a5, a1, a2
2517; RV32ZBB-NEXT:    bltz a6, .LBB25_2
2518; RV32ZBB-NEXT:  # %bb.1:
2519; RV32ZBB-NEXT:    mv a3, a5
2520; RV32ZBB-NEXT:    j .LBB25_3
2521; RV32ZBB-NEXT:  .LBB25_2:
2522; RV32ZBB-NEXT:    srl a3, a0, a2
2523; RV32ZBB-NEXT:    not a7, a2
2524; RV32ZBB-NEXT:    slli t0, a1, 1
2525; RV32ZBB-NEXT:    sll a7, t0, a7
2526; RV32ZBB-NEXT:    or a3, a3, a7
2527; RV32ZBB-NEXT:  .LBB25_3:
2528; RV32ZBB-NEXT:    srai a6, a6, 31
2529; RV32ZBB-NEXT:    li a7, 32
2530; RV32ZBB-NEXT:    and a5, a6, a5
2531; RV32ZBB-NEXT:    sub a6, a7, a2
2532; RV32ZBB-NEXT:    sll a7, a0, a4
2533; RV32ZBB-NEXT:    bltz a6, .LBB25_5
2534; RV32ZBB-NEXT:  # %bb.4:
2535; RV32ZBB-NEXT:    mv a1, a7
2536; RV32ZBB-NEXT:    j .LBB25_6
2537; RV32ZBB-NEXT:  .LBB25_5:
2538; RV32ZBB-NEXT:    li t0, 64
2539; RV32ZBB-NEXT:    sll a1, a1, a4
2540; RV32ZBB-NEXT:    sub a2, t0, a2
2541; RV32ZBB-NEXT:    not a2, a2
2542; RV32ZBB-NEXT:    srli a0, a0, 1
2543; RV32ZBB-NEXT:    srl a0, a0, a2
2544; RV32ZBB-NEXT:    or a1, a1, a0
2545; RV32ZBB-NEXT:  .LBB25_6:
2546; RV32ZBB-NEXT:    srai a0, a6, 31
2547; RV32ZBB-NEXT:    and a0, a0, a7
2548; RV32ZBB-NEXT:    or a0, a3, a0
2549; RV32ZBB-NEXT:    or a1, a5, a1
2550; RV32ZBB-NEXT:    ret
2551;
2552; RV64ZBB-LABEL: rotr_64_zext:
2553; RV64ZBB:       # %bb.0:
2554; RV64ZBB-NEXT:    ror a0, a0, a1
2555; RV64ZBB-NEXT:    ret
2556;
2557; RV32XTHEADBB-LABEL: rotr_64_zext:
2558; RV32XTHEADBB:       # %bb.0:
2559; RV32XTHEADBB-NEXT:    neg a4, a2
2560; RV32XTHEADBB-NEXT:    addi a6, a2, -32
2561; RV32XTHEADBB-NEXT:    srl a5, a1, a2
2562; RV32XTHEADBB-NEXT:    bltz a6, .LBB25_2
2563; RV32XTHEADBB-NEXT:  # %bb.1:
2564; RV32XTHEADBB-NEXT:    mv a3, a5
2565; RV32XTHEADBB-NEXT:    j .LBB25_3
2566; RV32XTHEADBB-NEXT:  .LBB25_2:
2567; RV32XTHEADBB-NEXT:    srl a3, a0, a2
2568; RV32XTHEADBB-NEXT:    not a7, a2
2569; RV32XTHEADBB-NEXT:    slli t0, a1, 1
2570; RV32XTHEADBB-NEXT:    sll a7, t0, a7
2571; RV32XTHEADBB-NEXT:    or a3, a3, a7
2572; RV32XTHEADBB-NEXT:  .LBB25_3:
2573; RV32XTHEADBB-NEXT:    srai a6, a6, 31
2574; RV32XTHEADBB-NEXT:    li a7, 32
2575; RV32XTHEADBB-NEXT:    and a5, a6, a5
2576; RV32XTHEADBB-NEXT:    sub a6, a7, a2
2577; RV32XTHEADBB-NEXT:    sll a7, a0, a4
2578; RV32XTHEADBB-NEXT:    bltz a6, .LBB25_5
2579; RV32XTHEADBB-NEXT:  # %bb.4:
2580; RV32XTHEADBB-NEXT:    mv a1, a7
2581; RV32XTHEADBB-NEXT:    j .LBB25_6
2582; RV32XTHEADBB-NEXT:  .LBB25_5:
2583; RV32XTHEADBB-NEXT:    li t0, 64
2584; RV32XTHEADBB-NEXT:    sll a1, a1, a4
2585; RV32XTHEADBB-NEXT:    sub a2, t0, a2
2586; RV32XTHEADBB-NEXT:    not a2, a2
2587; RV32XTHEADBB-NEXT:    srli a0, a0, 1
2588; RV32XTHEADBB-NEXT:    srl a0, a0, a2
2589; RV32XTHEADBB-NEXT:    or a1, a1, a0
2590; RV32XTHEADBB-NEXT:  .LBB25_6:
2591; RV32XTHEADBB-NEXT:    srai a0, a6, 31
2592; RV32XTHEADBB-NEXT:    and a0, a0, a7
2593; RV32XTHEADBB-NEXT:    or a0, a3, a0
2594; RV32XTHEADBB-NEXT:    or a1, a5, a1
2595; RV32XTHEADBB-NEXT:    ret
2596;
2597; RV64XTHEADBB-LABEL: rotr_64_zext:
2598; RV64XTHEADBB:       # %bb.0:
2599; RV64XTHEADBB-NEXT:    srl a2, a0, a1
2600; RV64XTHEADBB-NEXT:    negw a1, a1
2601; RV64XTHEADBB-NEXT:    sll a0, a0, a1
2602; RV64XTHEADBB-NEXT:    or a0, a2, a0
2603; RV64XTHEADBB-NEXT:    ret
2604  %z = sub i32 64, %y
2605  %zext = zext i32 %z to i64
2606  %zexty = zext i32 %y to i64
2607  %b = lshr i64 %x, %zexty
2608  %c = shl i64 %x, %zext
2609  %d = or i64 %b, %c
2610  ret i64 %d
2611}
2612