1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s
3
4; Compare if negative and select of constants where one constant is zero.
5
6define i32 @neg_sel_constants(i32 %a) {
7; CHECK-LABEL: neg_sel_constants:
8; CHECK:       // %bb.0:
9; CHECK-NEXT:    mov w8, #5
10; CHECK-NEXT:    and w0, w8, w0, asr #31
11; CHECK-NEXT:    ret
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  %tmp.1 = icmp slt i32 %a, 0
26  %retval = select i1 %tmp.1, i32 512, i32 0
27  ret i32 %retval
28}
29
30; Compare if negative and select variable or zero.
31
32define i32 @neg_sel_variable_and_zero(i32 %a, i32 %b) {
33; CHECK-LABEL: neg_sel_variable_and_zero:
34; CHECK:       // %bb.0:
35; CHECK-NEXT:    and w0, w1, w0, asr #31
36; CHECK-NEXT:    ret
37  %tmp.1 = icmp slt i32 %a, 0
38  %retval = select i1 %tmp.1, i32 %b, i32 0
39  ret i32 %retval
40}
41
42; Compare if not positive and select the same variable as being compared: smin(a, 0).
43
44define i32 @not_pos_sel_same_variable(i32 %a) {
45; CHECK-LABEL: not_pos_sel_same_variable:
46; CHECK:       // %bb.0:
47; CHECK-NEXT:    and w0, w0, w0, asr #31
48; CHECK-NEXT:    ret
49  %tmp = icmp slt i32 %a, 1
50  %min = select i1 %tmp, i32 %a, i32 0
51  ret i32 %min
52}
53
54; Flipping the comparison condition can be handled by getting the bitwise not of the sign mask.
55
56; Compare if positive and select of constants where one constant is zero.
57
58define i32 @pos_sel_constants(i32 %a) {
59; CHECK-LABEL: pos_sel_constants:
60; CHECK:       // %bb.0:
61; CHECK-NEXT:    mov w8, #5
62; CHECK-NEXT:    bic w0, w8, w0, asr #31
63; CHECK-NEXT:    ret
64  %tmp.1 = icmp sgt i32 %a, -1
65  %retval = select i1 %tmp.1, i32 5, i32 0
66  ret i32 %retval
67}
68
69; Compare if positive and select of constants where one constant is zero and the other is a single bit.
70
71define i32 @pos_sel_special_constant(i32 %a) {
72; CHECK-LABEL: pos_sel_special_constant:
73; CHECK:       // %bb.0:
74; CHECK-NEXT:    mov w8, #512
75; CHECK-NEXT:    bic w0, w8, w0, lsr #22
76; CHECK-NEXT:    ret
77  %tmp.1 = icmp sgt i32 %a, -1
78  %retval = select i1 %tmp.1, i32 512, i32 0
79  ret i32 %retval
80}
81
82; Compare if positive and select variable or zero.
83
84define i32 @pos_sel_variable_and_zero(i32 %a, i32 %b) {
85; CHECK-LABEL: pos_sel_variable_and_zero:
86; CHECK:       // %bb.0:
87; CHECK-NEXT:    bic w0, w1, w0, asr #31
88; CHECK-NEXT:    ret
89  %tmp.1 = icmp sgt i32 %a, -1
90  %retval = select i1 %tmp.1, i32 %b, i32 0
91  ret i32 %retval
92}
93
94; Compare if not negative or zero and select the same variable as being compared: smax(a, 0).
95
96define i32 @not_neg_sel_same_variable(i32 %a) {
97; CHECK-LABEL: not_neg_sel_same_variable:
98; CHECK:       // %bb.0:
99; CHECK-NEXT:    bic w0, w0, w0, asr #31
100; CHECK-NEXT:    ret
101  %tmp = icmp sgt i32 %a, 0
102  %min = select i1 %tmp, i32 %a, i32 0
103  ret i32 %min
104}
105
106; https://llvm.org/bugs/show_bug.cgi?id=31175
107
108; ret = (x-y) > 0 ? x-y : 0
109define i32 @PR31175(i32 %x, i32 %y) {
110; CHECK-LABEL: PR31175:
111; CHECK:       // %bb.0:
112; CHECK-NEXT:    sub w8, w0, w1
113; CHECK-NEXT:    bic w0, w8, w8, asr #31
114; CHECK-NEXT:    ret
115  %sub = sub nsw i32 %x, %y
116  %cmp = icmp sgt i32 %sub, 0
117  %sel = select i1 %cmp, i32 %sub, i32 0
118  ret i32 %sel
119}
120
121define i8 @sel_shift_bool_i8(i1 %t) {
122; CHECK-LABEL: sel_shift_bool_i8:
123; CHECK:       // %bb.0:
124; CHECK-NEXT:    tst w0, #0x1
125; CHECK-NEXT:    mov w8, #-128
126; CHECK-NEXT:    csel w0, w8, wzr, ne
127; CHECK-NEXT:    ret
128  %shl = select i1 %t, i8 128, i8 0
129  ret i8 %shl
130}
131
132define i16 @sel_shift_bool_i16(i1 %t) {
133; CHECK-LABEL: sel_shift_bool_i16:
134; CHECK:       // %bb.0:
135; CHECK-NEXT:    tst w0, #0x1
136; CHECK-NEXT:    mov w8, #128
137; CHECK-NEXT:    csel w0, w8, wzr, ne
138; CHECK-NEXT:    ret
139  %shl = select i1 %t, i16 128, i16 0
140  ret i16 %shl
141}
142
143define i32 @sel_shift_bool_i32(i1 %t) {
144; CHECK-LABEL: sel_shift_bool_i32:
145; CHECK:       // %bb.0:
146; CHECK-NEXT:    tst w0, #0x1
147; CHECK-NEXT:    mov w8, #64
148; CHECK-NEXT:    csel w0, w8, wzr, ne
149; CHECK-NEXT:    ret
150  %shl = select i1 %t, i32 64, i32 0
151  ret i32 %shl
152}
153
154define i64 @sel_shift_bool_i64(i1 %t) {
155; CHECK-LABEL: sel_shift_bool_i64:
156; CHECK:       // %bb.0:
157; CHECK-NEXT:    tst w0, #0x1
158; CHECK-NEXT:    mov w8, #65536
159; CHECK-NEXT:    csel x0, x8, xzr, ne
160; CHECK-NEXT:    ret
161  %shl = select i1 %t, i64 65536, i64 0
162  ret i64 %shl
163}
164
165define <16 x i8> @sel_shift_bool_v16i8(<16 x i1> %t) {
166; CHECK-LABEL: sel_shift_bool_v16i8:
167; CHECK:       // %bb.0:
168; CHECK-NEXT:    shl v0.16b, v0.16b, #7
169; CHECK-NEXT:    sshr v0.16b, v0.16b, #7
170; CHECK-NEXT:    movi v1.16b, #128
171; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
172; CHECK-NEXT:    ret
173  %shl = select <16 x i1> %t, <16 x i8> <i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128, i8 128>, <16 x i8> zeroinitializer
174  ret <16 x i8> %shl
175}
176
177define <8 x i16> @sel_shift_bool_v8i16(<8 x i1> %t) {
178; CHECK-LABEL: sel_shift_bool_v8i16:
179; CHECK:       // %bb.0:
180; CHECK-NEXT:    ushll v0.8h, v0.8b, #0
181; CHECK-NEXT:    shl v0.8h, v0.8h, #15
182; CHECK-NEXT:    sshr v0.8h, v0.8h, #15
183; CHECK-NEXT:    movi v1.8h, #128
184; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
185; CHECK-NEXT:    ret
186  %shl= select <8 x i1> %t, <8 x i16> <i16 128, i16 128, i16 128, i16 128, i16 128, i16 128, i16 128, i16 128>, <8 x i16> zeroinitializer
187  ret <8 x i16> %shl
188}
189
190define <4 x i32> @sel_shift_bool_v4i32(<4 x i1> %t) {
191; CHECK-LABEL: sel_shift_bool_v4i32:
192; CHECK:       // %bb.0:
193; CHECK-NEXT:    ushll v0.4s, v0.4h, #0
194; CHECK-NEXT:    shl v0.4s, v0.4s, #31
195; CHECK-NEXT:    sshr v0.4s, v0.4s, #31
196; CHECK-NEXT:    movi v1.4s, #64
197; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
198; CHECK-NEXT:    ret
199  %shl = select <4 x i1> %t, <4 x i32> <i32 64, i32 64, i32 64, i32 64>, <4 x i32> zeroinitializer
200  ret <4 x i32> %shl
201}
202
203define <2 x i64> @sel_shift_bool_v2i64(<2 x i1> %t) {
204; CHECK-LABEL: sel_shift_bool_v2i64:
205; CHECK:       // %bb.0:
206; CHECK-NEXT:    ushll v0.2d, v0.2s, #0
207; CHECK-NEXT:    mov w8, #65536
208; CHECK-NEXT:    shl v0.2d, v0.2d, #63
209; CHECK-NEXT:    sshr v0.2d, v0.2d, #63
210; CHECK-NEXT:    dup v1.2d, x8
211; CHECK-NEXT:    and v0.16b, v0.16b, v1.16b
212; CHECK-NEXT:    ret
213  %shl = select <2 x i1> %t, <2 x i64> <i64 65536, i64 65536>, <2 x i64> zeroinitializer
214  ret <2 x i64> %shl
215}
216