1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -global-isel -verify-machineinstrs < %s \
3 ; RUN: | FileCheck %s -check-prefixes=CHECK,RV32I
4 ; RUN: llc -mtriple=riscv32 -global-isel -mattr=+zbb -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s -check-prefixes=CHECK,RV32ZBB
7 declare i32 @llvm.ctlz.i32(i32, i1)
9 define i32 @ctlz_i32(i32 %a) nounwind {
10 ; RV32I-LABEL: ctlz_i32:
12 ; RV32I-NEXT: beqz a0, .LBB0_2
13 ; RV32I-NEXT: # %bb.1: # %cond.false
14 ; RV32I-NEXT: srli a1, a0, 1
15 ; RV32I-NEXT: lui a2, 349525
16 ; RV32I-NEXT: or a0, a0, a1
17 ; RV32I-NEXT: addi a1, a2, 1365
18 ; RV32I-NEXT: srli a2, a0, 2
19 ; RV32I-NEXT: or a0, a0, a2
20 ; RV32I-NEXT: srli a2, a0, 4
21 ; RV32I-NEXT: or a0, a0, a2
22 ; RV32I-NEXT: srli a2, a0, 8
23 ; RV32I-NEXT: or a0, a0, a2
24 ; RV32I-NEXT: srli a2, a0, 16
25 ; RV32I-NEXT: or a0, a0, a2
26 ; RV32I-NEXT: srli a2, a0, 1
27 ; RV32I-NEXT: and a1, a2, a1
28 ; RV32I-NEXT: lui a2, 209715
29 ; RV32I-NEXT: addi a2, a2, 819
30 ; RV32I-NEXT: sub a0, a0, a1
31 ; RV32I-NEXT: srli a1, a0, 2
32 ; RV32I-NEXT: and a0, a0, a2
33 ; RV32I-NEXT: and a1, a1, a2
34 ; RV32I-NEXT: lui a2, 61681
35 ; RV32I-NEXT: addi a2, a2, -241
36 ; RV32I-NEXT: add a0, a1, a0
37 ; RV32I-NEXT: srli a1, a0, 4
38 ; RV32I-NEXT: add a0, a1, a0
39 ; RV32I-NEXT: and a0, a0, a2
40 ; RV32I-NEXT: slli a1, a0, 8
41 ; RV32I-NEXT: add a0, a0, a1
42 ; RV32I-NEXT: slli a1, a0, 16
43 ; RV32I-NEXT: add a0, a0, a1
44 ; RV32I-NEXT: srli a0, a0, 24
45 ; RV32I-NEXT: li a1, 32
46 ; RV32I-NEXT: sub a0, a1, a0
48 ; RV32I-NEXT: .LBB0_2:
49 ; RV32I-NEXT: li a0, 32
52 ; RV32ZBB-LABEL: ctlz_i32:
54 ; RV32ZBB-NEXT: clz a0, a0
56 %1 = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
60 declare i64 @llvm.ctlz.i64(i64, i1)
62 define i64 @ctlz_i64(i64 %a) nounwind {
63 ; RV32I-LABEL: ctlz_i64:
65 ; RV32I-NEXT: lui a2, 349525
66 ; RV32I-NEXT: lui a3, 209715
67 ; RV32I-NEXT: lui a6, 61681
68 ; RV32I-NEXT: addi a5, a2, 1365
69 ; RV32I-NEXT: addi a4, a3, 819
70 ; RV32I-NEXT: addi a3, a6, -241
71 ; RV32I-NEXT: li a2, 32
72 ; RV32I-NEXT: beqz a1, .LBB1_2
73 ; RV32I-NEXT: # %bb.1:
74 ; RV32I-NEXT: srli a0, a1, 1
75 ; RV32I-NEXT: or a0, a1, a0
76 ; RV32I-NEXT: srli a1, a0, 2
77 ; RV32I-NEXT: or a0, a0, a1
78 ; RV32I-NEXT: srli a1, a0, 4
79 ; RV32I-NEXT: or a0, a0, a1
80 ; RV32I-NEXT: srli a1, a0, 8
81 ; RV32I-NEXT: or a0, a0, a1
82 ; RV32I-NEXT: srli a1, a0, 16
83 ; RV32I-NEXT: or a0, a0, a1
84 ; RV32I-NEXT: srli a1, a0, 1
85 ; RV32I-NEXT: and a1, a1, a5
86 ; RV32I-NEXT: sub a0, a0, a1
87 ; RV32I-NEXT: srli a1, a0, 2
88 ; RV32I-NEXT: and a1, a1, a4
89 ; RV32I-NEXT: and a0, a0, a4
90 ; RV32I-NEXT: add a0, a1, a0
91 ; RV32I-NEXT: srli a1, a0, 4
92 ; RV32I-NEXT: add a0, a1, a0
93 ; RV32I-NEXT: and a0, a0, a3
94 ; RV32I-NEXT: slli a1, a0, 8
95 ; RV32I-NEXT: add a0, a0, a1
96 ; RV32I-NEXT: slli a1, a0, 16
97 ; RV32I-NEXT: add a0, a0, a1
98 ; RV32I-NEXT: srli a0, a0, 24
99 ; RV32I-NEXT: sub a0, a2, a0
100 ; RV32I-NEXT: li a1, 0
102 ; RV32I-NEXT: .LBB1_2:
103 ; RV32I-NEXT: srli a1, a0, 1
104 ; RV32I-NEXT: or a0, a0, a1
105 ; RV32I-NEXT: srli a1, a0, 2
106 ; RV32I-NEXT: or a0, a0, a1
107 ; RV32I-NEXT: srli a1, a0, 4
108 ; RV32I-NEXT: or a0, a0, a1
109 ; RV32I-NEXT: srli a1, a0, 8
110 ; RV32I-NEXT: or a0, a0, a1
111 ; RV32I-NEXT: srli a1, a0, 16
112 ; RV32I-NEXT: or a0, a0, a1
113 ; RV32I-NEXT: srli a1, a0, 1
114 ; RV32I-NEXT: and a1, a1, a5
115 ; RV32I-NEXT: sub a0, a0, a1
116 ; RV32I-NEXT: srli a1, a0, 2
117 ; RV32I-NEXT: and a1, a1, a4
118 ; RV32I-NEXT: and a0, a0, a4
119 ; RV32I-NEXT: add a0, a1, a0
120 ; RV32I-NEXT: srli a1, a0, 4
121 ; RV32I-NEXT: add a0, a1, a0
122 ; RV32I-NEXT: and a0, a0, a3
123 ; RV32I-NEXT: slli a1, a0, 8
124 ; RV32I-NEXT: add a0, a0, a1
125 ; RV32I-NEXT: slli a1, a0, 16
126 ; RV32I-NEXT: add a0, a0, a1
127 ; RV32I-NEXT: srli a0, a0, 24
128 ; RV32I-NEXT: sub a2, a2, a0
129 ; RV32I-NEXT: addi a0, a2, 32
130 ; RV32I-NEXT: li a1, 0
133 ; RV32ZBB-LABEL: ctlz_i64:
135 ; RV32ZBB-NEXT: beqz a1, .LBB1_2
136 ; RV32ZBB-NEXT: # %bb.1:
137 ; RV32ZBB-NEXT: clz a0, a1
138 ; RV32ZBB-NEXT: li a1, 0
140 ; RV32ZBB-NEXT: .LBB1_2:
141 ; RV32ZBB-NEXT: clz a0, a0
142 ; RV32ZBB-NEXT: addi a0, a0, 32
143 ; RV32ZBB-NEXT: li a1, 0
145 %1 = call i64 @llvm.ctlz.i64(i64 %a, i1 false)
149 declare i32 @llvm.cttz.i32(i32, i1)
151 define i32 @cttz_i32(i32 %a) nounwind {
152 ; RV32I-LABEL: cttz_i32:
154 ; RV32I-NEXT: beqz a0, .LBB2_2
155 ; RV32I-NEXT: # %bb.1: # %cond.false
156 ; RV32I-NEXT: not a1, a0
157 ; RV32I-NEXT: addi a0, a0, -1
158 ; RV32I-NEXT: lui a2, 349525
159 ; RV32I-NEXT: and a0, a1, a0
160 ; RV32I-NEXT: addi a1, a2, 1365
161 ; RV32I-NEXT: srli a2, a0, 1
162 ; RV32I-NEXT: and a1, a2, a1
163 ; RV32I-NEXT: lui a2, 209715
164 ; RV32I-NEXT: addi a2, a2, 819
165 ; RV32I-NEXT: sub a0, a0, a1
166 ; RV32I-NEXT: srli a1, a0, 2
167 ; RV32I-NEXT: and a0, a0, a2
168 ; RV32I-NEXT: and a1, a1, a2
169 ; RV32I-NEXT: lui a2, 61681
170 ; RV32I-NEXT: add a0, a1, a0
171 ; RV32I-NEXT: srli a1, a0, 4
172 ; RV32I-NEXT: add a0, a1, a0
173 ; RV32I-NEXT: addi a1, a2, -241
174 ; RV32I-NEXT: and a0, a0, a1
175 ; RV32I-NEXT: slli a1, a0, 8
176 ; RV32I-NEXT: add a0, a0, a1
177 ; RV32I-NEXT: slli a1, a0, 16
178 ; RV32I-NEXT: add a0, a0, a1
179 ; RV32I-NEXT: srli a0, a0, 24
181 ; RV32I-NEXT: .LBB2_2:
182 ; RV32I-NEXT: li a0, 32
185 ; RV32ZBB-LABEL: cttz_i32:
187 ; RV32ZBB-NEXT: ctz a0, a0
189 %1 = call i32 @llvm.cttz.i32(i32 %a, i1 false)
193 declare i64 @llvm.cttz.i64(i64, i1)
195 define i64 @cttz_i64(i64 %a) nounwind {
196 ; RV32I-LABEL: cttz_i64:
198 ; RV32I-NEXT: lui a2, 349525
199 ; RV32I-NEXT: lui a3, 209715
200 ; RV32I-NEXT: lui a5, 61681
201 ; RV32I-NEXT: addi a4, a2, 1365
202 ; RV32I-NEXT: addi a3, a3, 819
203 ; RV32I-NEXT: addi a2, a5, -241
204 ; RV32I-NEXT: beqz a0, .LBB3_2
205 ; RV32I-NEXT: # %bb.1:
206 ; RV32I-NEXT: not a1, a0
207 ; RV32I-NEXT: addi a0, a0, -1
208 ; RV32I-NEXT: and a0, a1, a0
209 ; RV32I-NEXT: srli a1, a0, 1
210 ; RV32I-NEXT: and a1, a1, a4
211 ; RV32I-NEXT: sub a0, a0, a1
212 ; RV32I-NEXT: srli a1, a0, 2
213 ; RV32I-NEXT: and a1, a1, a3
214 ; RV32I-NEXT: and a0, a0, a3
215 ; RV32I-NEXT: add a0, a1, a0
216 ; RV32I-NEXT: srli a1, a0, 4
217 ; RV32I-NEXT: add a0, a1, a0
218 ; RV32I-NEXT: and a0, a0, a2
219 ; RV32I-NEXT: slli a1, a0, 8
220 ; RV32I-NEXT: add a0, a0, a1
221 ; RV32I-NEXT: slli a1, a0, 16
222 ; RV32I-NEXT: add a0, a0, a1
223 ; RV32I-NEXT: srli a0, a0, 24
224 ; RV32I-NEXT: li a1, 0
226 ; RV32I-NEXT: .LBB3_2:
227 ; RV32I-NEXT: not a0, a1
228 ; RV32I-NEXT: addi a1, a1, -1
229 ; RV32I-NEXT: and a0, a0, a1
230 ; RV32I-NEXT: srli a1, a0, 1
231 ; RV32I-NEXT: and a1, a1, a4
232 ; RV32I-NEXT: sub a0, a0, a1
233 ; RV32I-NEXT: srli a1, a0, 2
234 ; RV32I-NEXT: and a1, a1, a3
235 ; RV32I-NEXT: and a0, a0, a3
236 ; RV32I-NEXT: add a0, a1, a0
237 ; RV32I-NEXT: srli a1, a0, 4
238 ; RV32I-NEXT: add a0, a1, a0
239 ; RV32I-NEXT: and a0, a0, a2
240 ; RV32I-NEXT: slli a1, a0, 8
241 ; RV32I-NEXT: add a0, a0, a1
242 ; RV32I-NEXT: slli a1, a0, 16
243 ; RV32I-NEXT: add a0, a0, a1
244 ; RV32I-NEXT: srli a0, a0, 24
245 ; RV32I-NEXT: addi a0, a0, 32
246 ; RV32I-NEXT: li a1, 0
249 ; RV32ZBB-LABEL: cttz_i64:
251 ; RV32ZBB-NEXT: beqz a0, .LBB3_2
252 ; RV32ZBB-NEXT: # %bb.1:
253 ; RV32ZBB-NEXT: ctz a0, a0
254 ; RV32ZBB-NEXT: li a1, 0
256 ; RV32ZBB-NEXT: .LBB3_2:
257 ; RV32ZBB-NEXT: ctz a0, a1
258 ; RV32ZBB-NEXT: addi a0, a0, 32
259 ; RV32ZBB-NEXT: li a1, 0
261 %1 = call i64 @llvm.cttz.i64(i64 %a, i1 false)
265 declare i32 @llvm.ctpop.i32(i32)
267 define i32 @ctpop_i32(i32 %a) nounwind {
268 ; RV32I-LABEL: ctpop_i32:
270 ; RV32I-NEXT: srli a1, a0, 1
271 ; RV32I-NEXT: lui a2, 349525
272 ; RV32I-NEXT: addi a2, a2, 1365
273 ; RV32I-NEXT: and a1, a1, a2
274 ; RV32I-NEXT: lui a2, 209715
275 ; RV32I-NEXT: addi a2, a2, 819
276 ; RV32I-NEXT: sub a0, a0, a1
277 ; RV32I-NEXT: srli a1, a0, 2
278 ; RV32I-NEXT: and a0, a0, a2
279 ; RV32I-NEXT: and a1, a1, a2
280 ; RV32I-NEXT: lui a2, 61681
281 ; RV32I-NEXT: add a0, a1, a0
282 ; RV32I-NEXT: srli a1, a0, 4
283 ; RV32I-NEXT: add a0, a1, a0
284 ; RV32I-NEXT: addi a1, a2, -241
285 ; RV32I-NEXT: and a0, a0, a1
286 ; RV32I-NEXT: slli a1, a0, 8
287 ; RV32I-NEXT: add a0, a0, a1
288 ; RV32I-NEXT: slli a1, a0, 16
289 ; RV32I-NEXT: add a0, a0, a1
290 ; RV32I-NEXT: srli a0, a0, 24
293 ; RV32ZBB-LABEL: ctpop_i32:
295 ; RV32ZBB-NEXT: cpop a0, a0
297 %1 = call i32 @llvm.ctpop.i32(i32 %a)
301 declare i64 @llvm.ctpop.i64(i64)
303 define i64 @ctpop_i64(i64 %a) nounwind {
304 ; RV32I-LABEL: ctpop_i64:
306 ; RV32I-NEXT: srli a2, a0, 1
307 ; RV32I-NEXT: lui a3, 349525
308 ; RV32I-NEXT: lui a4, 209715
309 ; RV32I-NEXT: srli a5, a1, 1
310 ; RV32I-NEXT: addi a3, a3, 1365
311 ; RV32I-NEXT: and a2, a2, a3
312 ; RV32I-NEXT: and a3, a5, a3
313 ; RV32I-NEXT: lui a5, 61681
314 ; RV32I-NEXT: addi a4, a4, 819
315 ; RV32I-NEXT: addi a5, a5, -241
316 ; RV32I-NEXT: sub a0, a0, a2
317 ; RV32I-NEXT: sub a1, a1, a3
318 ; RV32I-NEXT: srli a2, a0, 2
319 ; RV32I-NEXT: and a0, a0, a4
320 ; RV32I-NEXT: srli a3, a1, 2
321 ; RV32I-NEXT: and a1, a1, a4
322 ; RV32I-NEXT: and a2, a2, a4
323 ; RV32I-NEXT: and a3, a3, a4
324 ; RV32I-NEXT: add a0, a2, a0
325 ; RV32I-NEXT: add a1, a3, a1
326 ; RV32I-NEXT: srli a2, a0, 4
327 ; RV32I-NEXT: srli a3, a1, 4
328 ; RV32I-NEXT: add a0, a2, a0
329 ; RV32I-NEXT: add a1, a3, a1
330 ; RV32I-NEXT: and a0, a0, a5
331 ; RV32I-NEXT: and a1, a1, a5
332 ; RV32I-NEXT: slli a2, a0, 8
333 ; RV32I-NEXT: slli a3, a1, 8
334 ; RV32I-NEXT: add a0, a0, a2
335 ; RV32I-NEXT: add a1, a1, a3
336 ; RV32I-NEXT: slli a2, a0, 16
337 ; RV32I-NEXT: slli a3, a1, 16
338 ; RV32I-NEXT: add a0, a0, a2
339 ; RV32I-NEXT: add a1, a1, a3
340 ; RV32I-NEXT: srli a0, a0, 24
341 ; RV32I-NEXT: srli a1, a1, 24
342 ; RV32I-NEXT: add a0, a1, a0
343 ; RV32I-NEXT: li a1, 0
346 ; RV32ZBB-LABEL: ctpop_i64:
348 ; RV32ZBB-NEXT: cpop a0, a0
349 ; RV32ZBB-NEXT: cpop a1, a1
350 ; RV32ZBB-NEXT: add a0, a1, a0
351 ; RV32ZBB-NEXT: li a1, 0
353 %1 = call i64 @llvm.ctpop.i64(i64 %a)
357 define i1 @ctpop_i64_ugt_two(i64 %a) nounwind {
358 ; RV32I-LABEL: ctpop_i64_ugt_two:
360 ; RV32I-NEXT: beqz zero, .LBB6_2
361 ; RV32I-NEXT: # %bb.1:
362 ; RV32I-NEXT: sltiu a0, zero, 0
364 ; RV32I-NEXT: .LBB6_2:
365 ; RV32I-NEXT: srli a2, a0, 1
366 ; RV32I-NEXT: lui a3, 349525
367 ; RV32I-NEXT: lui a4, 209715
368 ; RV32I-NEXT: srli a5, a1, 1
369 ; RV32I-NEXT: addi a3, a3, 1365
370 ; RV32I-NEXT: and a2, a2, a3
371 ; RV32I-NEXT: and a3, a5, a3
372 ; RV32I-NEXT: lui a5, 61681
373 ; RV32I-NEXT: addi a4, a4, 819
374 ; RV32I-NEXT: addi a5, a5, -241
375 ; RV32I-NEXT: sub a0, a0, a2
376 ; RV32I-NEXT: sub a1, a1, a3
377 ; RV32I-NEXT: srli a2, a0, 2
378 ; RV32I-NEXT: and a0, a0, a4
379 ; RV32I-NEXT: srli a3, a1, 2
380 ; RV32I-NEXT: and a1, a1, a4
381 ; RV32I-NEXT: and a2, a2, a4
382 ; RV32I-NEXT: and a3, a3, a4
383 ; RV32I-NEXT: add a0, a2, a0
384 ; RV32I-NEXT: add a1, a3, a1
385 ; RV32I-NEXT: srli a2, a0, 4
386 ; RV32I-NEXT: srli a3, a1, 4
387 ; RV32I-NEXT: add a0, a2, a0
388 ; RV32I-NEXT: add a1, a3, a1
389 ; RV32I-NEXT: and a0, a0, a5
390 ; RV32I-NEXT: and a1, a1, a5
391 ; RV32I-NEXT: slli a2, a0, 8
392 ; RV32I-NEXT: slli a3, a1, 8
393 ; RV32I-NEXT: add a0, a0, a2
394 ; RV32I-NEXT: add a1, a1, a3
395 ; RV32I-NEXT: slli a2, a0, 16
396 ; RV32I-NEXT: slli a3, a1, 16
397 ; RV32I-NEXT: add a0, a0, a2
398 ; RV32I-NEXT: add a1, a1, a3
399 ; RV32I-NEXT: srli a0, a0, 24
400 ; RV32I-NEXT: srli a1, a1, 24
401 ; RV32I-NEXT: add a0, a1, a0
402 ; RV32I-NEXT: sltiu a0, a0, 2
405 ; RV32ZBB-LABEL: ctpop_i64_ugt_two:
407 ; RV32ZBB-NEXT: beqz zero, .LBB6_2
408 ; RV32ZBB-NEXT: # %bb.1:
409 ; RV32ZBB-NEXT: sltiu a0, zero, 0
411 ; RV32ZBB-NEXT: .LBB6_2:
412 ; RV32ZBB-NEXT: cpop a0, a0
413 ; RV32ZBB-NEXT: cpop a1, a1
414 ; RV32ZBB-NEXT: add a0, a1, a0
415 ; RV32ZBB-NEXT: sltiu a0, a0, 2
417 %1 = call i64 @llvm.ctpop.i64(i64 %a)
418 %2 = icmp ult i64 %1, 2
422 define i1 @ctpop_i64_ugt_one(i64 %a) nounwind {
423 ; RV32I-LABEL: ctpop_i64_ugt_one:
425 ; RV32I-NEXT: beqz zero, .LBB7_2
426 ; RV32I-NEXT: # %bb.1:
427 ; RV32I-NEXT: snez a0, zero
429 ; RV32I-NEXT: .LBB7_2:
430 ; RV32I-NEXT: srli a2, a0, 1
431 ; RV32I-NEXT: lui a3, 349525
432 ; RV32I-NEXT: lui a4, 209715
433 ; RV32I-NEXT: srli a5, a1, 1
434 ; RV32I-NEXT: addi a3, a3, 1365
435 ; RV32I-NEXT: and a2, a2, a3
436 ; RV32I-NEXT: and a3, a5, a3
437 ; RV32I-NEXT: lui a5, 61681
438 ; RV32I-NEXT: addi a4, a4, 819
439 ; RV32I-NEXT: addi a5, a5, -241
440 ; RV32I-NEXT: sub a0, a0, a2
441 ; RV32I-NEXT: sub a1, a1, a3
442 ; RV32I-NEXT: srli a2, a0, 2
443 ; RV32I-NEXT: and a0, a0, a4
444 ; RV32I-NEXT: srli a3, a1, 2
445 ; RV32I-NEXT: and a1, a1, a4
446 ; RV32I-NEXT: and a2, a2, a4
447 ; RV32I-NEXT: and a3, a3, a4
448 ; RV32I-NEXT: add a0, a2, a0
449 ; RV32I-NEXT: add a1, a3, a1
450 ; RV32I-NEXT: srli a2, a0, 4
451 ; RV32I-NEXT: srli a3, a1, 4
452 ; RV32I-NEXT: add a0, a2, a0
453 ; RV32I-NEXT: add a1, a3, a1
454 ; RV32I-NEXT: and a0, a0, a5
455 ; RV32I-NEXT: and a1, a1, a5
456 ; RV32I-NEXT: slli a2, a0, 8
457 ; RV32I-NEXT: slli a3, a1, 8
458 ; RV32I-NEXT: add a0, a0, a2
459 ; RV32I-NEXT: add a1, a1, a3
460 ; RV32I-NEXT: slli a2, a0, 16
461 ; RV32I-NEXT: slli a3, a1, 16
462 ; RV32I-NEXT: add a0, a0, a2
463 ; RV32I-NEXT: add a1, a1, a3
464 ; RV32I-NEXT: srli a0, a0, 24
465 ; RV32I-NEXT: srli a1, a1, 24
466 ; RV32I-NEXT: add a0, a1, a0
467 ; RV32I-NEXT: sltiu a0, a0, 2
468 ; RV32I-NEXT: xori a0, a0, 1
471 ; RV32ZBB-LABEL: ctpop_i64_ugt_one:
473 ; RV32ZBB-NEXT: beqz zero, .LBB7_2
474 ; RV32ZBB-NEXT: # %bb.1:
475 ; RV32ZBB-NEXT: snez a0, zero
477 ; RV32ZBB-NEXT: .LBB7_2:
478 ; RV32ZBB-NEXT: cpop a0, a0
479 ; RV32ZBB-NEXT: cpop a1, a1
480 ; RV32ZBB-NEXT: add a0, a1, a0
481 ; RV32ZBB-NEXT: sltiu a0, a0, 2
482 ; RV32ZBB-NEXT: xori a0, a0, 1
484 %1 = call i64 @llvm.ctpop.i64(i64 %a)
485 %2 = icmp ugt i64 %1, 1
489 define i1 @ctpop_i64_eq_one(i64 %a) nounwind {
490 ; RV32I-LABEL: ctpop_i64_eq_one:
492 ; RV32I-NEXT: srli a2, a0, 1
493 ; RV32I-NEXT: lui a3, 349525
494 ; RV32I-NEXT: lui a4, 209715
495 ; RV32I-NEXT: srli a5, a1, 1
496 ; RV32I-NEXT: addi a3, a3, 1365
497 ; RV32I-NEXT: and a2, a2, a3
498 ; RV32I-NEXT: and a3, a5, a3
499 ; RV32I-NEXT: lui a5, 61681
500 ; RV32I-NEXT: addi a4, a4, 819
501 ; RV32I-NEXT: addi a5, a5, -241
502 ; RV32I-NEXT: sub a0, a0, a2
503 ; RV32I-NEXT: sub a1, a1, a3
504 ; RV32I-NEXT: srli a2, a0, 2
505 ; RV32I-NEXT: and a0, a0, a4
506 ; RV32I-NEXT: srli a3, a1, 2
507 ; RV32I-NEXT: and a1, a1, a4
508 ; RV32I-NEXT: and a2, a2, a4
509 ; RV32I-NEXT: and a3, a3, a4
510 ; RV32I-NEXT: add a0, a2, a0
511 ; RV32I-NEXT: add a1, a3, a1
512 ; RV32I-NEXT: srli a2, a0, 4
513 ; RV32I-NEXT: srli a3, a1, 4
514 ; RV32I-NEXT: add a0, a2, a0
515 ; RV32I-NEXT: add a1, a3, a1
516 ; RV32I-NEXT: and a0, a0, a5
517 ; RV32I-NEXT: and a1, a1, a5
518 ; RV32I-NEXT: slli a2, a0, 8
519 ; RV32I-NEXT: slli a3, a1, 8
520 ; RV32I-NEXT: add a0, a0, a2
521 ; RV32I-NEXT: add a1, a1, a3
522 ; RV32I-NEXT: slli a2, a0, 16
523 ; RV32I-NEXT: slli a3, a1, 16
524 ; RV32I-NEXT: add a0, a0, a2
525 ; RV32I-NEXT: add a1, a1, a3
526 ; RV32I-NEXT: srli a0, a0, 24
527 ; RV32I-NEXT: srli a1, a1, 24
528 ; RV32I-NEXT: add a0, a1, a0
529 ; RV32I-NEXT: xori a0, a0, 1
530 ; RV32I-NEXT: seqz a0, a0
533 ; RV32ZBB-LABEL: ctpop_i64_eq_one:
535 ; RV32ZBB-NEXT: cpop a0, a0
536 ; RV32ZBB-NEXT: cpop a1, a1
537 ; RV32ZBB-NEXT: add a0, a1, a0
538 ; RV32ZBB-NEXT: xori a0, a0, 1
539 ; RV32ZBB-NEXT: seqz a0, a0
541 %1 = call i64 @llvm.ctpop.i64(i64 %a)
542 %2 = icmp eq i64 %1, 1
546 define i1 @ctpop_i64_ne_one(i64 %a) nounwind {
547 ; RV32I-LABEL: ctpop_i64_ne_one:
549 ; RV32I-NEXT: srli a2, a0, 1
550 ; RV32I-NEXT: lui a3, 349525
551 ; RV32I-NEXT: lui a4, 209715
552 ; RV32I-NEXT: srli a5, a1, 1
553 ; RV32I-NEXT: addi a3, a3, 1365
554 ; RV32I-NEXT: and a2, a2, a3
555 ; RV32I-NEXT: and a3, a5, a3
556 ; RV32I-NEXT: lui a5, 61681
557 ; RV32I-NEXT: addi a4, a4, 819
558 ; RV32I-NEXT: addi a5, a5, -241
559 ; RV32I-NEXT: sub a0, a0, a2
560 ; RV32I-NEXT: sub a1, a1, a3
561 ; RV32I-NEXT: srli a2, a0, 2
562 ; RV32I-NEXT: and a0, a0, a4
563 ; RV32I-NEXT: srli a3, a1, 2
564 ; RV32I-NEXT: and a1, a1, a4
565 ; RV32I-NEXT: and a2, a2, a4
566 ; RV32I-NEXT: and a3, a3, a4
567 ; RV32I-NEXT: add a0, a2, a0
568 ; RV32I-NEXT: add a1, a3, a1
569 ; RV32I-NEXT: srli a2, a0, 4
570 ; RV32I-NEXT: srli a3, a1, 4
571 ; RV32I-NEXT: add a0, a2, a0
572 ; RV32I-NEXT: add a1, a3, a1
573 ; RV32I-NEXT: and a0, a0, a5
574 ; RV32I-NEXT: and a1, a1, a5
575 ; RV32I-NEXT: slli a2, a0, 8
576 ; RV32I-NEXT: slli a3, a1, 8
577 ; RV32I-NEXT: add a0, a0, a2
578 ; RV32I-NEXT: add a1, a1, a3
579 ; RV32I-NEXT: slli a2, a0, 16
580 ; RV32I-NEXT: slli a3, a1, 16
581 ; RV32I-NEXT: add a0, a0, a2
582 ; RV32I-NEXT: add a1, a1, a3
583 ; RV32I-NEXT: srli a0, a0, 24
584 ; RV32I-NEXT: srli a1, a1, 24
585 ; RV32I-NEXT: add a0, a1, a0
586 ; RV32I-NEXT: xori a0, a0, 1
587 ; RV32I-NEXT: snez a0, a0
590 ; RV32ZBB-LABEL: ctpop_i64_ne_one:
592 ; RV32ZBB-NEXT: cpop a0, a0
593 ; RV32ZBB-NEXT: cpop a1, a1
594 ; RV32ZBB-NEXT: add a0, a1, a0
595 ; RV32ZBB-NEXT: xori a0, a0, 1
596 ; RV32ZBB-NEXT: snez a0, a0
598 %1 = call i64 @llvm.ctpop.i64(i64 %a)
599 %2 = icmp ne i64 %1, 1
603 define i32 @sextb_i32(i32 %a) nounwind {
604 ; RV32I-LABEL: sextb_i32:
606 ; RV32I-NEXT: slli a0, a0, 24
607 ; RV32I-NEXT: srai a0, a0, 24
610 ; RV32ZBB-LABEL: sextb_i32:
612 ; RV32ZBB-NEXT: sext.b a0, a0
614 %shl = shl i32 %a, 24
615 %shr = ashr exact i32 %shl, 24
619 ; FIXME: Combine back to back srai.
620 define i64 @sextb_i64(i64 %a) nounwind {
621 ; RV32I-LABEL: sextb_i64:
623 ; RV32I-NEXT: slli a1, a0, 24
624 ; RV32I-NEXT: srai a0, a1, 24
625 ; RV32I-NEXT: srai a1, a1, 31
628 ; RV32ZBB-LABEL: sextb_i64:
630 ; RV32ZBB-NEXT: sext.b a0, a0
631 ; RV32ZBB-NEXT: srai a1, a0, 31
633 %shl = shl i64 %a, 56
634 %shr = ashr exact i64 %shl, 56
638 define i32 @sexth_i32(i32 %a) nounwind {
639 ; RV32I-LABEL: sexth_i32:
641 ; RV32I-NEXT: slli a0, a0, 16
642 ; RV32I-NEXT: srai a0, a0, 16
645 ; RV32ZBB-LABEL: sexth_i32:
647 ; RV32ZBB-NEXT: sext.h a0, a0
649 %shl = shl i32 %a, 16
650 %shr = ashr exact i32 %shl, 16
654 ; FIXME: Combine back to back srai.
655 define i64 @sexth_i64(i64 %a) nounwind {
656 ; RV32I-LABEL: sexth_i64:
658 ; RV32I-NEXT: slli a1, a0, 16
659 ; RV32I-NEXT: srai a0, a1, 16
660 ; RV32I-NEXT: srai a1, a1, 31
663 ; RV32ZBB-LABEL: sexth_i64:
665 ; RV32ZBB-NEXT: sext.h a0, a0
666 ; RV32ZBB-NEXT: srai a1, a0, 31
668 %shl = shl i64 %a, 48
669 %shr = ashr exact i64 %shl, 48
673 define i32 @min_i32(i32 %a, i32 %b) nounwind {
674 ; RV32I-LABEL: min_i32:
676 ; RV32I-NEXT: blt a0, a1, .LBB14_2
677 ; RV32I-NEXT: # %bb.1:
678 ; RV32I-NEXT: mv a0, a1
679 ; RV32I-NEXT: .LBB14_2:
682 ; RV32ZBB-LABEL: min_i32:
684 ; RV32ZBB-NEXT: min a0, a0, a1
686 %cmp = icmp slt i32 %a, %b
687 %cond = select i1 %cmp, i32 %a, i32 %b
691 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
692 ; don't have yet any matching bit manipulation instructions on RV32.
693 ; This test is presented here in case future expansions of the Bitmanip
694 ; extensions introduce instructions suitable for this pattern.
696 define i64 @min_i64(i64 %a, i64 %b) nounwind {
697 ; CHECK-LABEL: min_i64:
699 ; CHECK-NEXT: beq a1, a3, .LBB15_2
700 ; CHECK-NEXT: # %bb.1:
701 ; CHECK-NEXT: slt a4, a1, a3
702 ; CHECK-NEXT: beqz a4, .LBB15_3
703 ; CHECK-NEXT: j .LBB15_4
704 ; CHECK-NEXT: .LBB15_2:
705 ; CHECK-NEXT: sltu a4, a0, a2
706 ; CHECK-NEXT: bnez a4, .LBB15_4
707 ; CHECK-NEXT: .LBB15_3:
708 ; CHECK-NEXT: mv a0, a2
709 ; CHECK-NEXT: mv a1, a3
710 ; CHECK-NEXT: .LBB15_4:
712 %cmp = icmp slt i64 %a, %b
713 %cond = select i1 %cmp, i64 %a, i64 %b
717 define i32 @max_i32(i32 %a, i32 %b) nounwind {
718 ; RV32I-LABEL: max_i32:
720 ; RV32I-NEXT: blt a1, a0, .LBB16_2
721 ; RV32I-NEXT: # %bb.1:
722 ; RV32I-NEXT: mv a0, a1
723 ; RV32I-NEXT: .LBB16_2:
726 ; RV32ZBB-LABEL: max_i32:
728 ; RV32ZBB-NEXT: max a0, a0, a1
730 %cmp = icmp sgt i32 %a, %b
731 %cond = select i1 %cmp, i32 %a, i32 %b
735 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
736 ; don't have yet any matching bit manipulation instructions on RV32.
737 ; This test is presented here in case future expansions of the Bitmanip
738 ; extensions introduce instructions suitable for this pattern.
740 define i64 @max_i64(i64 %a, i64 %b) nounwind {
741 ; CHECK-LABEL: max_i64:
743 ; CHECK-NEXT: beq a1, a3, .LBB17_2
744 ; CHECK-NEXT: # %bb.1:
745 ; CHECK-NEXT: slt a4, a3, a1
746 ; CHECK-NEXT: beqz a4, .LBB17_3
747 ; CHECK-NEXT: j .LBB17_4
748 ; CHECK-NEXT: .LBB17_2:
749 ; CHECK-NEXT: sltu a4, a2, a0
750 ; CHECK-NEXT: bnez a4, .LBB17_4
751 ; CHECK-NEXT: .LBB17_3:
752 ; CHECK-NEXT: mv a0, a2
753 ; CHECK-NEXT: mv a1, a3
754 ; CHECK-NEXT: .LBB17_4:
756 %cmp = icmp sgt i64 %a, %b
757 %cond = select i1 %cmp, i64 %a, i64 %b
761 define i32 @minu_i32(i32 %a, i32 %b) nounwind {
762 ; RV32I-LABEL: minu_i32:
764 ; RV32I-NEXT: bltu a0, a1, .LBB18_2
765 ; RV32I-NEXT: # %bb.1:
766 ; RV32I-NEXT: mv a0, a1
767 ; RV32I-NEXT: .LBB18_2:
770 ; RV32ZBB-LABEL: minu_i32:
772 ; RV32ZBB-NEXT: minu a0, a0, a1
774 %cmp = icmp ult i32 %a, %b
775 %cond = select i1 %cmp, i32 %a, i32 %b
779 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
780 ; don't have yet any matching bit manipulation instructions on RV32.
781 ; This test is presented here in case future expansions of the Bitmanip
782 ; extensions introduce instructions suitable for this pattern.
784 define i64 @minu_i64(i64 %a, i64 %b) nounwind {
785 ; CHECK-LABEL: minu_i64:
787 ; CHECK-NEXT: beq a1, a3, .LBB19_2
788 ; CHECK-NEXT: # %bb.1:
789 ; CHECK-NEXT: sltu a4, a1, a3
790 ; CHECK-NEXT: beqz a4, .LBB19_3
791 ; CHECK-NEXT: j .LBB19_4
792 ; CHECK-NEXT: .LBB19_2:
793 ; CHECK-NEXT: sltu a4, a0, a2
794 ; CHECK-NEXT: bnez a4, .LBB19_4
795 ; CHECK-NEXT: .LBB19_3:
796 ; CHECK-NEXT: mv a0, a2
797 ; CHECK-NEXT: mv a1, a3
798 ; CHECK-NEXT: .LBB19_4:
800 %cmp = icmp ult i64 %a, %b
801 %cond = select i1 %cmp, i64 %a, i64 %b
805 define i32 @maxu_i32(i32 %a, i32 %b) nounwind {
806 ; RV32I-LABEL: maxu_i32:
808 ; RV32I-NEXT: bltu a1, a0, .LBB20_2
809 ; RV32I-NEXT: # %bb.1:
810 ; RV32I-NEXT: mv a0, a1
811 ; RV32I-NEXT: .LBB20_2:
814 ; RV32ZBB-LABEL: maxu_i32:
816 ; RV32ZBB-NEXT: maxu a0, a0, a1
818 %cmp = icmp ugt i32 %a, %b
819 %cond = select i1 %cmp, i32 %a, i32 %b
823 ; As we are not matching directly i64 code patterns on RV32 some i64 patterns
824 ; don't have yet any matching bit manipulation instructions on RV32.
825 ; This test is presented here in case future expansions of the Bitmanip
826 ; extensions introduce instructions suitable for this pattern.
828 define i64 @maxu_i64(i64 %a, i64 %b) nounwind {
829 ; CHECK-LABEL: maxu_i64:
831 ; CHECK-NEXT: beq a1, a3, .LBB21_2
832 ; CHECK-NEXT: # %bb.1:
833 ; CHECK-NEXT: sltu a4, a3, a1
834 ; CHECK-NEXT: beqz a4, .LBB21_3
835 ; CHECK-NEXT: j .LBB21_4
836 ; CHECK-NEXT: .LBB21_2:
837 ; CHECK-NEXT: sltu a4, a2, a0
838 ; CHECK-NEXT: bnez a4, .LBB21_4
839 ; CHECK-NEXT: .LBB21_3:
840 ; CHECK-NEXT: mv a0, a2
841 ; CHECK-NEXT: mv a1, a3
842 ; CHECK-NEXT: .LBB21_4:
844 %cmp = icmp ugt i64 %a, %b
845 %cond = select i1 %cmp, i64 %a, i64 %b
849 declare i32 @llvm.abs.i32(i32, i1 immarg)
851 define i32 @abs_i32(i32 %x) {
852 ; RV32I-LABEL: abs_i32:
854 ; RV32I-NEXT: srai a1, a0, 31
855 ; RV32I-NEXT: add a0, a0, a1
856 ; RV32I-NEXT: xor a0, a0, a1
859 ; RV32ZBB-LABEL: abs_i32:
861 ; RV32ZBB-NEXT: neg a1, a0
862 ; RV32ZBB-NEXT: max a0, a0, a1
864 %abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true)
868 declare i64 @llvm.abs.i64(i64, i1 immarg)
870 define i64 @abs_i64(i64 %x) {
871 ; CHECK-LABEL: abs_i64:
873 ; CHECK-NEXT: srai a2, a1, 31
874 ; CHECK-NEXT: add a0, a0, a2
875 ; CHECK-NEXT: add a1, a1, a2
876 ; CHECK-NEXT: sltu a3, a0, a2
877 ; CHECK-NEXT: add a1, a1, a3
878 ; CHECK-NEXT: xor a0, a0, a2
879 ; CHECK-NEXT: xor a1, a1, a2
881 %abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true)
885 define i32 @zexth_i32(i32 %a) nounwind {
886 ; RV32I-LABEL: zexth_i32:
888 ; RV32I-NEXT: lui a1, 16
889 ; RV32I-NEXT: addi a1, a1, -1
890 ; RV32I-NEXT: and a0, a0, a1
893 ; RV32ZBB-LABEL: zexth_i32:
895 ; RV32ZBB-NEXT: zext.h a0, a0
897 %and = and i32 %a, 65535
901 define i64 @zexth_i64(i64 %a) nounwind {
902 ; RV32I-LABEL: zexth_i64:
904 ; RV32I-NEXT: lui a1, 16
905 ; RV32I-NEXT: addi a1, a1, -1
906 ; RV32I-NEXT: and a0, a0, a1
907 ; RV32I-NEXT: li a1, 0
910 ; RV32ZBB-LABEL: zexth_i64:
912 ; RV32ZBB-NEXT: zext.h a0, a0
913 ; RV32ZBB-NEXT: li a1, 0
915 %and = and i64 %a, 65535
919 declare i32 @llvm.bswap.i32(i32)
921 define i32 @bswap_i32(i32 %a) nounwind {
922 ; RV32I-LABEL: bswap_i32:
924 ; RV32I-NEXT: slli a1, a0, 24
925 ; RV32I-NEXT: srli a2, a0, 24
926 ; RV32I-NEXT: lui a3, 16
927 ; RV32I-NEXT: or a1, a2, a1
928 ; RV32I-NEXT: srli a2, a0, 8
929 ; RV32I-NEXT: addi a3, a3, -256
930 ; RV32I-NEXT: and a0, a0, a3
931 ; RV32I-NEXT: and a2, a2, a3
932 ; RV32I-NEXT: slli a0, a0, 8
933 ; RV32I-NEXT: or a1, a1, a2
934 ; RV32I-NEXT: or a0, a1, a0
937 ; RV32ZBB-LABEL: bswap_i32:
939 ; RV32ZBB-NEXT: rev8 a0, a0
941 %1 = tail call i32 @llvm.bswap.i32(i32 %a)
945 declare i64 @llvm.bswap.i64(i64)
947 define i64 @bswap_i64(i64 %a) {
948 ; RV32I-LABEL: bswap_i64:
950 ; RV32I-NEXT: slli a2, a1, 24
951 ; RV32I-NEXT: srli a3, a1, 24
952 ; RV32I-NEXT: lui a4, 16
953 ; RV32I-NEXT: srli a5, a1, 8
954 ; RV32I-NEXT: slli a6, a0, 24
955 ; RV32I-NEXT: or a2, a3, a2
956 ; RV32I-NEXT: srli a3, a0, 24
957 ; RV32I-NEXT: or a3, a3, a6
958 ; RV32I-NEXT: srli a6, a0, 8
959 ; RV32I-NEXT: addi a4, a4, -256
960 ; RV32I-NEXT: and a1, a1, a4
961 ; RV32I-NEXT: and a5, a5, a4
962 ; RV32I-NEXT: and a0, a0, a4
963 ; RV32I-NEXT: and a4, a6, a4
964 ; RV32I-NEXT: or a2, a2, a5
965 ; RV32I-NEXT: slli a1, a1, 8
966 ; RV32I-NEXT: slli a5, a0, 8
967 ; RV32I-NEXT: or a3, a3, a4
968 ; RV32I-NEXT: or a0, a2, a1
969 ; RV32I-NEXT: or a1, a3, a5
972 ; RV32ZBB-LABEL: bswap_i64:
974 ; RV32ZBB-NEXT: rev8 a2, a1
975 ; RV32ZBB-NEXT: rev8 a1, a0
976 ; RV32ZBB-NEXT: mv a0, a2
978 %1 = call i64 @llvm.bswap.i64(i64 %a)