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