[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / CodeGen / RISCV / rv64zbb.ll
blobd67db77c04a8eaad7fdbe32bc08b1aa9130be629
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
7 declare i32 @llvm.ctlz.i32(i32, i1)
9 define 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
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
59 define 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
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
115 define 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
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
172 define 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
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
228 define 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
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
281 declare i64 @llvm.ctlz.i64(i64, i1)
283 define 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
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
343 declare i32 @llvm.cttz.i32(i32, i1)
345 define 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
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
377 define 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
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
404 define 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
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
442 define 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
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
483 declare i64 @llvm.cttz.i64(i64, i1)
485 define 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
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
517 declare i32 @llvm.ctpop.i32(i32)
519 define 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
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
553 define 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
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
571 define 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
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
590 define 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
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
609 define 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
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
629 define 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
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
666 declare <2 x i32> @llvm.ctpop.v2i32(<2 x i32>)
668 define <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
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
718 define <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
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
743 define <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
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
770 define <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
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
797 define <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
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
826 declare i64 @llvm.ctpop.i64(i64)
828 define 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
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
870 define 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
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
888 define 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
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
907 define 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
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
926 define 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
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
946 declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>)
948 define <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
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
1008 define <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
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
1031 define <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
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
1056 define <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
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
1081 define <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
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
1108 define 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
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
1124 define 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
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
1140 define 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
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
1156 define 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
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
1172 define 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
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
1190 define 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
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
1208 define 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
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
1226 define 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
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
1244 define 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
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
1262 define 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
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
1280 define 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
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
1298 define 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
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
1316 declare i32 @llvm.abs.i32(i32, i1 immarg)
1318 define 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
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
1336 define 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
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
1353 declare i64 @llvm.abs.i64(i64, i1 immarg)
1355 define 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
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
1372 define 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
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
1387 define 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
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
1402 declare i32 @llvm.bswap.i32(i32)
1404 define 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
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
1429 ; Similar to bswap_i32 but the result is not sign extended.
1430 define 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
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
1458 declare i64 @llvm.bswap.i64(i64)
1460 define 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
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
1498 define 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
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
1516 define 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
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
1538 define 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
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
1564 define 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
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
1582 define 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
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
1600 define 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
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
1614 entry:
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
1622 define 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
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
1636 entry:
1637   %popcnt = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x)
1638   %cmp = icmp eq i32 %popcnt, 1
1639   ret i1 %cmp
1642 define 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
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
1657 entry:
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
1663 define 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
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
1676 entry:
1677   %popcnt = call range(i64 1, 65) i64 @llvm.ctpop.i64(i64 %x)
1678   %cmp = icmp eq i64 %popcnt, 1
1679   ret i1 %cmp
1682 define 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
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
1697 entry:
1698   %popcnt = call range(i32 0, 16) i32 @llvm.ctpop.i32(i32 %x)
1699   %cmp = icmp eq i32 %popcnt, 1
1700   ret i1 %cmp