[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / ARM / CGP / arm-cgp-icmps.ll
blob76c9746c3556610e48015b69164ea04666498001
1 ; RUN: llc -mtriple=thumbv8m.main -mcpu=cortex-m33 %s -arm-disable-cgp=false -o - | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-NODSP
2 ; RUN: llc -mtriple=thumbv7em %s -arm-disable-cgp=false -arm-enable-scalar-dsp=true -o - | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-DSP
3 ; RUN: llc -mtriple=thumbv8 %s -arm-disable-cgp=false -arm-enable-scalar-dsp=true -arm-enable-scalar-dsp-imms=true -o - | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-DSP-IMM
5 ; CHECK-COMMON-LABEL: test_ult_254_inc_imm:
6 ; CHECK-DSP:        adds    r0, #1
7 ; CHECK-DSP-NEXT:   uxtb    r1, r0
8 ; CHECK-DSP-NEXT:   movs    r0, #47
9 ; CHECK-DSP-NEXT:   cmp     r1, #254
10 ; CHECK-DSP-NEXT:   it      lo
11 ; CHECK-DSP-NEXT:   movlo   r0, #35
13 ; CHECK-DSP-IMM:      movs r1, #1
14 ; CHECK-DSP-IMM-NEXT: uadd8 r1, r0, r1
15 ; CHECK-DSP-IMM-NEXT: movs  r0, #47
16 ; CHECK-DSP-IMM-NEXT: cmp r1, #254
17 ; CHECK-DSP-IMM-NEXT: it  lo
18 ; CHECK-DSP-IMM-NEXT: movlo r0, #35
19 define i32 @test_ult_254_inc_imm(i8 zeroext %x) {
20 entry:
21   %add = add i8 %x, 1
22   %cmp = icmp ult i8 %add, 254
23   %res = select i1 %cmp, i32 35, i32 47
24   ret i32 %res
27 ; CHECK-COMMON-LABEL: test_slt_254_inc_imm
28 ; CHECK-COMMON: adds
29 ; CHECK-COMMON: sxtb
30 define i32 @test_slt_254_inc_imm(i8 signext %x) {
31 entry:
32   %add = add i8 %x, 1
33   %cmp = icmp slt i8 %add, 254
34   %res = select i1 %cmp, i32 35, i32 47
35   ret i32 %res
38 ; CHECK-COMMON-LABEL: test_ult_254_inc_var:
39 ; CHECK-NODSP:      add     r0, r1
40 ; CHECK-NODSP-NEXT: uxtb    r1, r0
41 ; CHECK-NODSP-NEXT: movs    r0, #47
42 ; CHECK-NODSP-NEXT: cmp     r1, #254
43 ; CHECK-NODSP-NEXT: it      lo
44 ; CHECK-NODSP-NEXT: movlo   r0, #35
46 ; CHECK-DSP:        uadd8   r1, r0, r1
47 ; CHECK-DSP-NEXT:   movs    r0, #47
48 ; CHECK-DSP-NEXT:   cmp     r1, #254
49 ; CHECK-DSP-NEXT:   it      lo
50 ; CHECK-DSP-NEXT:   movlo   r0, #35
51 define i32 @test_ult_254_inc_var(i8 zeroext %x, i8 zeroext %y) {
52 entry:
53   %add = add i8 %x, %y
54   %cmp = icmp ult i8 %add, 254
55   %res = select i1 %cmp, i32 35, i32 47
56   ret i32 %res
59 ; CHECK-COMMON-LABEL: test_sle_254_inc_var
60 ; CHECK-COMMON: add
61 ; CHECK-COMMON: sxtb
62 ; CHECK-COMMON: cmp
63 define i32 @test_sle_254_inc_var(i8 %x, i8 %y) {
64 entry:
65   %add = add i8 %x, %y
66   %cmp = icmp sle i8 %add, 254
67   %res = select i1 %cmp, i32 35, i32 47
68   ret i32 %res
71 ; CHECK-COMMON-LABEL: test_ugt_1_dec_imm:
72 ; CHECK-COMMON:      subs    r1, r0, #1
73 ; CHECK-COMMON-NEXT: movs    r0, #47
74 ; CHECK-COMMON-NEXT: cmp     r1, #1
75 ; CHECK-COMMON-NEXT: it      hi
76 ; CHECK-COMMON-NEXT: movhi   r0, #35
77 define i32 @test_ugt_1_dec_imm(i8 zeroext %x) {
78 entry:
79   %add = add i8 %x, -1
80   %cmp = icmp ugt i8 %add, 1
81   %res = select i1 %cmp, i32 35, i32 47
82   ret i32 %res
85 ; CHECK-COMMON-LABEL: test_sgt_1_dec_imm
86 ; CHECK-COMMON: subs
87 ; CHECK-COMMON: sxtb
88 ; CHECK-COMMON: cmp
89 define i32 @test_sgt_1_dec_imm(i8 %x) {
90 entry:
91   %add = add i8 %x, -1
92   %cmp = icmp sgt i8 %add, 1
93   %res = select i1 %cmp, i32 35, i32 47
94   ret i32 %res
97 ; CHECK-COMMON-LABEL: test_ugt_1_dec_var:
98 ; CHECK-NODSP:      subs    r0, r0, r1
99 ; CHECK-NODSP-NEXT: uxtb    r1, r0
100 ; CHECK-NODSP-NEXT: movs    r0, #47
101 ; CHECK-NODSP-NEXT: cmp     r1, #1
102 ; CHECK-NODSP-NEXT: it      hi
103 ; CHECK-NODSP-NEXT: movhi   r0, #35
105 ; CHECK-DSP:      usub8   r1, r0, r1
106 ; CHECK-DSP-NEXT: movs    r0, #47
107 ; CHECK-DSP-NEXT: cmp     r1, #1
108 ; CHECK-DSP-NEXT: it      hi
109 ; CHECK-DSP-NEXT: movhi   r0, #35
110 define i32 @test_ugt_1_dec_var(i8 zeroext %x, i8 zeroext %y) {
111 entry:
112   %sub = sub i8 %x, %y
113   %cmp = icmp ugt i8 %sub, 1
114   %res = select i1 %cmp, i32 35, i32 47
115   ret i32 %res
118 ; CHECK-COMMON-LABEL: test_sge_1_dec_var
119 ; CHECK-COMMON: sub
120 ; CHECK-COMMON: sxtb
121 ; CHECK-COMMON: cmp
122 define i32 @test_sge_1_dec_var(i8 %x, i8 %y) {
123 entry:
124   %sub = sub i8 %x, %y
125   %cmp = icmp sge i8 %sub, 1
126   %res = select i1 %cmp, i32 35, i32 47
127   ret i32 %res
130 ; CHECK-COMMON-LABEL: dsp_imm1:
131 ; CHECK-DSP:      eors    r1, r0
132 ; CHECK-DSP-NEXT: and     r0, r0, #7
133 ; CHECK-DSP-NEXT: subs    r0, r0, r1
134 ; CHECK-DSP-NEXT: adds    r0, #1
135 ; CHECK-DSP-NEXT: uxtb    r1, r0
136 ; CHECK-DSP-NEXT: movs    r0, #47
137 ; CHECK-DSP-NEXT: cmp     r1, #254
138 ; CHECK-DSP-NEXT: it      lo
139 ; CHECK-DSP-NEXT: movlo   r0, #35
141 ; CHECK-DSP-IMM:      eors    r1, r0
142 ; CHECK-DSP-IMM-NEXT: and     r0, r0, #7
143 ; CHECK-DSP-IMM-NEXT: usub8   r0, r0, r1
144 ; CHECK-DSP-IMM-NEXT: movs    r1, #1
145 ; CHECK-DSP-IMM-NEXT: uadd8   r1, r0, r1
146 ; CHECK-DSP-IMM-NEXT: movs    r0, #47
147 ; CHECK-DSP-IMM-NEXT: cmp     r1, #254
148 ; CHECK-DSP-IMM-NEXT: it      lo
149 ; CHECK-DSP-IMM-NEXT: movlo   r0, #35
150 define i32 @dsp_imm1(i8 zeroext %x, i8 zeroext %y) {
151 entry:
152   %xor = xor i8 %x, %y
153   %and = and i8 %x, 7
154   %sub = sub i8 %and, %xor
155   %add = add i8 %sub, 1
156   %cmp = icmp ult i8 %add, 254
157   %res = select i1 %cmp, i32 35, i32 47
158   ret i32 %res
161 ; CHECK-COMMON-LABEL: dsp_var:
162 ; CHECK-COMMON:   eors    r1, r0
163 ; CHECK-COMMON:   and     r2, r0, #7
164 ; CHECK-NODSP:    subs    r1, r2, r1
165 ; CHECK-NODSP:    add.w   r0, r1, r0, lsl #1
166 ; CHECK-NODSP:    uxtb    r1, r0
167 ; CHECK-DSP:      usub8   r1, r2, r1
168 ; CHECK-DSP:      lsls    r0, r0, #1
169 ; CHECK-DSP:      uadd8   r1, r1, r0
170 ; CHECK-DSP-NOT:  uxt
171 ; CHECK-COMMON:   movs    r0, #47
172 ; CHECK-COMMON:   cmp     r1, #254
173 ; CHECK-COMMON:   it      lo
174 ; CHECK-COMMON:   movlo   r0, #35
175 define i32 @dsp_var(i8 zeroext %x, i8 zeroext %y) {
176   %xor = xor i8 %x, %y
177   %and = and i8 %x, 7
178   %sub = sub i8 %and, %xor
179   %mul = shl nuw i8 %x, 1
180   %add = add i8 %sub, %mul
181   %cmp = icmp ult i8 %add, 254
182   %res = select i1 %cmp, i32 35, i32 47
183   ret i32 %res
186 ; CHECK-COMMON-LABEL: store_dsp_res
187 ; CHECK-DSP: usub8 
188 ; CHECK-DSP: strb
189 define void @store_dsp_res(i8* %in, i8* %out, i8 %compare) {
190   %first = getelementptr inbounds i8, i8* %in, i32 0
191   %second = getelementptr inbounds i8, i8* %in, i32 1
192   %ld0 = load i8, i8* %first
193   %ld1 = load i8, i8* %second
194   %xor = xor i8 %ld0, -1
195   %cmp = icmp ult i8 %compare, %ld1
196   %select = select i1 %cmp, i8 %compare, i8 %xor
197   %sub = sub i8 %ld0, %select
198   store i8 %sub, i8* %out, align 1
199   ret void
202 ; CHECK-COMMON-LABEL: ugt_1_dec_imm:
203 ; CHECK-COMMON:      subs    r1, r0, #1
204 ; CHECK-COMMON-NEXT: movs    r0, #47
205 ; CHECK-COMMON-NEXT: cmp     r1, #1
206 ; CHECK-COMMON-NEXT: it      hi
207 ; CHECK-COMMON-NEXT: movhi   r0, #35
208 define i32 @ugt_1_dec_imm(i8 zeroext %x) {
209 entry:
210   %add = add i8 %x, -1
211   %cmp = icmp ugt i8 %add, 1
212   %res = select i1 %cmp, i32 35, i32 47
213   ret i32 %res
216 ; CHECK-COMMON-LABEL: ugt_1_dec_var:
217 ; CHECK-NODSP:      subs    r0, r0, r1
218 ; CHECK-NODSP-NEXT: uxtb    r1, r0
219 ; CHECK-NODSP-NEXT: movs    r0, #47
220 ; CHECK-NODSP-NEXT: cmp     r1, #1
221 ; CHECK-NODSP-NEXT: it      hi
222 ; CHECK-NODSP-NEXT: movhi   r0, #35
224 ; CHECK-DSP:      usub8   r1, r0, r1
225 ; CHECK-DSP-NEXT: movs    r0, #47
226 ; CHECK-DSP-NEXT: cmp     r1, #1
227 ; CHECK-DSP-NEXT: it      hi
228 ; CHECK-DSP-NEXT: movhi   r0, #35
229 define i32 @ugt_1_dec_var(i8 zeroext %x, i8 zeroext %y) {
230 entry:
231   %sub = sub i8 %x, %y
232   %cmp = icmp ugt i8 %sub, 1
233   %res = select i1 %cmp, i32 35, i32 47
234   ret i32 %res
237 ; CHECK-COMMON-LABEL: icmp_eq_minus_one
238 ; CHECK-COMMON: cmp {{r[0-9]+}}, #255
239 define i32 @icmp_eq_minus_one(i8* %ptr) {
240   %load = load i8, i8* %ptr, align 1
241   %conv = zext i8 %load to i32
242   %cmp = icmp eq i8 %load, -1
243   %ret = select i1 %cmp, i32 %conv, i32 -1
244   ret i32 %ret
247 ; CHECK-COMMON-LABEL: icmp_not
248 ; CHECK-COMMON: movw r2, #65535
249 ; CHECK-COMMON: eors r2, r0
250 ; CHECK-COMMON: movs r0, #32
251 ; CHECK-COMMON: cmp r2, r1
252 define i32 @icmp_not(i16 zeroext %arg0, i16 zeroext %arg1) {
253   %not = xor i16 %arg0, -1
254   %cmp = icmp eq i16 %not, %arg1
255   %res = select i1 %cmp, i32 16, i32 32
256   ret i32 %res
259 ; CHECK-COMMON-LABEL: icmp_i1
260 ; CHECK-NOT: uxt
261 define i32 @icmp_i1(i1* %arg0, i1 zeroext %arg1, i32 %a, i32 %b) {
262 entry:
263   %load = load i1, i1* %arg0
264   %not = xor i1 %load, 1
265   %cmp = icmp eq i1 %arg1, %not
266   %res = select i1 %cmp, i32 %a, i32 %b
267   ret i32 %res
270 ; CHECK-COMMON-LABEL: icmp_i7
271 ; CHECK-COMMON: ldrb
272 ; CHECK-COMMON: cmp
273 define i32 @icmp_i7(i7* %arg0, i7 zeroext %arg1, i32 %a, i32 %b) {
274 entry:
275   %load = load i7, i7* %arg0
276   %add = add nuw i7 %load, 1
277   %cmp = icmp ult i7 %arg1, %add
278   %res = select i1 %cmp, i32 %a, i32 %b
279   ret i32 %res
282 ; CHECK-COMMON-LABEL: icmp_i15
283 ; CHECK-COMMON: movw [[MINUS_ONE:r[0-9]+]], #32767
284 define i32 @icmp_i15(i15 zeroext %arg0, i15 zeroext %arg1) {
285   %xor = xor i15 %arg0, -1
286   %cmp = icmp eq i15 %xor, %arg1
287   %res = select i1 %cmp, i32 21, i32 42
288   ret i32 %res
291 ; CHECK-COMMON-LABEL: icmp_minus_imm
292 ; CHECK-NODSP: subs [[SUB:r[0-9]+]],
293 ; CHECK-NODSP: uxtb [[UXT:r[0-9]+]],
294 ; CHECK-NODSP: cmp [[UXT]], #251
296 ; CHECK-DSP: subs [[SUB:r[0-9]+]],
297 ; CHECK-DSP: uxtb [[UXT:r[0-9]+]],
298 ; CHECK-DSP: cmp [[UXT]], #251
300 ; CHECK-DSP-IMM: ldrb [[A:r[0-9]+]],
301 ; CHECK-DSP-IMM: movs  [[MINUS_7:r[0-9]+]], #249
302 ; CHECK-DSP-IMM: uadd8 [[RES:r[0-9]+]], [[A]], [[MINUS_7]]
303 ; CHECK-DSP-IMM: cmp [[RES]], #251
304 define i32 @icmp_minus_imm(i8* %a) {
305 entry:
306   %0 = load i8, i8* %a, align 1
307   %add.i = add i8 %0, -7
308   %cmp = icmp ugt i8 %add.i, -5
309   %conv1 = zext i1 %cmp to i32
310   ret i32 %conv1
313 ; CHECK-COMMON-LABEL: mul_with_neg_imm
314 ; CHECK-COMMON-NOT: uxtb
315 ; CHECK-COMMON:     and [[BIT0:r[0-9]+]], r0, #1
316 ; CHECK-COMMON:     add.w [[MUL32:r[0-9]+]], [[BIT0]], [[BIT0]], lsl #5
317 ; CHECK-COMMON:     cmp.w r0, [[MUL32]], lsl #2
318 define void @mul_with_neg_imm(i32, i32* %b) {
319 entry:
320   %1 = trunc i32 %0 to i8
321   %2 = and i8 %1, 1
322   %conv.i = mul nuw i8 %2, -124
323   %tobool = icmp eq i8 %conv.i, 0
324   br i1 %tobool, label %if.end, label %if.then
326 if.then:
327   store i32 0, i32* %b, align 4
328   br label %if.end
330 if.end:
331   ret void