1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2 ; RUN: llc -mtriple=aarch64-unknown-unknown < %s | FileCheck %s
4 declare void @use_i1(i1 %x)
5 declare void @use_i32(i32 %x)
7 ; Based on the IR generated for the `last` method of the type `slice` in Rust
8 define ptr @test_last_elem_from_ptr(ptr noundef readnone %x0, i64 noundef %x1) {
9 ; CHECK-LABEL: test_last_elem_from_ptr:
11 ; CHECK-NEXT: subs x8, x1, #1
12 ; CHECK-NEXT: add x8, x8, x0
13 ; CHECK-NEXT: csel x0, xzr, x8, lo
15 %cmp = icmp eq i64 %x1, 0
16 %add.ptr = getelementptr inbounds nuw i8, ptr %x0, i64 %x1
17 %add.ptr1 = getelementptr inbounds i8, ptr %add.ptr, i64 -1
18 %retval.0 = select i1 %cmp, ptr null, ptr %add.ptr1
22 define i32 @test_eq0_sub_add_i32(i32 %x0, i32 %x1) {
23 ; CHECK-LABEL: test_eq0_sub_add_i32:
25 ; CHECK-NEXT: subs w8, w1, #1
26 ; CHECK-NEXT: add w8, w8, w0
27 ; CHECK-NEXT: csel w0, wzr, w8, lo
29 %cmp = icmp eq i32 %x1, 0
30 %add = add nuw i32 %x0, %x1
31 %sub = sub i32 %add, 1
32 %ret = select i1 %cmp, i32 0, i32 %sub
36 define i32 @test_eq7_sub_add_i32(i32 %x0, i32 %x1) {
37 ; CHECK-LABEL: test_eq7_sub_add_i32:
39 ; CHECK-NEXT: subs w8, w1, #7
40 ; CHECK-NEXT: add w8, w8, w0
41 ; CHECK-NEXT: csel w0, wzr, w8, eq
43 %cmp = icmp eq i32 %x1, 7
44 %add = add nuw i32 %x0, %x1
45 %sub = sub i32 %add, 7
46 %ret = select i1 %cmp, i32 0, i32 %sub
50 define i32 @test_ule7_sub7_add_i32(i32 %x0, i32 %x1) {
51 ; CHECK-LABEL: test_ule7_sub7_add_i32:
53 ; CHECK-NEXT: subs w8, w1, #7
54 ; CHECK-NEXT: add w8, w8, w0
55 ; CHECK-NEXT: csel w0, wzr, w8, ls
57 %cmp = icmp ule i32 %x1, 7
58 %add = add i32 %x0, %x1
59 %sub = sub i32 %add, 7
60 %ret = select i1 %cmp, i32 0, i32 %sub
64 define i32 @test_ule7_sub8_add_i32(i32 %x0, i32 %x1) {
65 ; CHECK-LABEL: test_ule7_sub8_add_i32:
67 ; CHECK-NEXT: subs w8, w1, #8
68 ; CHECK-NEXT: add w8, w8, w0
69 ; CHECK-NEXT: csel w0, wzr, w8, lo
71 %cmp = icmp ule i32 %x1, 7
72 %add = add i32 %x0, %x1
73 %sub = sub i32 %add, 8
74 %ret = select i1 %cmp, i32 0, i32 %sub
78 define i32 @test_ule0_sub1_add_i32(i32 %x0, i32 %x1) {
79 ; CHECK-LABEL: test_ule0_sub1_add_i32:
81 ; CHECK-NEXT: subs w8, w1, #1
82 ; CHECK-NEXT: add w8, w8, w0
83 ; CHECK-NEXT: csel w0, wzr, w8, lo
85 %cmp = icmp ule i32 %x1, 0
86 %add = add i32 %x0, %x1
87 %sub = sub i32 %add, 1
88 %ret = select i1 %cmp, i32 0, i32 %sub
92 define i32 @test_ultminus2_subminus2_add_i32(i32 %x0, i32 %x1) {
93 ; CHECK-LABEL: test_ultminus2_subminus2_add_i32:
95 ; CHECK-NEXT: adds w8, w1, #2
96 ; CHECK-NEXT: add w8, w8, w0
97 ; CHECK-NEXT: csel w0, wzr, w8, lo
99 %cmp = icmp ult i32 %x1, -2
100 %add = add i32 %x0, %x1
101 %sub = sub i32 %add, -2
102 %ret = select i1 %cmp, i32 0, i32 %sub
106 define i32 @test_ultminus2_subminus3_add_i32(i32 %x0, i32 %x1) {
107 ; CHECK-LABEL: test_ultminus2_subminus3_add_i32:
109 ; CHECK-NEXT: adds w8, w1, #3
110 ; CHECK-NEXT: add w8, w8, w0
111 ; CHECK-NEXT: csel w0, wzr, w8, ls
113 %cmp = icmp ult i32 %x1, -2
114 %add = add i32 %x0, %x1
115 %sub = sub i32 %add, -3
116 %ret = select i1 %cmp, i32 0, i32 %sub
120 define i32 @test_ne0_sub_add_i32(i32 %x0, i32 %x1) {
121 ; CHECK-LABEL: test_ne0_sub_add_i32:
123 ; CHECK-NEXT: subs w8, w1, #1
124 ; CHECK-NEXT: add w8, w8, w0
125 ; CHECK-NEXT: csel w0, w8, wzr, hs
127 %cmp = icmp ne i32 %x1, 0
128 %add = add i32 %x0, %x1
129 %sub = sub i32 %add, 1
130 %ret = select i1 %cmp, i32 %sub, i32 0
134 define i32 @test_ne7_sub_add_i32(i32 %x0, i32 %x1) {
135 ; CHECK-LABEL: test_ne7_sub_add_i32:
137 ; CHECK-NEXT: subs w8, w1, #7
138 ; CHECK-NEXT: add w8, w8, w0
139 ; CHECK-NEXT: csel w0, w8, wzr, ne
141 %cmp = icmp ne i32 %x1, 7
142 %add = add i32 %x0, %x1
143 %sub = sub i32 %add, 7
144 %ret = select i1 %cmp, i32 %sub, i32 0
148 define i32 @test_ultminus1_sub_add_i32(i32 %x0, i32 %x1) {
149 ; CHECK-LABEL: test_ultminus1_sub_add_i32:
151 ; CHECK-NEXT: adds w8, w1, #1
152 ; CHECK-NEXT: add w8, w8, w0
153 ; CHECK-NEXT: csel w0, wzr, w8, ne
155 %cmp = icmp ult i32 %x1, -1
156 %add = add i32 %x0, %x1
157 %sub = sub i32 %add, -1
158 %ret = select i1 %cmp, i32 0, i32 %sub
162 define i32 @test_ugt7_sub7_add_i32(i32 %x0, i32 %x1) {
163 ; CHECK-LABEL: test_ugt7_sub7_add_i32:
165 ; CHECK-NEXT: subs w8, w1, #7
166 ; CHECK-NEXT: add w8, w8, w0
167 ; CHECK-NEXT: csel w0, wzr, w8, hi
169 %cmp = icmp ugt i32 %x1, 7
170 %add = add i32 %x0, %x1
171 %sub = sub i32 %add, 7
172 %ret = select i1 %cmp, i32 0, i32 %sub
176 define i32 @test_ugt7_sub8_add_i32(i32 %x0, i32 %x1) {
177 ; CHECK-LABEL: test_ugt7_sub8_add_i32:
179 ; CHECK-NEXT: subs w8, w1, #8
180 ; CHECK-NEXT: add w8, w8, w0
181 ; CHECK-NEXT: csel w0, wzr, w8, hs
183 %cmp = icmp ugt i32 %x1, 7
184 %add = add i32 %x0, %x1
185 %sub = sub i32 %add, 8
186 %ret = select i1 %cmp, i32 0, i32 %sub
190 define i32 @test_sle7_sub7_add_i32(i32 %x0, i32 %x1) {
191 ; CHECK-LABEL: test_sle7_sub7_add_i32:
193 ; CHECK-NEXT: subs w8, w1, #7
194 ; CHECK-NEXT: add w8, w8, w0
195 ; CHECK-NEXT: csel w0, wzr, w8, le
197 %cmp = icmp sle i32 %x1, 7
198 %add = add i32 %x0, %x1
199 %sub = sub i32 %add, 7
200 %ret = select i1 %cmp, i32 0, i32 %sub
204 define i32 @test_sle7_sub8_add_i32(i32 %x0, i32 %x1) {
205 ; CHECK-LABEL: test_sle7_sub8_add_i32:
207 ; CHECK-NEXT: subs w8, w1, #8
208 ; CHECK-NEXT: add w8, w8, w0
209 ; CHECK-NEXT: csel w0, wzr, w8, lt
211 %cmp = icmp sle i32 %x1, 7
212 %add = add i32 %x0, %x1
213 %sub = sub i32 %add, 8
214 %ret = select i1 %cmp, i32 0, i32 %sub
218 define i32 @test_slt8_sub8_add_i32(i32 %x0, i32 %x1) {
219 ; CHECK-LABEL: test_slt8_sub8_add_i32:
221 ; CHECK-NEXT: subs w8, w1, #8
222 ; CHECK-NEXT: add w8, w8, w0
223 ; CHECK-NEXT: csel w0, wzr, w8, lt
225 %cmp = icmp slt i32 %x1, 8
226 %add = add i32 %x0, %x1
227 %sub = sub i32 %add, 8
228 %ret = select i1 %cmp, i32 0, i32 %sub
232 define i32 @test_slt8_sub7_add_i32(i32 %x0, i32 %x1) {
233 ; CHECK-LABEL: test_slt8_sub7_add_i32:
235 ; CHECK-NEXT: subs w8, w1, #7
236 ; CHECK-NEXT: add w8, w8, w0
237 ; CHECK-NEXT: csel w0, wzr, w8, le
239 %cmp = icmp slt i32 %x1, 8
240 %add = add i32 %x0, %x1
241 %sub = sub i32 %add, 7
242 %ret = select i1 %cmp, i32 0, i32 %sub
246 define i32 @test_sltminus8_subminus8_add_i32(i32 %x0, i32 %x1) {
247 ; CHECK-LABEL: test_sltminus8_subminus8_add_i32:
249 ; CHECK-NEXT: adds w8, w1, #8
250 ; CHECK-NEXT: add w8, w8, w0
251 ; CHECK-NEXT: csel w0, wzr, w8, lt
253 %cmp = icmp slt i32 %x1, -8
254 %add = add i32 %x0, %x1
255 %sub = sub i32 %add, -8
256 %ret = select i1 %cmp, i32 0, i32 %sub
260 define i32 @test_sgtminus8_subminus8_add_i32(i32 %x0, i32 %x1) {
261 ; CHECK-LABEL: test_sgtminus8_subminus8_add_i32:
263 ; CHECK-NEXT: adds w8, w1, #8
264 ; CHECK-NEXT: add w8, w8, w0
265 ; CHECK-NEXT: csel w0, wzr, w8, gt
267 %cmp = icmp sgt i32 %x1, -8
268 %add = add i32 %x0, %x1
269 %sub = sub i32 %add, -8
270 %ret = select i1 %cmp, i32 0, i32 %sub
274 define i32 @test_sgtminus8_subminus7_add_i32(i32 %x0, i32 %x1) {
275 ; CHECK-LABEL: test_sgtminus8_subminus7_add_i32:
277 ; CHECK-NEXT: adds w8, w1, #7
278 ; CHECK-NEXT: add w8, w8, w0
279 ; CHECK-NEXT: csel w0, wzr, w8, ge
281 %cmp = icmp sgt i32 %x1, -8
282 %add = add i32 %x0, %x1
283 %sub = sub i32 %add, -7
284 %ret = select i1 %cmp, i32 0, i32 %sub
288 define i32 @test_eq0_sub_addcomm_i32(i32 %x0, i32 %x1) {
289 ; CHECK-LABEL: test_eq0_sub_addcomm_i32:
291 ; CHECK-NEXT: subs w8, w1, #1
292 ; CHECK-NEXT: add w8, w8, w0
293 ; CHECK-NEXT: csel w0, wzr, w8, lo
295 %cmp = icmp eq i32 %x1, 0
296 %add = add i32 %x1, %x0
297 %sub = sub i32 %add, 1
298 %ret = select i1 %cmp, i32 0, i32 %sub
302 define i32 @test_eq0_subcomm_add_i32(i32 %x0, i32 %x1) {
303 ; CHECK-LABEL: test_eq0_subcomm_add_i32:
305 ; CHECK-NEXT: subs w8, w1, #1
306 ; CHECK-NEXT: add w8, w8, w0
307 ; CHECK-NEXT: csel w0, wzr, w8, lo
309 %cmp = icmp eq i32 %x1, 0
310 %add = add i32 %x0, %x1
311 %sub = add i32 -1, %add
312 %ret = select i1 %cmp, i32 0, i32 %sub
316 define i32 @test_eq0_multi_use_sub_i32(i32 %x0, i32 %x1) {
317 ; CHECK-LABEL: test_eq0_multi_use_sub_i32:
319 ; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
320 ; CHECK-NEXT: .cfi_def_cfa_offset 16
321 ; CHECK-NEXT: .cfi_offset w19, -8
322 ; CHECK-NEXT: .cfi_offset w30, -16
323 ; CHECK-NEXT: subs w8, w1, #1
324 ; CHECK-NEXT: add w0, w8, w0
325 ; CHECK-NEXT: csel w19, wzr, w0, lo
326 ; CHECK-NEXT: bl use_i32
327 ; CHECK-NEXT: mov w0, w19
328 ; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
330 %cmp = icmp eq i32 %x1, 0
331 %add = add nuw i32 %x0, %x1
332 %sub = sub i32 %add, 1
333 tail call void @use_i32(i32 %sub)
334 %ret = select i1 %cmp, i32 0, i32 %sub
338 define i32 @test_eq_nonconst_sub_add_i32(i32 %x0, i32 %x1, i32 %x2) {
339 ; CHECK-LABEL: test_eq_nonconst_sub_add_i32:
341 ; CHECK-NEXT: subs w8, w1, w2
342 ; CHECK-NEXT: add w8, w8, w0
343 ; CHECK-NEXT: csel w0, wzr, w8, eq
345 %cmp = icmp eq i32 %x1, %x2
346 %add = add nuw i32 %x0, %x1
347 %sub = sub i32 %add, %x2
348 %ret = select i1 %cmp, i32 0, i32 %sub
352 define i32 @test_ne_nonconst_sub_add_i32(i32 %x0, i32 %x1, i32 %x2) {
353 ; CHECK-LABEL: test_ne_nonconst_sub_add_i32:
355 ; CHECK-NEXT: subs w8, w1, w2
356 ; CHECK-NEXT: add w8, w8, w0
357 ; CHECK-NEXT: csel w0, wzr, w8, ne
359 %cmp = icmp ne i32 %x1, %x2
360 %add = add nuw i32 %x0, %x1
361 %sub = sub i32 %add, %x2
362 %ret = select i1 %cmp, i32 0, i32 %sub
366 define i32 @test_ult_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
367 ; CHECK-LABEL: test_ult_nonconst_i32:
369 ; CHECK-NEXT: subs w8, w1, w2
370 ; CHECK-NEXT: add w8, w8, w0
371 ; CHECK-NEXT: csel w0, wzr, w8, lo
373 %cmp = icmp ult i32 %x1, %x2
374 %add = add i32 %x0, %x1
375 %sub = sub i32 %add, %x2
376 %ret = select i1 %cmp, i32 0, i32 %sub
380 define i32 @test_ule_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
381 ; CHECK-LABEL: test_ule_nonconst_i32:
383 ; CHECK-NEXT: subs w8, w1, w2
384 ; CHECK-NEXT: add w8, w8, w0
385 ; CHECK-NEXT: csel w0, wzr, w8, ls
387 %cmp = icmp ule i32 %x1, %x2
388 %add = add i32 %x0, %x1
389 %sub = sub i32 %add, %x2
390 %ret = select i1 %cmp, i32 0, i32 %sub
394 define i32 @test_ugt_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
395 ; CHECK-LABEL: test_ugt_nonconst_i32:
397 ; CHECK-NEXT: subs w8, w1, w2
398 ; CHECK-NEXT: add w8, w8, w0
399 ; CHECK-NEXT: csel w0, wzr, w8, hi
401 %cmp = icmp ugt i32 %x1, %x2
402 %add = add i32 %x0, %x1
403 %sub = sub i32 %add, %x2
404 %ret = select i1 %cmp, i32 0, i32 %sub
408 define i32 @test_uge_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
409 ; CHECK-LABEL: test_uge_nonconst_i32:
411 ; CHECK-NEXT: subs w8, w1, w2
412 ; CHECK-NEXT: add w8, w8, w0
413 ; CHECK-NEXT: csel w0, wzr, w8, hs
415 %cmp = icmp uge i32 %x1, %x2
416 %add = add i32 %x0, %x1
417 %sub = sub i32 %add, %x2
418 %ret = select i1 %cmp, i32 0, i32 %sub
422 define i32 @test_slt_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
423 ; CHECK-LABEL: test_slt_nonconst_i32:
425 ; CHECK-NEXT: subs w8, w1, w2
426 ; CHECK-NEXT: add w8, w8, w0
427 ; CHECK-NEXT: csel w0, wzr, w8, lt
429 %cmp = icmp slt i32 %x1, %x2
430 %add = add i32 %x0, %x1
431 %sub = sub i32 %add, %x2
432 %ret = select i1 %cmp, i32 0, i32 %sub
436 define i32 @test_sle_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
437 ; CHECK-LABEL: test_sle_nonconst_i32:
439 ; CHECK-NEXT: subs w8, w1, w2
440 ; CHECK-NEXT: add w8, w8, w0
441 ; CHECK-NEXT: csel w0, wzr, w8, le
443 %cmp = icmp sle i32 %x1, %x2
444 %add = add i32 %x0, %x1
445 %sub = sub i32 %add, %x2
446 %ret = select i1 %cmp, i32 0, i32 %sub
450 define i32 @test_sgt_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
451 ; CHECK-LABEL: test_sgt_nonconst_i32:
453 ; CHECK-NEXT: subs w8, w1, w2
454 ; CHECK-NEXT: add w8, w8, w0
455 ; CHECK-NEXT: csel w0, wzr, w8, gt
457 %cmp = icmp sgt i32 %x1, %x2
458 %add = add i32 %x0, %x1
459 %sub = sub i32 %add, %x2
460 %ret = select i1 %cmp, i32 0, i32 %sub
464 define i32 @test_sge_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
465 ; CHECK-LABEL: test_sge_nonconst_i32:
467 ; CHECK-NEXT: subs w8, w1, w2
468 ; CHECK-NEXT: add w8, w8, w0
469 ; CHECK-NEXT: csel w0, wzr, w8, ge
471 %cmp = icmp sge i32 %x1, %x2
472 %add = add i32 %x0, %x1
473 %sub = sub i32 %add, %x2
474 %ret = select i1 %cmp, i32 0, i32 %sub
478 define i64 @test_ult_nonconst_i64(i64 %x0, i64 %x1, i64 %x2) {
479 ; CHECK-LABEL: test_ult_nonconst_i64:
481 ; CHECK-NEXT: subs x8, x1, x2
482 ; CHECK-NEXT: add x8, x8, x0
483 ; CHECK-NEXT: csel x0, xzr, x8, lo
485 %cmp = icmp ult i64 %x1, %x2
486 %add = add i64 %x0, %x1
487 %sub = sub i64 %add, %x2
488 %ret = select i1 %cmp, i64 0, i64 %sub
492 define i32 @test_eq_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
493 ; CHECK-LABEL: test_eq_nonconst_sub_add_comm_i32:
495 ; CHECK-NEXT: subs w8, w1, w2
496 ; CHECK-NEXT: add w8, w8, w0
497 ; CHECK-NEXT: csel w0, wzr, w8, eq
499 %cmp = icmp eq i32 %x2, %x1
500 %add = add nuw i32 %x0, %x1
501 %sub = sub i32 %add, %x2
502 %ret = select i1 %cmp, i32 0, i32 %sub
506 define i32 @test_ne_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
507 ; CHECK-LABEL: test_ne_nonconst_sub_add_comm_i32:
509 ; CHECK-NEXT: subs w8, w1, w2
510 ; CHECK-NEXT: add w8, w8, w0
511 ; CHECK-NEXT: csel w0, wzr, w8, ne
513 %cmp = icmp ne i32 %x2, %x1
514 %add = add nuw i32 %x0, %x1
515 %sub = sub i32 %add, %x2
516 %ret = select i1 %cmp, i32 0, i32 %sub
520 define i32 @test_ult_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
521 ; CHECK-LABEL: test_ult_nonconst_sub_add_comm_i32:
523 ; CHECK-NEXT: subs w8, w1, w2
524 ; CHECK-NEXT: add w8, w8, w0
525 ; CHECK-NEXT: csel w0, wzr, w8, hi
527 %cmp = icmp ult i32 %x2, %x1
528 %add = add nuw i32 %x0, %x1
529 %sub = sub i32 %add, %x2
530 %ret = select i1 %cmp, i32 0, i32 %sub
534 define i32 @test_ule_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
535 ; CHECK-LABEL: test_ule_nonconst_sub_add_comm_i32:
537 ; CHECK-NEXT: subs w8, w1, w2
538 ; CHECK-NEXT: add w8, w8, w0
539 ; CHECK-NEXT: csel w0, wzr, w8, hs
541 %cmp = icmp ule i32 %x2, %x1
542 %add = add nuw i32 %x0, %x1
543 %sub = sub i32 %add, %x2
544 %ret = select i1 %cmp, i32 0, i32 %sub
548 define i32 @test_ugt_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
549 ; CHECK-LABEL: test_ugt_nonconst_sub_add_comm_i32:
551 ; CHECK-NEXT: subs w8, w1, w2
552 ; CHECK-NEXT: add w8, w8, w0
553 ; CHECK-NEXT: csel w0, wzr, w8, lo
555 %cmp = icmp ugt i32 %x2, %x1
556 %add = add nuw i32 %x0, %x1
557 %sub = sub i32 %add, %x2
558 %ret = select i1 %cmp, i32 0, i32 %sub
562 define i32 @test_uge_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
563 ; CHECK-LABEL: test_uge_nonconst_sub_add_comm_i32:
565 ; CHECK-NEXT: subs w8, w1, w2
566 ; CHECK-NEXT: add w8, w8, w0
567 ; CHECK-NEXT: csel w0, wzr, w8, ls
569 %cmp = icmp uge i32 %x2, %x1
570 %add = add nuw i32 %x0, %x1
571 %sub = sub i32 %add, %x2
572 %ret = select i1 %cmp, i32 0, i32 %sub
576 define i32 @test_slt_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
577 ; CHECK-LABEL: test_slt_nonconst_sub_add_comm_i32:
579 ; CHECK-NEXT: subs w8, w1, w2
580 ; CHECK-NEXT: add w8, w8, w0
581 ; CHECK-NEXT: csel w0, wzr, w8, gt
583 %cmp = icmp slt i32 %x2, %x1
584 %add = add nuw i32 %x0, %x1
585 %sub = sub i32 %add, %x2
586 %ret = select i1 %cmp, i32 0, i32 %sub
590 define i32 @test_sle_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
591 ; CHECK-LABEL: test_sle_nonconst_sub_add_comm_i32:
593 ; CHECK-NEXT: subs w8, w1, w2
594 ; CHECK-NEXT: add w8, w8, w0
595 ; CHECK-NEXT: csel w0, wzr, w8, ge
597 %cmp = icmp sle i32 %x2, %x1
598 %add = add nuw i32 %x0, %x1
599 %sub = sub i32 %add, %x2
600 %ret = select i1 %cmp, i32 0, i32 %sub
604 define i32 @test_sgt_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
605 ; CHECK-LABEL: test_sgt_nonconst_sub_add_comm_i32:
607 ; CHECK-NEXT: subs w8, w1, w2
608 ; CHECK-NEXT: add w8, w8, w0
609 ; CHECK-NEXT: csel w0, wzr, w8, lt
611 %cmp = icmp sgt i32 %x2, %x1
612 %add = add nuw i32 %x0, %x1
613 %sub = sub i32 %add, %x2
614 %ret = select i1 %cmp, i32 0, i32 %sub
618 define i32 @test_sge_nonconst_sub_add_comm_i32(i32 %x0, i32 %x1, i32 %x2) {
619 ; CHECK-LABEL: test_sge_nonconst_sub_add_comm_i32:
621 ; CHECK-NEXT: subs w8, w1, w2
622 ; CHECK-NEXT: add w8, w8, w0
623 ; CHECK-NEXT: csel w0, wzr, w8, le
625 %cmp = icmp sge i32 %x2, %x1
626 %add = add nuw i32 %x0, %x1
627 %sub = sub i32 %add, %x2
628 %ret = select i1 %cmp, i32 0, i32 %sub
633 define i32 @test_eq0_multi_use_cmp_i32(i32 %x0, i32 %x1) {
634 ; CHECK-LABEL: test_eq0_multi_use_cmp_i32:
636 ; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
637 ; CHECK-NEXT: .cfi_def_cfa_offset 16
638 ; CHECK-NEXT: .cfi_offset w19, -8
639 ; CHECK-NEXT: .cfi_offset w30, -16
640 ; CHECK-NEXT: add w8, w0, w1
641 ; CHECK-NEXT: cmp w1, #0
642 ; CHECK-NEXT: sub w8, w8, #1
643 ; CHECK-NEXT: cset w0, eq
644 ; CHECK-NEXT: csel w19, wzr, w8, eq
645 ; CHECK-NEXT: bl use_i1
646 ; CHECK-NEXT: mov w0, w19
647 ; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
649 %cmp = icmp eq i32 %x1, 0
650 tail call void @use_i1(i1 %cmp)
651 %add = add nuw i32 %x0, %x1
652 %sub = sub i32 %add, 1
653 %ret = select i1 %cmp, i32 0, i32 %sub
658 define i32 @test_eq0_multi_use_add_i32(i32 %x0, i32 %x1) {
659 ; CHECK-LABEL: test_eq0_multi_use_add_i32:
661 ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
662 ; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
663 ; CHECK-NEXT: .cfi_def_cfa_offset 32
664 ; CHECK-NEXT: .cfi_offset w19, -8
665 ; CHECK-NEXT: .cfi_offset w20, -16
666 ; CHECK-NEXT: .cfi_offset w30, -32
667 ; CHECK-NEXT: add w20, w0, w1
668 ; CHECK-NEXT: mov w19, w1
669 ; CHECK-NEXT: mov w0, w20
670 ; CHECK-NEXT: bl use_i32
671 ; CHECK-NEXT: sub w8, w20, #1
672 ; CHECK-NEXT: cmp w19, #0
673 ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
674 ; CHECK-NEXT: csel w0, wzr, w8, eq
675 ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
677 %cmp = icmp eq i32 %x1, 0
678 %add = add nuw i32 %x0, %x1
679 tail call void @use_i32(i32 %add)
680 %sub = sub i32 %add, 1
681 %ret = select i1 %cmp, i32 0, i32 %sub
686 define i32 @test_eq1_sub_add_i32(i32 %x0, i32 %x1) {
687 ; CHECK-LABEL: test_eq1_sub_add_i32:
689 ; CHECK-NEXT: add w8, w0, w1
690 ; CHECK-NEXT: cmp w1, #1
691 ; CHECK-NEXT: sub w8, w8, #2
692 ; CHECK-NEXT: csel w0, wzr, w8, eq
694 %cmp = icmp eq i32 %x1, 1
695 %add = add i32 %x0, %x1
696 %sub = sub i32 %add, 2
697 %ret = select i1 %cmp, i32 0, i32 %sub
702 define i32 @test_ugtsmax_sub_add_i32(i32 %x0, i32 %x1) {
703 ; CHECK-LABEL: test_ugtsmax_sub_add_i32:
705 ; CHECK-NEXT: mov w8, #-2147483648 // =0x80000000
706 ; CHECK-NEXT: add w9, w0, w1
707 ; CHECK-NEXT: cmp w1, #0
708 ; CHECK-NEXT: add w8, w9, w8
709 ; CHECK-NEXT: csel w0, wzr, w8, lt
711 %cmp = icmp ugt i32 %x1, 2147483647
712 %add = add i32 %x0, %x1
713 %sub = sub i32 %add, 2147483648
714 %ret = select i1 %cmp, i32 0, i32 %sub
719 define i32 @test_eq_const_mismatch_i32(i32 %x0, i32 %x1) {
720 ; CHECK-LABEL: test_eq_const_mismatch_i32:
722 ; CHECK-NEXT: add w8, w0, w1
723 ; CHECK-NEXT: cmp w1, #0
724 ; CHECK-NEXT: sub w8, w8, #2
725 ; CHECK-NEXT: csel w0, wzr, w8, eq
727 %cmp = icmp eq i32 %x1, 0
728 %add = add i32 %x0, %x1
729 %sub = sub i32 %add, 2
730 %ret = select i1 %cmp, i32 0, i32 %sub
735 define i32 @test_ne_const_mismatch_i32(i32 %x0, i32 %x1) {
736 ; CHECK-LABEL: test_ne_const_mismatch_i32:
738 ; CHECK-NEXT: add w8, w0, w1
739 ; CHECK-NEXT: cmp w1, #0
740 ; CHECK-NEXT: sub w8, w8, #2
741 ; CHECK-NEXT: csel w0, w8, wzr, ne
743 %cmp = icmp ne i32 %x1, 0
744 %add = add i32 %x0, %x1
745 %sub = sub i32 %add, 2
746 %ret = select i1 %cmp, i32 %sub, i32 0
751 define i32 @test_ult7_const_mismatch_i32(i32 %x0, i32 %x1) {
752 ; CHECK-LABEL: test_ult7_const_mismatch_i32:
754 ; CHECK-NEXT: add w8, w0, w1
755 ; CHECK-NEXT: cmp w1, #7
756 ; CHECK-NEXT: sub w8, w8, #8
757 ; CHECK-NEXT: csel w0, wzr, w8, lo
759 %cmp = icmp ult i32 %x1, 7
760 %add = add i32 %x0, %x1
761 %sub = sub i32 %add, 8
762 %ret = select i1 %cmp, i32 0, i32 %sub
767 define i32 @test_ule7_const_mismatch_i32(i32 %x0, i32 %x1) {
768 ; CHECK-LABEL: test_ule7_const_mismatch_i32:
770 ; CHECK-NEXT: add w8, w0, w1
771 ; CHECK-NEXT: cmp w1, #8
772 ; CHECK-NEXT: sub w8, w8, #6
773 ; CHECK-NEXT: csel w0, wzr, w8, lo
775 %cmp = icmp ule i32 %x1, 7
776 %add = add i32 %x0, %x1
777 %sub = sub i32 %add, 6
778 %ret = select i1 %cmp, i32 0, i32 %sub
783 define i32 @test_ugt7_const_mismatch_i32(i32 %x0, i32 %x1) {
784 ; CHECK-LABEL: test_ugt7_const_mismatch_i32:
786 ; CHECK-NEXT: add w8, w0, w1
787 ; CHECK-NEXT: cmp w1, #7
788 ; CHECK-NEXT: sub w8, w8, #6
789 ; CHECK-NEXT: csel w0, wzr, w8, hi
791 %cmp = icmp ugt i32 %x1, 7
792 %add = add i32 %x0, %x1
793 %sub = sub i32 %add, 6
794 %ret = select i1 %cmp, i32 0, i32 %sub
799 define i32 @test_uge7_const_mismatch_i32(i32 %x0, i32 %x1) {
800 ; CHECK-LABEL: test_uge7_const_mismatch_i32:
802 ; CHECK-NEXT: add w8, w0, w1
803 ; CHECK-NEXT: cmp w1, #6
804 ; CHECK-NEXT: sub w8, w8, #8
805 ; CHECK-NEXT: csel w0, wzr, w8, hi
807 %cmp = icmp uge i32 %x1, 7
808 %add = add i32 %x0, %x1
809 %sub = sub i32 %add, 8
810 %ret = select i1 %cmp, i32 0, i32 %sub
815 define i32 @test_slt7_const_mismatch_i32(i32 %x0, i32 %x1) {
816 ; CHECK-LABEL: test_slt7_const_mismatch_i32:
818 ; CHECK-NEXT: add w8, w0, w1
819 ; CHECK-NEXT: cmp w1, #7
820 ; CHECK-NEXT: sub w8, w8, #8
821 ; CHECK-NEXT: csel w0, wzr, w8, lt
823 %cmp = icmp slt i32 %x1, 7
824 %add = add i32 %x0, %x1
825 %sub = sub i32 %add, 8
826 %ret = select i1 %cmp, i32 0, i32 %sub
831 define i32 @test_sle7_const_mismatch_i32(i32 %x0, i32 %x1) {
832 ; CHECK-LABEL: test_sle7_const_mismatch_i32:
834 ; CHECK-NEXT: add w8, w0, w1
835 ; CHECK-NEXT: cmp w1, #8
836 ; CHECK-NEXT: sub w8, w8, #6
837 ; CHECK-NEXT: csel w0, wzr, w8, lt
839 %cmp = icmp sle i32 %x1, 7
840 %add = add i32 %x0, %x1
841 %sub = sub i32 %add, 6
842 %ret = select i1 %cmp, i32 0, i32 %sub
847 define i32 @test_sgt7_const_mismatch_i32(i32 %x0, i32 %x1) {
848 ; CHECK-LABEL: test_sgt7_const_mismatch_i32:
850 ; CHECK-NEXT: add w8, w0, w1
851 ; CHECK-NEXT: cmp w1, #7
852 ; CHECK-NEXT: sub w8, w8, #6
853 ; CHECK-NEXT: csel w0, wzr, w8, gt
855 %cmp = icmp sgt i32 %x1, 7
856 %add = add i32 %x0, %x1
857 %sub = sub i32 %add, 6
858 %ret = select i1 %cmp, i32 0, i32 %sub
863 define i32 @test_sge7_const_mismatch_i32(i32 %x0, i32 %x1) {
864 ; CHECK-LABEL: test_sge7_const_mismatch_i32:
866 ; CHECK-NEXT: add w8, w0, w1
867 ; CHECK-NEXT: cmp w1, #6
868 ; CHECK-NEXT: sub w8, w8, #8
869 ; CHECK-NEXT: csel w0, wzr, w8, gt
871 %cmp = icmp sge i32 %x1, 7
872 %add = add i32 %x0, %x1
873 %sub = sub i32 %add, 8
874 %ret = select i1 %cmp, i32 0, i32 %sub
879 define i32 @test_unrelated_add_i32(i32 %x0, i32 %x1, i32 %x2) {
880 ; CHECK-LABEL: test_unrelated_add_i32:
882 ; CHECK-NEXT: add w8, w0, w2
883 ; CHECK-NEXT: cmp w1, #0
884 ; CHECK-NEXT: sub w8, w8, #1
885 ; CHECK-NEXT: csel w0, wzr, w8, eq
887 %cmp = icmp eq i32 %x1, 0
888 %add = add nuw i32 %x0, %x2
889 %sub = sub i32 %add, 1
890 %ret = select i1 %cmp, i32 0, i32 %sub
895 define i16 @test_eq0_sub_add_i16(i16 %x0, i16 %x1) {
896 ; CHECK-LABEL: test_eq0_sub_add_i16:
898 ; CHECK-NEXT: add w8, w0, w1
899 ; CHECK-NEXT: tst w1, #0xffff
900 ; CHECK-NEXT: sub w8, w8, #1
901 ; CHECK-NEXT: csel w0, wzr, w8, eq
903 %cmp = icmp eq i16 %x1, 0
904 %add = add nuw i16 %x0, %x1
905 %sub = sub i16 %add, 1
906 %ret = select i1 %cmp, i16 0, i16 %sub
911 define i8 @test_eq_nonconst_sub_add_i8(i8 %x0, i8 %x1, i8 %x2) {
912 ; CHECK-LABEL: test_eq_nonconst_sub_add_i8:
914 ; CHECK-NEXT: and w8, w1, #0xff
915 ; CHECK-NEXT: add w9, w0, w1
916 ; CHECK-NEXT: sub w9, w9, w2
917 ; CHECK-NEXT: cmp w8, w2, uxtb
918 ; CHECK-NEXT: csel w0, wzr, w9, eq
920 %cmp = icmp eq i8 %x1, %x2
921 %add = add nuw i8 %x0, %x1
922 %sub = sub i8 %add, %x2
923 %ret = select i1 %cmp, i8 0, i8 %sub
928 define i16 @test_eq_nonconst_sub_add_i16(i16 %x0, i16 %x1, i16 %x2) {
929 ; CHECK-LABEL: test_eq_nonconst_sub_add_i16:
931 ; CHECK-NEXT: and w8, w1, #0xffff
932 ; CHECK-NEXT: add w9, w0, w1
933 ; CHECK-NEXT: sub w9, w9, w2
934 ; CHECK-NEXT: cmp w8, w2, uxth
935 ; CHECK-NEXT: csel w0, wzr, w9, eq
937 %cmp = icmp eq i16 %x1, %x2
938 %add = add nuw i16 %x0, %x1
939 %sub = sub i16 %add, %x2
940 %ret = select i1 %cmp, i16 0, i16 %sub
945 define i32 @test_ule_unsigned_overflow(i32 %x0, i32 %x1) {
946 ; CHECK-LABEL: test_ule_unsigned_overflow:
948 ; CHECK-NEXT: mov w0, wzr
950 %cmp = icmp ule i32 %x1, -1
951 %add = add i32 %x0, %x1
952 %sub = sub i32 %add, 0
953 %ret = select i1 %cmp, i32 0, i32 %sub
958 define i32 @test_ugt_unsigned_overflow(i32 %x0, i32 %x1) {
959 ; CHECK-LABEL: test_ugt_unsigned_overflow:
961 ; CHECK-NEXT: add w0, w0, w1
963 %cmp = icmp ugt i32 %x1, -1
964 %add = add i32 %x0, %x1
965 %sub = sub i32 %add, 0
966 %ret = select i1 %cmp, i32 0, i32 %sub
971 define i32 @test_ult_unsigned_overflow(i32 %x0, i32 %x1) {
972 ; CHECK-LABEL: test_ult_unsigned_overflow:
974 ; CHECK-NEXT: add w8, w0, w1
975 ; CHECK-NEXT: add w0, w8, #1
977 %cmp = icmp ult i32 %x1, 0
978 %add = add i32 %x0, %x1
979 %sub = sub i32 %add, -1
980 %ret = select i1 %cmp, i32 0, i32 %sub
985 define i32 @test_uge_unsigned_overflow(i32 %x0, i32 %x1) {
986 ; CHECK-LABEL: test_uge_unsigned_overflow:
988 ; CHECK-NEXT: mov w0, wzr
990 %cmp = icmp uge i32 %x1, 0
991 %add = add i32 %x0, %x1
992 %sub = sub i32 %add, -1
993 %ret = select i1 %cmp, i32 0, i32 %sub
998 define i32 @test_slt_signed_overflow(i32 %x0, i32 %x1) {
999 ; CHECK-LABEL: test_slt_signed_overflow:
1001 ; CHECK-NEXT: mov w8, #-2147483647 // =0x80000001
1002 ; CHECK-NEXT: add w9, w0, w1
1003 ; CHECK-NEXT: add w0, w9, w8
1005 %cmp = icmp slt i32 %x1, 2147483648
1006 %add = add i32 %x0, %x1
1007 %sub = sub i32 %add, 2147483647
1008 %ret = select i1 %cmp, i32 0, i32 %sub
1013 define i32 @test_sle_signed_overflow(i32 %x0, i32 %x1) {
1014 ; CHECK-LABEL: test_sle_signed_overflow:
1016 ; CHECK-NEXT: mov w0, wzr
1018 %cmp = icmp sle i32 %x1, 2147483647
1019 %add = add i32 %x0, %x1
1020 %sub = sub i32 %add, 2147483648
1021 %ret = select i1 %cmp, i32 0, i32 %sub
1026 define i32 @test_sgt_signed_overflow(i32 %x0, i32 %x1) {
1027 ; CHECK-LABEL: test_sgt_signed_overflow:
1029 ; CHECK-NEXT: mov w8, #-2147483648 // =0x80000000
1030 ; CHECK-NEXT: add w9, w0, w1
1031 ; CHECK-NEXT: add w0, w9, w8
1033 %cmp = icmp sgt i32 %x1, 2147483647
1034 %add = add i32 %x0, %x1
1035 %sub = sub i32 %add, 2147483648
1036 %ret = select i1 %cmp, i32 0, i32 %sub
1041 define i32 @test_sge_signed_overflow(i32 %x0, i32 %x1) {
1042 ; CHECK-LABEL: test_sge_signed_overflow:
1044 ; CHECK-NEXT: mov w0, wzr
1046 %cmp = icmp sge i32 %x1, 2147483648
1047 %add = add i32 %x0, %x1
1048 %sub = sub i32 %add, 2147483647
1049 %ret = select i1 %cmp, i32 0, i32 %sub
1054 define i32 @test_eq0_bitwidth_mismatch(i32 %x0, i32 %x1) {
1055 ; CHECK-LABEL: test_eq0_bitwidth_mismatch:
1057 ; CHECK-NEXT: add w8, w0, w1
1058 ; CHECK-NEXT: tst w1, #0xffff
1059 ; CHECK-NEXT: sub w8, w8, #1
1060 ; CHECK-NEXT: csel w0, wzr, w8, eq
1062 %x1t = trunc i32 %x1 to i16
1063 %cmp = icmp eq i16 %x1t, 0
1064 %add = add i32 %x0, %x1
1065 %sub = sub i32 %add, 1
1066 %ret = select i1 %cmp, i32 0, i32 %sub
1071 define i32 @test_eq0_bitwidth_mismatch_2(i32 %x0, i64 %x1) {
1072 ; CHECK-LABEL: test_eq0_bitwidth_mismatch_2:
1074 ; CHECK-NEXT: add w8, w0, w1
1075 ; CHECK-NEXT: cmp x1, #0
1076 ; CHECK-NEXT: sub w8, w8, #1
1077 ; CHECK-NEXT: csel w0, wzr, w8, eq
1079 %x1t = trunc i64 %x1 to i32
1080 %cmp = icmp eq i64 %x1, 0
1081 %add = add i32 %x0, %x1t
1082 %sub = sub i32 %add, 1
1083 %ret = select i1 %cmp, i32 0, i32 %sub
1088 define i32 @test_ult_nonconst_op_mismatch_i32(i32 %x0, i32 %x1, i32 %x2) {
1089 ; CHECK-LABEL: test_ult_nonconst_op_mismatch_i32:
1091 ; CHECK-NEXT: add w8, w0, w1
1092 ; CHECK-NEXT: cmp w1, w2
1093 ; CHECK-NEXT: add w8, w8, w2
1094 ; CHECK-NEXT: csel w0, wzr, w8, lo
1096 %cmp = icmp ult i32 %x1, %x2
1097 %add = add i32 %x0, %x1
1098 %sub = add i32 %add, %x2
1099 %ret = select i1 %cmp, i32 0, i32 %sub
1104 define i32 @test_ult_nonconst_unrelated_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) {
1105 ; CHECK-LABEL: test_ult_nonconst_unrelated_i32:
1107 ; CHECK-NEXT: add w8, w0, w1
1108 ; CHECK-NEXT: cmp w1, w2
1109 ; CHECK-NEXT: sub w8, w8, w3
1110 ; CHECK-NEXT: csel w0, wzr, w8, lo
1112 %cmp = icmp ult i32 %x1, %x2
1113 %add = add i32 %x0, %x1
1114 %sub = sub i32 %add, %x3
1115 %ret = select i1 %cmp, i32 0, i32 %sub
1120 define i32 @test_ult_nonconst_unrelated_2_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) {
1121 ; CHECK-LABEL: test_ult_nonconst_unrelated_2_i32:
1123 ; CHECK-NEXT: add w8, w0, w1
1124 ; CHECK-NEXT: cmp w2, w1
1125 ; CHECK-NEXT: sub w8, w8, w3
1126 ; CHECK-NEXT: csel w0, wzr, w8, lo
1128 %cmp = icmp ult i32 %x2, %x1
1129 %add = add i32 %x0, %x1
1130 %sub = sub i32 %add, %x3
1131 %ret = select i1 %cmp, i32 0, i32 %sub