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 {
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
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
21 define i32 @foo2(i32 %b, i32 %c) nounwind readnone ssp {
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
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
36 define i32 @foo3(i32 %b, i32 %c) nounwind readnone ssp {
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
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
52 define i32@foo4(i32 %a) nounwind ssp {
55 ; CHECK-NEXT: cmp w0, #0
56 ; CHECK-NEXT: cneg w0, w0, mi
58 %cmp = icmp sgt i32 %a, -1
59 %neg = sub nsw i32 0, %a
60 %cond = select i1 %cmp, i32 %a, i32 %neg
64 define i32@foo5(i32 %a, i32 %b) nounwind ssp {
66 ; CHECK: // %bb.0: // %entry
67 ; CHECK-NEXT: subs w8, w0, w1
68 ; CHECK-NEXT: cneg w0, w8, mi
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
78 ; make sure we can handle branch instruction in optimizeCompare.
79 define i32@foo6(i32 %a, i32 %b) nounwind ssp {
81 ; CHECK: // %bb.0: // %common.ret
82 ; CHECK-NEXT: subs w8, w0, w1
83 ; CHECK-NEXT: csinc w0, w8, wzr, le
85 %sub = sub nsw i32 %a, %b
86 %cmp = icmp sgt i32 %sub, 0
87 br i1 %cmp, label %l.if, label %l.else
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 {
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
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
115 %cmp2 = icmp slt i32 %sub, -1
116 %sel = select i1 %cmp2, i32 %cond, i32 %a
123 define i32 @foo8(i32 %v, i32 %a, i32 %b) nounwind readnone ssp {
125 ; CHECK: // %bb.0: // %entry
126 ; CHECK-NEXT: cmp w0, #0
127 ; CHECK-NEXT: csinv w0, w1, w2, ne
130 %tobool = icmp eq i32 %v, 0
131 %neg = xor i32 -1, %b
132 %cond = select i1 %tobool, i32 %neg, i32 %a
136 define i32 @foo9(i32 %v) nounwind readnone optsize ssp {
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
144 %tobool = icmp ne i32 %v, 0
145 %cond = select i1 %tobool, i32 4, i32 -5
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
157 %tobool = icmp ne i64 %v, 0
158 %cond = select i1 %tobool, i64 4, i64 -5
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
170 %tobool = icmp ne i32 %v, 0
171 %cond = select i1 %tobool, i32 4, i32 -4
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
183 %tobool = icmp ne i64 %v, 0
184 %cond = select i1 %tobool, i64 4, i64 -4
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
195 %tobool = icmp eq i32 %v, 0
197 %cond = select i1 %tobool, i32 %sub, i32 %a
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
208 %tobool = icmp eq i64 %v, 0
210 %cond = select i1 %tobool, i64 %sub, i64 %a
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
222 %cmp = icmp sgt i32 %a, %b
223 %. = select i1 %cmp, i32 2, i32 1
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
235 %cmp = icmp sgt i32 %a, %b
236 %. = select i1 %cmp, i32 1, i32 2
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
248 %cmp = icmp sgt i64 %a, %b
249 %. = select i1 %cmp, i64 2, i64 1
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
261 %cmp = icmp sgt i64 %a, %b
262 %. = select i1 %cmp, i64 1, i64 2
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
275 %cmp = icmp sgt i64 %a, %b
276 %. = select i1 %cmp, i64 9223372036854775807, i64 0
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
289 %cmp = icmp sgt i64 %a, %b
290 %. = select i1 %cmp, i64 0, i64 9223372036854775807
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
303 %. = select i1 %cmp, i64 -9223372036854775808, i64 0
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
316 %. = select i1 %cmp, i64 0, i64 -9223372036854775808
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
327 %cmp = icmp ult i64 %a, %b
328 %inc = zext i1 %cmp to i64
329 %inc.c = add i64 %inc, %c
333 define i32 @foo20(i32 %x) {
334 ; CHECK-LABEL: foo20:
336 ; CHECK-NEXT: mov w8, #6 // =0x6
337 ; CHECK-NEXT: cmp w0, #5
338 ; CHECK-NEXT: csinc w0, w8, wzr, eq
340 %cmp = icmp eq i32 %x, 5
341 %res = select i1 %cmp, i32 6, i32 1
345 define i64 @foo21(i64 %x) {
346 ; CHECK-LABEL: foo21:
348 ; CHECK-NEXT: mov w8, #6 // =0x6
349 ; CHECK-NEXT: cmp x0, #5
350 ; CHECK-NEXT: csinc x0, x8, xzr, eq
352 %cmp = icmp eq i64 %x, 5
353 %res = select i1 %cmp, i64 6, i64 1
357 define i32 @foo22(i32 %x) {
358 ; CHECK-LABEL: foo22:
360 ; CHECK-NEXT: mov w8, #6 // =0x6
361 ; CHECK-NEXT: cmp w0, #5
362 ; CHECK-NEXT: csinc w0, w8, wzr, ne
364 %cmp = icmp eq i32 %x, 5
365 %res = select i1 %cmp, i32 1, i32 6
369 define i64 @foo23(i64 %x) {
370 ; CHECK-LABEL: foo23:
372 ; CHECK-NEXT: mov w8, #6 // =0x6
373 ; CHECK-NEXT: cmp x0, #5
374 ; CHECK-NEXT: csinc x0, x8, xzr, ne
376 %cmp = icmp eq i64 %x, 5
377 %res = select i1 %cmp, i64 1, i64 6
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
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
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
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