1; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s
2
3; Compare if negative and select of constants where one constant is zero.
4
5define i32 @neg_sel_constants(i32 %a) {
6; CHECK-LABEL: neg_sel_constants:
7; CHECK:       // BB#0:
8; CHECK-NEXT:    mov w8, #5
9; CHECK-NEXT:    and w0, w8, w0, asr #31
10; CHECK-NEXT:    ret
11;
12  %tmp.1 = icmp slt i32 %a, 0
13  %retval = select i1 %tmp.1, i32 5, i32 0
14  ret i32 %retval
15}
16
17; Compare if negative and select of constants where one constant is zero and the other is a single bit.
18
19define i32 @neg_sel_special_constant(i32 %a) {
20; CHECK-LABEL: neg_sel_special_constant:
21; CHECK:       // BB#0:
22; CHECK-NEXT:    lsr w8, w0, #22
23; CHECK-NEXT:    and w0, w8, #0x200
24; CHECK-NEXT:    ret
25;
26  %tmp.1 = icmp slt i32 %a, 0
27  %retval = select i1 %tmp.1, i32 512, i32 0
28  ret i32 %retval
29}
30
31; Compare if negative and select variable or zero.
32
33define i32 @neg_sel_variable_and_zero(i32 %a, i32 %b) {
34; CHECK-LABEL: neg_sel_variable_and_zero:
35; CHECK:       // BB#0:
36; CHECK-NEXT:    and w0, w1, w0, asr #31
37; CHECK-NEXT:    ret
38;
39  %tmp.1 = icmp slt i32 %a, 0
40  %retval = select i1 %tmp.1, i32 %b, i32 0
41  ret i32 %retval
42}
43
44; Compare if not positive and select the same variable as being compared: smin(a, 0).
45
46define i32 @not_pos_sel_same_variable(i32 %a) {
47; CHECK-LABEL: not_pos_sel_same_variable:
48; CHECK:       // BB#0:
49; CHECK-NEXT:    and w0, w0, w0, asr #31
50; CHECK-NEXT:    ret
51;
52  %tmp = icmp slt i32 %a, 1
53  %min = select i1 %tmp, i32 %a, i32 0
54  ret i32 %min
55}
56
57; FIXME: Flipping the comparison condition can be handled by getting the bitwise not of the sign mask.
58
59; Compare if positive and select of constants where one constant is zero.
60
61define i32 @pos_sel_constants(i32 %a) {
62; CHECK-LABEL: pos_sel_constants:
63; CHECK:       // BB#0:
64; CHECK-NEXT:    cmp w0, #0
65; CHECK-NEXT:    mov w8, #5
66; CHECK-NEXT:    csel w0, w8, wzr, ge
67; CHECK-NEXT:    ret
68;
69  %tmp.1 = icmp sgt i32 %a, -1
70  %retval = select i1 %tmp.1, i32 5, i32 0
71  ret i32 %retval
72}
73
74; Compare if positive and select of constants where one constant is zero and the other is a single bit.
75
76define i32 @pos_sel_special_constant(i32 %a) {
77; CHECK-LABEL: pos_sel_special_constant:
78; CHECK:       // BB#0:
79; CHECK-NEXT:    cmp w0, #0
80; CHECK-NEXT:    cset w8, ge
81; CHECK-NEXT:    lsl w0, w8, #9
82; CHECK-NEXT:    ret
83;
84  %tmp.1 = icmp sgt i32 %a, -1
85  %retval = select i1 %tmp.1, i32 512, i32 0
86  ret i32 %retval
87}
88
89; Compare if positive and select variable or zero.
90
91define i32 @pos_sel_variable_and_zero(i32 %a, i32 %b) {
92; CHECK-LABEL: pos_sel_variable_and_zero:
93; CHECK:       // BB#0:
94; CHECK-NEXT:    cmp w0, #0
95; CHECK-NEXT:    csel w0, w1, wzr, ge
96; CHECK-NEXT:    ret
97;
98  %tmp.1 = icmp sgt i32 %a, -1
99  %retval = select i1 %tmp.1, i32 %b, i32 0
100  ret i32 %retval
101}
102
103; Compare if not negative or zero and select the same variable as being compared: smax(a, 0).
104
105define i32 @not_neg_sel_same_variable(i32 %a) {
106; CHECK-LABEL: not_neg_sel_same_variable:
107; CHECK:       // BB#0:
108; CHECK-NEXT:    cmp w0, #0
109; CHECK-NEXT:    csel w0, w0, wzr, gt
110; CHECK-NEXT:    ret
111;
112  %tmp = icmp sgt i32 %a, 0
113  %min = select i1 %tmp, i32 %a, i32 0
114  ret i32 %min
115}
116
117; https://llvm.org/bugs/show_bug.cgi?id=31175
118
119; ret = (x-y) > 0 ? x-y : 0
120define i32 @PR31175(i32 %x, i32 %y) {
121; CHECK-LABEL: PR31175:
122; CHECK:       // BB#0:
123; CHECK-NEXT:    sub w8, w0, w1
124; CHECK-NEXT:    cmp w8, #0
125; CHECK-NEXT:    csel w0, w8, wzr, gt
126; CHECK-NEXT:    ret
127;
128  %sub = sub nsw i32 %x, %y
129  %cmp = icmp sgt i32 %sub, 0
130  %sel = select i1 %cmp, i32 %sub, i32 0
131  ret i32 %sel
132}
133
134