[Xtensa] Implement Windowed Register Option. (#124656)
[llvm-project.git] / llvm / test / CodeGen / AArch64 / csel-cmp-cse.ll
blobe745326323329c9919d79af5a0ba368f5c1051e7
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:
10 ; CHECK:       // %bb.0:
11 ; CHECK-NEXT:    subs x8, x1, #1
12 ; CHECK-NEXT:    add x8, x8, x0
13 ; CHECK-NEXT:    csel x0, xzr, x8, lo
14 ; CHECK-NEXT:    ret
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
19   ret ptr %retval.0
22 define i32 @test_eq0_sub_add_i32(i32 %x0, i32 %x1) {
23 ; CHECK-LABEL: test_eq0_sub_add_i32:
24 ; CHECK:       // %bb.0:
25 ; CHECK-NEXT:    subs w8, w1, #1
26 ; CHECK-NEXT:    add w8, w8, w0
27 ; CHECK-NEXT:    csel w0, wzr, w8, lo
28 ; CHECK-NEXT:    ret
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
33   ret i32 %ret
36 define i32 @test_eq7_sub_add_i32(i32 %x0, i32 %x1) {
37 ; CHECK-LABEL: test_eq7_sub_add_i32:
38 ; CHECK:       // %bb.0:
39 ; CHECK-NEXT:    subs w8, w1, #7
40 ; CHECK-NEXT:    add w8, w8, w0
41 ; CHECK-NEXT:    csel w0, wzr, w8, eq
42 ; CHECK-NEXT:    ret
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
47   ret i32 %ret
50 define i32 @test_ule7_sub7_add_i32(i32 %x0, i32 %x1) {
51 ; CHECK-LABEL: test_ule7_sub7_add_i32:
52 ; CHECK:       // %bb.0:
53 ; CHECK-NEXT:    subs w8, w1, #7
54 ; CHECK-NEXT:    add w8, w8, w0
55 ; CHECK-NEXT:    csel w0, wzr, w8, ls
56 ; CHECK-NEXT:    ret
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
61   ret i32 %ret
64 define i32 @test_ule7_sub8_add_i32(i32 %x0, i32 %x1) {
65 ; CHECK-LABEL: test_ule7_sub8_add_i32:
66 ; CHECK:       // %bb.0:
67 ; CHECK-NEXT:    subs w8, w1, #8
68 ; CHECK-NEXT:    add w8, w8, w0
69 ; CHECK-NEXT:    csel w0, wzr, w8, lo
70 ; CHECK-NEXT:    ret
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
75   ret i32 %ret
78 define i32 @test_ule0_sub1_add_i32(i32 %x0, i32 %x1) {
79 ; CHECK-LABEL: test_ule0_sub1_add_i32:
80 ; CHECK:       // %bb.0:
81 ; CHECK-NEXT:    subs w8, w1, #1
82 ; CHECK-NEXT:    add w8, w8, w0
83 ; CHECK-NEXT:    csel w0, wzr, w8, lo
84 ; CHECK-NEXT:    ret
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
89   ret i32 %ret
92 define i32 @test_ultminus2_subminus2_add_i32(i32 %x0, i32 %x1) {
93 ; CHECK-LABEL: test_ultminus2_subminus2_add_i32:
94 ; CHECK:       // %bb.0:
95 ; CHECK-NEXT:    adds w8, w1, #2
96 ; CHECK-NEXT:    add w8, w8, w0
97 ; CHECK-NEXT:    csel w0, wzr, w8, lo
98 ; CHECK-NEXT:    ret
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
103   ret i32 %ret
106 define i32 @test_ultminus2_subminus3_add_i32(i32 %x0, i32 %x1) {
107 ; CHECK-LABEL: test_ultminus2_subminus3_add_i32:
108 ; CHECK:       // %bb.0:
109 ; CHECK-NEXT:    adds w8, w1, #3
110 ; CHECK-NEXT:    add w8, w8, w0
111 ; CHECK-NEXT:    csel w0, wzr, w8, ls
112 ; CHECK-NEXT:    ret
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
117   ret i32 %ret
120 define i32 @test_ne0_sub_add_i32(i32 %x0, i32 %x1) {
121 ; CHECK-LABEL: test_ne0_sub_add_i32:
122 ; CHECK:       // %bb.0:
123 ; CHECK-NEXT:    subs w8, w1, #1
124 ; CHECK-NEXT:    add w8, w8, w0
125 ; CHECK-NEXT:    csel w0, w8, wzr, hs
126 ; CHECK-NEXT:    ret
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
131   ret i32 %ret
134 define i32 @test_ne7_sub_add_i32(i32 %x0, i32 %x1) {
135 ; CHECK-LABEL: test_ne7_sub_add_i32:
136 ; CHECK:       // %bb.0:
137 ; CHECK-NEXT:    subs w8, w1, #7
138 ; CHECK-NEXT:    add w8, w8, w0
139 ; CHECK-NEXT:    csel w0, w8, wzr, ne
140 ; CHECK-NEXT:    ret
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
145   ret i32 %ret
148 define i32 @test_ultminus1_sub_add_i32(i32 %x0, i32 %x1) {
149 ; CHECK-LABEL: test_ultminus1_sub_add_i32:
150 ; CHECK:       // %bb.0:
151 ; CHECK-NEXT:    adds w8, w1, #1
152 ; CHECK-NEXT:    add w8, w8, w0
153 ; CHECK-NEXT:    csel w0, wzr, w8, ne
154 ; CHECK-NEXT:    ret
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
159   ret i32 %ret
162 define i32 @test_ugt7_sub7_add_i32(i32 %x0, i32 %x1) {
163 ; CHECK-LABEL: test_ugt7_sub7_add_i32:
164 ; CHECK:       // %bb.0:
165 ; CHECK-NEXT:    subs w8, w1, #7
166 ; CHECK-NEXT:    add w8, w8, w0
167 ; CHECK-NEXT:    csel w0, wzr, w8, hi
168 ; CHECK-NEXT:    ret
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
173   ret i32 %ret
176 define i32 @test_ugt7_sub8_add_i32(i32 %x0, i32 %x1) {
177 ; CHECK-LABEL: test_ugt7_sub8_add_i32:
178 ; CHECK:       // %bb.0:
179 ; CHECK-NEXT:    subs w8, w1, #8
180 ; CHECK-NEXT:    add w8, w8, w0
181 ; CHECK-NEXT:    csel w0, wzr, w8, hs
182 ; CHECK-NEXT:    ret
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
187   ret i32 %ret
190 define i32 @test_sle7_sub7_add_i32(i32 %x0, i32 %x1) {
191 ; CHECK-LABEL: test_sle7_sub7_add_i32:
192 ; CHECK:       // %bb.0:
193 ; CHECK-NEXT:    subs w8, w1, #7
194 ; CHECK-NEXT:    add w8, w8, w0
195 ; CHECK-NEXT:    csel w0, wzr, w8, le
196 ; CHECK-NEXT:    ret
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
201   ret i32 %ret
204 define i32 @test_sle7_sub8_add_i32(i32 %x0, i32 %x1) {
205 ; CHECK-LABEL: test_sle7_sub8_add_i32:
206 ; CHECK:       // %bb.0:
207 ; CHECK-NEXT:    subs w8, w1, #8
208 ; CHECK-NEXT:    add w8, w8, w0
209 ; CHECK-NEXT:    csel w0, wzr, w8, lt
210 ; CHECK-NEXT:    ret
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
215   ret i32 %ret
218 define i32 @test_slt8_sub8_add_i32(i32 %x0, i32 %x1) {
219 ; CHECK-LABEL: test_slt8_sub8_add_i32:
220 ; CHECK:       // %bb.0:
221 ; CHECK-NEXT:    subs w8, w1, #8
222 ; CHECK-NEXT:    add w8, w8, w0
223 ; CHECK-NEXT:    csel w0, wzr, w8, lt
224 ; CHECK-NEXT:    ret
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
229   ret i32 %ret
232 define i32 @test_slt8_sub7_add_i32(i32 %x0, i32 %x1) {
233 ; CHECK-LABEL: test_slt8_sub7_add_i32:
234 ; CHECK:       // %bb.0:
235 ; CHECK-NEXT:    subs w8, w1, #7
236 ; CHECK-NEXT:    add w8, w8, w0
237 ; CHECK-NEXT:    csel w0, wzr, w8, le
238 ; CHECK-NEXT:    ret
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
243   ret i32 %ret
246 define i32 @test_sltminus8_subminus8_add_i32(i32 %x0, i32 %x1) {
247 ; CHECK-LABEL: test_sltminus8_subminus8_add_i32:
248 ; CHECK:       // %bb.0:
249 ; CHECK-NEXT:    adds w8, w1, #8
250 ; CHECK-NEXT:    add w8, w8, w0
251 ; CHECK-NEXT:    csel w0, wzr, w8, lt
252 ; CHECK-NEXT:    ret
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
257   ret i32 %ret
260 define i32 @test_sgtminus8_subminus8_add_i32(i32 %x0, i32 %x1) {
261 ; CHECK-LABEL: test_sgtminus8_subminus8_add_i32:
262 ; CHECK:       // %bb.0:
263 ; CHECK-NEXT:    adds w8, w1, #8
264 ; CHECK-NEXT:    add w8, w8, w0
265 ; CHECK-NEXT:    csel w0, wzr, w8, gt
266 ; CHECK-NEXT:    ret
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
271   ret i32 %ret
274 define i32 @test_sgtminus8_subminus7_add_i32(i32 %x0, i32 %x1) {
275 ; CHECK-LABEL: test_sgtminus8_subminus7_add_i32:
276 ; CHECK:       // %bb.0:
277 ; CHECK-NEXT:    adds w8, w1, #7
278 ; CHECK-NEXT:    add w8, w8, w0
279 ; CHECK-NEXT:    csel w0, wzr, w8, ge
280 ; CHECK-NEXT:    ret
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
285   ret i32 %ret
288 define i32 @test_eq0_sub_addcomm_i32(i32 %x0, i32 %x1) {
289 ; CHECK-LABEL: test_eq0_sub_addcomm_i32:
290 ; CHECK:       // %bb.0:
291 ; CHECK-NEXT:    subs w8, w1, #1
292 ; CHECK-NEXT:    add w8, w8, w0
293 ; CHECK-NEXT:    csel w0, wzr, w8, lo
294 ; CHECK-NEXT:    ret
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
299   ret i32 %ret
302 define i32 @test_eq0_subcomm_add_i32(i32 %x0, i32 %x1) {
303 ; CHECK-LABEL: test_eq0_subcomm_add_i32:
304 ; CHECK:       // %bb.0:
305 ; CHECK-NEXT:    subs w8, w1, #1
306 ; CHECK-NEXT:    add w8, w8, w0
307 ; CHECK-NEXT:    csel w0, wzr, w8, lo
308 ; CHECK-NEXT:    ret
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
313   ret i32 %ret
316 define i32 @test_eq0_multi_use_sub_i32(i32 %x0, i32 %x1) {
317 ; CHECK-LABEL: test_eq0_multi_use_sub_i32:
318 ; CHECK:       // %bb.0:
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
329 ; CHECK-NEXT:    ret
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
335   ret i32 %ret
338 define i32 @test_eq_nonconst_sub_add_i32(i32 %x0, i32 %x1, i32 %x2) {
339 ; CHECK-LABEL: test_eq_nonconst_sub_add_i32:
340 ; CHECK:       // %bb.0:
341 ; CHECK-NEXT:    subs w8, w1, w2
342 ; CHECK-NEXT:    add w8, w8, w0
343 ; CHECK-NEXT:    csel w0, wzr, w8, eq
344 ; CHECK-NEXT:    ret
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
349   ret i32 %ret
352 define i32 @test_ne_nonconst_sub_add_i32(i32 %x0, i32 %x1, i32 %x2) {
353 ; CHECK-LABEL: test_ne_nonconst_sub_add_i32:
354 ; CHECK:       // %bb.0:
355 ; CHECK-NEXT:    subs w8, w1, w2
356 ; CHECK-NEXT:    add w8, w8, w0
357 ; CHECK-NEXT:    csel w0, wzr, w8, ne
358 ; CHECK-NEXT:    ret
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
363   ret i32 %ret
366 define i32 @test_ult_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
367 ; CHECK-LABEL: test_ult_nonconst_i32:
368 ; CHECK:       // %bb.0:
369 ; CHECK-NEXT:    subs w8, w1, w2
370 ; CHECK-NEXT:    add w8, w8, w0
371 ; CHECK-NEXT:    csel w0, wzr, w8, lo
372 ; CHECK-NEXT:    ret
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
377   ret i32 %ret
380 define i32 @test_ule_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
381 ; CHECK-LABEL: test_ule_nonconst_i32:
382 ; CHECK:       // %bb.0:
383 ; CHECK-NEXT:    subs w8, w1, w2
384 ; CHECK-NEXT:    add w8, w8, w0
385 ; CHECK-NEXT:    csel w0, wzr, w8, ls
386 ; CHECK-NEXT:    ret
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
391   ret i32 %ret
394 define i32 @test_ugt_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
395 ; CHECK-LABEL: test_ugt_nonconst_i32:
396 ; CHECK:       // %bb.0:
397 ; CHECK-NEXT:    subs w8, w1, w2
398 ; CHECK-NEXT:    add w8, w8, w0
399 ; CHECK-NEXT:    csel w0, wzr, w8, hi
400 ; CHECK-NEXT:    ret
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
405   ret i32 %ret
408 define i32 @test_uge_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
409 ; CHECK-LABEL: test_uge_nonconst_i32:
410 ; CHECK:       // %bb.0:
411 ; CHECK-NEXT:    subs w8, w1, w2
412 ; CHECK-NEXT:    add w8, w8, w0
413 ; CHECK-NEXT:    csel w0, wzr, w8, hs
414 ; CHECK-NEXT:    ret
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
419   ret i32 %ret
422 define i32 @test_slt_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
423 ; CHECK-LABEL: test_slt_nonconst_i32:
424 ; CHECK:       // %bb.0:
425 ; CHECK-NEXT:    subs w8, w1, w2
426 ; CHECK-NEXT:    add w8, w8, w0
427 ; CHECK-NEXT:    csel w0, wzr, w8, lt
428 ; CHECK-NEXT:    ret
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
433   ret i32 %ret
436 define i32 @test_sle_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
437 ; CHECK-LABEL: test_sle_nonconst_i32:
438 ; CHECK:       // %bb.0:
439 ; CHECK-NEXT:    subs w8, w1, w2
440 ; CHECK-NEXT:    add w8, w8, w0
441 ; CHECK-NEXT:    csel w0, wzr, w8, le
442 ; CHECK-NEXT:    ret
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
447   ret i32 %ret
450 define i32 @test_sgt_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
451 ; CHECK-LABEL: test_sgt_nonconst_i32:
452 ; CHECK:       // %bb.0:
453 ; CHECK-NEXT:    subs w8, w1, w2
454 ; CHECK-NEXT:    add w8, w8, w0
455 ; CHECK-NEXT:    csel w0, wzr, w8, gt
456 ; CHECK-NEXT:    ret
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
461   ret i32 %ret
464 define i32 @test_sge_nonconst_i32(i32 %x0, i32 %x1, i32 %x2) {
465 ; CHECK-LABEL: test_sge_nonconst_i32:
466 ; CHECK:       // %bb.0:
467 ; CHECK-NEXT:    subs w8, w1, w2
468 ; CHECK-NEXT:    add w8, w8, w0
469 ; CHECK-NEXT:    csel w0, wzr, w8, ge
470 ; CHECK-NEXT:    ret
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
475   ret i32 %ret
478 define i64 @test_ult_nonconst_i64(i64 %x0, i64 %x1, i64 %x2) {
479 ; CHECK-LABEL: test_ult_nonconst_i64:
480 ; CHECK:       // %bb.0:
481 ; CHECK-NEXT:    subs x8, x1, x2
482 ; CHECK-NEXT:    add x8, x8, x0
483 ; CHECK-NEXT:    csel x0, xzr, x8, lo
484 ; CHECK-NEXT:    ret
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
489   ret i64 %ret
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:
494 ; CHECK:       // %bb.0:
495 ; CHECK-NEXT:    subs w8, w1, w2
496 ; CHECK-NEXT:    add w8, w8, w0
497 ; CHECK-NEXT:    csel w0, wzr, w8, eq
498 ; CHECK-NEXT:    ret
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
503   ret i32 %ret
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:
508 ; CHECK:       // %bb.0:
509 ; CHECK-NEXT:    subs w8, w1, w2
510 ; CHECK-NEXT:    add w8, w8, w0
511 ; CHECK-NEXT:    csel w0, wzr, w8, ne
512 ; CHECK-NEXT:    ret
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
517   ret i32 %ret
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:
522 ; CHECK:       // %bb.0:
523 ; CHECK-NEXT:    subs w8, w1, w2
524 ; CHECK-NEXT:    add w8, w8, w0
525 ; CHECK-NEXT:    csel w0, wzr, w8, hi
526 ; CHECK-NEXT:    ret
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
531   ret i32 %ret
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:
536 ; CHECK:       // %bb.0:
537 ; CHECK-NEXT:    subs w8, w1, w2
538 ; CHECK-NEXT:    add w8, w8, w0
539 ; CHECK-NEXT:    csel w0, wzr, w8, hs
540 ; CHECK-NEXT:    ret
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
545   ret i32 %ret
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:
550 ; CHECK:       // %bb.0:
551 ; CHECK-NEXT:    subs w8, w1, w2
552 ; CHECK-NEXT:    add w8, w8, w0
553 ; CHECK-NEXT:    csel w0, wzr, w8, lo
554 ; CHECK-NEXT:    ret
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
559   ret i32 %ret
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:
564 ; CHECK:       // %bb.0:
565 ; CHECK-NEXT:    subs w8, w1, w2
566 ; CHECK-NEXT:    add w8, w8, w0
567 ; CHECK-NEXT:    csel w0, wzr, w8, ls
568 ; CHECK-NEXT:    ret
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
573   ret i32 %ret
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:
578 ; CHECK:       // %bb.0:
579 ; CHECK-NEXT:    subs w8, w1, w2
580 ; CHECK-NEXT:    add w8, w8, w0
581 ; CHECK-NEXT:    csel w0, wzr, w8, gt
582 ; CHECK-NEXT:    ret
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
587   ret i32 %ret
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:
592 ; CHECK:       // %bb.0:
593 ; CHECK-NEXT:    subs w8, w1, w2
594 ; CHECK-NEXT:    add w8, w8, w0
595 ; CHECK-NEXT:    csel w0, wzr, w8, ge
596 ; CHECK-NEXT:    ret
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
601   ret i32 %ret
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:
606 ; CHECK:       // %bb.0:
607 ; CHECK-NEXT:    subs w8, w1, w2
608 ; CHECK-NEXT:    add w8, w8, w0
609 ; CHECK-NEXT:    csel w0, wzr, w8, lt
610 ; CHECK-NEXT:    ret
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
615   ret i32 %ret
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:
620 ; CHECK:       // %bb.0:
621 ; CHECK-NEXT:    subs w8, w1, w2
622 ; CHECK-NEXT:    add w8, w8, w0
623 ; CHECK-NEXT:    csel w0, wzr, w8, le
624 ; CHECK-NEXT:    ret
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
629   ret i32 %ret
632 ; Negative test
633 define i32 @test_eq0_multi_use_cmp_i32(i32 %x0, i32 %x1) {
634 ; CHECK-LABEL: test_eq0_multi_use_cmp_i32:
635 ; CHECK:       // %bb.0:
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
648 ; CHECK-NEXT:    ret
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
654   ret i32 %ret
657 ; Negative test
658 define i32 @test_eq0_multi_use_add_i32(i32 %x0, i32 %x1) {
659 ; CHECK-LABEL: test_eq0_multi_use_add_i32:
660 ; CHECK:       // %bb.0:
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
676 ; CHECK-NEXT:    ret
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
682   ret i32 %ret
685 ; Negative test
686 define i32 @test_eq1_sub_add_i32(i32 %x0, i32 %x1) {
687 ; CHECK-LABEL: test_eq1_sub_add_i32:
688 ; CHECK:       // %bb.0:
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
693 ; CHECK-NEXT:    ret
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
698   ret i32 %ret
701 ; Negative test
702 define i32 @test_ugtsmax_sub_add_i32(i32 %x0, i32 %x1) {
703 ; CHECK-LABEL: test_ugtsmax_sub_add_i32:
704 ; CHECK:       // %bb.0:
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
710 ; CHECK-NEXT:    ret
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
715   ret i32 %ret
718 ; Negative test
719 define i32 @test_eq_const_mismatch_i32(i32 %x0, i32 %x1) {
720 ; CHECK-LABEL: test_eq_const_mismatch_i32:
721 ; CHECK:       // %bb.0:
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
726 ; CHECK-NEXT:    ret
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
731   ret i32 %ret
734 ; Negative test
735 define i32 @test_ne_const_mismatch_i32(i32 %x0, i32 %x1) {
736 ; CHECK-LABEL: test_ne_const_mismatch_i32:
737 ; CHECK:       // %bb.0:
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
742 ; CHECK-NEXT:    ret
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
747   ret i32 %ret
750 ; Negative test
751 define i32 @test_ult7_const_mismatch_i32(i32 %x0, i32 %x1) {
752 ; CHECK-LABEL: test_ult7_const_mismatch_i32:
753 ; CHECK:       // %bb.0:
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
758 ; CHECK-NEXT:    ret
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
763   ret i32 %ret
766 ; Negative test
767 define i32 @test_ule7_const_mismatch_i32(i32 %x0, i32 %x1) {
768 ; CHECK-LABEL: test_ule7_const_mismatch_i32:
769 ; CHECK:       // %bb.0:
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
774 ; CHECK-NEXT:    ret
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
779   ret i32 %ret
782 ; Negative test
783 define i32 @test_ugt7_const_mismatch_i32(i32 %x0, i32 %x1) {
784 ; CHECK-LABEL: test_ugt7_const_mismatch_i32:
785 ; CHECK:       // %bb.0:
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
790 ; CHECK-NEXT:    ret
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
795   ret i32 %ret
798 ; Negative test
799 define i32 @test_uge7_const_mismatch_i32(i32 %x0, i32 %x1) {
800 ; CHECK-LABEL: test_uge7_const_mismatch_i32:
801 ; CHECK:       // %bb.0:
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
806 ; CHECK-NEXT:    ret
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
811   ret i32 %ret
814 ; Negative test
815 define i32 @test_slt7_const_mismatch_i32(i32 %x0, i32 %x1) {
816 ; CHECK-LABEL: test_slt7_const_mismatch_i32:
817 ; CHECK:       // %bb.0:
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
822 ; CHECK-NEXT:    ret
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
827   ret i32 %ret
830 ; Negative test
831 define i32 @test_sle7_const_mismatch_i32(i32 %x0, i32 %x1) {
832 ; CHECK-LABEL: test_sle7_const_mismatch_i32:
833 ; CHECK:       // %bb.0:
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
838 ; CHECK-NEXT:    ret
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
843   ret i32 %ret
846 ; Negative test
847 define i32 @test_sgt7_const_mismatch_i32(i32 %x0, i32 %x1) {
848 ; CHECK-LABEL: test_sgt7_const_mismatch_i32:
849 ; CHECK:       // %bb.0:
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
854 ; CHECK-NEXT:    ret
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
859   ret i32 %ret
862 ; Negative test
863 define i32 @test_sge7_const_mismatch_i32(i32 %x0, i32 %x1) {
864 ; CHECK-LABEL: test_sge7_const_mismatch_i32:
865 ; CHECK:       // %bb.0:
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
870 ; CHECK-NEXT:    ret
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
875   ret i32 %ret
878 ; Negative test
879 define i32 @test_unrelated_add_i32(i32 %x0, i32 %x1, i32 %x2) {
880 ; CHECK-LABEL: test_unrelated_add_i32:
881 ; CHECK:       // %bb.0:
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
886 ; CHECK-NEXT:    ret
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
891   ret i32 %ret
894 ; Negative test
895 define i16 @test_eq0_sub_add_i16(i16 %x0, i16 %x1) {
896 ; CHECK-LABEL: test_eq0_sub_add_i16:
897 ; CHECK:       // %bb.0:
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
902 ; CHECK-NEXT:    ret
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
907   ret i16 %ret
910 ; Negative test
911 define i8 @test_eq_nonconst_sub_add_i8(i8 %x0, i8 %x1, i8 %x2) {
912 ; CHECK-LABEL: test_eq_nonconst_sub_add_i8:
913 ; CHECK:       // %bb.0:
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
919 ; CHECK-NEXT:    ret
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
924   ret i8 %ret
927 ; Negative test
928 define i16 @test_eq_nonconst_sub_add_i16(i16 %x0, i16 %x1, i16 %x2) {
929 ; CHECK-LABEL: test_eq_nonconst_sub_add_i16:
930 ; CHECK:       // %bb.0:
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
936 ; CHECK-NEXT:    ret
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
941   ret i16 %ret
944 ; Negative test
945 define i32 @test_ule_unsigned_overflow(i32 %x0, i32 %x1) {
946 ; CHECK-LABEL: test_ule_unsigned_overflow:
947 ; CHECK:       // %bb.0:
948 ; CHECK-NEXT:    mov w0, wzr
949 ; CHECK-NEXT:    ret
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
954   ret i32 %ret
957 ; Negative test
958 define i32 @test_ugt_unsigned_overflow(i32 %x0, i32 %x1) {
959 ; CHECK-LABEL: test_ugt_unsigned_overflow:
960 ; CHECK:       // %bb.0:
961 ; CHECK-NEXT:    add w0, w0, w1
962 ; CHECK-NEXT:    ret
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
967   ret i32 %ret
970 ; Negative test
971 define i32 @test_ult_unsigned_overflow(i32 %x0, i32 %x1) {
972 ; CHECK-LABEL: test_ult_unsigned_overflow:
973 ; CHECK:       // %bb.0:
974 ; CHECK-NEXT:    add w8, w0, w1
975 ; CHECK-NEXT:    add w0, w8, #1
976 ; CHECK-NEXT:    ret
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
981   ret i32 %ret
984 ; Negative test
985 define i32 @test_uge_unsigned_overflow(i32 %x0, i32 %x1) {
986 ; CHECK-LABEL: test_uge_unsigned_overflow:
987 ; CHECK:       // %bb.0:
988 ; CHECK-NEXT:    mov w0, wzr
989 ; CHECK-NEXT:    ret
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
994   ret i32 %ret
997 ; Negative test
998 define i32 @test_slt_signed_overflow(i32 %x0, i32 %x1) {
999 ; CHECK-LABEL: test_slt_signed_overflow:
1000 ; CHECK:       // %bb.0:
1001 ; CHECK-NEXT:    mov w8, #-2147483647 // =0x80000001
1002 ; CHECK-NEXT:    add w9, w0, w1
1003 ; CHECK-NEXT:    add w0, w9, w8
1004 ; CHECK-NEXT:    ret
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
1009   ret i32 %ret
1012 ; Negative test
1013 define i32 @test_sle_signed_overflow(i32 %x0, i32 %x1) {
1014 ; CHECK-LABEL: test_sle_signed_overflow:
1015 ; CHECK:       // %bb.0:
1016 ; CHECK-NEXT:    mov w0, wzr
1017 ; CHECK-NEXT:    ret
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
1022   ret i32 %ret
1025 ; Negative test
1026 define i32 @test_sgt_signed_overflow(i32 %x0, i32 %x1) {
1027 ; CHECK-LABEL: test_sgt_signed_overflow:
1028 ; CHECK:       // %bb.0:
1029 ; CHECK-NEXT:    mov w8, #-2147483648 // =0x80000000
1030 ; CHECK-NEXT:    add w9, w0, w1
1031 ; CHECK-NEXT:    add w0, w9, w8
1032 ; CHECK-NEXT:    ret
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
1037   ret i32 %ret
1040 ; Negative test
1041 define i32 @test_sge_signed_overflow(i32 %x0, i32 %x1) {
1042 ; CHECK-LABEL: test_sge_signed_overflow:
1043 ; CHECK:       // %bb.0:
1044 ; CHECK-NEXT:    mov w0, wzr
1045 ; CHECK-NEXT:    ret
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
1050   ret i32 %ret
1053 ; Negative test
1054 define i32 @test_eq0_bitwidth_mismatch(i32 %x0, i32 %x1) {
1055 ; CHECK-LABEL: test_eq0_bitwidth_mismatch:
1056 ; CHECK:       // %bb.0:
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
1061 ; CHECK-NEXT:    ret
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
1067   ret i32 %ret
1070 ; Negative test
1071 define i32 @test_eq0_bitwidth_mismatch_2(i32 %x0, i64 %x1) {
1072 ; CHECK-LABEL: test_eq0_bitwidth_mismatch_2:
1073 ; CHECK:       // %bb.0:
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
1078 ; CHECK-NEXT:    ret
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
1084   ret i32 %ret
1087 ; Negative test
1088 define i32 @test_ult_nonconst_op_mismatch_i32(i32 %x0, i32 %x1, i32 %x2) {
1089 ; CHECK-LABEL: test_ult_nonconst_op_mismatch_i32:
1090 ; CHECK:       // %bb.0:
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
1095 ; CHECK-NEXT:    ret
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
1100   ret i32 %ret
1103 ; Negative test
1104 define i32 @test_ult_nonconst_unrelated_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) {
1105 ; CHECK-LABEL: test_ult_nonconst_unrelated_i32:
1106 ; CHECK:       // %bb.0:
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
1111 ; CHECK-NEXT:    ret
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
1116   ret i32 %ret
1119 ; Negative test
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:
1122 ; CHECK:       // %bb.0:
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
1127 ; CHECK-NEXT:    ret
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
1132   ret i32 %ret