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=+experimental-b -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s -check-prefix=RV64IB
6 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbb -verify-machineinstrs < %s \
7 ; RUN: | FileCheck %s -check-prefix=RV64IBB
9 define signext i32 @slo_i32(i32 signext %a, i32 signext %b) nounwind {
10 ; RV64I-LABEL: slo_i32:
12 ; RV64I-NEXT: not a0, a0
13 ; RV64I-NEXT: sllw a0, a0, a1
14 ; RV64I-NEXT: not a0, a0
17 ; RV64IB-LABEL: slo_i32:
19 ; RV64IB-NEXT: slow a0, a0, a1
22 ; RV64IBB-LABEL: slo_i32:
24 ; RV64IBB-NEXT: slow a0, a0, a1
27 %shl = shl i32 %neg, %b
28 %neg1 = xor i32 %shl, -1
32 define i64 @slo_i64(i64 %a, i64 %b) nounwind {
33 ; RV64I-LABEL: slo_i64:
35 ; RV64I-NEXT: not a0, a0
36 ; RV64I-NEXT: sll a0, a0, a1
37 ; RV64I-NEXT: not a0, a0
40 ; RV64IB-LABEL: slo_i64:
42 ; RV64IB-NEXT: slo a0, a0, a1
45 ; RV64IBB-LABEL: slo_i64:
47 ; RV64IBB-NEXT: slo a0, a0, a1
50 %shl = shl i64 %neg, %b
51 %neg1 = xor i64 %shl, -1
55 define signext i32 @sro_i32(i32 signext %a, i32 signext %b) nounwind {
56 ; RV64I-LABEL: sro_i32:
58 ; RV64I-NEXT: not a0, a0
59 ; RV64I-NEXT: srlw a0, a0, a1
60 ; RV64I-NEXT: not a0, a0
63 ; RV64IB-LABEL: sro_i32:
65 ; RV64IB-NEXT: srow a0, a0, a1
68 ; RV64IBB-LABEL: sro_i32:
70 ; RV64IBB-NEXT: srow a0, a0, a1
73 %shr = lshr i32 %neg, %b
74 %neg1 = xor i32 %shr, -1
78 define i64 @sro_i64(i64 %a, i64 %b) nounwind {
79 ; RV64I-LABEL: sro_i64:
81 ; RV64I-NEXT: not a0, a0
82 ; RV64I-NEXT: srl a0, a0, a1
83 ; RV64I-NEXT: not a0, a0
86 ; RV64IB-LABEL: sro_i64:
88 ; RV64IB-NEXT: sro a0, a0, a1
91 ; RV64IBB-LABEL: sro_i64:
93 ; RV64IBB-NEXT: sro a0, a0, a1
96 %shr = lshr i64 %neg, %b
97 %neg1 = xor i64 %shr, -1
101 define signext i32 @sloi_i32(i32 signext %a) nounwind {
102 ; RV64I-LABEL: sloi_i32:
104 ; RV64I-NEXT: slli a0, a0, 1
105 ; RV64I-NEXT: ori a0, a0, 1
106 ; RV64I-NEXT: sext.w a0, a0
109 ; RV64IB-LABEL: sloi_i32:
111 ; RV64IB-NEXT: sloiw a0, a0, 1
114 ; RV64IBB-LABEL: sloi_i32:
116 ; RV64IBB-NEXT: sloiw a0, a0, 1
119 %neg12 = or i32 %neg, 1
123 define i64 @sloi_i64(i64 %a) nounwind {
124 ; RV64I-LABEL: sloi_i64:
126 ; RV64I-NEXT: slli a0, a0, 1
127 ; RV64I-NEXT: ori a0, a0, 1
130 ; RV64IB-LABEL: sloi_i64:
132 ; RV64IB-NEXT: sloi a0, a0, 1
135 ; RV64IBB-LABEL: sloi_i64:
137 ; RV64IBB-NEXT: sloi a0, a0, 1
140 %neg12 = or i64 %neg, 1
144 define signext i32 @sroi_i32(i32 signext %a) nounwind {
145 ; RV64I-LABEL: sroi_i32:
147 ; RV64I-NEXT: srli a0, a0, 1
148 ; RV64I-NEXT: lui a1, 524288
149 ; RV64I-NEXT: or a0, a0, a1
152 ; RV64IB-LABEL: sroi_i32:
154 ; RV64IB-NEXT: sroiw a0, a0, 1
157 ; RV64IBB-LABEL: sroi_i32:
159 ; RV64IBB-NEXT: sroiw a0, a0, 1
161 %neg = lshr i32 %a, 1
162 %neg12 = or i32 %neg, -2147483648
166 ; This is similar to the type legalized version of sroiw but the mask is 0 in
167 ; the upper bits instead of 1 so the result is not sign extended. Make sure we
168 ; don't match it to sroiw.
169 define i64 @sroiw_bug(i64 %a) nounwind {
170 ; RV64I-LABEL: sroiw_bug:
172 ; RV64I-NEXT: srli a0, a0, 1
173 ; RV64I-NEXT: addi a1, zero, 1
174 ; RV64I-NEXT: slli a1, a1, 31
175 ; RV64I-NEXT: or a0, a0, a1
178 ; RV64IB-LABEL: sroiw_bug:
180 ; RV64IB-NEXT: srli a0, a0, 1
181 ; RV64IB-NEXT: sbseti a0, a0, 31
184 ; RV64IBB-LABEL: sroiw_bug:
186 ; RV64IBB-NEXT: srli a0, a0, 1
187 ; RV64IBB-NEXT: addi a1, zero, 1
188 ; RV64IBB-NEXT: slli a1, a1, 31
189 ; RV64IBB-NEXT: or a0, a0, a1
191 %neg = lshr i64 %a, 1
192 %neg12 = or i64 %neg, 2147483648
196 define i64 @sroi_i64(i64 %a) nounwind {
197 ; RV64I-LABEL: sroi_i64:
199 ; RV64I-NEXT: srli a0, a0, 1
200 ; RV64I-NEXT: addi a1, zero, -1
201 ; RV64I-NEXT: slli a1, a1, 63
202 ; RV64I-NEXT: or a0, a0, a1
205 ; RV64IB-LABEL: sroi_i64:
207 ; RV64IB-NEXT: sroi a0, a0, 1
210 ; RV64IBB-LABEL: sroi_i64:
212 ; RV64IBB-NEXT: sroi a0, a0, 1
214 %neg = lshr i64 %a, 1
215 %neg12 = or i64 %neg, -9223372036854775808
219 declare i32 @llvm.ctlz.i32(i32, i1)
221 define signext i32 @ctlz_i32(i32 signext %a) nounwind {
222 ; RV64I-LABEL: ctlz_i32:
224 ; RV64I-NEXT: addi sp, sp, -16
225 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
226 ; RV64I-NEXT: beqz a0, .LBB9_2
227 ; RV64I-NEXT: # %bb.1: # %cond.false
228 ; RV64I-NEXT: srliw a1, a0, 1
229 ; RV64I-NEXT: slli a0, a0, 32
230 ; RV64I-NEXT: srli a0, a0, 32
231 ; RV64I-NEXT: or a0, a0, a1
232 ; RV64I-NEXT: srli a1, a0, 2
233 ; RV64I-NEXT: or a0, a0, a1
234 ; RV64I-NEXT: srli a1, a0, 4
235 ; RV64I-NEXT: or a0, a0, a1
236 ; RV64I-NEXT: srli a1, a0, 8
237 ; RV64I-NEXT: or a0, a0, a1
238 ; RV64I-NEXT: srli a1, a0, 16
239 ; RV64I-NEXT: or a0, a0, a1
240 ; RV64I-NEXT: srli a1, a0, 32
241 ; RV64I-NEXT: or a0, a0, a1
242 ; RV64I-NEXT: not a0, a0
243 ; RV64I-NEXT: srli a1, a0, 1
244 ; RV64I-NEXT: lui a2, 21845
245 ; RV64I-NEXT: addiw a2, a2, 1365
246 ; RV64I-NEXT: slli a2, a2, 12
247 ; RV64I-NEXT: addi a2, a2, 1365
248 ; RV64I-NEXT: slli a2, a2, 12
249 ; RV64I-NEXT: addi a2, a2, 1365
250 ; RV64I-NEXT: slli a2, a2, 12
251 ; RV64I-NEXT: addi a2, a2, 1365
252 ; RV64I-NEXT: and a1, a1, a2
253 ; RV64I-NEXT: sub a0, a0, a1
254 ; RV64I-NEXT: lui a1, 13107
255 ; RV64I-NEXT: addiw a1, a1, 819
256 ; RV64I-NEXT: slli a1, a1, 12
257 ; RV64I-NEXT: addi a1, a1, 819
258 ; RV64I-NEXT: slli a1, a1, 12
259 ; RV64I-NEXT: addi a1, a1, 819
260 ; RV64I-NEXT: slli a1, a1, 12
261 ; RV64I-NEXT: addi a1, a1, 819
262 ; RV64I-NEXT: and a2, a0, a1
263 ; RV64I-NEXT: srli a0, a0, 2
264 ; RV64I-NEXT: and a0, a0, a1
265 ; RV64I-NEXT: add a0, a2, a0
266 ; RV64I-NEXT: srli a1, a0, 4
267 ; RV64I-NEXT: add a0, a0, a1
268 ; RV64I-NEXT: lui a1, 3855
269 ; RV64I-NEXT: addiw a1, a1, 241
270 ; RV64I-NEXT: slli a1, a1, 12
271 ; RV64I-NEXT: addi a1, a1, -241
272 ; RV64I-NEXT: slli a1, a1, 12
273 ; RV64I-NEXT: addi a1, a1, 241
274 ; RV64I-NEXT: slli a1, a1, 12
275 ; RV64I-NEXT: addi a1, a1, -241
276 ; RV64I-NEXT: and a0, a0, a1
277 ; RV64I-NEXT: lui a1, 4112
278 ; RV64I-NEXT: addiw a1, a1, 257
279 ; RV64I-NEXT: slli a1, a1, 16
280 ; RV64I-NEXT: addi a1, a1, 257
281 ; RV64I-NEXT: slli a1, a1, 16
282 ; RV64I-NEXT: addi a1, a1, 257
283 ; RV64I-NEXT: call __muldi3@plt
284 ; RV64I-NEXT: srli a0, a0, 56
285 ; RV64I-NEXT: addi a0, a0, -32
286 ; RV64I-NEXT: j .LBB9_3
287 ; RV64I-NEXT: .LBB9_2:
288 ; RV64I-NEXT: addi a0, zero, 32
289 ; RV64I-NEXT: .LBB9_3: # %cond.end
290 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
291 ; RV64I-NEXT: addi sp, sp, 16
294 ; RV64IB-LABEL: ctlz_i32:
296 ; RV64IB-NEXT: clzw a0, a0
299 ; RV64IBB-LABEL: ctlz_i32:
301 ; RV64IBB-NEXT: clzw a0, a0
303 %1 = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
307 declare i64 @llvm.ctlz.i64(i64, i1)
309 define i64 @ctlz_i64(i64 %a) nounwind {
310 ; RV64I-LABEL: ctlz_i64:
312 ; RV64I-NEXT: addi sp, sp, -16
313 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
314 ; RV64I-NEXT: beqz a0, .LBB10_2
315 ; RV64I-NEXT: # %bb.1: # %cond.false
316 ; RV64I-NEXT: srli a1, a0, 1
317 ; RV64I-NEXT: or a0, a0, a1
318 ; RV64I-NEXT: srli a1, a0, 2
319 ; RV64I-NEXT: or a0, a0, a1
320 ; RV64I-NEXT: srli a1, a0, 4
321 ; RV64I-NEXT: or a0, a0, a1
322 ; RV64I-NEXT: srli a1, a0, 8
323 ; RV64I-NEXT: or a0, a0, a1
324 ; RV64I-NEXT: srli a1, a0, 16
325 ; RV64I-NEXT: or a0, a0, a1
326 ; RV64I-NEXT: srli a1, a0, 32
327 ; RV64I-NEXT: or a0, a0, a1
328 ; RV64I-NEXT: not a0, a0
329 ; RV64I-NEXT: srli a1, a0, 1
330 ; RV64I-NEXT: lui a2, 21845
331 ; RV64I-NEXT: addiw a2, a2, 1365
332 ; RV64I-NEXT: slli a2, a2, 12
333 ; RV64I-NEXT: addi a2, a2, 1365
334 ; RV64I-NEXT: slli a2, a2, 12
335 ; RV64I-NEXT: addi a2, a2, 1365
336 ; RV64I-NEXT: slli a2, a2, 12
337 ; RV64I-NEXT: addi a2, a2, 1365
338 ; RV64I-NEXT: and a1, a1, a2
339 ; RV64I-NEXT: sub a0, a0, a1
340 ; RV64I-NEXT: lui a1, 13107
341 ; RV64I-NEXT: addiw a1, a1, 819
342 ; RV64I-NEXT: slli a1, a1, 12
343 ; RV64I-NEXT: addi a1, a1, 819
344 ; RV64I-NEXT: slli a1, a1, 12
345 ; RV64I-NEXT: addi a1, a1, 819
346 ; RV64I-NEXT: slli a1, a1, 12
347 ; RV64I-NEXT: addi a1, a1, 819
348 ; RV64I-NEXT: and a2, a0, a1
349 ; RV64I-NEXT: srli a0, a0, 2
350 ; RV64I-NEXT: and a0, a0, a1
351 ; RV64I-NEXT: add a0, a2, a0
352 ; RV64I-NEXT: srli a1, a0, 4
353 ; RV64I-NEXT: add a0, a0, a1
354 ; RV64I-NEXT: lui a1, 3855
355 ; RV64I-NEXT: addiw a1, a1, 241
356 ; RV64I-NEXT: slli a1, a1, 12
357 ; RV64I-NEXT: addi a1, a1, -241
358 ; RV64I-NEXT: slli a1, a1, 12
359 ; RV64I-NEXT: addi a1, a1, 241
360 ; RV64I-NEXT: slli a1, a1, 12
361 ; RV64I-NEXT: addi a1, a1, -241
362 ; RV64I-NEXT: and a0, a0, a1
363 ; RV64I-NEXT: lui a1, 4112
364 ; RV64I-NEXT: addiw a1, a1, 257
365 ; RV64I-NEXT: slli a1, a1, 16
366 ; RV64I-NEXT: addi a1, a1, 257
367 ; RV64I-NEXT: slli a1, a1, 16
368 ; RV64I-NEXT: addi a1, a1, 257
369 ; RV64I-NEXT: call __muldi3@plt
370 ; RV64I-NEXT: srli a0, a0, 56
371 ; RV64I-NEXT: j .LBB10_3
372 ; RV64I-NEXT: .LBB10_2:
373 ; RV64I-NEXT: addi a0, zero, 64
374 ; RV64I-NEXT: .LBB10_3: # %cond.end
375 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
376 ; RV64I-NEXT: addi sp, sp, 16
379 ; RV64IB-LABEL: ctlz_i64:
381 ; RV64IB-NEXT: clz a0, a0
384 ; RV64IBB-LABEL: ctlz_i64:
386 ; RV64IBB-NEXT: clz a0, a0
388 %1 = call i64 @llvm.ctlz.i64(i64 %a, i1 false)
392 declare i32 @llvm.cttz.i32(i32, i1)
394 define signext i32 @cttz_i32(i32 signext %a) nounwind {
395 ; RV64I-LABEL: cttz_i32:
397 ; RV64I-NEXT: addi sp, sp, -16
398 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
399 ; RV64I-NEXT: beqz a0, .LBB11_2
400 ; RV64I-NEXT: # %bb.1: # %cond.false
401 ; RV64I-NEXT: addi a1, a0, -1
402 ; RV64I-NEXT: not a0, a0
403 ; RV64I-NEXT: and a0, a0, a1
404 ; RV64I-NEXT: srli a1, a0, 1
405 ; RV64I-NEXT: lui a2, 21845
406 ; RV64I-NEXT: addiw a2, a2, 1365
407 ; RV64I-NEXT: slli a2, a2, 12
408 ; RV64I-NEXT: addi a2, a2, 1365
409 ; RV64I-NEXT: slli a2, a2, 12
410 ; RV64I-NEXT: addi a2, a2, 1365
411 ; RV64I-NEXT: slli a2, a2, 12
412 ; RV64I-NEXT: addi a2, a2, 1365
413 ; RV64I-NEXT: and a1, a1, a2
414 ; RV64I-NEXT: sub a0, a0, a1
415 ; RV64I-NEXT: lui a1, 13107
416 ; RV64I-NEXT: addiw a1, a1, 819
417 ; RV64I-NEXT: slli a1, a1, 12
418 ; RV64I-NEXT: addi a1, a1, 819
419 ; RV64I-NEXT: slli a1, a1, 12
420 ; RV64I-NEXT: addi a1, a1, 819
421 ; RV64I-NEXT: slli a1, a1, 12
422 ; RV64I-NEXT: addi a1, a1, 819
423 ; RV64I-NEXT: and a2, a0, a1
424 ; RV64I-NEXT: srli a0, a0, 2
425 ; RV64I-NEXT: and a0, a0, a1
426 ; RV64I-NEXT: add a0, a2, a0
427 ; RV64I-NEXT: srli a1, a0, 4
428 ; RV64I-NEXT: add a0, a0, a1
429 ; RV64I-NEXT: lui a1, 3855
430 ; RV64I-NEXT: addiw a1, a1, 241
431 ; RV64I-NEXT: slli a1, a1, 12
432 ; RV64I-NEXT: addi a1, a1, -241
433 ; RV64I-NEXT: slli a1, a1, 12
434 ; RV64I-NEXT: addi a1, a1, 241
435 ; RV64I-NEXT: slli a1, a1, 12
436 ; RV64I-NEXT: addi a1, a1, -241
437 ; RV64I-NEXT: and a0, a0, a1
438 ; RV64I-NEXT: lui a1, 4112
439 ; RV64I-NEXT: addiw a1, a1, 257
440 ; RV64I-NEXT: slli a1, a1, 16
441 ; RV64I-NEXT: addi a1, a1, 257
442 ; RV64I-NEXT: slli a1, a1, 16
443 ; RV64I-NEXT: addi a1, a1, 257
444 ; RV64I-NEXT: call __muldi3@plt
445 ; RV64I-NEXT: srli a0, a0, 56
446 ; RV64I-NEXT: j .LBB11_3
447 ; RV64I-NEXT: .LBB11_2:
448 ; RV64I-NEXT: addi a0, zero, 32
449 ; RV64I-NEXT: .LBB11_3: # %cond.end
450 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
451 ; RV64I-NEXT: addi sp, sp, 16
454 ; RV64IB-LABEL: cttz_i32:
456 ; RV64IB-NEXT: ctzw a0, a0
459 ; RV64IBB-LABEL: cttz_i32:
461 ; RV64IBB-NEXT: ctzw a0, a0
463 %1 = call i32 @llvm.cttz.i32(i32 %a, i1 false)
467 declare i64 @llvm.cttz.i64(i64, i1)
469 define i64 @cttz_i64(i64 %a) nounwind {
470 ; RV64I-LABEL: cttz_i64:
472 ; RV64I-NEXT: addi sp, sp, -16
473 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
474 ; RV64I-NEXT: beqz a0, .LBB12_2
475 ; RV64I-NEXT: # %bb.1: # %cond.false
476 ; RV64I-NEXT: addi a1, a0, -1
477 ; RV64I-NEXT: not a0, a0
478 ; RV64I-NEXT: and a0, a0, a1
479 ; RV64I-NEXT: srli a1, a0, 1
480 ; RV64I-NEXT: lui a2, 21845
481 ; RV64I-NEXT: addiw a2, a2, 1365
482 ; RV64I-NEXT: slli a2, a2, 12
483 ; RV64I-NEXT: addi a2, a2, 1365
484 ; RV64I-NEXT: slli a2, a2, 12
485 ; RV64I-NEXT: addi a2, a2, 1365
486 ; RV64I-NEXT: slli a2, a2, 12
487 ; RV64I-NEXT: addi a2, a2, 1365
488 ; RV64I-NEXT: and a1, a1, a2
489 ; RV64I-NEXT: sub a0, a0, a1
490 ; RV64I-NEXT: lui a1, 13107
491 ; RV64I-NEXT: addiw a1, a1, 819
492 ; RV64I-NEXT: slli a1, a1, 12
493 ; RV64I-NEXT: addi a1, a1, 819
494 ; RV64I-NEXT: slli a1, a1, 12
495 ; RV64I-NEXT: addi a1, a1, 819
496 ; RV64I-NEXT: slli a1, a1, 12
497 ; RV64I-NEXT: addi a1, a1, 819
498 ; RV64I-NEXT: and a2, a0, a1
499 ; RV64I-NEXT: srli a0, a0, 2
500 ; RV64I-NEXT: and a0, a0, a1
501 ; RV64I-NEXT: add a0, a2, a0
502 ; RV64I-NEXT: srli a1, a0, 4
503 ; RV64I-NEXT: add a0, a0, a1
504 ; RV64I-NEXT: lui a1, 3855
505 ; RV64I-NEXT: addiw a1, a1, 241
506 ; RV64I-NEXT: slli a1, a1, 12
507 ; RV64I-NEXT: addi a1, a1, -241
508 ; RV64I-NEXT: slli a1, a1, 12
509 ; RV64I-NEXT: addi a1, a1, 241
510 ; RV64I-NEXT: slli a1, a1, 12
511 ; RV64I-NEXT: addi a1, a1, -241
512 ; RV64I-NEXT: and a0, a0, a1
513 ; RV64I-NEXT: lui a1, 4112
514 ; RV64I-NEXT: addiw a1, a1, 257
515 ; RV64I-NEXT: slli a1, a1, 16
516 ; RV64I-NEXT: addi a1, a1, 257
517 ; RV64I-NEXT: slli a1, a1, 16
518 ; RV64I-NEXT: addi a1, a1, 257
519 ; RV64I-NEXT: call __muldi3@plt
520 ; RV64I-NEXT: srli a0, a0, 56
521 ; RV64I-NEXT: j .LBB12_3
522 ; RV64I-NEXT: .LBB12_2:
523 ; RV64I-NEXT: addi a0, zero, 64
524 ; RV64I-NEXT: .LBB12_3: # %cond.end
525 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
526 ; RV64I-NEXT: addi sp, sp, 16
529 ; RV64IB-LABEL: cttz_i64:
531 ; RV64IB-NEXT: ctz a0, a0
534 ; RV64IBB-LABEL: cttz_i64:
536 ; RV64IBB-NEXT: ctz a0, a0
538 %1 = call i64 @llvm.cttz.i64(i64 %a, i1 false)
542 declare i32 @llvm.ctpop.i32(i32)
544 define signext i32 @ctpop_i32(i32 signext %a) nounwind {
545 ; RV64I-LABEL: ctpop_i32:
547 ; RV64I-NEXT: addi sp, sp, -16
548 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
549 ; RV64I-NEXT: slli a1, a0, 32
550 ; RV64I-NEXT: srli a1, a1, 32
551 ; RV64I-NEXT: srliw a0, a0, 1
552 ; RV64I-NEXT: lui a2, 349525
553 ; RV64I-NEXT: addiw a2, a2, 1365
554 ; RV64I-NEXT: and a0, a0, a2
555 ; RV64I-NEXT: sub a0, a1, a0
556 ; RV64I-NEXT: srli a1, a0, 2
557 ; RV64I-NEXT: lui a2, 13107
558 ; RV64I-NEXT: addiw a2, a2, 819
559 ; RV64I-NEXT: slli a2, a2, 12
560 ; RV64I-NEXT: addi a2, a2, 819
561 ; RV64I-NEXT: slli a2, a2, 12
562 ; RV64I-NEXT: addi a2, a2, 819
563 ; RV64I-NEXT: slli a2, a2, 12
564 ; RV64I-NEXT: addi a2, a2, 819
565 ; RV64I-NEXT: and a1, a1, a2
566 ; RV64I-NEXT: and a0, a0, a2
567 ; RV64I-NEXT: add a0, a0, a1
568 ; RV64I-NEXT: srli a1, a0, 4
569 ; RV64I-NEXT: add a0, a0, a1
570 ; RV64I-NEXT: lui a1, 3855
571 ; RV64I-NEXT: addiw a1, a1, 241
572 ; RV64I-NEXT: slli a1, a1, 12
573 ; RV64I-NEXT: addi a1, a1, -241
574 ; RV64I-NEXT: slli a1, a1, 12
575 ; RV64I-NEXT: addi a1, a1, 241
576 ; RV64I-NEXT: slli a1, a1, 12
577 ; RV64I-NEXT: addi a1, a1, -241
578 ; RV64I-NEXT: and a0, a0, a1
579 ; RV64I-NEXT: lui a1, 4112
580 ; RV64I-NEXT: addiw a1, a1, 257
581 ; RV64I-NEXT: slli a1, a1, 16
582 ; RV64I-NEXT: addi a1, a1, 257
583 ; RV64I-NEXT: slli a1, a1, 16
584 ; RV64I-NEXT: addi a1, a1, 257
585 ; RV64I-NEXT: call __muldi3@plt
586 ; RV64I-NEXT: srli a0, a0, 56
587 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
588 ; RV64I-NEXT: addi sp, sp, 16
591 ; RV64IB-LABEL: ctpop_i32:
593 ; RV64IB-NEXT: pcntw a0, a0
596 ; RV64IBB-LABEL: ctpop_i32:
598 ; RV64IBB-NEXT: pcntw a0, a0
600 %1 = call i32 @llvm.ctpop.i32(i32 %a)
604 declare i64 @llvm.ctpop.i64(i64)
606 define i64 @ctpop_i64(i64 %a) nounwind {
607 ; RV64I-LABEL: ctpop_i64:
609 ; RV64I-NEXT: addi sp, sp, -16
610 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
611 ; RV64I-NEXT: srli a1, a0, 1
612 ; RV64I-NEXT: lui a2, 21845
613 ; RV64I-NEXT: addiw a2, a2, 1365
614 ; RV64I-NEXT: slli a2, a2, 12
615 ; RV64I-NEXT: addi a2, a2, 1365
616 ; RV64I-NEXT: slli a2, a2, 12
617 ; RV64I-NEXT: addi a2, a2, 1365
618 ; RV64I-NEXT: slli a2, a2, 12
619 ; RV64I-NEXT: addi a2, a2, 1365
620 ; RV64I-NEXT: and a1, a1, a2
621 ; RV64I-NEXT: sub a0, a0, a1
622 ; RV64I-NEXT: lui a1, 13107
623 ; RV64I-NEXT: addiw a1, a1, 819
624 ; RV64I-NEXT: slli a1, a1, 12
625 ; RV64I-NEXT: addi a1, a1, 819
626 ; RV64I-NEXT: slli a1, a1, 12
627 ; RV64I-NEXT: addi a1, a1, 819
628 ; RV64I-NEXT: slli a1, a1, 12
629 ; RV64I-NEXT: addi a1, a1, 819
630 ; RV64I-NEXT: and a2, a0, a1
631 ; RV64I-NEXT: srli a0, a0, 2
632 ; RV64I-NEXT: and a0, a0, a1
633 ; RV64I-NEXT: add a0, a2, a0
634 ; RV64I-NEXT: srli a1, a0, 4
635 ; RV64I-NEXT: add a0, a0, a1
636 ; RV64I-NEXT: lui a1, 3855
637 ; RV64I-NEXT: addiw a1, a1, 241
638 ; RV64I-NEXT: slli a1, a1, 12
639 ; RV64I-NEXT: addi a1, a1, -241
640 ; RV64I-NEXT: slli a1, a1, 12
641 ; RV64I-NEXT: addi a1, a1, 241
642 ; RV64I-NEXT: slli a1, a1, 12
643 ; RV64I-NEXT: addi a1, a1, -241
644 ; RV64I-NEXT: and a0, a0, a1
645 ; RV64I-NEXT: lui a1, 4112
646 ; RV64I-NEXT: addiw a1, a1, 257
647 ; RV64I-NEXT: slli a1, a1, 16
648 ; RV64I-NEXT: addi a1, a1, 257
649 ; RV64I-NEXT: slli a1, a1, 16
650 ; RV64I-NEXT: addi a1, a1, 257
651 ; RV64I-NEXT: call __muldi3@plt
652 ; RV64I-NEXT: srli a0, a0, 56
653 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
654 ; RV64I-NEXT: addi sp, sp, 16
657 ; RV64IB-LABEL: ctpop_i64:
659 ; RV64IB-NEXT: pcnt a0, a0
662 ; RV64IBB-LABEL: ctpop_i64:
664 ; RV64IBB-NEXT: pcnt a0, a0
666 %1 = call i64 @llvm.ctpop.i64(i64 %a)
670 define signext i32 @sextb_i32(i32 signext %a) nounwind {
671 ; RV64I-LABEL: sextb_i32:
673 ; RV64I-NEXT: slli a0, a0, 56
674 ; RV64I-NEXT: srai a0, a0, 56
677 ; RV64IB-LABEL: sextb_i32:
679 ; RV64IB-NEXT: sext.b a0, a0
682 ; RV64IBB-LABEL: sextb_i32:
684 ; RV64IBB-NEXT: sext.b a0, a0
686 %shl = shl i32 %a, 24
687 %shr = ashr exact i32 %shl, 24
691 define i64 @sextb_i64(i64 %a) nounwind {
692 ; RV64I-LABEL: sextb_i64:
694 ; RV64I-NEXT: slli a0, a0, 56
695 ; RV64I-NEXT: srai a0, a0, 56
698 ; RV64IB-LABEL: sextb_i64:
700 ; RV64IB-NEXT: sext.b a0, a0
703 ; RV64IBB-LABEL: sextb_i64:
705 ; RV64IBB-NEXT: sext.b a0, a0
707 %shl = shl i64 %a, 56
708 %shr = ashr exact i64 %shl, 56
712 define signext i32 @sexth_i32(i32 signext %a) nounwind {
713 ; RV64I-LABEL: sexth_i32:
715 ; RV64I-NEXT: slli a0, a0, 48
716 ; RV64I-NEXT: srai a0, a0, 48
719 ; RV64IB-LABEL: sexth_i32:
721 ; RV64IB-NEXT: sext.h a0, a0
724 ; RV64IBB-LABEL: sexth_i32:
726 ; RV64IBB-NEXT: sext.h a0, a0
728 %shl = shl i32 %a, 16
729 %shr = ashr exact i32 %shl, 16
733 define i64 @sexth_i64(i64 %a) nounwind {
734 ; RV64I-LABEL: sexth_i64:
736 ; RV64I-NEXT: slli a0, a0, 48
737 ; RV64I-NEXT: srai a0, a0, 48
740 ; RV64IB-LABEL: sexth_i64:
742 ; RV64IB-NEXT: sext.h a0, a0
745 ; RV64IBB-LABEL: sexth_i64:
747 ; RV64IBB-NEXT: sext.h a0, a0
749 %shl = shl i64 %a, 48
750 %shr = ashr exact i64 %shl, 48
754 define signext i32 @min_i32(i32 signext %a, i32 signext %b) nounwind {
755 ; RV64I-LABEL: min_i32:
757 ; RV64I-NEXT: blt a0, a1, .LBB19_2
758 ; RV64I-NEXT: # %bb.1:
759 ; RV64I-NEXT: mv a0, a1
760 ; RV64I-NEXT: .LBB19_2:
763 ; RV64IB-LABEL: min_i32:
765 ; RV64IB-NEXT: min a0, a0, a1
768 ; RV64IBB-LABEL: min_i32:
770 ; RV64IBB-NEXT: min a0, a0, a1
772 %cmp = icmp slt i32 %a, %b
773 %cond = select i1 %cmp, i32 %a, i32 %b
777 define i64 @min_i64(i64 %a, i64 %b) nounwind {
778 ; RV64I-LABEL: min_i64:
780 ; RV64I-NEXT: blt a0, a1, .LBB20_2
781 ; RV64I-NEXT: # %bb.1:
782 ; RV64I-NEXT: mv a0, a1
783 ; RV64I-NEXT: .LBB20_2:
786 ; RV64IB-LABEL: min_i64:
788 ; RV64IB-NEXT: min a0, a0, a1
791 ; RV64IBB-LABEL: min_i64:
793 ; RV64IBB-NEXT: min a0, a0, a1
795 %cmp = icmp slt i64 %a, %b
796 %cond = select i1 %cmp, i64 %a, i64 %b
800 define signext i32 @max_i32(i32 signext %a, i32 signext %b) nounwind {
801 ; RV64I-LABEL: max_i32:
803 ; RV64I-NEXT: blt a1, a0, .LBB21_2
804 ; RV64I-NEXT: # %bb.1:
805 ; RV64I-NEXT: mv a0, a1
806 ; RV64I-NEXT: .LBB21_2:
809 ; RV64IB-LABEL: max_i32:
811 ; RV64IB-NEXT: max a0, a0, a1
814 ; RV64IBB-LABEL: max_i32:
816 ; RV64IBB-NEXT: max a0, a0, a1
818 %cmp = icmp sgt i32 %a, %b
819 %cond = select i1 %cmp, i32 %a, i32 %b
823 define i64 @max_i64(i64 %a, i64 %b) nounwind {
824 ; RV64I-LABEL: max_i64:
826 ; RV64I-NEXT: blt a1, a0, .LBB22_2
827 ; RV64I-NEXT: # %bb.1:
828 ; RV64I-NEXT: mv a0, a1
829 ; RV64I-NEXT: .LBB22_2:
832 ; RV64IB-LABEL: max_i64:
834 ; RV64IB-NEXT: max a0, a0, a1
837 ; RV64IBB-LABEL: max_i64:
839 ; RV64IBB-NEXT: max a0, a0, a1
841 %cmp = icmp sgt i64 %a, %b
842 %cond = select i1 %cmp, i64 %a, i64 %b
846 define signext i32 @minu_i32(i32 signext %a, i32 signext %b) nounwind {
847 ; RV64I-LABEL: minu_i32:
849 ; RV64I-NEXT: bltu a0, a1, .LBB23_2
850 ; RV64I-NEXT: # %bb.1:
851 ; RV64I-NEXT: mv a0, a1
852 ; RV64I-NEXT: .LBB23_2:
855 ; RV64IB-LABEL: minu_i32:
857 ; RV64IB-NEXT: minu a0, a0, a1
860 ; RV64IBB-LABEL: minu_i32:
862 ; RV64IBB-NEXT: minu a0, a0, a1
864 %cmp = icmp ult i32 %a, %b
865 %cond = select i1 %cmp, i32 %a, i32 %b
869 define i64 @minu_i64(i64 %a, i64 %b) nounwind {
870 ; RV64I-LABEL: minu_i64:
872 ; RV64I-NEXT: bltu a0, a1, .LBB24_2
873 ; RV64I-NEXT: # %bb.1:
874 ; RV64I-NEXT: mv a0, a1
875 ; RV64I-NEXT: .LBB24_2:
878 ; RV64IB-LABEL: minu_i64:
880 ; RV64IB-NEXT: minu a0, a0, a1
883 ; RV64IBB-LABEL: minu_i64:
885 ; RV64IBB-NEXT: minu a0, a0, a1
887 %cmp = icmp ult i64 %a, %b
888 %cond = select i1 %cmp, i64 %a, i64 %b
892 define signext i32 @maxu_i32(i32 signext %a, i32 signext %b) nounwind {
893 ; RV64I-LABEL: maxu_i32:
895 ; RV64I-NEXT: bltu a1, a0, .LBB25_2
896 ; RV64I-NEXT: # %bb.1:
897 ; RV64I-NEXT: mv a0, a1
898 ; RV64I-NEXT: .LBB25_2:
901 ; RV64IB-LABEL: maxu_i32:
903 ; RV64IB-NEXT: maxu a0, a0, a1
906 ; RV64IBB-LABEL: maxu_i32:
908 ; RV64IBB-NEXT: maxu a0, a0, a1
910 %cmp = icmp ugt i32 %a, %b
911 %cond = select i1 %cmp, i32 %a, i32 %b
915 define i64 @maxu_i64(i64 %a, i64 %b) nounwind {
916 ; RV64I-LABEL: maxu_i64:
918 ; RV64I-NEXT: bltu a1, a0, .LBB26_2
919 ; RV64I-NEXT: # %bb.1:
920 ; RV64I-NEXT: mv a0, a1
921 ; RV64I-NEXT: .LBB26_2:
924 ; RV64IB-LABEL: maxu_i64:
926 ; RV64IB-NEXT: maxu a0, a0, a1
929 ; RV64IBB-LABEL: maxu_i64:
931 ; RV64IBB-NEXT: maxu a0, a0, a1
933 %cmp = icmp ugt i64 %a, %b
934 %cond = select i1 %cmp, i64 %a, i64 %b
938 declare i32 @llvm.abs.i32(i32, i1 immarg)
940 define i32 @abs_i32(i32 %x) {
941 ; RV64I-LABEL: abs_i32:
943 ; RV64I-NEXT: sext.w a0, a0
944 ; RV64I-NEXT: srai a1, a0, 63
945 ; RV64I-NEXT: add a0, a0, a1
946 ; RV64I-NEXT: xor a0, a0, a1
949 ; RV64IB-LABEL: abs_i32:
951 ; RV64IB-NEXT: sext.w a0, a0
952 ; RV64IB-NEXT: neg a1, a0
953 ; RV64IB-NEXT: max a0, a0, a1
956 ; RV64IBB-LABEL: abs_i32:
958 ; RV64IBB-NEXT: sext.w a0, a0
959 ; RV64IBB-NEXT: neg a1, a0
960 ; RV64IBB-NEXT: max a0, a0, a1
962 %abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true)
966 declare i64 @llvm.abs.i64(i64, i1 immarg)
968 define i64 @abs_i64(i64 %x) {
969 ; RV64I-LABEL: abs_i64:
971 ; RV64I-NEXT: srai a1, a0, 63
972 ; RV64I-NEXT: add a0, a0, a1
973 ; RV64I-NEXT: xor a0, a0, a1
976 ; RV64IB-LABEL: abs_i64:
978 ; RV64IB-NEXT: neg a1, a0
979 ; RV64IB-NEXT: max a0, a0, a1
982 ; RV64IBB-LABEL: abs_i64:
984 ; RV64IBB-NEXT: neg a1, a0
985 ; RV64IBB-NEXT: max a0, a0, a1
987 %abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true)
991 ; We select a i32 addi that zero-extends the result on RV64 as addiwu
993 define zeroext i32 @zext_add_to_addiwu(i32 signext %a) nounwind {
994 ; RV64I-LABEL: zext_add_to_addiwu:
996 ; RV64I-NEXT: addi a0, a0, 1
997 ; RV64I-NEXT: slli a0, a0, 32
998 ; RV64I-NEXT: srli a0, a0, 32
1001 ; RV64IB-LABEL: zext_add_to_addiwu:
1003 ; RV64IB-NEXT: addiwu a0, a0, 1
1006 ; RV64IBB-LABEL: zext_add_to_addiwu:
1008 ; RV64IBB-NEXT: addiwu a0, a0, 1
1010 %add = add i32 %a, 1
1014 define i64 @addiwu(i64 %a) nounwind {
1015 ; RV64I-LABEL: addiwu:
1017 ; RV64I-NEXT: addi a0, a0, 1
1018 ; RV64I-NEXT: slli a0, a0, 32
1019 ; RV64I-NEXT: srli a0, a0, 32
1022 ; RV64IB-LABEL: addiwu:
1024 ; RV64IB-NEXT: addiwu a0, a0, 1
1027 ; RV64IBB-LABEL: addiwu:
1029 ; RV64IBB-NEXT: addiwu a0, a0, 1
1031 %conv = add i64 %a, 1
1032 %conv1 = and i64 %conv, 4294967295
1036 define i64 @slliuw(i64 %a) nounwind {
1037 ; RV64I-LABEL: slliuw:
1039 ; RV64I-NEXT: slli a0, a0, 1
1040 ; RV64I-NEXT: addi a1, zero, 1
1041 ; RV64I-NEXT: slli a1, a1, 33
1042 ; RV64I-NEXT: addi a1, a1, -2
1043 ; RV64I-NEXT: and a0, a0, a1
1046 ; RV64IB-LABEL: slliuw:
1048 ; RV64IB-NEXT: slliu.w a0, a0, 1
1051 ; RV64IBB-LABEL: slliuw:
1053 ; RV64IBB-NEXT: slliu.w a0, a0, 1
1055 %conv1 = shl i64 %a, 1
1056 %shl = and i64 %conv1, 8589934590
1060 ; We select a i32 add that zero-extends the result on RV64 as addwu
1062 define zeroext i32 @zext_add_to_addwu(i32 signext %a, i32 signext %b) nounwind {
1063 ; RV64I-LABEL: zext_add_to_addwu:
1065 ; RV64I-NEXT: add a0, a0, a1
1066 ; RV64I-NEXT: slli a0, a0, 32
1067 ; RV64I-NEXT: srli a0, a0, 32
1070 ; RV64IB-LABEL: zext_add_to_addwu:
1072 ; RV64IB-NEXT: addwu a0, a0, a1
1075 ; RV64IBB-LABEL: zext_add_to_addwu:
1077 ; RV64IBB-NEXT: addwu a0, a0, a1
1079 %add = add i32 %a, %b
1083 define i64 @addwu(i64 %a, i64 %b) nounwind {
1084 ; RV64I-LABEL: addwu:
1086 ; RV64I-NEXT: add a0, a1, a0
1087 ; RV64I-NEXT: slli a0, a0, 32
1088 ; RV64I-NEXT: srli a0, a0, 32
1091 ; RV64IB-LABEL: addwu:
1093 ; RV64IB-NEXT: addwu a0, a1, a0
1096 ; RV64IBB-LABEL: addwu:
1098 ; RV64IBB-NEXT: addwu a0, a1, a0
1100 %add = add i64 %b, %a
1101 %conv1 = and i64 %add, 4294967295
1105 ; We select a i32 sub that zero-extends the result on RV64 as subwu
1107 define zeroext i32 @zext_sub_to_subwu(i32 signext %a, i32 signext %b) nounwind {
1108 ; RV64I-LABEL: zext_sub_to_subwu:
1110 ; RV64I-NEXT: sub a0, a0, a1
1111 ; RV64I-NEXT: slli a0, a0, 32
1112 ; RV64I-NEXT: srli a0, a0, 32
1115 ; RV64IB-LABEL: zext_sub_to_subwu:
1117 ; RV64IB-NEXT: subwu a0, a0, a1
1120 ; RV64IBB-LABEL: zext_sub_to_subwu:
1122 ; RV64IBB-NEXT: subwu a0, a0, a1
1124 %sub = sub i32 %a, %b
1128 define i64 @subwu(i64 %a, i64 %b) nounwind {
1129 ; RV64I-LABEL: subwu:
1131 ; RV64I-NEXT: sub a0, a0, a1
1132 ; RV64I-NEXT: slli a0, a0, 32
1133 ; RV64I-NEXT: srli a0, a0, 32
1136 ; RV64IB-LABEL: subwu:
1138 ; RV64IB-NEXT: subwu a0, a0, a1
1141 ; RV64IBB-LABEL: subwu:
1143 ; RV64IBB-NEXT: subwu a0, a0, a1
1145 %sub = sub i64 %a, %b
1146 %conv1 = and i64 %sub, 4294967295
1150 define i64 @adduw(i64 %a, i64 %b) nounwind {
1151 ; RV64I-LABEL: adduw:
1153 ; RV64I-NEXT: slli a1, a1, 32
1154 ; RV64I-NEXT: srli a1, a1, 32
1155 ; RV64I-NEXT: add a0, a1, a0
1158 ; RV64IB-LABEL: adduw:
1160 ; RV64IB-NEXT: addu.w a0, a0, a1
1163 ; RV64IBB-LABEL: adduw:
1165 ; RV64IBB-NEXT: addu.w a0, a0, a1
1167 %and = and i64 %b, 4294967295
1168 %add = add i64 %and, %a
1172 define i64 @subuw(i64 %a, i64 %b) nounwind {
1173 ; RV64I-LABEL: subuw:
1175 ; RV64I-NEXT: slli a1, a1, 32
1176 ; RV64I-NEXT: srli a1, a1, 32
1177 ; RV64I-NEXT: sub a0, a0, a1
1180 ; RV64IB-LABEL: subuw:
1182 ; RV64IB-NEXT: subu.w a0, a0, a1
1185 ; RV64IBB-LABEL: subuw:
1187 ; RV64IBB-NEXT: subu.w a0, a0, a1
1189 %and = and i64 %b, 4294967295
1190 %sub = sub i64 %a, %and