1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3 ; RUN: | FileCheck %s -check-prefix=RV32I
4 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s -check-prefixes=RV64,RV64I
6 ; RUN: llc -mtriple=riscv64 -mattr=+zbb -verify-machineinstrs < %s \
7 ; RUN: | FileCheck %s -check-prefixes=RV64,RV64ZBB
9 define i8 @sext_i1_to_i8(i1 %a) nounwind {
10 ; RV32I-LABEL: sext_i1_to_i8:
12 ; RV32I-NEXT: slli a0, a0, 31
13 ; RV32I-NEXT: srai a0, a0, 31
16 ; RV64-LABEL: sext_i1_to_i8:
18 ; RV64-NEXT: slli a0, a0, 63
19 ; RV64-NEXT: srai a0, a0, 63
25 define i16 @sext_i1_to_i16(i1 %a) nounwind {
26 ; RV32I-LABEL: sext_i1_to_i16:
28 ; RV32I-NEXT: slli a0, a0, 31
29 ; RV32I-NEXT: srai a0, a0, 31
32 ; RV64-LABEL: sext_i1_to_i16:
34 ; RV64-NEXT: slli a0, a0, 63
35 ; RV64-NEXT: srai a0, a0, 63
37 %1 = sext i1 %a to i16
41 define i32 @sext_i1_to_i32(i1 %a) nounwind {
42 ; RV32I-LABEL: sext_i1_to_i32:
44 ; RV32I-NEXT: slli a0, a0, 31
45 ; RV32I-NEXT: srai a0, a0, 31
48 ; RV64-LABEL: sext_i1_to_i32:
50 ; RV64-NEXT: slli a0, a0, 63
51 ; RV64-NEXT: srai a0, a0, 63
53 %1 = sext i1 %a to i32
57 define i64 @sext_i1_to_i64(i1 %a) nounwind {
58 ; RV32I-LABEL: sext_i1_to_i64:
60 ; RV32I-NEXT: slli a0, a0, 31
61 ; RV32I-NEXT: srai a0, a0, 31
62 ; RV32I-NEXT: mv a1, a0
65 ; RV64-LABEL: sext_i1_to_i64:
67 ; RV64-NEXT: slli a0, a0, 63
68 ; RV64-NEXT: srai a0, a0, 63
70 %1 = sext i1 %a to i64
74 define i16 @sext_i8_to_i16(i8 %a) nounwind {
75 ; RV32I-LABEL: sext_i8_to_i16:
77 ; RV32I-NEXT: slli a0, a0, 24
78 ; RV32I-NEXT: srai a0, a0, 24
81 ; RV64I-LABEL: sext_i8_to_i16:
83 ; RV64I-NEXT: slli a0, a0, 56
84 ; RV64I-NEXT: srai a0, a0, 56
87 ; RV64ZBB-LABEL: sext_i8_to_i16:
89 ; RV64ZBB-NEXT: sext.b a0, a0
91 %1 = sext i8 %a to i16
95 define i32 @sext_i8_to_i32(i8 %a) nounwind {
96 ; RV32I-LABEL: sext_i8_to_i32:
98 ; RV32I-NEXT: slli a0, a0, 24
99 ; RV32I-NEXT: srai a0, a0, 24
102 ; RV64I-LABEL: sext_i8_to_i32:
104 ; RV64I-NEXT: slli a0, a0, 56
105 ; RV64I-NEXT: srai a0, a0, 56
108 ; RV64ZBB-LABEL: sext_i8_to_i32:
110 ; RV64ZBB-NEXT: sext.b a0, a0
112 %1 = sext i8 %a to i32
116 define i64 @sext_i8_to_i64(i8 %a) nounwind {
117 ; RV32I-LABEL: sext_i8_to_i64:
119 ; RV32I-NEXT: slli a1, a0, 24
120 ; RV32I-NEXT: srai a0, a1, 24
121 ; RV32I-NEXT: srai a1, a1, 31
124 ; RV64I-LABEL: sext_i8_to_i64:
126 ; RV64I-NEXT: slli a0, a0, 56
127 ; RV64I-NEXT: srai a0, a0, 56
130 ; RV64ZBB-LABEL: sext_i8_to_i64:
132 ; RV64ZBB-NEXT: sext.b a0, a0
134 %1 = sext i8 %a to i64
138 define i32 @sext_i16_to_i32(i16 %a) nounwind {
139 ; RV32I-LABEL: sext_i16_to_i32:
141 ; RV32I-NEXT: slli a0, a0, 16
142 ; RV32I-NEXT: srai a0, a0, 16
145 ; RV64I-LABEL: sext_i16_to_i32:
147 ; RV64I-NEXT: slli a0, a0, 48
148 ; RV64I-NEXT: srai a0, a0, 48
151 ; RV64ZBB-LABEL: sext_i16_to_i32:
153 ; RV64ZBB-NEXT: sext.h a0, a0
155 %1 = sext i16 %a to i32
159 define i64 @sext_i16_to_i64(i16 %a) nounwind {
160 ; RV32I-LABEL: sext_i16_to_i64:
162 ; RV32I-NEXT: slli a1, a0, 16
163 ; RV32I-NEXT: srai a0, a1, 16
164 ; RV32I-NEXT: srai a1, a1, 31
167 ; RV64I-LABEL: sext_i16_to_i64:
169 ; RV64I-NEXT: slli a0, a0, 48
170 ; RV64I-NEXT: srai a0, a0, 48
173 ; RV64ZBB-LABEL: sext_i16_to_i64:
175 ; RV64ZBB-NEXT: sext.h a0, a0
177 %1 = sext i16 %a to i64
181 define i64 @sext_i32_to_i64(i32 %a) nounwind {
182 ; RV32I-LABEL: sext_i32_to_i64:
184 ; RV32I-NEXT: srai a1, a0, 31
187 ; RV64-LABEL: sext_i32_to_i64:
189 ; RV64-NEXT: sext.w a0, a0
191 %1 = sext i32 %a to i64
195 define i8 @zext_i1_to_i8(i1 %a) nounwind {
196 ; RV32I-LABEL: zext_i1_to_i8:
198 ; RV32I-NEXT: andi a0, a0, 1
201 ; RV64-LABEL: zext_i1_to_i8:
203 ; RV64-NEXT: andi a0, a0, 1
205 %1 = zext i1 %a to i8
209 define i16 @zext_i1_to_i16(i1 %a) nounwind {
210 ; RV32I-LABEL: zext_i1_to_i16:
212 ; RV32I-NEXT: andi a0, a0, 1
215 ; RV64-LABEL: zext_i1_to_i16:
217 ; RV64-NEXT: andi a0, a0, 1
219 %1 = zext i1 %a to i16
223 define i32 @zext_i1_to_i32(i1 %a) nounwind {
224 ; RV32I-LABEL: zext_i1_to_i32:
226 ; RV32I-NEXT: andi a0, a0, 1
229 ; RV64-LABEL: zext_i1_to_i32:
231 ; RV64-NEXT: andi a0, a0, 1
233 %1 = zext i1 %a to i32
237 define i64 @zext_i1_to_i64(i1 %a) nounwind {
238 ; RV32I-LABEL: zext_i1_to_i64:
240 ; RV32I-NEXT: andi a0, a0, 1
241 ; RV32I-NEXT: li a1, 0
244 ; RV64-LABEL: zext_i1_to_i64:
246 ; RV64-NEXT: andi a0, a0, 1
248 %1 = zext i1 %a to i64
252 define i16 @zext_i8_to_i16(i8 %a) nounwind {
253 ; RV32I-LABEL: zext_i8_to_i16:
255 ; RV32I-NEXT: andi a0, a0, 255
258 ; RV64-LABEL: zext_i8_to_i16:
260 ; RV64-NEXT: andi a0, a0, 255
262 %1 = zext i8 %a to i16
266 define i32 @zext_i8_to_i32(i8 %a) nounwind {
267 ; RV32I-LABEL: zext_i8_to_i32:
269 ; RV32I-NEXT: andi a0, a0, 255
272 ; RV64-LABEL: zext_i8_to_i32:
274 ; RV64-NEXT: andi a0, a0, 255
276 %1 = zext i8 %a to i32
280 define i64 @zext_i8_to_i64(i8 %a) nounwind {
281 ; RV32I-LABEL: zext_i8_to_i64:
283 ; RV32I-NEXT: andi a0, a0, 255
284 ; RV32I-NEXT: li a1, 0
287 ; RV64-LABEL: zext_i8_to_i64:
289 ; RV64-NEXT: andi a0, a0, 255
291 %1 = zext i8 %a to i64
295 define i32 @zext_i16_to_i32(i16 %a) nounwind {
296 ; RV32I-LABEL: zext_i16_to_i32:
298 ; RV32I-NEXT: slli a0, a0, 16
299 ; RV32I-NEXT: srli a0, a0, 16
302 ; RV64I-LABEL: zext_i16_to_i32:
304 ; RV64I-NEXT: slli a0, a0, 48
305 ; RV64I-NEXT: srli a0, a0, 48
308 ; RV64ZBB-LABEL: zext_i16_to_i32:
310 ; RV64ZBB-NEXT: zext.h a0, a0
312 %1 = zext i16 %a to i32
316 define i64 @zext_i16_to_i64(i16 %a) nounwind {
317 ; RV32I-LABEL: zext_i16_to_i64:
319 ; RV32I-NEXT: slli a0, a0, 16
320 ; RV32I-NEXT: srli a0, a0, 16
321 ; RV32I-NEXT: li a1, 0
324 ; RV64I-LABEL: zext_i16_to_i64:
326 ; RV64I-NEXT: slli a0, a0, 48
327 ; RV64I-NEXT: srli a0, a0, 48
330 ; RV64ZBB-LABEL: zext_i16_to_i64:
332 ; RV64ZBB-NEXT: zext.h a0, a0
334 %1 = zext i16 %a to i64
338 define i64 @zext_i32_to_i64(i32 %a) nounwind {
339 ; RV32I-LABEL: zext_i32_to_i64:
341 ; RV32I-NEXT: li a1, 0
344 ; RV64-LABEL: zext_i32_to_i64:
346 ; RV64-NEXT: slli a0, a0, 32
347 ; RV64-NEXT: srli a0, a0, 32
349 %1 = zext i32 %a to i64
353 define i8 @zext_nneg_i1_to_i8(i1 %a) nounwind {
354 ; RV32I-LABEL: zext_nneg_i1_to_i8:
356 ; RV32I-NEXT: andi a0, a0, 1
359 ; RV64-LABEL: zext_nneg_i1_to_i8:
361 ; RV64-NEXT: andi a0, a0, 1
363 %1 = zext nneg i1 %a to i8
367 define i16 @zext_nneg_i1_to_i16(i1 %a) nounwind {
368 ; RV32I-LABEL: zext_nneg_i1_to_i16:
370 ; RV32I-NEXT: andi a0, a0, 1
373 ; RV64-LABEL: zext_nneg_i1_to_i16:
375 ; RV64-NEXT: andi a0, a0, 1
377 %1 = zext nneg i1 %a to i16
381 define i32 @zext_nneg_i1_to_i32(i1 %a) nounwind {
382 ; RV32I-LABEL: zext_nneg_i1_to_i32:
384 ; RV32I-NEXT: andi a0, a0, 1
387 ; RV64-LABEL: zext_nneg_i1_to_i32:
389 ; RV64-NEXT: andi a0, a0, 1
391 %1 = zext nneg i1 %a to i32
395 define i64 @zext_nneg_i1_to_i64(i1 %a) nounwind {
396 ; RV32I-LABEL: zext_nneg_i1_to_i64:
398 ; RV32I-NEXT: andi a0, a0, 1
399 ; RV32I-NEXT: li a1, 0
402 ; RV64-LABEL: zext_nneg_i1_to_i64:
404 ; RV64-NEXT: andi a0, a0, 1
406 %1 = zext nneg i1 %a to i64
410 define i16 @zext_nneg_i8_to_i16(i8 %a) nounwind {
411 ; RV32I-LABEL: zext_nneg_i8_to_i16:
413 ; RV32I-NEXT: andi a0, a0, 255
416 ; RV64-LABEL: zext_nneg_i8_to_i16:
418 ; RV64-NEXT: andi a0, a0, 255
420 %1 = zext nneg i8 %a to i16
424 define i32 @zext_nneg_i8_to_i32(i8 %a) nounwind {
425 ; RV32I-LABEL: zext_nneg_i8_to_i32:
427 ; RV32I-NEXT: andi a0, a0, 255
430 ; RV64-LABEL: zext_nneg_i8_to_i32:
432 ; RV64-NEXT: andi a0, a0, 255
434 %1 = zext nneg i8 %a to i32
438 define i64 @zext_nneg_i8_to_i64(i8 %a) nounwind {
439 ; RV32I-LABEL: zext_nneg_i8_to_i64:
441 ; RV32I-NEXT: andi a0, a0, 255
442 ; RV32I-NEXT: li a1, 0
445 ; RV64-LABEL: zext_nneg_i8_to_i64:
447 ; RV64-NEXT: andi a0, a0, 255
449 %1 = zext nneg i8 %a to i64
453 define i32 @zext_nneg_i16_to_i32(i16 %a) nounwind {
454 ; RV32I-LABEL: zext_nneg_i16_to_i32:
456 ; RV32I-NEXT: slli a0, a0, 16
457 ; RV32I-NEXT: srli a0, a0, 16
460 ; RV64I-LABEL: zext_nneg_i16_to_i32:
462 ; RV64I-NEXT: slli a0, a0, 48
463 ; RV64I-NEXT: srli a0, a0, 48
466 ; RV64ZBB-LABEL: zext_nneg_i16_to_i32:
468 ; RV64ZBB-NEXT: zext.h a0, a0
470 %1 = zext nneg i16 %a to i32
474 define i64 @zext_nneg_i16_to_i64(i16 %a) nounwind {
475 ; RV32I-LABEL: zext_nneg_i16_to_i64:
477 ; RV32I-NEXT: slli a0, a0, 16
478 ; RV32I-NEXT: srli a0, a0, 16
479 ; RV32I-NEXT: li a1, 0
482 ; RV64I-LABEL: zext_nneg_i16_to_i64:
484 ; RV64I-NEXT: slli a0, a0, 48
485 ; RV64I-NEXT: srli a0, a0, 48
488 ; RV64ZBB-LABEL: zext_nneg_i16_to_i64:
490 ; RV64ZBB-NEXT: zext.h a0, a0
492 %1 = zext nneg i16 %a to i64
496 define i64 @zext_nneg_i32_to_i64(i32 %a) nounwind {
497 ; RV32I-LABEL: zext_nneg_i32_to_i64:
499 ; RV32I-NEXT: li a1, 0
502 ; RV64-LABEL: zext_nneg_i32_to_i64:
504 ; RV64-NEXT: sext.w a0, a0
506 %1 = zext nneg i32 %a to i64
510 define i1 @trunc_i8_to_i1(i8 %a) nounwind {
511 ; RV32I-LABEL: trunc_i8_to_i1:
515 ; RV64-LABEL: trunc_i8_to_i1:
518 %1 = trunc i8 %a to i1
522 define i1 @trunc_i16_to_i1(i16 %a) nounwind {
523 ; RV32I-LABEL: trunc_i16_to_i1:
527 ; RV64-LABEL: trunc_i16_to_i1:
530 %1 = trunc i16 %a to i1
534 define i1 @trunc_i32_to_i1(i32 %a) nounwind {
535 ; RV32I-LABEL: trunc_i32_to_i1:
539 ; RV64-LABEL: trunc_i32_to_i1:
542 %1 = trunc i32 %a to i1
546 define i1 @trunc_i64_to_i1(i64 %a) nounwind {
547 ; RV32I-LABEL: trunc_i64_to_i1:
551 ; RV64-LABEL: trunc_i64_to_i1:
554 %1 = trunc i64 %a to i1
558 define i8 @trunc_i16_to_i8(i16 %a) nounwind {
559 ; RV32I-LABEL: trunc_i16_to_i8:
563 ; RV64-LABEL: trunc_i16_to_i8:
566 %1 = trunc i16 %a to i8
570 define i8 @trunc_i32_to_i8(i32 %a) nounwind {
571 ; RV32I-LABEL: trunc_i32_to_i8:
575 ; RV64-LABEL: trunc_i32_to_i8:
578 %1 = trunc i32 %a to i8
582 define i8 @trunc_i64_to_i8(i64 %a) nounwind {
583 ; RV32I-LABEL: trunc_i64_to_i8:
587 ; RV64-LABEL: trunc_i64_to_i8:
590 %1 = trunc i64 %a to i8
594 define i16 @trunc_i32_to_i16(i32 %a) nounwind {
595 ; RV32I-LABEL: trunc_i32_to_i16:
599 ; RV64-LABEL: trunc_i32_to_i16:
602 %1 = trunc i32 %a to i16
606 define i16 @trunc_i64_to_i16(i64 %a) nounwind {
607 ; RV32I-LABEL: trunc_i64_to_i16:
611 ; RV64-LABEL: trunc_i64_to_i16:
614 %1 = trunc i64 %a to i16
618 define i32 @trunc_i64_to_i32(i64 %a) nounwind {
619 ; RV32I-LABEL: trunc_i64_to_i32:
623 ; RV64-LABEL: trunc_i64_to_i32:
626 %1 = trunc i64 %a to i32
630 ;; fold (sext (not x)) -> (add (zext x) -1)
631 define i32 @sext_of_not_i32(i1 %x) {
632 ; RV32I-LABEL: sext_of_not_i32:
634 ; RV32I-NEXT: andi a0, a0, 1
635 ; RV32I-NEXT: addi a0, a0, -1
638 ; RV64-LABEL: sext_of_not_i32:
640 ; RV64-NEXT: andi a0, a0, 1
641 ; RV64-NEXT: addi a0, a0, -1
644 %sext = sext i1 %xor to i32
648 define i64 @sext_of_not_i64(i1 %x) {
649 ; RV32I-LABEL: sext_of_not_i64:
651 ; RV32I-NEXT: andi a0, a0, 1
652 ; RV32I-NEXT: addi a0, a0, -1
653 ; RV32I-NEXT: mv a1, a0
656 ; RV64-LABEL: sext_of_not_i64:
658 ; RV64-NEXT: andi a0, a0, 1
659 ; RV64-NEXT: addi a0, a0, -1
662 %sext = sext i1 %xor to i64
666 ;; fold (sext (not (setcc a, b, cc))) -> (sext (setcc a, b, !cc))
667 define i32 @sext_of_not_cmp_i32(i32 %x) {
668 ; RV32I-LABEL: sext_of_not_cmp_i32:
670 ; RV32I-NEXT: addi a0, a0, -7
671 ; RV32I-NEXT: seqz a0, a0
672 ; RV32I-NEXT: addi a0, a0, -1
675 ; RV64-LABEL: sext_of_not_cmp_i32:
677 ; RV64-NEXT: sext.w a0, a0
678 ; RV64-NEXT: addi a0, a0, -7
679 ; RV64-NEXT: seqz a0, a0
680 ; RV64-NEXT: addi a0, a0, -1
682 %cmp = icmp eq i32 %x, 7
683 %xor = xor i1 %cmp, 1
684 %sext = sext i1 %xor to i32
688 define i64 @sext_of_not_cmp_i64(i64 %x) {
689 ; RV32I-LABEL: sext_of_not_cmp_i64:
691 ; RV32I-NEXT: xori a0, a0, 7
692 ; RV32I-NEXT: or a0, a0, a1
693 ; RV32I-NEXT: seqz a0, a0
694 ; RV32I-NEXT: addi a0, a0, -1
695 ; RV32I-NEXT: mv a1, a0
698 ; RV64-LABEL: sext_of_not_cmp_i64:
700 ; RV64-NEXT: addi a0, a0, -7
701 ; RV64-NEXT: seqz a0, a0
702 ; RV64-NEXT: addi a0, a0, -1
704 %cmp = icmp eq i64 %x, 7
705 %xor = xor i1 %cmp, 1
706 %sext = sext i1 %xor to i64
710 ;; TODO: fold (add (zext (setcc a, b, cc)), -1) -> (sext (setcc a, b, !cc))
711 define i32 @dec_of_zexted_cmp_i32(i32 %x) {
712 ; RV32I-LABEL: dec_of_zexted_cmp_i32:
714 ; RV32I-NEXT: addi a0, a0, -7
715 ; RV32I-NEXT: seqz a0, a0
716 ; RV32I-NEXT: addi a0, a0, -1
719 ; RV64-LABEL: dec_of_zexted_cmp_i32:
721 ; RV64-NEXT: sext.w a0, a0
722 ; RV64-NEXT: addi a0, a0, -7
723 ; RV64-NEXT: seqz a0, a0
724 ; RV64-NEXT: addi a0, a0, -1
726 %cmp = icmp eq i32 %x, 7
727 %zext = zext i1 %cmp to i32
728 %dec = sub i32 %zext, 1
732 define i64 @dec_of_zexted_cmp_i64(i64 %x) {
733 ; RV32I-LABEL: dec_of_zexted_cmp_i64:
735 ; RV32I-NEXT: xori a0, a0, 7
736 ; RV32I-NEXT: or a0, a0, a1
737 ; RV32I-NEXT: seqz a0, a0
738 ; RV32I-NEXT: addi a0, a0, -1
739 ; RV32I-NEXT: mv a1, a0
742 ; RV64-LABEL: dec_of_zexted_cmp_i64:
744 ; RV64-NEXT: addi a0, a0, -7
745 ; RV64-NEXT: seqz a0, a0
746 ; RV64-NEXT: addi a0, a0, -1
748 %cmp = icmp eq i64 %x, 7
749 %zext = zext i1 %cmp to i64
750 %dec = sub i64 %zext, 1