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