llvm.org GIT mirror llvm / e637084
[GlobalISel][X86] G_ICMP support. Summary: support G_ICMP for scalar types i8/i16/i64. Reviewers: zvi, guyblank Reviewed By: guyblank Subscribers: rovka, kristof.beyls, llvm-commits, krytarowski Differential Revision: https://reviews.llvm.org/D32995 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302774 91177308-0d34-0410-b5e6-96231b3b80d8 Igor Breger 3 years ago
6 changed file(s) with 1090 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
7272 MachineFunction &MF) const;
7373 bool selectZext(MachineInstr &I, MachineRegisterInfo &MRI,
7474 MachineFunction &MF) const;
75 bool selectCmp(MachineInstr &I, MachineRegisterInfo &MRI,
76 MachineFunction &MF) const;
7577
7678 const X86TargetMachine &TM;
7779 const X86Subtarget &STI;
243245 if (selectTrunc(I, MRI, MF))
244246 return true;
245247 if (selectZext(I, MRI, MF))
248 return true;
249 if (selectCmp(I, MRI, MF))
246250 return true;
247251
248252 return false;
611615 return false;
612616 }
613617
618 bool X86InstructionSelector::selectCmp(MachineInstr &I,
619 MachineRegisterInfo &MRI,
620 MachineFunction &MF) const {
621 if (I.getOpcode() != TargetOpcode::G_ICMP)
622 return false;
623
624 X86::CondCode CC;
625 bool SwapArgs;
626 std::tie(CC, SwapArgs) = X86::getX86ConditionCode(
627 (CmpInst::Predicate)I.getOperand(1).getPredicate());
628 unsigned OpSet = X86::getSETFromCond(CC);
629
630 unsigned LHS = I.getOperand(2).getReg();
631 unsigned RHS = I.getOperand(3).getReg();
632
633 if (SwapArgs)
634 std::swap(LHS, RHS);
635
636 unsigned OpCmp;
637 LLT Ty = MRI.getType(LHS);
638
639 switch (Ty.getSizeInBits()) {
640 default:
641 return false;
642 case 8:
643 OpCmp = X86::CMP8rr;
644 break;
645 case 16:
646 OpCmp = X86::CMP16rr;
647 break;
648 case 32:
649 OpCmp = X86::CMP32rr;
650 break;
651 case 64:
652 OpCmp = X86::CMP64rr;
653 break;
654 }
655
656 MachineInstr &CmpInst =
657 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp))
658 .addReg(LHS)
659 .addReg(RHS);
660
661 MachineInstr &SetInst = *BuildMI(*I.getParent(), I, I.getDebugLoc(),
662 TII.get(OpSet), I.getOperand(0).getReg());
663
664 constrainSelectedInstRegOperands(CmpInst, TII, TRI, RBI);
665 constrainSelectedInstRegOperands(SetInst, TII, TRI, RBI);
666
667 I.eraseFromParent();
668 return true;
669 }
670
614671 InstructionSelector *
615672 llvm::createX86InstructionSelector(const X86TargetMachine &TM,
616673 X86Subtarget &Subtarget,
9090 setAction({G_ZEXT, 1, Ty}, Legal);
9191 setAction({G_SEXT, 1, Ty}, Legal);
9292 }
93
94 // Comparison
95 setAction({G_ICMP, s1}, Legal);
96
97 for (auto Ty : {s8, s16, s32, p0})
98 setAction({G_ICMP, 1, Ty}, Legal);
9399 }
94100
95101 void X86LegalizerInfo::setLegalizerInfo64bit() {
142148 setAction({G_ZEXT, 1, Ty}, Legal);
143149 setAction({G_SEXT, 1, Ty}, Legal);
144150 }
151
152 // Comparison
153 setAction({G_ICMP, s1}, Legal);
154
155 for (auto Ty : {s8, s16, s32, s64, p0})
156 setAction({G_ICMP, 1, Ty}, Legal);
145157 }
146158
147159 void X86LegalizerInfo::setLegalizerInfoSSE1() {
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=x86_64-linux-gnu -global-isel < %s -o - | FileCheck %s --check-prefix=ALL
2
3 define i32 @test_icmp_eq_i8(i8 %a, i8 %b) {
4 ; ALL-LABEL: test_icmp_eq_i8:
5 ; ALL: # BB#0:
6 ; ALL-NEXT: cmpb %sil, %dil
7 ; ALL-NEXT: sete %al
8 ; ALL-NEXT: andl $1, %eax
9 ; ALL-NEXT: retq
10 %r = icmp eq i8 %a, %b
11 %res = zext i1 %r to i32
12 ret i32 %res
13 }
14
15 define i32 @test_icmp_eq_i16(i16 %a, i16 %b) {
16 ; ALL-LABEL: test_icmp_eq_i16:
17 ; ALL: # BB#0:
18 ; ALL-NEXT: cmpw %si, %di
19 ; ALL-NEXT: sete %al
20 ; ALL-NEXT: andl $1, %eax
21 ; ALL-NEXT: retq
22 %r = icmp eq i16 %a, %b
23 %res = zext i1 %r to i32
24 ret i32 %res
25 }
26
27 define i32 @test_icmp_eq_i64(i64 %a, i64 %b) {
28 ; ALL-LABEL: test_icmp_eq_i64:
29 ; ALL: # BB#0:
30 ; ALL-NEXT: cmpq %rsi, %rdi
31 ; ALL-NEXT: sete %al
32 ; ALL-NEXT: andl $1, %eax
33 ; ALL-NEXT: retq
34 %r = icmp eq i64 %a, %b
35 %res = zext i1 %r to i32
36 ret i32 %res
37 }
38
39 define i32 @test_icmp_eq_i32(i32 %a, i32 %b) {
40 ; ALL-LABEL: test_icmp_eq_i32:
41 ; ALL: # BB#0:
42 ; ALL-NEXT: cmpl %esi, %edi
43 ; ALL-NEXT: sete %al
44 ; ALL-NEXT: andl $1, %eax
45 ; ALL-NEXT: retq
46 %r = icmp eq i32 %a, %b
47 %res = zext i1 %r to i32
48 ret i32 %res
49 }
50
51 define i32 @test_icmp_ne_i32(i32 %a, i32 %b) {
52 ; ALL-LABEL: test_icmp_ne_i32:
53 ; ALL: # BB#0:
54 ; ALL-NEXT: cmpl %esi, %edi
55 ; ALL-NEXT: setne %al
56 ; ALL-NEXT: andl $1, %eax
57 ; ALL-NEXT: retq
58 %r = icmp ne i32 %a, %b
59 %res = zext i1 %r to i32
60 ret i32 %res
61 }
62
63 define i32 @test_icmp_ugt_i32(i32 %a, i32 %b) {
64 ; ALL-LABEL: test_icmp_ugt_i32:
65 ; ALL: # BB#0:
66 ; ALL-NEXT: cmpl %esi, %edi
67 ; ALL-NEXT: seta %al
68 ; ALL-NEXT: andl $1, %eax
69 ; ALL-NEXT: retq
70 %r = icmp ugt i32 %a, %b
71 %res = zext i1 %r to i32
72 ret i32 %res
73 }
74
75 define i32 @test_icmp_uge_i32(i32 %a, i32 %b) {
76 ; ALL-LABEL: test_icmp_uge_i32:
77 ; ALL: # BB#0:
78 ; ALL-NEXT: cmpl %esi, %edi
79 ; ALL-NEXT: setae %al
80 ; ALL-NEXT: andl $1, %eax
81 ; ALL-NEXT: retq
82 %r = icmp uge i32 %a, %b
83 %res = zext i1 %r to i32
84 ret i32 %res
85 }
86
87 define i32 @test_icmp_ult_i32(i32 %a, i32 %b) {
88 ; ALL-LABEL: test_icmp_ult_i32:
89 ; ALL: # BB#0:
90 ; ALL-NEXT: cmpl %esi, %edi
91 ; ALL-NEXT: setb %al
92 ; ALL-NEXT: andl $1, %eax
93 ; ALL-NEXT: retq
94 %r = icmp ult i32 %a, %b
95 %res = zext i1 %r to i32
96 ret i32 %res
97 }
98
99 define i32 @test_icmp_ule_i32(i32 %a, i32 %b) {
100 ; ALL-LABEL: test_icmp_ule_i32:
101 ; ALL: # BB#0:
102 ; ALL-NEXT: cmpl %esi, %edi
103 ; ALL-NEXT: setbe %al
104 ; ALL-NEXT: andl $1, %eax
105 ; ALL-NEXT: retq
106 %r = icmp ule i32 %a, %b
107 %res = zext i1 %r to i32
108 ret i32 %res
109 }
110
111 define i32 @test_icmp_sgt_i32(i32 %a, i32 %b) {
112 ; ALL-LABEL: test_icmp_sgt_i32:
113 ; ALL: # BB#0:
114 ; ALL-NEXT: cmpl %esi, %edi
115 ; ALL-NEXT: setg %al
116 ; ALL-NEXT: andl $1, %eax
117 ; ALL-NEXT: retq
118 %r = icmp sgt i32 %a, %b
119 %res = zext i1 %r to i32
120 ret i32 %res
121 }
122
123 define i32 @test_icmp_sge_i32(i32 %a, i32 %b) {
124 ; ALL-LABEL: test_icmp_sge_i32:
125 ; ALL: # BB#0:
126 ; ALL-NEXT: cmpl %esi, %edi
127 ; ALL-NEXT: setge %al
128 ; ALL-NEXT: andl $1, %eax
129 ; ALL-NEXT: retq
130 %r = icmp sge i32 %a, %b
131 %res = zext i1 %r to i32
132 ret i32 %res
133 }
134
135 define i32 @test_icmp_slt_i32(i32 %a, i32 %b) {
136 ; ALL-LABEL: test_icmp_slt_i32:
137 ; ALL: # BB#0:
138 ; ALL-NEXT: cmpl %esi, %edi
139 ; ALL-NEXT: setl %al
140 ; ALL-NEXT: andl $1, %eax
141 ; ALL-NEXT: retq
142 %r = icmp slt i32 %a, %b
143 %res = zext i1 %r to i32
144 ret i32 %res
145 }
146
147 define i32 @test_icmp_sle_i32(i32 %a, i32 %b) {
148 ; ALL-LABEL: test_icmp_sle_i32:
149 ; ALL: # BB#0:
150 ; ALL-NEXT: cmpl %esi, %edi
151 ; ALL-NEXT: setle %al
152 ; ALL-NEXT: andl $1, %eax
153 ; ALL-NEXT: retq
154 %r = icmp sle i32 %a, %b
155 %res = zext i1 %r to i32
156 ret i32 %res
157 }
158
0 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s
1
2 --- |
3 define i32 @test_cmp_i8(i8 %a, i8 %b) {
4 %r = icmp ult i8 %a, %b
5 %res = zext i1 %r to i32
6 ret i32 %res
7 }
8
9 define i32 @test_cmp_i16(i16 %a, i16 %b) {
10 %r = icmp ult i16 %a, %b
11 %res = zext i1 %r to i32
12 ret i32 %res
13 }
14
15 define i32 @test_cmp_i32(i32 %a, i32 %b) {
16 %r = icmp ult i32 %a, %b
17 %res = zext i1 %r to i32
18 ret i32 %res
19 }
20
21 define i32 @test_cmp_i64(i64 %a, i64 %b) {
22 %r = icmp ult i64 %a, %b
23 %res = zext i1 %r to i32
24 ret i32 %res
25 }
26
27 define i32 @test_cmp_p0(i32* %a, i32* %b) {
28 %r = icmp ult i32* %a, %b
29 %res = zext i1 %r to i32
30 ret i32 %res
31 }
32
33 ...
34 ---
35 name: test_cmp_i8
36 # CHECK-LABEL: name: test_cmp_i8
37 alignment: 4
38 legalized: false
39 regBankSelected: false
40 registers:
41 - { id: 0, class: _ }
42 - { id: 1, class: _ }
43 - { id: 2, class: _ }
44 - { id: 3, class: _ }
45 # CHECK: %0(s8) = COPY %edi
46 # CHECK-NEXT: %1(s8) = COPY %esi
47 # CHECK-NEXT: %2(s1) = G_ICMP intpred(ult), %0(s8), %1
48 # CHECK-NEXT: %3(s32) = G_ZEXT %2(s1)
49 # CHECK-NEXT: %eax = COPY %3(s32)
50 # CHECK-NEXT: RET 0, implicit %eax
51 body: |
52 bb.1 (%ir-block.0):
53 liveins: %edi, %esi
54
55 %0(s8) = COPY %edi
56 %1(s8) = COPY %esi
57 %2(s1) = G_ICMP intpred(ult), %0(s8), %1
58 %3(s32) = G_ZEXT %2(s1)
59 %eax = COPY %3(s32)
60 RET 0, implicit %eax
61
62 ...
63 ---
64 name: test_cmp_i16
65 # CHECK-LABEL: name: test_cmp_i16
66 alignment: 4
67 legalized: false
68 regBankSelected: false
69 registers:
70 - { id: 0, class: _ }
71 - { id: 1, class: _ }
72 - { id: 2, class: _ }
73 - { id: 3, class: _ }
74 # CHECK: %0(s16) = COPY %edi
75 # CHECK-NEXT: %1(s16) = COPY %esi
76 # CHECK-NEXT: %2(s1) = G_ICMP intpred(ult), %0(s16), %1
77 # CHECK-NEXT: %3(s32) = G_ZEXT %2(s1)
78 # CHECK-NEXT: %eax = COPY %3(s32)
79 # CHECK-NEXT: RET 0, implicit %eax
80 body: |
81 bb.1 (%ir-block.0):
82 liveins: %edi, %esi
83
84 %0(s16) = COPY %edi
85 %1(s16) = COPY %esi
86 %2(s1) = G_ICMP intpred(ult), %0(s16), %1
87 %3(s32) = G_ZEXT %2(s1)
88 %eax = COPY %3(s32)
89 RET 0, implicit %eax
90
91 ...
92 ---
93 name: test_cmp_i32
94 # CHECK-LABEL: name: test_cmp_i32
95 alignment: 4
96 legalized: false
97 regBankSelected: false
98 registers:
99 - { id: 0, class: _ }
100 - { id: 1, class: _ }
101 - { id: 2, class: _ }
102 - { id: 3, class: _ }
103 # CHECK: %0(s32) = COPY %edi
104 # CHECK-NEXT: %1(s32) = COPY %esi
105 # CHECK-NEXT: %2(s1) = G_ICMP intpred(ult), %0(s32), %1
106 # CHECK-NEXT: %3(s32) = G_ZEXT %2(s1)
107 # CHECK-NEXT: %eax = COPY %3(s32)
108 # CHECK-NEXT: RET 0, implicit %eax
109 body: |
110 bb.1 (%ir-block.0):
111 liveins: %edi, %esi
112
113 %0(s32) = COPY %edi
114 %1(s32) = COPY %esi
115 %2(s1) = G_ICMP intpred(ult), %0(s32), %1
116 %3(s32) = G_ZEXT %2(s1)
117 %eax = COPY %3(s32)
118 RET 0, implicit %eax
119
120 ...
121 ---
122 name: test_cmp_i64
123 # CHECK-LABEL: name: test_cmp_i64
124 alignment: 4
125 legalized: false
126 regBankSelected: false
127 registers:
128 - { id: 0, class: _ }
129 - { id: 1, class: _ }
130 - { id: 2, class: _ }
131 - { id: 3, class: _ }
132 # CHECK: %0(s64) = COPY %rdi
133 # CHECK-NEXT: %1(s64) = COPY %rsi
134 # CHECK-NEXT: %2(s1) = G_ICMP intpred(ult), %0(s64), %1
135 # CHECK-NEXT: %3(s32) = G_ZEXT %2(s1)
136 # CHECK-NEXT: %eax = COPY %3(s32)
137 # CHECK-NEXT: RET 0, implicit %eax
138 body: |
139 bb.1 (%ir-block.0):
140 liveins: %rdi, %rsi
141
142 %0(s64) = COPY %rdi
143 %1(s64) = COPY %rsi
144 %2(s1) = G_ICMP intpred(ult), %0(s64), %1
145 %3(s32) = G_ZEXT %2(s1)
146 %eax = COPY %3(s32)
147 RET 0, implicit %eax
148
149 ...
150 ---
151 name: test_cmp_p0
152 # CHECK-LABEL: name: test_cmp_p0
153 alignment: 4
154 legalized: false
155 regBankSelected: false
156 registers:
157 - { id: 0, class: _ }
158 - { id: 1, class: _ }
159 - { id: 2, class: _ }
160 - { id: 3, class: _ }
161 # CHECK: %0(p0) = COPY %rdi
162 # CHECK-NEXT: %1(p0) = COPY %rsi
163 # CHECK-NEXT: %2(s1) = G_ICMP intpred(ult), %0(p0), %1
164 # CHECK-NEXT: %3(s32) = G_ZEXT %2(s1)
165 # CHECK-NEXT: %eax = COPY %3(s32)
166 # CHECK-NEXT: RET 0, implicit %eax
167 body: |
168 bb.1 (%ir-block.0):
169 liveins: %rdi, %rsi
170
171 %0(p0) = COPY %rdi
172 %1(p0) = COPY %rsi
173 %2(s1) = G_ICMP intpred(ult), %0(p0), %1
174 %3(s32) = G_ZEXT %2(s1)
175 %eax = COPY %3(s32)
176 RET 0, implicit %eax
177
178 ...
11 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -regbankselect-greedy -run-pass=regbankselect %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=GREEDY
22
33 --- |
4 ; ModuleID = 'tmp.ll'
5 source_filename = "tmp.ll"
6 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7 target triple = "x86_64--linux-gnu"
8
94 define i8 @test_add_i8(i8 %arg1, i8 %arg2) {
105 %ret = add i8 %arg1, %arg2
116 ret i8 %ret
117112 %p1 = getelementptr i32, i32* undef, i32 5
118113 %p2 = getelementptr i32, i32* undef, i64 5
119114 ret void
115 }
116
117 define i1 @test_icmp_eq_i8(i8 %a, i8 %b) {
118 %r = icmp eq i8 %a, %b
119 ret i1 %r
120 }
121
122 define i1 @test_icmp_eq_i16(i16 %a, i16 %b) {
123 %r = icmp eq i16 %a, %b
124 ret i1 %r
125 }
126
127 define i1 @test_icmp_eq_i32(i32 %a, i32 %b) {
128 %r = icmp eq i32 %a, %b
129 ret i1 %r
130 }
131
132 define i1 @test_icmp_eq_i64(i64 %a, i64 %b) {
133 %r = icmp eq i64 %a, %b
134 ret i1 %r
120135 }
121136
122137 ...
734749 RET 0
735750
736751 ...
752 ---
753 name: test_icmp_eq_i8
754 # CHECK-LABEL: name: test_icmp_eq_i8
755 alignment: 4
756 legalized: true
757 regBankSelected: false
758 # CHECK: registers:
759 # CHECK-NEXT: - { id: 0, class: gpr }
760 # CHECK-NEXT: - { id: 1, class: gpr }
761 # CHECK-NEXT: - { id: 2, class: gpr }
762 registers:
763 - { id: 0, class: _ }
764 - { id: 1, class: _ }
765 - { id: 2, class: _ }
766 body: |
767 bb.1 (%ir-block.0):
768 liveins: %edi, %esi
769
770 %0(s8) = COPY %edi
771 %1(s8) = COPY %esi
772 %2(s1) = G_ICMP intpred(eq), %0(s8), %1
773 %al = COPY %2(s1)
774 RET 0, implicit %al
775
776 ...
777 ---
778 name: test_icmp_eq_i16
779 # CHECK-LABEL: name: test_icmp_eq_i16
780 alignment: 4
781 legalized: true
782 regBankSelected: false
783 # CHECK: registers:
784 # CHECK-NEXT: - { id: 0, class: gpr }
785 # CHECK-NEXT: - { id: 1, class: gpr }
786 # CHECK-NEXT: - { id: 2, class: gpr }
787 registers:
788 - { id: 0, class: _ }
789 - { id: 1, class: _ }
790 - { id: 2, class: _ }
791 body: |
792 bb.1 (%ir-block.0):
793 liveins: %edi, %esi
794
795 %0(s16) = COPY %edi
796 %1(s16) = COPY %esi
797 %2(s1) = G_ICMP intpred(eq), %0(s16), %1
798 %al = COPY %2(s1)
799 RET 0, implicit %al
800
801 ...
802 ---
803 name: test_icmp_eq_i32
804 # CHECK-LABEL: name: test_icmp_eq_i32
805 alignment: 4
806 legalized: true
807 regBankSelected: false
808 # CHECK: registers:
809 # CHECK-NEXT: - { id: 0, class: gpr }
810 # CHECK-NEXT: - { id: 1, class: gpr }
811 # CHECK-NEXT: - { id: 2, class: gpr }
812 registers:
813 - { id: 0, class: _ }
814 - { id: 1, class: _ }
815 - { id: 2, class: _ }
816 body: |
817 bb.1 (%ir-block.0):
818 liveins: %edi, %esi
819
820 %0(s32) = COPY %edi
821 %1(s32) = COPY %esi
822 %2(s1) = G_ICMP intpred(eq), %0(s32), %1
823 %al = COPY %2(s1)
824 RET 0, implicit %al
825
826 ...
827 ---
828 name: test_icmp_eq_i64
829 # CHECK-LABEL: name: test_icmp_eq_i64
830 alignment: 4
831 legalized: true
832 regBankSelected: false
833 # CHECK: registers:
834 # CHECK-NEXT: - { id: 0, class: gpr }
835 # CHECK-NEXT: - { id: 1, class: gpr }
836 # CHECK-NEXT: - { id: 2, class: gpr }
837 registers:
838 - { id: 0, class: _ }
839 - { id: 1, class: _ }
840 - { id: 2, class: _ }
841 body: |
842 bb.1 (%ir-block.0):
843 liveins: %rdi, %rsi
844
845 %0(s64) = COPY %rdi
846 %1(s64) = COPY %rsi
847 %2(s1) = G_ICMP intpred(eq), %0(s64), %1
848 %al = COPY %2(s1)
849 RET 0, implicit %al
850
851 ...
0 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select %s -o - | FileCheck %s --check-prefix=CHECK
1
2 --- |
3 define i32 @test_icmp_eq_i8(i8 %a, i8 %b) {
4 %r = icmp eq i8 %a, %b
5 %res = zext i1 %r to i32
6 ret i32 %res
7 }
8
9 define i32 @test_icmp_eq_i16(i16 %a, i16 %b) {
10 %r = icmp eq i16 %a, %b
11 %res = zext i1 %r to i32
12 ret i32 %res
13 }
14
15 define i32 @test_icmp_eq_i64(i64 %a, i64 %b) {
16 %r = icmp eq i64 %a, %b
17 %res = zext i1 %r to i32
18 ret i32 %res
19 }
20
21 define i32 @test_icmp_eq_i32(i32 %a, i32 %b) {
22 %r = icmp eq i32 %a, %b
23 %res = zext i1 %r to i32
24 ret i32 %res
25 }
26
27 define i32 @test_icmp_ne_i32(i32 %a, i32 %b) {
28 %r = icmp ne i32 %a, %b
29 %res = zext i1 %r to i32
30 ret i32 %res
31 }
32
33 define i32 @test_icmp_ugt_i32(i32 %a, i32 %b) {
34 %r = icmp ugt i32 %a, %b
35 %res = zext i1 %r to i32
36 ret i32 %res
37 }
38
39 define i32 @test_icmp_uge_i32(i32 %a, i32 %b) {
40 %r = icmp uge i32 %a, %b
41 %res = zext i1 %r to i32
42 ret i32 %res
43 }
44
45 define i32 @test_icmp_ult_i32(i32 %a, i32 %b) {
46 %r = icmp ult i32 %a, %b
47 %res = zext i1 %r to i32
48 ret i32 %res
49 }
50
51 define i32 @test_icmp_ule_i32(i32 %a, i32 %b) {
52 %r = icmp ule i32 %a, %b
53 %res = zext i1 %r to i32
54 ret i32 %res
55 }
56
57 define i32 @test_icmp_sgt_i32(i32 %a, i32 %b) {
58 %r = icmp sgt i32 %a, %b
59 %res = zext i1 %r to i32
60 ret i32 %res
61 }
62
63 define i32 @test_icmp_sge_i32(i32 %a, i32 %b) {
64 %r = icmp sge i32 %a, %b
65 %res = zext i1 %r to i32
66 ret i32 %res
67 }
68
69 define i32 @test_icmp_slt_i32(i32 %a, i32 %b) {
70 %r = icmp slt i32 %a, %b
71 %res = zext i1 %r to i32
72 ret i32 %res
73 }
74
75 define i32 @test_icmp_sle_i32(i32 %a, i32 %b) {
76 %r = icmp sle i32 %a, %b
77 %res = zext i1 %r to i32
78 ret i32 %res
79 }
80
81 ...
82 ---
83 name: test_icmp_eq_i8
84 # CHECK-LABEL: name: test_icmp_eq_i8
85 alignment: 4
86 legalized: true
87 regBankSelected: true
88 # CHECK: registers:
89 # CHECK-NEXT: - { id: 0, class: gr8 }
90 # CHECK-NEXT: - { id: 1, class: gr8 }
91 # CHECK-NEXT: - { id: 2, class: gr8 }
92 # CHECK-NEXT: - { id: 3, class: gr32 }
93 # CHECK-NEXT: - { id: 4, class: gr32 }
94 registers:
95 - { id: 0, class: gpr }
96 - { id: 1, class: gpr }
97 - { id: 2, class: gpr }
98 - { id: 3, class: gpr }
99 # CHECK: %0 = COPY %dil
100 # CHECK-NEXT: %1 = COPY %sil
101 # CHECK-NEXT: CMP8rr %0, %1, implicit-def %eflags
102 # CHECK-NEXT: %2 = SETEr implicit %eflags
103 # CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
104 # CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
105 # CHECK-NEXT: %eax = COPY %3
106 # CHECK-NEXT: RET 0, implicit %eax
107 body: |
108 bb.1 (%ir-block.0):
109 liveins: %edi, %esi
110
111 %0(s8) = COPY %edi
112 %1(s8) = COPY %esi
113 %2(s1) = G_ICMP intpred(eq), %0(s8), %1
114 %3(s32) = G_ZEXT %2(s1)
115 %eax = COPY %3(s32)
116 RET 0, implicit %eax
117
118 ...
119 ---
120 name: test_icmp_eq_i16
121 # CHECK-LABEL: name: test_icmp_eq_i16
122 alignment: 4
123 legalized: true
124 regBankSelected: true
125 # CHECK: registers:
126 # CHECK-NEXT: - { id: 0, class: gr16 }
127 # CHECK-NEXT: - { id: 1, class: gr16 }
128 # CHECK-NEXT: - { id: 2, class: gr8 }
129 # CHECK-NEXT: - { id: 3, class: gr32 }
130 # CHECK-NEXT: - { id: 4, class: gr32 }
131 registers:
132 - { id: 0, class: gpr }
133 - { id: 1, class: gpr }
134 - { id: 2, class: gpr }
135 - { id: 3, class: gpr }
136 # CHECK: %0 = COPY %di
137 # CHECK-NEXT: %1 = COPY %si
138 # CHECK-NEXT: CMP16rr %0, %1, implicit-def %eflags
139 # CHECK-NEXT: %2 = SETEr implicit %eflags
140 # CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
141 # CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
142 # CHECK-NEXT: %eax = COPY %3
143 # CHECK-NEXT: RET 0, implicit %eax
144 body: |
145 bb.1 (%ir-block.0):
146 liveins: %edi, %esi
147
148 %0(s16) = COPY %edi
149 %1(s16) = COPY %esi
150 %2(s1) = G_ICMP intpred(eq), %0(s16), %1
151 %3(s32) = G_ZEXT %2(s1)
152 %eax = COPY %3(s32)
153 RET 0, implicit %eax
154
155 ...
156 ---
157 name: test_icmp_eq_i64
158 # CHECK-LABEL: name: test_icmp_eq_i64
159 alignment: 4
160 legalized: true
161 regBankSelected: true
162 # CHECK: registers:
163 # CHECK-NEXT: - { id: 0, class: gr64 }
164 # CHECK-NEXT: - { id: 1, class: gr64 }
165 # CHECK-NEXT: - { id: 2, class: gr8 }
166 # CHECK-NEXT: - { id: 3, class: gr32 }
167 # CHECK-NEXT: - { id: 4, class: gr32 }
168 registers:
169 - { id: 0, class: gpr }
170 - { id: 1, class: gpr }
171 - { id: 2, class: gpr }
172 - { id: 3, class: gpr }
173 # CHECK: %0 = COPY %rdi
174 # CHECK-NEXT: %1 = COPY %rsi
175 # CHECK-NEXT: CMP64rr %0, %1, implicit-def %eflags
176 # CHECK-NEXT: %2 = SETEr implicit %eflags
177 # CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
178 # CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
179 # CHECK-NEXT: %eax = COPY %3
180 # CHECK-NEXT: RET 0, implicit %eax
181 body: |
182 bb.1 (%ir-block.0):
183 liveins: %rdi, %rsi
184
185 %0(s64) = COPY %rdi
186 %1(s64) = COPY %rsi
187 %2(s1) = G_ICMP intpred(eq), %0(s64), %1
188 %3(s32) = G_ZEXT %2(s1)
189 %eax = COPY %3(s32)
190 RET 0, implicit %eax
191
192 ...
193 ---
194 name: test_icmp_eq_i32
195 # CHECK-LABEL: name: test_icmp_eq_i32
196 alignment: 4
197 legalized: true
198 regBankSelected: true
199 # CHECK: registers:
200 # CHECK-NEXT: - { id: 0, class: gr32 }
201 # CHECK-NEXT: - { id: 1, class: gr32 }
202 # CHECK-NEXT: - { id: 2, class: gr8 }
203 # CHECK-NEXT: - { id: 3, class: gr32 }
204 # CHECK-NEXT: - { id: 4, class: gr32 }
205 registers:
206 - { id: 0, class: gpr }
207 - { id: 1, class: gpr }
208 - { id: 2, class: gpr }
209 - { id: 3, class: gpr }
210 # CHECK: %0 = COPY %edi
211 # CHECK-NEXT: %1 = COPY %esi
212 # CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
213 # CHECK-NEXT: %2 = SETEr implicit %eflags
214 # CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
215 # CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
216 # CHECK-NEXT: %eax = COPY %3
217 # CHECK-NEXT: RET 0, implicit %eax
218 body: |
219 bb.1 (%ir-block.0):
220 liveins: %edi, %esi
221
222 %0(s32) = COPY %edi
223 %1(s32) = COPY %esi
224 %2(s1) = G_ICMP intpred(eq), %0(s32), %1
225 %3(s32) = G_ZEXT %2(s1)
226 %eax = COPY %3(s32)
227 RET 0, implicit %eax
228
229 ...
230 ---
231 name: test_icmp_ne_i32
232 # CHECK-LABEL: name: test_icmp_ne_i32
233 alignment: 4
234 legalized: true
235 regBankSelected: true
236 # CHECK: registers:
237 # CHECK-NEXT: - { id: 0, class: gr32 }
238 # CHECK-NEXT: - { id: 1, class: gr32 }
239 # CHECK-NEXT: - { id: 2, class: gr8 }
240 # CHECK-NEXT: - { id: 3, class: gr32 }
241 # CHECK-NEXT: - { id: 4, class: gr32 }
242 registers:
243 - { id: 0, class: gpr }
244 - { id: 1, class: gpr }
245 - { id: 2, class: gpr }
246 - { id: 3, class: gpr }
247 # CHECK: %0 = COPY %edi
248 # CHECK-NEXT: %1 = COPY %esi
249 # CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
250 # CHECK-NEXT: %2 = SETNEr implicit %eflags
251 # CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
252 # CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
253 # CHECK-NEXT: %eax = COPY %3
254 # CHECK-NEXT: RET 0, implicit %eax
255 body: |
256 bb.1 (%ir-block.0):
257 liveins: %edi, %esi
258
259 %0(s32) = COPY %edi
260 %1(s32) = COPY %esi
261 %2(s1) = G_ICMP intpred(ne), %0(s32), %1
262 %3(s32) = G_ZEXT %2(s1)
263 %eax = COPY %3(s32)
264 RET 0, implicit %eax
265
266 ...
267 ---
268 name: test_icmp_ugt_i32
269 # CHECK-LABEL: name: test_icmp_ugt_i32
270 alignment: 4
271 legalized: true
272 regBankSelected: true
273 # CHECK: registers:
274 # CHECK-NEXT: - { id: 0, class: gr32 }
275 # CHECK-NEXT: - { id: 1, class: gr32 }
276 # CHECK-NEXT: - { id: 2, class: gr8 }
277 # CHECK-NEXT: - { id: 3, class: gr32 }
278 # CHECK-NEXT: - { id: 4, class: gr32 }
279 registers:
280 - { id: 0, class: gpr }
281 - { id: 1, class: gpr }
282 - { id: 2, class: gpr }
283 - { id: 3, class: gpr }
284 # CHECK: %0 = COPY %edi
285 # CHECK-NEXT: %1 = COPY %esi
286 # CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
287 # CHECK-NEXT: %2 = SETAr implicit %eflags
288 # CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
289 # CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
290 # CHECK-NEXT: %eax = COPY %3
291 # CHECK-NEXT: RET 0, implicit %eax
292 body: |
293 bb.1 (%ir-block.0):
294 liveins: %edi, %esi
295
296 %0(s32) = COPY %edi
297 %1(s32) = COPY %esi
298 %2(s1) = G_ICMP intpred(ugt), %0(s32), %1
299 %3(s32) = G_ZEXT %2(s1)
300 %eax = COPY %3(s32)
301 RET 0, implicit %eax
302
303 ...
304 ---
305 name: test_icmp_uge_i32
306 # CHECK-LABEL: name: test_icmp_uge_i32
307 alignment: 4
308 legalized: true
309 regBankSelected: true
310 # CHECK: registers:
311 # CHECK-NEXT: - { id: 0, class: gr32 }
312 # CHECK-NEXT: - { id: 1, class: gr32 }
313 # CHECK-NEXT: - { id: 2, class: gr8 }
314 # CHECK-NEXT: - { id: 3, class: gr32 }
315 # CHECK-NEXT: - { id: 4, class: gr32 }
316 registers:
317 - { id: 0, class: gpr }
318 - { id: 1, class: gpr }
319 - { id: 2, class: gpr }
320 - { id: 3, class: gpr }
321 # CHECK: %0 = COPY %edi
322 # CHECK-NEXT: %1 = COPY %esi
323 # CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
324 # CHECK-NEXT: %2 = SETAEr implicit %eflags
325 # CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
326 # CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
327 # CHECK-NEXT: %eax = COPY %3
328 # CHECK-NEXT: RET 0, implicit %eax
329 body: |
330 bb.1 (%ir-block.0):
331 liveins: %edi, %esi
332
333 %0(s32) = COPY %edi
334 %1(s32) = COPY %esi
335 %2(s1) = G_ICMP intpred(uge), %0(s32), %1
336 %3(s32) = G_ZEXT %2(s1)
337 %eax = COPY %3(s32)
338 RET 0, implicit %eax
339
340 ...
341 ---
342 name: test_icmp_ult_i32
343 # CHECK-LABEL: name: test_icmp_ult_i32
344 alignment: 4
345 legalized: true
346 regBankSelected: true
347 # CHECK: registers:
348 # CHECK-NEXT: - { id: 0, class: gr32 }
349 # CHECK-NEXT: - { id: 1, class: gr32 }
350 # CHECK-NEXT: - { id: 2, class: gr8 }
351 # CHECK-NEXT: - { id: 3, class: gr32 }
352 # CHECK-NEXT: - { id: 4, class: gr32 }
353 registers:
354 - { id: 0, class: gpr }
355 - { id: 1, class: gpr }
356 - { id: 2, class: gpr }
357 - { id: 3, class: gpr }
358 # CHECK: %0 = COPY %edi
359 # CHECK-NEXT: %1 = COPY %esi
360 # CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
361 # CHECK-NEXT: %2 = SETBr implicit %eflags
362 # CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
363 # CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
364 # CHECK-NEXT: %eax = COPY %3
365 # CHECK-NEXT: RET 0, implicit %eax
366 body: |
367 bb.1 (%ir-block.0):
368 liveins: %edi, %esi
369
370 %0(s32) = COPY %edi
371 %1(s32) = COPY %esi
372 %2(s1) = G_ICMP intpred(ult), %0(s32), %1
373 %3(s32) = G_ZEXT %2(s1)
374 %eax = COPY %3(s32)
375 RET 0, implicit %eax
376
377 ...
378 ---
379 name: test_icmp_ule_i32
380 # CHECK-LABEL: name: test_icmp_ule_i32
381 alignment: 4
382 legalized: true
383 regBankSelected: true
384 # CHECK: registers:
385 # CHECK-NEXT: - { id: 0, class: gr32 }
386 # CHECK-NEXT: - { id: 1, class: gr32 }
387 # CHECK-NEXT: - { id: 2, class: gr8 }
388 # CHECK-NEXT: - { id: 3, class: gr32 }
389 # CHECK-NEXT: - { id: 4, class: gr32 }
390 registers:
391 - { id: 0, class: gpr }
392 - { id: 1, class: gpr }
393 - { id: 2, class: gpr }
394 - { id: 3, class: gpr }
395 # CHECK: %0 = COPY %edi
396 # CHECK-NEXT: %1 = COPY %esi
397 # CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
398 # CHECK-NEXT: %2 = SETBEr implicit %eflags
399 # CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
400 # CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
401 # CHECK-NEXT: %eax = COPY %3
402 # CHECK-NEXT: RET 0, implicit %eax
403 body: |
404 bb.1 (%ir-block.0):
405 liveins: %edi, %esi
406
407 %0(s32) = COPY %edi
408 %1(s32) = COPY %esi
409 %2(s1) = G_ICMP intpred(ule), %0(s32), %1
410 %3(s32) = G_ZEXT %2(s1)
411 %eax = COPY %3(s32)
412 RET 0, implicit %eax
413
414 ...
415 ---
416 name: test_icmp_sgt_i32
417 # CHECK-LABEL: name: test_icmp_sgt_i32
418 alignment: 4
419 legalized: true
420 regBankSelected: true
421 # CHECK: registers:
422 # CHECK-NEXT: - { id: 0, class: gr32 }
423 # CHECK-NEXT: - { id: 1, class: gr32 }
424 # CHECK-NEXT: - { id: 2, class: gr8 }
425 # CHECK-NEXT: - { id: 3, class: gr32 }
426 # CHECK-NEXT: - { id: 4, class: gr32 }
427 registers:
428 - { id: 0, class: gpr }
429 - { id: 1, class: gpr }
430 - { id: 2, class: gpr }
431 - { id: 3, class: gpr }
432 # CHECK: %0 = COPY %edi
433 # CHECK-NEXT: %1 = COPY %esi
434 # CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
435 # CHECK-NEXT: %2 = SETGr implicit %eflags
436 # CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
437 # CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
438 # CHECK-NEXT: %eax = COPY %3
439 # CHECK-NEXT: RET 0, implicit %eax
440 body: |
441 bb.1 (%ir-block.0):
442 liveins: %edi, %esi
443
444 %0(s32) = COPY %edi
445 %1(s32) = COPY %esi
446 %2(s1) = G_ICMP intpred(sgt), %0(s32), %1
447 %3(s32) = G_ZEXT %2(s1)
448 %eax = COPY %3(s32)
449 RET 0, implicit %eax
450
451 ...
452 ---
453 name: test_icmp_sge_i32
454 # CHECK-LABEL: name: test_icmp_sge_i32
455 alignment: 4
456 legalized: true
457 regBankSelected: true
458 # CHECK: registers:
459 # CHECK-NEXT: - { id: 0, class: gr32 }
460 # CHECK-NEXT: - { id: 1, class: gr32 }
461 # CHECK-NEXT: - { id: 2, class: gr8 }
462 # CHECK-NEXT: - { id: 3, class: gr32 }
463 # CHECK-NEXT: - { id: 4, class: gr32 }
464 registers:
465 - { id: 0, class: gpr }
466 - { id: 1, class: gpr }
467 - { id: 2, class: gpr }
468 - { id: 3, class: gpr }
469 # CHECK: %0 = COPY %edi
470 # CHECK-NEXT: %1 = COPY %esi
471 # CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
472 # CHECK-NEXT: %2 = SETGEr implicit %eflags
473 # CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
474 # CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
475 # CHECK-NEXT: %eax = COPY %3
476 # CHECK-NEXT: RET 0, implicit %eax
477 body: |
478 bb.1 (%ir-block.0):
479 liveins: %edi, %esi
480
481 %0(s32) = COPY %edi
482 %1(s32) = COPY %esi
483 %2(s1) = G_ICMP intpred(sge), %0(s32), %1
484 %3(s32) = G_ZEXT %2(s1)
485 %eax = COPY %3(s32)
486 RET 0, implicit %eax
487
488 ...
489 ---
490 name: test_icmp_slt_i32
491 # CHECK-LABEL: name: test_icmp_slt_i32
492 alignment: 4
493 legalized: true
494 regBankSelected: true
495 # CHECK: registers:
496 # CHECK-NEXT: - { id: 0, class: gr32 }
497 # CHECK-NEXT: - { id: 1, class: gr32 }
498 # CHECK-NEXT: - { id: 2, class: gr8 }
499 # CHECK-NEXT: - { id: 3, class: gr32 }
500 # CHECK-NEXT: - { id: 4, class: gr32 }
501 registers:
502 - { id: 0, class: gpr }
503 - { id: 1, class: gpr }
504 - { id: 2, class: gpr }
505 - { id: 3, class: gpr }
506 # CHECK: %0 = COPY %edi
507 # CHECK-NEXT: %1 = COPY %esi
508 # CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
509 # CHECK-NEXT: %2 = SETLr implicit %eflags
510 # CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
511 # CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
512 # CHECK-NEXT: %eax = COPY %3
513 # CHECK-NEXT: RET 0, implicit %eax
514 body: |
515 bb.1 (%ir-block.0):
516 liveins: %edi, %esi
517
518 %0(s32) = COPY %edi
519 %1(s32) = COPY %esi
520 %2(s1) = G_ICMP intpred(slt), %0(s32), %1
521 %3(s32) = G_ZEXT %2(s1)
522 %eax = COPY %3(s32)
523 RET 0, implicit %eax
524
525 ...
526 ---
527 name: test_icmp_sle_i32
528 # CHECK-LABEL: name: test_icmp_sle_i32
529 alignment: 4
530 legalized: true
531 regBankSelected: true
532 # CHECK: registers:
533 # CHECK-NEXT: - { id: 0, class: gr32 }
534 # CHECK-NEXT: - { id: 1, class: gr32 }
535 # CHECK-NEXT: - { id: 2, class: gr8 }
536 # CHECK-NEXT: - { id: 3, class: gr32 }
537 # CHECK-NEXT: - { id: 4, class: gr32 }
538 registers:
539 - { id: 0, class: gpr }
540 - { id: 1, class: gpr }
541 - { id: 2, class: gpr }
542 - { id: 3, class: gpr }
543 # CHECK: %0 = COPY %edi
544 # CHECK-NEXT: %1 = COPY %esi
545 # CHECK-NEXT: CMP32rr %0, %1, implicit-def %eflags
546 # CHECK-NEXT: %2 = SETLEr implicit %eflags
547 # CHECK-NEXT: %4 = SUBREG_TO_REG 0, %2, 1
548 # CHECK-NEXT: %3 = AND32ri8 %4, 1, implicit-def %eflags
549 # CHECK-NEXT: %eax = COPY %3
550 # CHECK-NEXT: RET 0, implicit %eax
551 body: |
552 bb.1 (%ir-block.0):
553 liveins: %edi, %esi
554
555 %0(s32) = COPY %edi
556 %1(s32) = COPY %esi
557 %2(s1) = G_ICMP intpred(sle), %0(s32), %1
558 %3(s32) = G_ZEXT %2(s1)
559 %eax = COPY %3(s32)
560 RET 0, implicit %eax
561
562 ...