[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / arm64-csel.ll
blob35051d0c6017e93425e8230f155450252edba23e
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -debugify-and-strip-all-safe -O3 < %s | FileCheck %s
3 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32:64"
4 target triple = "arm64-unknown-unknown"
6 define i32 @foo1(i32 %b, i32 %c) nounwind readnone ssp {
7 ; CHECK-LABEL: foo1:
8 ; CHECK:       // %bb.0: // %entry
9 ; CHECK-NEXT:    cmp w1, #0
10 ; CHECK-NEXT:    add w8, w1, w0
11 ; CHECK-NEXT:    cinc w0, w8, ne
12 ; CHECK-NEXT:    ret
13 entry:
14   %not.tobool = icmp ne i32 %c, 0
15   %add = zext i1 %not.tobool to i32
16   %b.add = add i32 %c, %b
17   %add1 = add i32 %b.add, %add
18   ret i32 %add1
21 define i32 @foo2(i32 %b, i32 %c) nounwind readnone ssp {
22 ; CHECK-LABEL: foo2:
23 ; CHECK:       // %bb.0: // %entry
24 ; CHECK-NEXT:    cmp w1, #0
25 ; CHECK-NEXT:    cneg w8, w0, ne
26 ; CHECK-NEXT:    add w0, w8, w1
27 ; CHECK-NEXT:    ret
28 entry:
29   %mul = sub i32 0, %b
30   %tobool = icmp eq i32 %c, 0
31   %b.mul = select i1 %tobool, i32 %b, i32 %mul
32   %add = add nsw i32 %b.mul, %c
33   ret i32 %add
36 define i32 @foo3(i32 %b, i32 %c) nounwind readnone ssp {
37 ; CHECK-LABEL: foo3:
38 ; CHECK:       // %bb.0: // %entry
39 ; CHECK-NEXT:    cmp w1, #0
40 ; CHECK-NEXT:    cinv w8, w0, ne
41 ; CHECK-NEXT:    add w0, w8, w1
42 ; CHECK-NEXT:    ret
43 entry:
44   %not.tobool = icmp ne i32 %c, 0
45   %xor = sext i1 %not.tobool to i32
46   %b.xor = xor i32 %xor, %b
47   %add = add nsw i32 %b.xor, %c
48   ret i32 %add
51 ; rdar://11632325
52 define i32@foo4(i32 %a) nounwind ssp {
53 ; CHECK-LABEL: foo4:
54 ; CHECK:       // %bb.0:
55 ; CHECK-NEXT:    cmp w0, #0
56 ; CHECK-NEXT:    cneg w0, w0, mi
57 ; CHECK-NEXT:    ret
58   %cmp = icmp sgt i32 %a, -1
59   %neg = sub nsw i32 0, %a
60   %cond = select i1 %cmp, i32 %a, i32 %neg
61   ret i32 %cond
64 define i32@foo5(i32 %a, i32 %b) nounwind ssp {
65 ; CHECK-LABEL: foo5:
66 ; CHECK:       // %bb.0: // %entry
67 ; CHECK-NEXT:    subs w8, w0, w1
68 ; CHECK-NEXT:    cneg w0, w8, mi
69 ; CHECK-NEXT:    ret
70 entry:
71   %sub = sub nsw i32 %a, %b
72   %cmp = icmp sgt i32 %sub, -1
73   %sub3 = sub nsw i32 0, %sub
74   %cond = select i1 %cmp, i32 %sub, i32 %sub3
75   ret i32 %cond
78 ; make sure we can handle branch instruction in optimizeCompare.
79 define i32@foo6(i32 %a, i32 %b) nounwind ssp {
80 ; CHECK-LABEL: foo6:
81 ; CHECK:       // %bb.0: // %common.ret
82 ; CHECK-NEXT:    subs w8, w0, w1
83 ; CHECK-NEXT:    csinc w0, w8, wzr, le
84 ; CHECK-NEXT:    ret
85   %sub = sub nsw i32 %a, %b
86   %cmp = icmp sgt i32 %sub, 0
87   br i1 %cmp, label %l.if, label %l.else
89 l.if:
90   ret i32 1
92 l.else:
93   ret i32 %sub
96 ; If CPSR is used multiple times and V flag is used, we don't remove cmp.
97 define i32 @foo7(i32 %a, i32 %b) nounwind {
98 ; CHECK-LABEL: foo7:
99 ; CHECK:       // %bb.0: // %entry
100 ; CHECK-NEXT:    subs w8, w0, w1
101 ; CHECK-NEXT:    cneg w9, w8, mi
102 ; CHECK-NEXT:    cmn w8, #1
103 ; CHECK-NEXT:    csel w10, w9, w0, lt
104 ; CHECK-NEXT:    cmp w8, #0
105 ; CHECK-NEXT:    csel w0, w10, w9, ge
106 ; CHECK-NEXT:    ret
107 entry:
108   %sub = sub nsw i32 %a, %b
109   %cmp = icmp sgt i32 %sub, -1
110   %sub3 = sub nsw i32 0, %sub
111   %cond = select i1 %cmp, i32 %sub, i32 %sub3
112   br i1 %cmp, label %if.then, label %if.else
114 if.then:
115   %cmp2 = icmp slt i32 %sub, -1
116   %sel = select i1 %cmp2, i32 %cond, i32 %a
117   ret i32 %sel
119 if.else:
120   ret i32 %cond
123 define i32 @foo8(i32 %v, i32 %a, i32 %b) nounwind readnone ssp {
124 ; CHECK-LABEL: foo8:
125 ; CHECK:       // %bb.0: // %entry
126 ; CHECK-NEXT:    cmp w0, #0
127 ; CHECK-NEXT:    csinv w0, w1, w2, ne
128 ; CHECK-NEXT:    ret
129 entry:
130   %tobool = icmp eq i32 %v, 0
131   %neg = xor i32 -1, %b
132   %cond = select i1 %tobool, i32 %neg, i32 %a
133   ret i32 %cond
136 define i32 @foo9(i32 %v) nounwind readnone optsize ssp {
137 ; CHECK-LABEL: foo9:
138 ; CHECK:       // %bb.0: // %entry
139 ; CHECK-NEXT:    mov w8, #4 // =0x4
140 ; CHECK-NEXT:    cmp w0, #0
141 ; CHECK-NEXT:    cinv w0, w8, eq
142 ; CHECK-NEXT:    ret
143 entry:
144   %tobool = icmp ne i32 %v, 0
145   %cond = select i1 %tobool, i32 4, i32 -5
146   ret i32 %cond
149 define i64 @foo10(i64 %v) nounwind readnone optsize ssp {
150 ; CHECK-LABEL: foo10:
151 ; CHECK:       // %bb.0: // %entry
152 ; CHECK-NEXT:    mov w8, #4 // =0x4
153 ; CHECK-NEXT:    cmp x0, #0
154 ; CHECK-NEXT:    cinv x0, x8, eq
155 ; CHECK-NEXT:    ret
156 entry:
157   %tobool = icmp ne i64 %v, 0
158   %cond = select i1 %tobool, i64 4, i64 -5
159   ret i64 %cond
162 define i32 @foo11(i32 %v) nounwind readnone optsize ssp {
163 ; CHECK-LABEL: foo11:
164 ; CHECK:       // %bb.0: // %entry
165 ; CHECK-NEXT:    mov w8, #4 // =0x4
166 ; CHECK-NEXT:    cmp w0, #0
167 ; CHECK-NEXT:    cneg w0, w8, eq
168 ; CHECK-NEXT:    ret
169 entry:
170   %tobool = icmp ne i32 %v, 0
171   %cond = select i1 %tobool, i32 4, i32 -4
172   ret i32 %cond
175 define i64 @foo12(i64 %v) nounwind readnone optsize ssp {
176 ; CHECK-LABEL: foo12:
177 ; CHECK:       // %bb.0: // %entry
178 ; CHECK-NEXT:    mov w8, #4 // =0x4
179 ; CHECK-NEXT:    cmp x0, #0
180 ; CHECK-NEXT:    cneg x0, x8, eq
181 ; CHECK-NEXT:    ret
182 entry:
183   %tobool = icmp ne i64 %v, 0
184   %cond = select i1 %tobool, i64 4, i64 -4
185   ret i64 %cond
188 define i32 @foo13(i32 %v, i32 %a, i32 %b) nounwind readnone optsize ssp {
189 ; CHECK-LABEL: foo13:
190 ; CHECK:       // %bb.0: // %entry
191 ; CHECK-NEXT:    cmp w0, #0
192 ; CHECK-NEXT:    csneg w0, w1, w2, ne
193 ; CHECK-NEXT:    ret
194 entry:
195   %tobool = icmp eq i32 %v, 0
196   %sub = sub i32 0, %b
197   %cond = select i1 %tobool, i32 %sub, i32 %a
198   ret i32 %cond
201 define i64 @foo14(i64 %v, i64 %a, i64 %b) nounwind readnone optsize ssp {
202 ; CHECK-LABEL: foo14:
203 ; CHECK:       // %bb.0: // %entry
204 ; CHECK-NEXT:    cmp x0, #0
205 ; CHECK-NEXT:    csneg x0, x1, x2, ne
206 ; CHECK-NEXT:    ret
207 entry:
208   %tobool = icmp eq i64 %v, 0
209   %sub = sub i64 0, %b
210   %cond = select i1 %tobool, i64 %sub, i64 %a
211   ret i64 %cond
214 define i32 @foo15(i32 %a, i32 %b) nounwind readnone optsize ssp {
215 ; CHECK-LABEL: foo15:
216 ; CHECK:       // %bb.0: // %entry
217 ; CHECK-NEXT:    mov w8, #1 // =0x1
218 ; CHECK-NEXT:    cmp w0, w1
219 ; CHECK-NEXT:    cinc w0, w8, gt
220 ; CHECK-NEXT:    ret
221 entry:
222   %cmp = icmp sgt i32 %a, %b
223   %. = select i1 %cmp, i32 2, i32 1
224   ret i32 %.
227 define i32 @foo16(i32 %a, i32 %b) nounwind readnone optsize ssp {
228 ; CHECK-LABEL: foo16:
229 ; CHECK:       // %bb.0: // %entry
230 ; CHECK-NEXT:    mov w8, #1 // =0x1
231 ; CHECK-NEXT:    cmp w0, w1
232 ; CHECK-NEXT:    cinc w0, w8, le
233 ; CHECK-NEXT:    ret
234 entry:
235   %cmp = icmp sgt i32 %a, %b
236   %. = select i1 %cmp, i32 1, i32 2
237   ret i32 %.
240 define i64 @foo17(i64 %a, i64 %b) nounwind readnone optsize ssp {
241 ; CHECK-LABEL: foo17:
242 ; CHECK:       // %bb.0: // %entry
243 ; CHECK-NEXT:    mov w8, #1 // =0x1
244 ; CHECK-NEXT:    cmp x0, x1
245 ; CHECK-NEXT:    cinc x0, x8, gt
246 ; CHECK-NEXT:    ret
247 entry:
248   %cmp = icmp sgt i64 %a, %b
249   %. = select i1 %cmp, i64 2, i64 1
250   ret i64 %.
253 define i64 @foo18(i64 %a, i64 %b) nounwind readnone optsize ssp {
254 ; CHECK-LABEL: foo18:
255 ; CHECK:       // %bb.0: // %entry
256 ; CHECK-NEXT:    mov w8, #1 // =0x1
257 ; CHECK-NEXT:    cmp x0, x1
258 ; CHECK-NEXT:    cinc x0, x8, le
259 ; CHECK-NEXT:    ret
260 entry:
261   %cmp = icmp sgt i64 %a, %b
262   %. = select i1 %cmp, i64 1, i64 2
263   ret i64 %.
266 ; Regression test for TrueVal + 1 overflow
267 define i64 @foo18_overflow1(i64 %a, i64 %b) nounwind readnone optsize ssp {
268 ; CHECK-LABEL: foo18_overflow1:
269 ; CHECK:       // %bb.0: // %entry
270 ; CHECK-NEXT:    mov x8, #9223372036854775807 // =0x7fffffffffffffff
271 ; CHECK-NEXT:    cmp x0, x1
272 ; CHECK-NEXT:    csel x0, x8, xzr, gt
273 ; CHECK-NEXT:    ret
274 entry:
275   %cmp = icmp sgt i64 %a, %b
276   %. = select i1 %cmp, i64 9223372036854775807, i64 0
277   ret i64 %.
280 ; Regression test for FalseVal + 1 overflow
281 define i64 @foo18_overflow2(i64 %a, i64 %b) nounwind readnone optsize ssp {
282 ; CHECK-LABEL: foo18_overflow2:
283 ; CHECK:       // %bb.0: // %entry
284 ; CHECK-NEXT:    mov x8, #9223372036854775807 // =0x7fffffffffffffff
285 ; CHECK-NEXT:    cmp x0, x1
286 ; CHECK-NEXT:    csel x0, xzr, x8, gt
287 ; CHECK-NEXT:    ret
288 entry:
289   %cmp = icmp sgt i64 %a, %b
290   %. = select i1 %cmp, i64 0, i64 9223372036854775807
291   ret i64 %.
294 ; Regression test for FalseVal - TrueVal overflow
295 define i64 @foo18_overflow3(i1 %cmp) nounwind readnone optsize ssp {
296 ; CHECK-LABEL: foo18_overflow3:
297 ; CHECK:       // %bb.0: // %entry
298 ; CHECK-NEXT:    mov x8, #-9223372036854775808 // =0x8000000000000000
299 ; CHECK-NEXT:    tst w0, #0x1
300 ; CHECK-NEXT:    csel x0, x8, xzr, ne
301 ; CHECK-NEXT:    ret
302 entry:
303   %. = select i1 %cmp, i64 -9223372036854775808, i64 0
304   ret i64 %.
307 ; Regression test for TrueVal - FalseVal overflow
308 define i64 @foo18_overflow4(i1 %cmp) nounwind readnone optsize ssp {
309 ; CHECK-LABEL: foo18_overflow4:
310 ; CHECK:       // %bb.0: // %entry
311 ; CHECK-NEXT:    mov x8, #-9223372036854775808 // =0x8000000000000000
312 ; CHECK-NEXT:    tst w0, #0x1
313 ; CHECK-NEXT:    csel x0, xzr, x8, ne
314 ; CHECK-NEXT:    ret
315 entry:
316   %. = select i1 %cmp, i64 0, i64 -9223372036854775808
317   ret i64 %.
320 define i64 @foo19(i64 %a, i64 %b, i64 %c) {
321 ; CHECK-LABEL: foo19:
322 ; CHECK:       // %bb.0: // %entry
323 ; CHECK-NEXT:    cmp x0, x1
324 ; CHECK-NEXT:    cinc x0, x2, lo
325 ; CHECK-NEXT:    ret
326 entry:
327   %cmp = icmp ult i64 %a, %b
328   %inc = zext i1 %cmp to i64
329   %inc.c = add i64 %inc, %c
330   ret i64 %inc.c
333 define i32 @foo20(i32 %x) {
334 ; CHECK-LABEL: foo20:
335 ; CHECK:       // %bb.0:
336 ; CHECK-NEXT:    mov w8, #6 // =0x6
337 ; CHECK-NEXT:    cmp w0, #5
338 ; CHECK-NEXT:    csinc w0, w8, wzr, eq
339 ; CHECK-NEXT:    ret
340   %cmp = icmp eq i32 %x, 5
341   %res = select i1 %cmp, i32 6, i32 1
342   ret i32 %res
345 define i64 @foo21(i64 %x) {
346 ; CHECK-LABEL: foo21:
347 ; CHECK:       // %bb.0:
348 ; CHECK-NEXT:    mov w8, #6 // =0x6
349 ; CHECK-NEXT:    cmp x0, #5
350 ; CHECK-NEXT:    csinc x0, x8, xzr, eq
351 ; CHECK-NEXT:    ret
352   %cmp = icmp eq i64 %x, 5
353   %res = select i1 %cmp, i64 6, i64 1
354   ret i64 %res
357 define i32 @foo22(i32 %x) {
358 ; CHECK-LABEL: foo22:
359 ; CHECK:       // %bb.0:
360 ; CHECK-NEXT:    mov w8, #6 // =0x6
361 ; CHECK-NEXT:    cmp w0, #5
362 ; CHECK-NEXT:    csinc w0, w8, wzr, ne
363 ; CHECK-NEXT:    ret
364   %cmp = icmp eq i32 %x, 5
365   %res = select i1 %cmp, i32 1, i32 6
366   ret i32 %res
369 define i64 @foo23(i64 %x) {
370 ; CHECK-LABEL: foo23:
371 ; CHECK:       // %bb.0:
372 ; CHECK-NEXT:    mov w8, #6 // =0x6
373 ; CHECK-NEXT:    cmp x0, #5
374 ; CHECK-NEXT:    csinc x0, x8, xzr, ne
375 ; CHECK-NEXT:    ret
376   %cmp = icmp eq i64 %x, 5
377   %res = select i1 %cmp, i64 1, i64 6
378   ret i64 %res
381 define i16 @foo24(ptr nocapture readonly %A, ptr nocapture readonly %B) {
382 ; CHECK-LABEL: foo24:
383 ; CHECK:       // %bb.0: // %entry
384 ; CHECK-NEXT:    ldrb w8, [x0]
385 ; CHECK-NEXT:    ldrb w9, [x1]
386 ; CHECK-NEXT:    cmp w8, #3
387 ; CHECK-NEXT:    cset w8, hi
388 ; CHECK-NEXT:    cmp w9, #33
389 ; CHECK-NEXT:    cinc w0, w8, hi
390 ; CHECK-NEXT:    ret
391 entry:
392   %0 = load i8, ptr %A, align 1
393   %cmp = icmp ugt i8 %0, 3
394   %conv1 = zext i1 %cmp to i16
395   %1 = load i8, ptr %B, align 1
396   %cmp4 = icmp ugt i8 %1, 33
397   %conv5 = zext i1 %cmp4 to i16
398   %add = add nuw nsw i16 %conv5, %conv1
399   ret i16 %add
402 define i64 @foo25(ptr nocapture readonly %A, ptr nocapture readonly %B) {
403 ; CHECK-LABEL: foo25:
404 ; CHECK:       // %bb.0: // %entry
405 ; CHECK-NEXT:    ldr x8, [x1]
406 ; CHECK-NEXT:    ldr x9, [x0]
407 ; CHECK-NEXT:    cmp x8, #33
408 ; CHECK-NEXT:    cset w8, hi
409 ; CHECK-NEXT:    cmp x9, #3
410 ; CHECK-NEXT:    cinc x0, x8, hi
411 ; CHECK-NEXT:    ret
412 entry:
413   %0 = load i64, ptr %A, align 1
414   %cmp = icmp ugt i64 %0, 3
415   %conv1 = zext i1 %cmp to i64
416   %1 = load i64, ptr %B, align 1
417   %cmp4 = icmp ugt i64 %1, 33
418   %conv5 = zext i1 %cmp4 to i64
419   %add = add nuw nsw i64 %conv5, %conv1
420   ret i64 %add