[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / AArch64 / arm64-fast-isel-icmp.ll
blobdc64123b33c0e2f3c0ced2014b08987df91bae17
1 ; RUN: llc -O0 -fast-isel -fast-isel-abort=1 -verify-machineinstrs -mtriple=arm64-apple-darwin < %s | FileCheck %s
3 define i32 @icmp_eq_imm(i32 %a) nounwind ssp {
4 entry:
5 ; CHECK-LABEL: icmp_eq_imm
6 ; CHECK:       cmp w0, #31
7 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], eq
8 ; CHECK-NEXT:  and w0, [[REG]], #0x1
9   %cmp = icmp eq i32 %a, 31
10   %conv = zext i1 %cmp to i32
11   ret i32 %conv
14 define i32 @icmp_eq_neg_imm(i32 %a) nounwind ssp {
15 entry:
16 ; CHECK-LABEL: icmp_eq_neg_imm
17 ; CHECK:       cmn w0, #7
18 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], eq
19 ; CHECK-NEXT:  and w0, [[REG]], #0x1
20   %cmp = icmp eq i32 %a, -7
21   %conv = zext i1 %cmp to i32
22   ret i32 %conv
25 define i32 @icmp_eq_i32(i32 %a, i32 %b) nounwind ssp {
26 entry:
27 ; CHECK-LABEL: icmp_eq_i32
28 ; CHECK:       cmp w0, w1
29 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], eq
30 ; CHECK-NEXT:  and w0, [[REG]], #0x1
31   %cmp = icmp eq i32 %a, %b
32   %conv = zext i1 %cmp to i32
33   ret i32 %conv
36 define i32 @icmp_ne(i32 %a, i32 %b) nounwind ssp {
37 entry:
38 ; CHECK-LABEL: icmp_ne
39 ; CHECK:       cmp w0, w1
40 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], ne
41 ; CHECK-NEXT:  and w0, [[REG]], #0x1
42   %cmp = icmp ne i32 %a, %b
43   %conv = zext i1 %cmp to i32
44   ret i32 %conv
47 define i32 @icmp_eq_ptr(i8* %a) {
48 entry:
49 ; CHECK-LABEL: icmp_eq_ptr
50 ; CHECK:       cmp x0, #0
51 ; CHECK-NEXT:  cset {{.+}}, eq
52   %cmp = icmp eq i8* %a, null
53   %conv = zext i1 %cmp to i32
54   ret i32 %conv
57 define i32 @icmp_ne_ptr(i8* %a) {
58 entry:
59 ; CHECK-LABEL: icmp_ne_ptr
60 ; CHECK:       cmp x0, #0
61 ; CHECK-NEXT:  cset {{.+}}, ne
62   %cmp = icmp ne i8* %a, null
63   %conv = zext i1 %cmp to i32
64   ret i32 %conv
67 define i32 @icmp_ugt(i32 %a, i32 %b) nounwind ssp {
68 entry:
69 ; CHECK-LABEL: icmp_ugt
70 ; CHECK:       cmp w0, w1
71 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], hi
72 ; CHECK-NEXT:  and w0, [[REG]], #0x1
73   %cmp = icmp ugt i32 %a, %b
74   %conv = zext i1 %cmp to i32
75   ret i32 %conv
78 define i32 @icmp_uge(i32 %a, i32 %b) nounwind ssp {
79 entry:
80 ; CHECK-LABEL: icmp_uge
81 ; CHECK:       cmp w0, w1
82 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], hs
83 ; CHECK-NEXT:  and w0, [[REG]], #0x1
84   %cmp = icmp uge i32 %a, %b
85   %conv = zext i1 %cmp to i32
86   ret i32 %conv
89 define i32 @icmp_ult(i32 %a, i32 %b) nounwind ssp {
90 entry:
91 ; CHECK-LABEL: icmp_ult
92 ; CHECK:       cmp w0, w1
93 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], lo
94 ; CHECK-NEXT:  and w0, [[REG]], #0x1
95   %cmp = icmp ult i32 %a, %b
96   %conv = zext i1 %cmp to i32
97   ret i32 %conv
100 define i32 @icmp_ule(i32 %a, i32 %b) nounwind ssp {
101 entry:
102 ; CHECK-LABEL: icmp_ule
103 ; CHECK:       cmp w0, w1
104 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], ls
105 ; CHECK-NEXT:  and w0, [[REG]], #0x1
106   %cmp = icmp ule i32 %a, %b
107   %conv = zext i1 %cmp to i32
108   ret i32 %conv
111 define i32 @icmp_sgt(i32 %a, i32 %b) nounwind ssp {
112 entry:
113 ; CHECK-LABEL: icmp_sgt
114 ; CHECK:       cmp w0, w1
115 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], gt
116 ; CHECK-NEXT:  and w0, [[REG]], #0x1
117   %cmp = icmp sgt i32 %a, %b
118   %conv = zext i1 %cmp to i32
119   ret i32 %conv
122 define i32 @icmp_sge(i32 %a, i32 %b) nounwind ssp {
123 entry:
124 ; CHECK-LABEL: icmp_sge
125 ; CHECK:       cmp w0, w1
126 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], ge
127 ; CHECK-NEXT:  and w0, [[REG]], #0x1
128   %cmp = icmp sge i32 %a, %b
129   %conv = zext i1 %cmp to i32
130   ret i32 %conv
133 define i32 @icmp_slt(i32 %a, i32 %b) nounwind ssp {
134 entry:
135 ; CHECK-LABEL: icmp_slt
136 ; CHECK:       cmp w0, w1
137 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], lt
138 ; CHECK-NEXT:  and w0, [[REG]], #0x1
139   %cmp = icmp slt i32 %a, %b
140   %conv = zext i1 %cmp to i32
141   ret i32 %conv
144 define i32 @icmp_sle(i32 %a, i32 %b) nounwind ssp {
145 entry:
146 ; CHECK-LABEL: icmp_sle
147 ; CHECK:       cmp w0, w1
148 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], le
149 ; CHECK-NEXT:  and w0, [[REG]], #0x1
150   %cmp = icmp sle i32 %a, %b
151   %conv = zext i1 %cmp to i32
152   ret i32 %conv
155 define i32 @icmp_i64(i64 %a, i64 %b) nounwind ssp {
156 entry:
157 ; CHECK-LABEL: icmp_i64
158 ; CHECK:       cmp  x0, x1
159 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], le
160 ; CHECK-NEXT:  and w0, [[REG]], #0x1
161   %cmp = icmp sle i64 %a, %b
162   %conv = zext i1 %cmp to i32
163   ret i32 %conv
166 define zeroext i1 @icmp_eq_i16(i16 %a, i16 %b) nounwind ssp {
167 entry:
168 ; CHECK-LABEL: icmp_eq_i16
169 ; CHECK:       sxth [[REG0:w[0-9]+]], w0
170 ; CHECK:       cmp [[REG0]], w1, sxth
171 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], eq
172 ; CHECK-NEXT:  and w0, [[REG]], #0x1
173   %cmp = icmp eq i16 %a, %b
174   ret i1 %cmp
177 define zeroext i1 @icmp_eq_i8(i8 %a, i8 %b) nounwind ssp {
178 entry:
179 ; CHECK-LABEL: icmp_eq_i8
180 ; CHECK:       sxtb [[REG0:w[0-9]+]], w0
181 ; CHECK-NEXT:  cmp [[REG0]], w1, sxtb
182 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], eq
183 ; CHECK-NEXT:  and w0, [[REG]], #0x1
184   %cmp = icmp eq i8 %a, %b
185   ret i1 %cmp
188 define i32 @icmp_i16_unsigned(i16 %a, i16 %b) nounwind {
189 entry:
190 ; CHECK-LABEL: icmp_i16_unsigned
191 ; CHECK:       uxth [[REG0:w[0-9]+]], w0
192 ; CHECK-NEXT:  cmp [[REG0]], w1, uxth
193 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], lo
194 ; CHECK-NEXT:  and w0, [[REG]], #0x1
195   %cmp = icmp ult i16 %a, %b
196   %conv2 = zext i1 %cmp to i32
197   ret i32 %conv2
200 define i32 @icmp_i8_signed(i8 %a, i8 %b) nounwind {
201 entry:
202 ; CHECK-LABEL: icmp_i8_signed
203 ; CHECK:       sxtb [[REG0:w[0-9]+]], w0
204 ; CHECK-NEXT:  cmp [[REG0]], w1, sxtb
205 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], gt
206 ; CHECK-NEXT:  and w0, [[REG]], #0x1
207   %cmp = icmp sgt i8 %a, %b
208   %conv2 = zext i1 %cmp to i32
209   ret i32 %conv2
212 define i32 @icmp_i1_signed(i1 %a, i1 %b) nounwind {
213 entry:
214 ; CHECK-LABEL: icmp_i1_signed
215 ; CHECK:       sbfx [[REG1:w[0-9]+]], w0, #0, #1
216 ; CHECK-NEXT:  sbfx [[REG2:w[0-9]+]], w1, #0, #1
217 ; CHECK-NEXT:  cmp  [[REG1]], [[REG2]]
218 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], gt
219 ; CHECK-NEXT:  and w0, [[REG]], #0x1
220   %cmp = icmp sgt i1 %a, %b
221   %conv2 = zext i1 %cmp to i32
222   ret i32 %conv2
225 define i32 @icmp_i16_signed_const(i16 %a) nounwind {
226 entry:
227 ; CHECK-LABEL: icmp_i16_signed_const
228 ; CHECK:       sxth [[REG0:w[0-9]+]], w0
229 ; CHECK-NEXT:  cmn [[REG0]], #233
230 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], lt
231 ; CHECK-NEXT:  and w0, [[REG]], #0x1
232   %cmp = icmp slt i16 %a, -233
233   %conv2 = zext i1 %cmp to i32
234   ret i32 %conv2
237 define i32 @icmp_i8_signed_const(i8 %a) nounwind {
238 entry:
239 ; CHECK-LABEL: icmp_i8_signed_const
240 ; CHECK:       sxtb [[REG0:w[0-9]+]], w0
241 ; CHECK-NEXT:  cmp [[REG0]], #124
242 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], gt
243 ; CHECK-NEXT:  and w0, [[REG]], #0x1
244   %cmp = icmp sgt i8 %a, 124
245   %conv2 = zext i1 %cmp to i32
246   ret i32 %conv2
249 define i32 @icmp_i1_unsigned_const(i1 %a) nounwind {
250 entry:
251 ; CHECK-LABEL: icmp_i1_unsigned_const
252 ; CHECK:       and [[REG0:w[0-9]+]], w0, #0x1
253 ; CHECK-NEXT:  cmp [[REG0]], #0
254 ; CHECK-NEXT:  cset [[REG:w[0-9]+]], lo
255 ; CHECK-NEXT:  and w0, [[REG]], #0x1
256   %cmp = icmp ult i1 %a, 0
257   %conv2 = zext i1 %cmp to i32
258   ret i32 %conv2