1; RUN: llc < %s -verify-machineinstrs -mtriple=arm64-none-linux-gnu -mattr=+neon -fp-contract=fast | FileCheck %s
2
3define <8x i8> @test_select_cc_v8i8_i8(i8 %a, i8 %b, <8x i8> %c, <8x i8> %d ) {
4; CHECK-LABEL: test_select_cc_v8i8_i8:
5; CHECK-DAG: fmov s[[LHS:[0-9]+]], w0
6; CHECK-DAG: fmov s[[RHS:[0-9]+]], w1
7; CHECK: cmeq [[MASK:v[0-9]+]].8b, v[[LHS]].8b, v[[RHS]].8b
8; CHECK: dup [[DUPMASK:v[0-9]+]].8b, [[MASK]].b[0]
9; CHECK: bsl [[DUPMASK]].8b, v0.8b, v1.8b
10  %cmp31 = icmp eq i8 %a, %b
11  %e = select i1 %cmp31, <8x i8> %c, <8x i8> %d
12  ret <8x i8> %e
13}
14
15define <8x i8> @test_select_cc_v8i8_f32(float %a, float %b, <8x i8> %c, <8x i8> %d ) {
16; CHECK-LABEL: test_select_cc_v8i8_f32:
17; CHECK: fcmeq [[MASK:v[0-9]+]].2s, v0.2s, v1.2s
18; CHECK-NEXT: dup [[DUPMASK:v[0-9]+]].2s, [[MASK]].s[0]
19; CHECK-NEXT: bsl [[DUPMASK]].8b, v2.8b, v3.8b
20  %cmp31 = fcmp oeq float %a, %b
21  %e = select i1 %cmp31, <8x i8> %c, <8x i8> %d
22  ret <8x i8> %e
23}
24
25define <8x i8> @test_select_cc_v8i8_f64(double %a, double %b, <8x i8> %c, <8x i8> %d ) {
26; CHECK-LABEL: test_select_cc_v8i8_f64:
27; CHECK: fcmeq d[[MASK:[0-9]+]], d0, d1
28; CHECK-NEXT: bsl v[[MASK]].8b, v2.8b, v3.8b
29  %cmp31 = fcmp oeq double %a, %b
30  %e = select i1 %cmp31, <8x i8> %c, <8x i8> %d
31  ret <8x i8> %e
32}
33
34define <16x i8> @test_select_cc_v16i8_i8(i8 %a, i8 %b, <16x i8> %c, <16x i8> %d ) {
35; CHECK-LABEL: test_select_cc_v16i8_i8:
36; CHECK-DAG: fmov s[[LHS:[0-9]+]], w0
37; CHECK-DAG: fmov s[[RHS:[0-9]+]], w1
38; CHECK: cmeq [[MASK:v[0-9]+]].16b, v[[LHS]].16b, v[[RHS]].16b
39; CHECK: dup [[DUPMASK:v[0-9]+]].16b, [[MASK]].b[0]
40; CHECK: bsl [[DUPMASK]].16b, v0.16b, v1.16b
41  %cmp31 = icmp eq i8 %a, %b
42  %e = select i1 %cmp31, <16x i8> %c, <16x i8> %d
43  ret <16x i8> %e
44}
45
46define <16x i8> @test_select_cc_v16i8_f32(float %a, float %b, <16x i8> %c, <16x i8> %d ) {
47; CHECK-LABEL: test_select_cc_v16i8_f32:
48; CHECK: fcmeq [[MASK:v[0-9]+]].4s, v0.4s, v1.4s
49; CHECK-NEXT: dup [[DUPMASK:v[0-9]+]].4s, [[MASK]].s[0]
50; CHECK-NEXT: bsl [[DUPMASK]].16b, v2.16b, v3.16b
51  %cmp31 = fcmp oeq float %a, %b
52  %e = select i1 %cmp31, <16x i8> %c, <16x i8> %d
53  ret <16x i8> %e
54}
55
56define <16x i8> @test_select_cc_v16i8_f64(double %a, double %b, <16x i8> %c, <16x i8> %d ) {
57; CHECK-LABEL: test_select_cc_v16i8_f64:
58; CHECK: fcmeq [[MASK:v[0-9]+]].2d, v0.2d, v1.2d
59; CHECK-NEXT: dup [[DUPMASK:v[0-9]+]].2d, [[MASK]].d[0]
60; CHECK-NEXT: bsl [[DUPMASK]].16b, v2.16b, v3.16b
61  %cmp31 = fcmp oeq double %a, %b
62  %e = select i1 %cmp31, <16x i8> %c, <16x i8> %d
63  ret <16x i8> %e
64}
65
66define <4x i16> @test_select_cc_v4i16(i16 %a, i16 %b, <4x i16> %c, <4x i16> %d ) {
67; CHECK-LABEL: test_select_cc_v4i16:
68; CHECK-DAG: fmov s[[LHS:[0-9]+]], w0
69; CHECK-DAG: fmov s[[RHS:[0-9]+]], w1
70; CHECK: cmeq [[MASK:v[0-9]+]].4h, v[[LHS]].4h, v[[RHS]].4h
71; CHECK: dup [[DUPMASK:v[0-9]+]].4h, [[MASK]].h[0]
72; CHECK: bsl [[DUPMASK]].8b, v0.8b, v1.8b
73  %cmp31 = icmp eq i16 %a, %b
74  %e = select i1 %cmp31, <4x i16> %c, <4x i16> %d
75  ret <4x i16> %e
76}
77
78define <8x i16> @test_select_cc_v8i16(i16 %a, i16 %b, <8x i16> %c, <8x i16> %d ) {
79; CHECK-LABEL: test_select_cc_v8i16:
80; CHECK-DAG: fmov s[[LHS:[0-9]+]], w0
81; CHECK-DAG: fmov s[[RHS:[0-9]+]], w1
82; CHECK: cmeq [[MASK:v[0-9]+]].8h, v[[LHS]].8h, v[[RHS]].8h
83; CHECK: dup [[DUPMASK:v[0-9]+]].8h, [[MASK]].h[0]
84; CHECK: bsl [[DUPMASK]].16b, v0.16b, v1.16b
85  %cmp31 = icmp eq i16 %a, %b
86  %e = select i1 %cmp31, <8x i16> %c, <8x i16> %d
87  ret <8x i16> %e
88}
89
90define <2x i32> @test_select_cc_v2i32(i32 %a, i32 %b, <2x i32> %c, <2x i32> %d ) {
91; CHECK-LABEL: test_select_cc_v2i32:
92; CHECK-DAG: fmov s[[LHS:[0-9]+]], w0
93; CHECK-DAG: fmov s[[RHS:[0-9]+]], w1
94; CHECK: cmeq [[MASK:v[0-9]+]].2s, v[[LHS]].2s, v[[RHS]].2s
95; CHECK: dup [[DUPMASK:v[0-9]+]].2s, [[MASK]].s[0]
96; CHECK: bsl [[DUPMASK]].8b, v0.8b, v1.8b
97  %cmp31 = icmp eq i32 %a, %b
98  %e = select i1 %cmp31, <2x i32> %c, <2x i32> %d
99  ret <2x i32> %e
100}
101
102define <4x i32> @test_select_cc_v4i32(i32 %a, i32 %b, <4x i32> %c, <4x i32> %d ) {
103; CHECK-LABEL: test_select_cc_v4i32:
104; CHECK-DAG: fmov s[[LHS:[0-9]+]], w0
105; CHECK-DAG: fmov s[[RHS:[0-9]+]], w1
106; CHECK: cmeq [[MASK:v[0-9]+]].4s, v[[LHS]].4s, v[[RHS]].4s
107; CHECK: dup [[DUPMASK:v[0-9]+]].4s, [[MASK]].s[0]
108; CHECK: bsl [[DUPMASK]].16b, v0.16b, v1.16b
109  %cmp31 = icmp eq i32 %a, %b
110  %e = select i1 %cmp31, <4x i32> %c, <4x i32> %d
111  ret <4x i32> %e
112}
113
114define <1x i64> @test_select_cc_v1i64(i64 %a, i64 %b, <1x i64> %c, <1x i64> %d ) {
115; CHECK-LABEL: test_select_cc_v1i64:
116; CHECK-DAG: fmov d[[LHS:[0-9]+]], x0
117; CHECK-DAG: fmov d[[RHS:[0-9]+]], x1
118; CHECK: cmeq d[[MASK:[0-9]+]], d[[LHS]], d[[RHS]]
119; CHECK: bsl v[[MASK]].8b, v0.8b, v1.8b
120  %cmp31 = icmp eq i64 %a, %b
121  %e = select i1 %cmp31, <1x i64> %c, <1x i64> %d
122  ret <1x i64> %e
123}
124
125define <2x i64> @test_select_cc_v2i64(i64 %a, i64 %b, <2x i64> %c, <2x i64> %d ) {
126; CHECK-LABEL: test_select_cc_v2i64:
127; CHECK-DAG: fmov d[[LHS:[0-9]+]], x0
128; CHECK-DAG: fmov d[[RHS:[0-9]+]], x1
129; CHECK: cmeq [[MASK:v[0-9]+]].2d, v[[LHS]].2d, v[[RHS]].2d
130; CHECK: dup [[DUPMASK:v[0-9]+]].2d, [[MASK]].d[0]
131; CHECK: bsl [[DUPMASK]].16b, v0.16b, v1.16b
132  %cmp31 = icmp eq i64 %a, %b
133  %e = select i1 %cmp31, <2x i64> %c, <2x i64> %d
134  ret <2x i64> %e
135}
136
137define <1 x float> @test_select_cc_v1f32(float %a, float %b, <1 x float> %c, <1 x float> %d ) {
138; CHECK-LABEL: test_select_cc_v1f32:
139; CHECK: fcmeq [[MASK:v[0-9]+]].2s, v0.2s, v1.2s
140; CHECK-NEXT: bsl [[MASK]].8b, v2.8b, v3.8b
141  %cmp31 = fcmp oeq float %a, %b
142  %e = select i1 %cmp31, <1 x float> %c, <1 x float> %d
143  ret <1 x float> %e
144}
145
146define <2 x float> @test_select_cc_v2f32(float %a, float %b, <2 x float> %c, <2 x float> %d ) {
147; CHECK-LABEL: test_select_cc_v2f32:
148; CHECK: fcmeq [[MASK:v[0-9]+]].2s, v0.2s, v1.2s
149; CHECK: dup [[DUPMASK:v[0-9]+]].2s, [[MASK]].s[0]
150; CHECK: bsl [[DUPMASK]].8b, v2.8b, v3.8b
151  %cmp31 = fcmp oeq float %a, %b
152  %e = select i1 %cmp31, <2 x float> %c, <2 x float> %d
153  ret <2 x float> %e
154}
155
156define <4x float> @test_select_cc_v4f32(float %a, float %b, <4x float> %c, <4x float> %d ) {
157; CHECK-LABEL: test_select_cc_v4f32:
158; CHECK: fcmeq [[MASK:v[0-9]+]].4s, v0.4s, v1.4s
159; CHECK: dup [[DUPMASK:v[0-9]+]].4s, [[MASK]].s[0]
160; CHECK: bsl [[DUPMASK]].16b, v2.16b, v3.16b
161  %cmp31 = fcmp oeq float %a, %b
162  %e = select i1 %cmp31, <4x float> %c, <4x float> %d
163  ret <4x float> %e
164}
165
166define <4x float> @test_select_cc_v4f32_icmp(i32 %a, i32 %b, <4x float> %c, <4x float> %d ) {
167; CHECK-LABEL: test_select_cc_v4f32_icmp:
168; CHECK-DAG: fmov s[[LHS:[0-9]+]], w0
169; CHECK-DAG: fmov s[[RHS:[0-9]+]], w1
170; CHECK: cmeq [[MASK:v[0-9]+]].4s, v[[LHS]].4s, v[[RHS]].4s
171; CHECK: dup [[DUPMASK:v[0-9]+]].4s, [[MASK]].s[0]
172; CHECK: bsl [[DUPMASK]].16b, v0.16b, v1.16b
173  %cmp31 = icmp eq i32 %a, %b
174  %e = select i1 %cmp31, <4x float> %c, <4x float> %d
175  ret <4x float> %e
176}
177
178define <1 x double> @test_select_cc_v1f64(double %a, double %b, <1 x double> %c, <1 x double> %d ) {
179; CHECK-LABEL: test_select_cc_v1f64:
180; CHECK: fcmeq d[[MASK:[0-9]+]], d0, d1
181; CHECK: bsl v[[MASK]].8b, v2.8b, v3.8b
182  %cmp31 = fcmp oeq double %a, %b
183  %e = select i1 %cmp31, <1 x double> %c, <1 x double> %d
184  ret <1 x double> %e
185}
186
187define <1 x double> @test_select_cc_v1f64_icmp(i64 %a, i64 %b, <1 x double> %c, <1 x double> %d ) {
188; CHECK-LABEL: test_select_cc_v1f64_icmp:
189; CHECK-DAG: fmov [[LHS:d[0-9]+]], x0
190; CHECK-DAG: fmov [[RHS:d[0-9]+]], x1
191; CHECK: cmeq d[[MASK:[0-9]+]], [[LHS]], [[RHS]]
192; CHECK: bsl v[[MASK]].8b, v0.8b, v1.8b
193  %cmp31 = icmp eq i64 %a, %b
194  %e = select i1 %cmp31, <1 x double> %c, <1 x double> %d
195  ret <1 x double> %e
196}
197
198define <2 x double> @test_select_cc_v2f64(double %a, double %b, <2 x double> %c, <2 x double> %d ) {
199; CHECK-LABEL: test_select_cc_v2f64:
200; CHECK: fcmeq [[MASK:v[0-9]+]].2d, v0.2d, v1.2d
201; CHECK: dup [[DUPMASK:v[0-9]+]].2d, [[MASK]].d[0]
202; CHECK: bsl [[DUPMASK]].16b, v2.16b, v3.16b
203  %cmp31 = fcmp oeq double %a, %b
204  %e = select i1 %cmp31, <2 x double> %c, <2 x double> %d
205  ret <2 x double> %e
206}
207
208; Special case: when the select condition is an icmp with i1 operands, don't
209; do the comparison on vectors.
210; Part of PR21549.
211define <2 x i32> @test_select_cc_v2i32_icmpi1(i1 %cc, <2 x i32> %a, <2 x i32> %b) {
212; CHECK-LABEL: test_select_cc_v2i32_icmpi1:
213; CHECK: tst   w0, #0x1
214; CHECK: csetm [[MASK:w[0-9]+]], ne
215; CHECK: dup   [[DUPMASK:v[0-9]+]].2s, [[MASK]]
216; CHECK: bsl   [[DUPMASK]].8b, v0.8b, v1.8b
217; CHECK: mov   v0.16b, [[DUPMASK]].16b
218  %cmp = icmp ne i1 %cc, 0
219  %e = select i1 %cmp, <2 x i32> %a, <2 x i32> %b
220  ret <2 x i32> %e
221}
222