xref: /llvm-project/llvm/test/CodeGen/AArch64/csel-cmp-cse.ll (revision c22364a4324218e29512740466a2b2cb1a406d8b)
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
3
4declare void @use_i1(i1 %x)
5declare void @use_i32(i32 %x)
6
7; Based on the IR generated for the `last` method of the type `slice` in Rust
8define 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
20}
21
22define 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
34}
35
36define 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
48}
49
50define 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
62}
63
64define 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
76}
77
78define 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
90}
91
92define 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
104}
105
106define 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
118}
119
120define 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
132}
133
134define 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
146}
147
148define 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
160}
161
162define 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
174}
175
176define 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
188}
189
190define 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
202}
203
204define 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
216}
217
218define 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
230}
231
232define 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
244}
245
246define 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
258}
259
260define 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
272}
273
274define 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
286}
287
288define 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
300}
301
302define 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
314}
315
316define 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
336}
337
338define 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
350}
351
352define 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
364}
365
366define 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
378}
379
380define 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
392}
393
394define 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
406}
407
408define 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
420}
421
422define 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
434}
435
436define 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
448}
449
450define 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
462}
463
464define 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
476}
477
478define 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
490}
491
492define 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
504}
505
506define 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
518}
519
520define 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
532}
533
534define 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
546}
547
548define 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
560}
561
562define 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
574}
575
576define 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
588}
589
590define 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
602}
603
604define 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
616}
617
618define 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
630}
631
632; Negative test
633define 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
655}
656
657; Negative test
658define 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
683}
684
685; Negative test
686define 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
699}
700
701; Negative test
702define 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
716}
717
718; Negative test
719define 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
732}
733
734; Negative test
735define 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
748}
749
750; Negative test
751define 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
764}
765
766; Negative test
767define 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
780}
781
782; Negative test
783define 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
796}
797
798; Negative test
799define 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
812}
813
814; Negative test
815define 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
828}
829
830; Negative test
831define 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
844}
845
846; Negative test
847define 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
860}
861
862; Negative test
863define 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
876}
877
878; Negative test
879define 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
892}
893
894; Negative test
895define 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
908}
909
910; Negative test
911define 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
925}
926
927; Negative test
928define 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
942}
943
944; Negative test
945define 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
955}
956
957; Negative test
958define 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
968}
969
970; Negative test
971define 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
982}
983
984; Negative test
985define 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
995}
996
997; Negative test
998define 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
1010}
1011
1012; Negative test
1013define 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
1023}
1024
1025; Negative test
1026define 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
1038}
1039
1040; Negative test
1041define 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
1051}
1052
1053; Negative test
1054define 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
1068}
1069
1070; Negative test
1071define 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
1085}
1086
1087; Negative test
1088define 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
1101}
1102
1103; Negative test
1104define 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
1117}
1118
1119; Negative test
1120define 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
1133}
1134