1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=SSE
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+xop  | FileCheck %s --check-prefix=XOP
4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx  | FileCheck %s --check-prefixes=AVX,AVX1
5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX2
6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefixes=AVX512,AVX512F
7; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512vl | FileCheck %s --check-prefixes=AVX512,AVX512VL
8
9;
10; 128-bit vectors
11;
12
13define <2 x i64> @bitselect_v2i64_rr(<2 x i64>, <2 x i64>) {
14; SSE-LABEL: bitselect_v2i64_rr:
15; SSE:       # %bb.0:
16; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
17; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
18; SSE-NEXT:    orps %xmm1, %xmm0
19; SSE-NEXT:    retq
20;
21; XOP-LABEL: bitselect_v2i64_rr:
22; XOP:       # %bb.0:
23; XOP-NEXT:    vpcmov {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm1, %xmm0
24; XOP-NEXT:    retq
25;
26; AVX-LABEL: bitselect_v2i64_rr:
27; AVX:       # %bb.0:
28; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
29; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1
30; AVX-NEXT:    vorps %xmm0, %xmm1, %xmm0
31; AVX-NEXT:    retq
32;
33; AVX512F-LABEL: bitselect_v2i64_rr:
34; AVX512F:       # %bb.0:
35; AVX512F-NEXT:    # kill: def $xmm1 killed $xmm1 def $zmm1
36; AVX512F-NEXT:    # kill: def $xmm0 killed $xmm0 def $zmm0
37; AVX512F-NEXT:    vmovdqa {{.*#+}} xmm2 = [18446744069414584319,18446744060824649725]
38; AVX512F-NEXT:    vpternlogq $216, %zmm2, %zmm1, %zmm0
39; AVX512F-NEXT:    # kill: def $xmm0 killed $xmm0 killed $zmm0
40; AVX512F-NEXT:    vzeroupper
41; AVX512F-NEXT:    retq
42;
43; AVX512VL-LABEL: bitselect_v2i64_rr:
44; AVX512VL:       # %bb.0:
45; AVX512VL-NEXT:    vpternlogq $216, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm0
46; AVX512VL-NEXT:    retq
47  %3 = and <2 x i64> %0, <i64 4294967296, i64 12884901890>
48  %4 = and <2 x i64> %1, <i64 -4294967297, i64 -12884901891>
49  %5 = or <2 x i64> %4, %3
50  ret <2 x i64> %5
51}
52
53define <2 x i64> @bitselect_v2i64_rm(<2 x i64>, ptr nocapture readonly) {
54; SSE-LABEL: bitselect_v2i64_rm:
55; SSE:       # %bb.0:
56; SSE-NEXT:    movaps (%rdi), %xmm1
57; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
58; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
59; SSE-NEXT:    orps %xmm1, %xmm0
60; SSE-NEXT:    retq
61;
62; XOP-LABEL: bitselect_v2i64_rm:
63; XOP:       # %bb.0:
64; XOP-NEXT:    vmovdqa (%rdi), %xmm1
65; XOP-NEXT:    vpcmov {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm1, %xmm0
66; XOP-NEXT:    retq
67;
68; AVX-LABEL: bitselect_v2i64_rm:
69; AVX:       # %bb.0:
70; AVX-NEXT:    vmovaps (%rdi), %xmm1
71; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
72; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1
73; AVX-NEXT:    vorps %xmm0, %xmm1, %xmm0
74; AVX-NEXT:    retq
75;
76; AVX512F-LABEL: bitselect_v2i64_rm:
77; AVX512F:       # %bb.0:
78; AVX512F-NEXT:    # kill: def $xmm0 killed $xmm0 def $zmm0
79; AVX512F-NEXT:    vmovdqa (%rdi), %xmm1
80; AVX512F-NEXT:    vmovdqa {{.*#+}} xmm2 = [18446744065119617022,18446744073709551612]
81; AVX512F-NEXT:    vpternlogq $184, %zmm1, %zmm2, %zmm0
82; AVX512F-NEXT:    # kill: def $xmm0 killed $xmm0 killed $zmm0
83; AVX512F-NEXT:    vzeroupper
84; AVX512F-NEXT:    retq
85;
86; AVX512VL-LABEL: bitselect_v2i64_rm:
87; AVX512VL:       # %bb.0:
88; AVX512VL-NEXT:    vmovdqa (%rdi), %xmm1
89; AVX512VL-NEXT:    vpternlogq $216, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm0
90; AVX512VL-NEXT:    retq
91  %3 = load <2 x i64>, ptr %1
92  %4 = and <2 x i64> %0, <i64 8589934593, i64 3>
93  %5 = and <2 x i64> %3, <i64 -8589934594, i64 -4>
94  %6 = or <2 x i64> %5, %4
95  ret <2 x i64> %6
96}
97
98define <2 x i64> @bitselect_v2i64_mr(ptr nocapture readonly, <2 x i64>) {
99; SSE-LABEL: bitselect_v2i64_mr:
100; SSE:       # %bb.0:
101; SSE-NEXT:    movaps (%rdi), %xmm1
102; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
103; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
104; SSE-NEXT:    orps %xmm1, %xmm0
105; SSE-NEXT:    retq
106;
107; XOP-LABEL: bitselect_v2i64_mr:
108; XOP:       # %bb.0:
109; XOP-NEXT:    vmovdqa (%rdi), %xmm1
110; XOP-NEXT:    vpcmov {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm1, %xmm0
111; XOP-NEXT:    retq
112;
113; AVX-LABEL: bitselect_v2i64_mr:
114; AVX:       # %bb.0:
115; AVX-NEXT:    vmovaps (%rdi), %xmm1
116; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1
117; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
118; AVX-NEXT:    vorps %xmm0, %xmm1, %xmm0
119; AVX-NEXT:    retq
120;
121; AVX512F-LABEL: bitselect_v2i64_mr:
122; AVX512F:       # %bb.0:
123; AVX512F-NEXT:    # kill: def $xmm0 killed $xmm0 def $zmm0
124; AVX512F-NEXT:    vmovdqa (%rdi), %xmm1
125; AVX512F-NEXT:    vmovdqa {{.*#+}} xmm2 = [12884901890,4294967296]
126; AVX512F-NEXT:    vpternlogq $184, %zmm1, %zmm2, %zmm0
127; AVX512F-NEXT:    # kill: def $xmm0 killed $xmm0 killed $zmm0
128; AVX512F-NEXT:    vzeroupper
129; AVX512F-NEXT:    retq
130;
131; AVX512VL-LABEL: bitselect_v2i64_mr:
132; AVX512VL:       # %bb.0:
133; AVX512VL-NEXT:    vmovdqa (%rdi), %xmm1
134; AVX512VL-NEXT:    vpternlogq $216, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm0
135; AVX512VL-NEXT:    retq
136  %3 = load <2 x i64>, ptr %0
137  %4 = and <2 x i64> %3, <i64 12884901890, i64 4294967296>
138  %5 = and <2 x i64> %1, <i64 -12884901891, i64 -4294967297>
139  %6 = or <2 x i64> %4, %5
140  ret <2 x i64> %6
141}
142
143define <2 x i64> @bitselect_v2i64_mm(ptr nocapture readonly, ptr nocapture readonly) {
144; SSE-LABEL: bitselect_v2i64_mm:
145; SSE:       # %bb.0:
146; SSE-NEXT:    movaps (%rdi), %xmm1
147; SSE-NEXT:    movaps (%rsi), %xmm0
148; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
149; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
150; SSE-NEXT:    orps %xmm1, %xmm0
151; SSE-NEXT:    retq
152;
153; XOP-LABEL: bitselect_v2i64_mm:
154; XOP:       # %bb.0:
155; XOP-NEXT:    vmovdqa (%rsi), %xmm0
156; XOP-NEXT:    vmovdqa {{.*#+}} xmm1 = [18446744073709551612,18446744065119617022]
157; XOP-NEXT:    vpcmov %xmm1, (%rdi), %xmm0, %xmm0
158; XOP-NEXT:    retq
159;
160; AVX-LABEL: bitselect_v2i64_mm:
161; AVX:       # %bb.0:
162; AVX-NEXT:    vmovaps (%rdi), %xmm0
163; AVX-NEXT:    vmovaps (%rsi), %xmm1
164; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
165; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1
166; AVX-NEXT:    vorps %xmm0, %xmm1, %xmm0
167; AVX-NEXT:    retq
168;
169; AVX512F-LABEL: bitselect_v2i64_mm:
170; AVX512F:       # %bb.0:
171; AVX512F-NEXT:    vmovdqa (%rdi), %xmm1
172; AVX512F-NEXT:    vmovdqa (%rsi), %xmm0
173; AVX512F-NEXT:    vmovdqa {{.*#+}} xmm2 = [18446744073709551612,18446744065119617022]
174; AVX512F-NEXT:    vpternlogq $226, %zmm1, %zmm2, %zmm0
175; AVX512F-NEXT:    # kill: def $xmm0 killed $xmm0 killed $zmm0
176; AVX512F-NEXT:    vzeroupper
177; AVX512F-NEXT:    retq
178;
179; AVX512VL-LABEL: bitselect_v2i64_mm:
180; AVX512VL:       # %bb.0:
181; AVX512VL-NEXT:    vmovdqa (%rsi), %xmm1
182; AVX512VL-NEXT:    vmovdqa {{.*#+}} xmm0 = [18446744073709551612,18446744065119617022]
183; AVX512VL-NEXT:    vpternlogq $202, (%rdi), %xmm1, %xmm0
184; AVX512VL-NEXT:    retq
185  %3 = load <2 x i64>, ptr %0
186  %4 = load <2 x i64>, ptr %1
187  %5 = and <2 x i64> %3, <i64 3, i64 8589934593>
188  %6 = and <2 x i64> %4, <i64 -4, i64 -8589934594>
189  %7 = or <2 x i64> %6, %5
190  ret <2 x i64> %7
191}
192
193define <2 x i64> @bitselect_v2i64_broadcast_rrr(<2 x i64> %a0, <2 x i64> %a1, i64 %a2) {
194; SSE-LABEL: bitselect_v2i64_broadcast_rrr:
195; SSE:       # %bb.0:
196; SSE-NEXT:    movq %rdi, %xmm2
197; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,1,0,1]
198; SSE-NEXT:    pand %xmm2, %xmm0
199; SSE-NEXT:    pandn %xmm1, %xmm2
200; SSE-NEXT:    por %xmm2, %xmm0
201; SSE-NEXT:    retq
202;
203; XOP-LABEL: bitselect_v2i64_broadcast_rrr:
204; XOP:       # %bb.0:
205; XOP-NEXT:    vmovq %rdi, %xmm2
206; XOP-NEXT:    vpshufd {{.*#+}} xmm2 = xmm2[0,1,0,1]
207; XOP-NEXT:    vpcmov %xmm2, %xmm1, %xmm0, %xmm0
208; XOP-NEXT:    retq
209;
210; AVX1-LABEL: bitselect_v2i64_broadcast_rrr:
211; AVX1:       # %bb.0:
212; AVX1-NEXT:    vmovq %rdi, %xmm2
213; AVX1-NEXT:    vpshufd {{.*#+}} xmm2 = xmm2[0,1,0,1]
214; AVX1-NEXT:    vpand %xmm2, %xmm0, %xmm0
215; AVX1-NEXT:    vpandn %xmm1, %xmm2, %xmm1
216; AVX1-NEXT:    vpor %xmm1, %xmm0, %xmm0
217; AVX1-NEXT:    retq
218;
219; AVX2-LABEL: bitselect_v2i64_broadcast_rrr:
220; AVX2:       # %bb.0:
221; AVX2-NEXT:    vmovq %rdi, %xmm2
222; AVX2-NEXT:    vpbroadcastq %xmm2, %xmm2
223; AVX2-NEXT:    vpand %xmm2, %xmm0, %xmm0
224; AVX2-NEXT:    vpandn %xmm1, %xmm2, %xmm1
225; AVX2-NEXT:    vpor %xmm1, %xmm0, %xmm0
226; AVX2-NEXT:    retq
227;
228; AVX512F-LABEL: bitselect_v2i64_broadcast_rrr:
229; AVX512F:       # %bb.0:
230; AVX512F-NEXT:    vmovq %rdi, %xmm2
231; AVX512F-NEXT:    vpbroadcastq %xmm2, %xmm2
232; AVX512F-NEXT:    vpand %xmm2, %xmm0, %xmm0
233; AVX512F-NEXT:    vpandn %xmm1, %xmm2, %xmm1
234; AVX512F-NEXT:    vpor %xmm1, %xmm0, %xmm0
235; AVX512F-NEXT:    retq
236;
237; AVX512VL-LABEL: bitselect_v2i64_broadcast_rrr:
238; AVX512VL:       # %bb.0:
239; AVX512VL-NEXT:    vpbroadcastq %rdi, %xmm2
240; AVX512VL-NEXT:    vpternlogq $226, %xmm1, %xmm2, %xmm0
241; AVX512VL-NEXT:    retq
242  %1 = insertelement <2 x i64> undef, i64 %a2, i32 0
243  %2 = shufflevector <2 x i64> %1, <2 x i64> undef, <2 x i32> zeroinitializer
244  %3 = xor <2 x i64> %1, <i64 -1, i64 undef>
245  %4 = shufflevector <2 x i64> %3, <2 x i64> undef, <2 x i32> zeroinitializer
246  %5 = and <2 x i64> %a0, %2
247  %6 = and <2 x i64> %a1, %4
248  %7 = or <2 x i64> %5, %6
249  ret <2 x i64> %7
250}
251
252define <2 x i64> @bitselect_v2i64_broadcast_rrm(<2 x i64> %a0, <2 x i64> %a1, ptr %p2) {
253; SSE-LABEL: bitselect_v2i64_broadcast_rrm:
254; SSE:       # %bb.0:
255; SSE-NEXT:    movq {{.*#+}} xmm2 = mem[0],zero
256; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,1,0,1]
257; SSE-NEXT:    pand %xmm2, %xmm0
258; SSE-NEXT:    pandn %xmm1, %xmm2
259; SSE-NEXT:    por %xmm2, %xmm0
260; SSE-NEXT:    retq
261;
262; XOP-LABEL: bitselect_v2i64_broadcast_rrm:
263; XOP:       # %bb.0:
264; XOP-NEXT:    vmovddup {{.*#+}} xmm2 = mem[0,0]
265; XOP-NEXT:    vpcmov %xmm2, %xmm1, %xmm0, %xmm0
266; XOP-NEXT:    retq
267;
268; AVX-LABEL: bitselect_v2i64_broadcast_rrm:
269; AVX:       # %bb.0:
270; AVX-NEXT:    vmovddup {{.*#+}} xmm2 = mem[0,0]
271; AVX-NEXT:    vandps %xmm2, %xmm0, %xmm0
272; AVX-NEXT:    vandnps %xmm1, %xmm2, %xmm1
273; AVX-NEXT:    vorps %xmm1, %xmm0, %xmm0
274; AVX-NEXT:    retq
275;
276; AVX512F-LABEL: bitselect_v2i64_broadcast_rrm:
277; AVX512F:       # %bb.0:
278; AVX512F-NEXT:    vmovddup {{.*#+}} xmm2 = mem[0,0]
279; AVX512F-NEXT:    vandps %xmm2, %xmm0, %xmm0
280; AVX512F-NEXT:    vandnps %xmm1, %xmm2, %xmm1
281; AVX512F-NEXT:    vorps %xmm1, %xmm0, %xmm0
282; AVX512F-NEXT:    retq
283;
284; AVX512VL-LABEL: bitselect_v2i64_broadcast_rrm:
285; AVX512VL:       # %bb.0:
286; AVX512VL-NEXT:    vpternlogq $228, (%rdi){1to2}, %xmm1, %xmm0
287; AVX512VL-NEXT:    retq
288  %a2 = load i64, ptr %p2
289  %1 = insertelement <2 x i64> undef, i64 %a2, i32 0
290  %2 = shufflevector <2 x i64> %1, <2 x i64> undef, <2 x i32> zeroinitializer
291  %3 = xor <2 x i64> %1, <i64 -1, i64 undef>
292  %4 = shufflevector <2 x i64> %3, <2 x i64> undef, <2 x i32> zeroinitializer
293  %5 = and <2 x i64> %a0, %2
294  %6 = and <2 x i64> %a1, %4
295  %7 = or <2 x i64> %5, %6
296  ret <2 x i64> %7
297}
298
299;
300; 256-bit vectors
301;
302
303define <4 x i64> @bitselect_v4i64_rr(<4 x i64>, <4 x i64>) {
304; SSE-LABEL: bitselect_v4i64_rr:
305; SSE:       # %bb.0:
306; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
307; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
308; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm3
309; SSE-NEXT:    orps %xmm3, %xmm1
310; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
311; SSE-NEXT:    orps %xmm2, %xmm0
312; SSE-NEXT:    retq
313;
314; XOP-LABEL: bitselect_v4i64_rr:
315; XOP:       # %bb.0:
316; XOP-NEXT:    vpcmov {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm1, %ymm0
317; XOP-NEXT:    retq
318;
319; AVX-LABEL: bitselect_v4i64_rr:
320; AVX:       # %bb.0:
321; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
322; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm1, %ymm1
323; AVX-NEXT:    vorps %ymm0, %ymm1, %ymm0
324; AVX-NEXT:    retq
325;
326; AVX512F-LABEL: bitselect_v4i64_rr:
327; AVX512F:       # %bb.0:
328; AVX512F-NEXT:    # kill: def $ymm1 killed $ymm1 def $zmm1
329; AVX512F-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
330; AVX512F-NEXT:    vmovdqa {{.*#+}} ymm2 = [18446744069414584319,18446744060824649725,18446744060824649725,18446744060824649725]
331; AVX512F-NEXT:    vpternlogq $216, %zmm2, %zmm1, %zmm0
332; AVX512F-NEXT:    # kill: def $ymm0 killed $ymm0 killed $zmm0
333; AVX512F-NEXT:    retq
334;
335; AVX512VL-LABEL: bitselect_v4i64_rr:
336; AVX512VL:       # %bb.0:
337; AVX512VL-NEXT:    vpternlogq $216, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm1, %ymm0
338; AVX512VL-NEXT:    retq
339  %3 = and <4 x i64> %0, <i64 4294967296, i64 12884901890, i64 12884901890, i64 12884901890>
340  %4 = and <4 x i64> %1, <i64 -4294967297, i64 -12884901891, i64 -12884901891, i64 -12884901891>
341  %5 = or <4 x i64> %4, %3
342  ret <4 x i64> %5
343}
344
345define <4 x i64> @bitselect_v4i64_rm(<4 x i64>, ptr nocapture readonly) {
346; SSE-LABEL: bitselect_v4i64_rm:
347; SSE:       # %bb.0:
348; SSE-NEXT:    movaps {{.*#+}} xmm2 = [18446744065119617022,18446744073709551612]
349; SSE-NEXT:    movaps 16(%rdi), %xmm4
350; SSE-NEXT:    andps %xmm2, %xmm4
351; SSE-NEXT:    movaps (%rdi), %xmm5
352; SSE-NEXT:    andps %xmm2, %xmm5
353; SSE-NEXT:    movaps %xmm2, %xmm3
354; SSE-NEXT:    andnps %xmm0, %xmm3
355; SSE-NEXT:    orps %xmm5, %xmm3
356; SSE-NEXT:    andnps %xmm1, %xmm2
357; SSE-NEXT:    orps %xmm4, %xmm2
358; SSE-NEXT:    movaps %xmm3, %xmm0
359; SSE-NEXT:    movaps %xmm2, %xmm1
360; SSE-NEXT:    retq
361;
362; XOP-LABEL: bitselect_v4i64_rm:
363; XOP:       # %bb.0:
364; XOP-NEXT:    vmovdqa (%rdi), %ymm1
365; XOP-NEXT:    vpcmov {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm1, %ymm0
366; XOP-NEXT:    retq
367;
368; AVX-LABEL: bitselect_v4i64_rm:
369; AVX:       # %bb.0:
370; AVX-NEXT:    vmovaps (%rdi), %ymm1
371; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
372; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm1, %ymm1
373; AVX-NEXT:    vorps %ymm0, %ymm1, %ymm0
374; AVX-NEXT:    retq
375;
376; AVX512F-LABEL: bitselect_v4i64_rm:
377; AVX512F:       # %bb.0:
378; AVX512F-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
379; AVX512F-NEXT:    vmovdqa (%rdi), %ymm1
380; AVX512F-NEXT:    vmovdqa {{.*#+}} ymm2 = [18446744065119617022,18446744073709551612,18446744065119617022,18446744073709551612]
381; AVX512F-NEXT:    vpternlogq $184, %zmm1, %zmm2, %zmm0
382; AVX512F-NEXT:    # kill: def $ymm0 killed $ymm0 killed $zmm0
383; AVX512F-NEXT:    retq
384;
385; AVX512VL-LABEL: bitselect_v4i64_rm:
386; AVX512VL:       # %bb.0:
387; AVX512VL-NEXT:    vmovdqa (%rdi), %ymm1
388; AVX512VL-NEXT:    vpternlogq $216, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm1, %ymm0
389; AVX512VL-NEXT:    retq
390  %3 = load <4 x i64>, ptr %1
391  %4 = and <4 x i64> %0, <i64 8589934593, i64 3, i64 8589934593, i64 3>
392  %5 = and <4 x i64> %3, <i64 -8589934594, i64 -4, i64 -8589934594, i64 -4>
393  %6 = or <4 x i64> %5, %4
394  ret <4 x i64> %6
395}
396
397define <4 x i64> @bitselect_v4i64_mr(ptr nocapture readonly, <4 x i64>) {
398; SSE-LABEL: bitselect_v4i64_mr:
399; SSE:       # %bb.0:
400; SSE-NEXT:    movaps {{.*#+}} xmm2 = [12884901890,4294967296]
401; SSE-NEXT:    movaps 16(%rdi), %xmm4
402; SSE-NEXT:    andps %xmm2, %xmm4
403; SSE-NEXT:    movaps (%rdi), %xmm5
404; SSE-NEXT:    andps %xmm2, %xmm5
405; SSE-NEXT:    movaps %xmm2, %xmm3
406; SSE-NEXT:    andnps %xmm0, %xmm3
407; SSE-NEXT:    orps %xmm5, %xmm3
408; SSE-NEXT:    andnps %xmm1, %xmm2
409; SSE-NEXT:    orps %xmm4, %xmm2
410; SSE-NEXT:    movaps %xmm3, %xmm0
411; SSE-NEXT:    movaps %xmm2, %xmm1
412; SSE-NEXT:    retq
413;
414; XOP-LABEL: bitselect_v4i64_mr:
415; XOP:       # %bb.0:
416; XOP-NEXT:    vmovdqa (%rdi), %ymm1
417; XOP-NEXT:    vpcmov {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm1, %ymm0
418; XOP-NEXT:    retq
419;
420; AVX-LABEL: bitselect_v4i64_mr:
421; AVX:       # %bb.0:
422; AVX-NEXT:    vmovaps (%rdi), %ymm1
423; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm1, %ymm1
424; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
425; AVX-NEXT:    vorps %ymm0, %ymm1, %ymm0
426; AVX-NEXT:    retq
427;
428; AVX512F-LABEL: bitselect_v4i64_mr:
429; AVX512F:       # %bb.0:
430; AVX512F-NEXT:    # kill: def $ymm0 killed $ymm0 def $zmm0
431; AVX512F-NEXT:    vmovdqa (%rdi), %ymm1
432; AVX512F-NEXT:    vmovdqa {{.*#+}} ymm2 = [12884901890,4294967296,12884901890,4294967296]
433; AVX512F-NEXT:    vpternlogq $184, %zmm1, %zmm2, %zmm0
434; AVX512F-NEXT:    # kill: def $ymm0 killed $ymm0 killed $zmm0
435; AVX512F-NEXT:    retq
436;
437; AVX512VL-LABEL: bitselect_v4i64_mr:
438; AVX512VL:       # %bb.0:
439; AVX512VL-NEXT:    vmovdqa (%rdi), %ymm1
440; AVX512VL-NEXT:    vpternlogq $216, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm1, %ymm0
441; AVX512VL-NEXT:    retq
442  %3 = load <4 x i64>, ptr %0
443  %4 = and <4 x i64> %3, <i64 12884901890, i64 4294967296, i64 12884901890, i64 4294967296>
444  %5 = and <4 x i64> %1, <i64 -12884901891, i64 -4294967297, i64 -12884901891, i64 -4294967297>
445  %6 = or <4 x i64> %4, %5
446  ret <4 x i64> %6
447}
448
449define <4 x i64> @bitselect_v4i64_mm(ptr nocapture readonly, ptr nocapture readonly) {
450; SSE-LABEL: bitselect_v4i64_mm:
451; SSE:       # %bb.0:
452; SSE-NEXT:    movaps {{.*#+}} xmm1 = [18446744073709551612,18446744065119617022]
453; SSE-NEXT:    movaps 16(%rsi), %xmm2
454; SSE-NEXT:    andps %xmm1, %xmm2
455; SSE-NEXT:    movaps (%rsi), %xmm3
456; SSE-NEXT:    andps %xmm1, %xmm3
457; SSE-NEXT:    movaps %xmm1, %xmm0
458; SSE-NEXT:    andnps (%rdi), %xmm0
459; SSE-NEXT:    orps %xmm3, %xmm0
460; SSE-NEXT:    andnps 16(%rdi), %xmm1
461; SSE-NEXT:    orps %xmm2, %xmm1
462; SSE-NEXT:    retq
463;
464; XOP-LABEL: bitselect_v4i64_mm:
465; XOP:       # %bb.0:
466; XOP-NEXT:    vmovdqa (%rsi), %ymm0
467; XOP-NEXT:    vmovdqa {{.*#+}} ymm1 = [18446744073709551612,18446744065119617022,18446744073709551612,18446744065119617022]
468; XOP-NEXT:    vpcmov %ymm1, (%rdi), %ymm0, %ymm0
469; XOP-NEXT:    retq
470;
471; AVX-LABEL: bitselect_v4i64_mm:
472; AVX:       # %bb.0:
473; AVX-NEXT:    vmovaps (%rdi), %ymm0
474; AVX-NEXT:    vmovaps (%rsi), %ymm1
475; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0
476; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm1, %ymm1
477; AVX-NEXT:    vorps %ymm0, %ymm1, %ymm0
478; AVX-NEXT:    retq
479;
480; AVX512F-LABEL: bitselect_v4i64_mm:
481; AVX512F:       # %bb.0:
482; AVX512F-NEXT:    vmovdqa (%rdi), %ymm1
483; AVX512F-NEXT:    vmovdqa (%rsi), %ymm0
484; AVX512F-NEXT:    vmovdqa {{.*#+}} ymm2 = [18446744073709551612,18446744065119617022,18446744073709551612,18446744065119617022]
485; AVX512F-NEXT:    vpternlogq $226, %zmm1, %zmm2, %zmm0
486; AVX512F-NEXT:    # kill: def $ymm0 killed $ymm0 killed $zmm0
487; AVX512F-NEXT:    retq
488;
489; AVX512VL-LABEL: bitselect_v4i64_mm:
490; AVX512VL:       # %bb.0:
491; AVX512VL-NEXT:    vmovdqa (%rsi), %ymm1
492; AVX512VL-NEXT:    vmovdqa {{.*#+}} ymm0 = [18446744073709551612,18446744065119617022,18446744073709551612,18446744065119617022]
493; AVX512VL-NEXT:    vpternlogq $202, (%rdi), %ymm1, %ymm0
494; AVX512VL-NEXT:    retq
495  %3 = load <4 x i64>, ptr %0
496  %4 = load <4 x i64>, ptr %1
497  %5 = and <4 x i64> %3, <i64 3, i64 8589934593, i64 3, i64 8589934593>
498  %6 = and <4 x i64> %4, <i64 -4, i64 -8589934594, i64 -4, i64 -8589934594>
499  %7 = or <4 x i64> %6, %5
500  ret <4 x i64> %7
501}
502
503define <4 x i64> @bitselect_v4i64_broadcast_rrr(<4 x i64> %a0, <4 x i64> %a1, i64 %a2) {
504; SSE-LABEL: bitselect_v4i64_broadcast_rrr:
505; SSE:       # %bb.0:
506; SSE-NEXT:    movq %rdi, %xmm4
507; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[0,1,0,1]
508; SSE-NEXT:    pand %xmm4, %xmm1
509; SSE-NEXT:    pand %xmm4, %xmm0
510; SSE-NEXT:    movdqa %xmm4, %xmm5
511; SSE-NEXT:    pandn %xmm3, %xmm5
512; SSE-NEXT:    por %xmm5, %xmm1
513; SSE-NEXT:    pandn %xmm2, %xmm4
514; SSE-NEXT:    por %xmm4, %xmm0
515; SSE-NEXT:    retq
516;
517; XOP-LABEL: bitselect_v4i64_broadcast_rrr:
518; XOP:       # %bb.0:
519; XOP-NEXT:    vmovq %rdi, %xmm2
520; XOP-NEXT:    vpshufd {{.*#+}} xmm2 = xmm2[0,1,0,1]
521; XOP-NEXT:    vinsertf128 $1, %xmm2, %ymm2, %ymm2
522; XOP-NEXT:    vpcmov %ymm2, %ymm1, %ymm0, %ymm0
523; XOP-NEXT:    retq
524;
525; AVX1-LABEL: bitselect_v4i64_broadcast_rrr:
526; AVX1:       # %bb.0:
527; AVX1-NEXT:    vmovq %rdi, %xmm2
528; AVX1-NEXT:    vpshufd {{.*#+}} xmm2 = xmm2[0,1,0,1]
529; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm2, %ymm2
530; AVX1-NEXT:    vandps %ymm2, %ymm0, %ymm0
531; AVX1-NEXT:    vandnps %ymm1, %ymm2, %ymm1
532; AVX1-NEXT:    vorps %ymm1, %ymm0, %ymm0
533; AVX1-NEXT:    retq
534;
535; AVX2-LABEL: bitselect_v4i64_broadcast_rrr:
536; AVX2:       # %bb.0:
537; AVX2-NEXT:    vmovq %rdi, %xmm2
538; AVX2-NEXT:    vpbroadcastq %xmm2, %ymm2
539; AVX2-NEXT:    vpand %ymm2, %ymm0, %ymm0
540; AVX2-NEXT:    vpandn %ymm1, %ymm2, %ymm1
541; AVX2-NEXT:    vpor %ymm1, %ymm0, %ymm0
542; AVX2-NEXT:    retq
543;
544; AVX512F-LABEL: bitselect_v4i64_broadcast_rrr:
545; AVX512F:       # %bb.0:
546; AVX512F-NEXT:    vmovq %rdi, %xmm2
547; AVX512F-NEXT:    vpbroadcastq %xmm2, %ymm2
548; AVX512F-NEXT:    vpand %ymm2, %ymm0, %ymm0
549; AVX512F-NEXT:    vpandn %ymm1, %ymm2, %ymm1
550; AVX512F-NEXT:    vpor %ymm1, %ymm0, %ymm0
551; AVX512F-NEXT:    retq
552;
553; AVX512VL-LABEL: bitselect_v4i64_broadcast_rrr:
554; AVX512VL:       # %bb.0:
555; AVX512VL-NEXT:    vpbroadcastq %rdi, %ymm2
556; AVX512VL-NEXT:    vpternlogq $226, %ymm1, %ymm2, %ymm0
557; AVX512VL-NEXT:    retq
558  %1 = insertelement <4 x i64> undef, i64 %a2, i32 0
559  %2 = shufflevector <4 x i64> %1, <4 x i64> undef, <4 x i32> zeroinitializer
560  %3 = xor <4 x i64> %1, <i64 -1, i64 undef, i64 undef, i64 undef>
561  %4 = shufflevector <4 x i64> %3, <4 x i64> undef, <4 x i32> zeroinitializer
562  %5 = and <4 x i64> %a0, %2
563  %6 = and <4 x i64> %a1, %4
564  %7 = or <4 x i64> %5, %6
565  ret <4 x i64> %7
566}
567
568define <4 x i64> @bitselect_v4i64_broadcast_rrm(<4 x i64> %a0, <4 x i64> %a1, ptr %p2) {
569; SSE-LABEL: bitselect_v4i64_broadcast_rrm:
570; SSE:       # %bb.0:
571; SSE-NEXT:    movq {{.*#+}} xmm4 = mem[0],zero
572; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[0,1,0,1]
573; SSE-NEXT:    pand %xmm4, %xmm1
574; SSE-NEXT:    pand %xmm4, %xmm0
575; SSE-NEXT:    movdqa %xmm4, %xmm5
576; SSE-NEXT:    pandn %xmm3, %xmm5
577; SSE-NEXT:    por %xmm5, %xmm1
578; SSE-NEXT:    pandn %xmm2, %xmm4
579; SSE-NEXT:    por %xmm4, %xmm0
580; SSE-NEXT:    retq
581;
582; XOP-LABEL: bitselect_v4i64_broadcast_rrm:
583; XOP:       # %bb.0:
584; XOP-NEXT:    vbroadcastsd (%rdi), %ymm2
585; XOP-NEXT:    vpcmov %ymm2, %ymm1, %ymm0, %ymm0
586; XOP-NEXT:    retq
587;
588; AVX-LABEL: bitselect_v4i64_broadcast_rrm:
589; AVX:       # %bb.0:
590; AVX-NEXT:    vbroadcastsd (%rdi), %ymm2
591; AVX-NEXT:    vandps %ymm2, %ymm0, %ymm0
592; AVX-NEXT:    vandnps %ymm1, %ymm2, %ymm1
593; AVX-NEXT:    vorps %ymm1, %ymm0, %ymm0
594; AVX-NEXT:    retq
595;
596; AVX512F-LABEL: bitselect_v4i64_broadcast_rrm:
597; AVX512F:       # %bb.0:
598; AVX512F-NEXT:    vbroadcastsd (%rdi), %ymm2
599; AVX512F-NEXT:    vandps %ymm2, %ymm0, %ymm0
600; AVX512F-NEXT:    vandnps %ymm1, %ymm2, %ymm1
601; AVX512F-NEXT:    vorps %ymm1, %ymm0, %ymm0
602; AVX512F-NEXT:    retq
603;
604; AVX512VL-LABEL: bitselect_v4i64_broadcast_rrm:
605; AVX512VL:       # %bb.0:
606; AVX512VL-NEXT:    vpternlogq $228, (%rdi){1to4}, %ymm1, %ymm0
607; AVX512VL-NEXT:    retq
608  %a2 = load i64, ptr %p2
609  %1 = insertelement <4 x i64> undef, i64 %a2, i32 0
610  %2 = shufflevector <4 x i64> %1, <4 x i64> undef, <4 x i32> zeroinitializer
611  %3 = xor <4 x i64> %1, <i64 -1, i64 undef, i64 undef, i64 undef>
612  %4 = shufflevector <4 x i64> %3, <4 x i64> undef, <4 x i32> zeroinitializer
613  %5 = and <4 x i64> %a0, %2
614  %6 = and <4 x i64> %a1, %4
615  %7 = or <4 x i64> %5, %6
616  ret <4 x i64> %7
617}
618
619;
620; 512-bit vectors
621;
622
623define <8 x i64> @bitselect_v8i64_rr(<8 x i64>, <8 x i64>) {
624; SSE-LABEL: bitselect_v8i64_rr:
625; SSE:       # %bb.0:
626; SSE-NEXT:    movaps {{.*#+}} xmm8 = [18446744060824649725,18446744060824649725]
627; SSE-NEXT:    andps %xmm8, %xmm7
628; SSE-NEXT:    movaps {{.*#+}} xmm9 = [18446744069414584319,18446744060824649725]
629; SSE-NEXT:    andps %xmm9, %xmm6
630; SSE-NEXT:    andps %xmm8, %xmm5
631; SSE-NEXT:    andps %xmm9, %xmm4
632; SSE-NEXT:    movaps %xmm9, %xmm10
633; SSE-NEXT:    andnps %xmm0, %xmm10
634; SSE-NEXT:    orps %xmm4, %xmm10
635; SSE-NEXT:    movaps %xmm8, %xmm4
636; SSE-NEXT:    andnps %xmm1, %xmm4
637; SSE-NEXT:    orps %xmm5, %xmm4
638; SSE-NEXT:    andnps %xmm2, %xmm9
639; SSE-NEXT:    orps %xmm6, %xmm9
640; SSE-NEXT:    andnps %xmm3, %xmm8
641; SSE-NEXT:    orps %xmm7, %xmm8
642; SSE-NEXT:    movaps %xmm10, %xmm0
643; SSE-NEXT:    movaps %xmm4, %xmm1
644; SSE-NEXT:    movaps %xmm9, %xmm2
645; SSE-NEXT:    movaps %xmm8, %xmm3
646; SSE-NEXT:    retq
647;
648; XOP-LABEL: bitselect_v8i64_rr:
649; XOP:       # %bb.0:
650; XOP-NEXT:    vmovdqa {{.*#+}} ymm4 = [18446744069414584319,18446744060824649725,18446744060824649725,18446744060824649725]
651; XOP-NEXT:    vpcmov %ymm4, %ymm0, %ymm2, %ymm0
652; XOP-NEXT:    vpcmov %ymm4, %ymm1, %ymm3, %ymm1
653; XOP-NEXT:    retq
654;
655; AVX-LABEL: bitselect_v8i64_rr:
656; AVX:       # %bb.0:
657; AVX-NEXT:    vmovaps {{.*#+}} ymm4 = [18446744069414584319,18446744060824649725,18446744060824649725,18446744060824649725]
658; AVX-NEXT:    vandps %ymm4, %ymm3, %ymm3
659; AVX-NEXT:    vandps %ymm4, %ymm2, %ymm2
660; AVX-NEXT:    vandnps %ymm0, %ymm4, %ymm0
661; AVX-NEXT:    vorps %ymm0, %ymm2, %ymm0
662; AVX-NEXT:    vandnps %ymm1, %ymm4, %ymm1
663; AVX-NEXT:    vorps %ymm1, %ymm3, %ymm1
664; AVX-NEXT:    retq
665;
666; AVX512-LABEL: bitselect_v8i64_rr:
667; AVX512:       # %bb.0:
668; AVX512-NEXT:    vpternlogq $216, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %zmm1, %zmm0
669; AVX512-NEXT:    retq
670  %3 = and <8 x i64> %0, <i64 4294967296, i64 12884901890, i64 12884901890, i64 12884901890, i64 4294967296, i64 12884901890, i64 12884901890, i64 12884901890>
671  %4 = and <8 x i64> %1, <i64 -4294967297, i64 -12884901891, i64 -12884901891, i64 -12884901891, i64 -4294967297, i64 -12884901891, i64 -12884901891, i64 -12884901891>
672  %5 = or <8 x i64> %4, %3
673  ret <8 x i64> %5
674}
675
676define <8 x i64> @bitselect_v8i64_rm(<8 x i64>, ptr nocapture readonly) {
677; SSE-LABEL: bitselect_v8i64_rm:
678; SSE:       # %bb.0:
679; SSE-NEXT:    movaps {{.*#+}} xmm4 = [18446744065119617022,18446744073709551612]
680; SSE-NEXT:    movaps 48(%rdi), %xmm8
681; SSE-NEXT:    andps %xmm4, %xmm8
682; SSE-NEXT:    movaps 32(%rdi), %xmm9
683; SSE-NEXT:    andps %xmm4, %xmm9
684; SSE-NEXT:    movaps 16(%rdi), %xmm7
685; SSE-NEXT:    andps %xmm4, %xmm7
686; SSE-NEXT:    movaps (%rdi), %xmm6
687; SSE-NEXT:    andps %xmm4, %xmm6
688; SSE-NEXT:    movaps %xmm4, %xmm5
689; SSE-NEXT:    andnps %xmm0, %xmm5
690; SSE-NEXT:    orps %xmm6, %xmm5
691; SSE-NEXT:    movaps %xmm4, %xmm6
692; SSE-NEXT:    andnps %xmm1, %xmm6
693; SSE-NEXT:    orps %xmm7, %xmm6
694; SSE-NEXT:    movaps %xmm4, %xmm7
695; SSE-NEXT:    andnps %xmm2, %xmm7
696; SSE-NEXT:    orps %xmm9, %xmm7
697; SSE-NEXT:    andnps %xmm3, %xmm4
698; SSE-NEXT:    orps %xmm8, %xmm4
699; SSE-NEXT:    movaps %xmm5, %xmm0
700; SSE-NEXT:    movaps %xmm6, %xmm1
701; SSE-NEXT:    movaps %xmm7, %xmm2
702; SSE-NEXT:    movaps %xmm4, %xmm3
703; SSE-NEXT:    retq
704;
705; XOP-LABEL: bitselect_v8i64_rm:
706; XOP:       # %bb.0:
707; XOP-NEXT:    vmovdqa (%rdi), %ymm2
708; XOP-NEXT:    vmovdqa 32(%rdi), %ymm3
709; XOP-NEXT:    vbroadcastf128 {{.*#+}} ymm4 = [18446744065119617022,18446744073709551612,18446744065119617022,18446744073709551612]
710; XOP-NEXT:    # ymm4 = mem[0,1,0,1]
711; XOP-NEXT:    vpcmov %ymm4, %ymm0, %ymm2, %ymm0
712; XOP-NEXT:    vpcmov %ymm4, %ymm1, %ymm3, %ymm1
713; XOP-NEXT:    retq
714;
715; AVX-LABEL: bitselect_v8i64_rm:
716; AVX:       # %bb.0:
717; AVX-NEXT:    vbroadcastf128 {{.*#+}} ymm2 = [18446744065119617022,18446744073709551612,18446744065119617022,18446744073709551612]
718; AVX-NEXT:    # ymm2 = mem[0,1,0,1]
719; AVX-NEXT:    vandps 32(%rdi), %ymm2, %ymm3
720; AVX-NEXT:    vandps (%rdi), %ymm2, %ymm4
721; AVX-NEXT:    vandnps %ymm0, %ymm2, %ymm0
722; AVX-NEXT:    vorps %ymm0, %ymm4, %ymm0
723; AVX-NEXT:    vandnps %ymm1, %ymm2, %ymm1
724; AVX-NEXT:    vorps %ymm1, %ymm3, %ymm1
725; AVX-NEXT:    retq
726;
727; AVX512-LABEL: bitselect_v8i64_rm:
728; AVX512:       # %bb.0:
729; AVX512-NEXT:    vmovdqa64 (%rdi), %zmm1
730; AVX512-NEXT:    vpternlogq $216, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %zmm1, %zmm0
731; AVX512-NEXT:    retq
732  %3 = load <8 x i64>, ptr %1
733  %4 = and <8 x i64> %0, <i64 8589934593, i64 3, i64 8589934593, i64 3, i64 8589934593, i64 3, i64 8589934593, i64 3>
734  %5 = and <8 x i64> %3, <i64 -8589934594, i64 -4, i64 -8589934594, i64 -4, i64 -8589934594, i64 -4, i64 -8589934594, i64 -4>
735  %6 = or <8 x i64> %5, %4
736  ret <8 x i64> %6
737}
738
739define <8 x i64> @bitselect_v8i64_mr(ptr nocapture readonly, <8 x i64>) {
740; SSE-LABEL: bitselect_v8i64_mr:
741; SSE:       # %bb.0:
742; SSE-NEXT:    movaps {{.*#+}} xmm4 = [12884901890,4294967296]
743; SSE-NEXT:    movaps 48(%rdi), %xmm8
744; SSE-NEXT:    andps %xmm4, %xmm8
745; SSE-NEXT:    movaps 32(%rdi), %xmm9
746; SSE-NEXT:    andps %xmm4, %xmm9
747; SSE-NEXT:    movaps 16(%rdi), %xmm7
748; SSE-NEXT:    andps %xmm4, %xmm7
749; SSE-NEXT:    movaps (%rdi), %xmm6
750; SSE-NEXT:    andps %xmm4, %xmm6
751; SSE-NEXT:    movaps %xmm4, %xmm5
752; SSE-NEXT:    andnps %xmm0, %xmm5
753; SSE-NEXT:    orps %xmm6, %xmm5
754; SSE-NEXT:    movaps %xmm4, %xmm6
755; SSE-NEXT:    andnps %xmm1, %xmm6
756; SSE-NEXT:    orps %xmm7, %xmm6
757; SSE-NEXT:    movaps %xmm4, %xmm7
758; SSE-NEXT:    andnps %xmm2, %xmm7
759; SSE-NEXT:    orps %xmm9, %xmm7
760; SSE-NEXT:    andnps %xmm3, %xmm4
761; SSE-NEXT:    orps %xmm8, %xmm4
762; SSE-NEXT:    movaps %xmm5, %xmm0
763; SSE-NEXT:    movaps %xmm6, %xmm1
764; SSE-NEXT:    movaps %xmm7, %xmm2
765; SSE-NEXT:    movaps %xmm4, %xmm3
766; SSE-NEXT:    retq
767;
768; XOP-LABEL: bitselect_v8i64_mr:
769; XOP:       # %bb.0:
770; XOP-NEXT:    vmovdqa (%rdi), %ymm2
771; XOP-NEXT:    vmovdqa 32(%rdi), %ymm3
772; XOP-NEXT:    vbroadcastf128 {{.*#+}} ymm4 = [12884901890,4294967296,12884901890,4294967296]
773; XOP-NEXT:    # ymm4 = mem[0,1,0,1]
774; XOP-NEXT:    vpcmov %ymm4, %ymm0, %ymm2, %ymm0
775; XOP-NEXT:    vpcmov %ymm4, %ymm1, %ymm3, %ymm1
776; XOP-NEXT:    retq
777;
778; AVX-LABEL: bitselect_v8i64_mr:
779; AVX:       # %bb.0:
780; AVX-NEXT:    vbroadcastf128 {{.*#+}} ymm2 = [12884901890,4294967296,12884901890,4294967296]
781; AVX-NEXT:    # ymm2 = mem[0,1,0,1]
782; AVX-NEXT:    vandps 32(%rdi), %ymm2, %ymm3
783; AVX-NEXT:    vandps (%rdi), %ymm2, %ymm4
784; AVX-NEXT:    vandnps %ymm0, %ymm2, %ymm0
785; AVX-NEXT:    vorps %ymm0, %ymm4, %ymm0
786; AVX-NEXT:    vandnps %ymm1, %ymm2, %ymm1
787; AVX-NEXT:    vorps %ymm1, %ymm3, %ymm1
788; AVX-NEXT:    retq
789;
790; AVX512-LABEL: bitselect_v8i64_mr:
791; AVX512:       # %bb.0:
792; AVX512-NEXT:    vmovdqa64 (%rdi), %zmm1
793; AVX512-NEXT:    vpternlogq $216, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %zmm1, %zmm0
794; AVX512-NEXT:    retq
795  %3 = load <8 x i64>, ptr %0
796  %4 = and <8 x i64> %3, <i64 12884901890, i64 4294967296, i64 12884901890, i64 4294967296, i64 12884901890, i64 4294967296, i64 12884901890, i64 4294967296>
797  %5 = and <8 x i64> %1, <i64 -12884901891, i64 -4294967297, i64 -12884901891, i64 -4294967297, i64 -12884901891, i64 -4294967297, i64 -12884901891, i64 -4294967297>
798  %6 = or <8 x i64> %4, %5
799  ret <8 x i64> %6
800}
801
802define <8 x i64> @bitselect_v8i64_mm(ptr nocapture readonly, ptr nocapture readonly) {
803; SSE-LABEL: bitselect_v8i64_mm:
804; SSE:       # %bb.0:
805; SSE-NEXT:    movaps {{.*#+}} xmm3 = [18446744073709551612,18446744065119617022]
806; SSE-NEXT:    movaps 48(%rsi), %xmm4
807; SSE-NEXT:    andps %xmm3, %xmm4
808; SSE-NEXT:    movaps 32(%rsi), %xmm5
809; SSE-NEXT:    andps %xmm3, %xmm5
810; SSE-NEXT:    movaps 16(%rsi), %xmm2
811; SSE-NEXT:    andps %xmm3, %xmm2
812; SSE-NEXT:    movaps (%rsi), %xmm1
813; SSE-NEXT:    andps %xmm3, %xmm1
814; SSE-NEXT:    movaps %xmm3, %xmm0
815; SSE-NEXT:    andnps (%rdi), %xmm0
816; SSE-NEXT:    orps %xmm1, %xmm0
817; SSE-NEXT:    movaps %xmm3, %xmm1
818; SSE-NEXT:    andnps 16(%rdi), %xmm1
819; SSE-NEXT:    orps %xmm2, %xmm1
820; SSE-NEXT:    movaps %xmm3, %xmm2
821; SSE-NEXT:    andnps 32(%rdi), %xmm2
822; SSE-NEXT:    orps %xmm5, %xmm2
823; SSE-NEXT:    andnps 48(%rdi), %xmm3
824; SSE-NEXT:    orps %xmm4, %xmm3
825; SSE-NEXT:    retq
826;
827; XOP-LABEL: bitselect_v8i64_mm:
828; XOP:       # %bb.0:
829; XOP-NEXT:    vmovdqa (%rsi), %ymm0
830; XOP-NEXT:    vmovdqa 32(%rsi), %ymm1
831; XOP-NEXT:    vbroadcastf128 {{.*#+}} ymm2 = [18446744073709551612,18446744065119617022,18446744073709551612,18446744065119617022]
832; XOP-NEXT:    # ymm2 = mem[0,1,0,1]
833; XOP-NEXT:    vpcmov %ymm2, (%rdi), %ymm0, %ymm0
834; XOP-NEXT:    vpcmov %ymm2, 32(%rdi), %ymm1, %ymm1
835; XOP-NEXT:    retq
836;
837; AVX-LABEL: bitselect_v8i64_mm:
838; AVX:       # %bb.0:
839; AVX-NEXT:    vbroadcastf128 {{.*#+}} ymm1 = [18446744073709551612,18446744065119617022,18446744073709551612,18446744065119617022]
840; AVX-NEXT:    # ymm1 = mem[0,1,0,1]
841; AVX-NEXT:    vandps 32(%rsi), %ymm1, %ymm2
842; AVX-NEXT:    vandps (%rsi), %ymm1, %ymm0
843; AVX-NEXT:    vandnps (%rdi), %ymm1, %ymm3
844; AVX-NEXT:    vorps %ymm3, %ymm0, %ymm0
845; AVX-NEXT:    vandnps 32(%rdi), %ymm1, %ymm1
846; AVX-NEXT:    vorps %ymm1, %ymm2, %ymm1
847; AVX-NEXT:    retq
848;
849; AVX512-LABEL: bitselect_v8i64_mm:
850; AVX512:       # %bb.0:
851; AVX512-NEXT:    vmovdqa64 (%rsi), %zmm1
852; AVX512-NEXT:    vmovdqa64 {{.*#+}} zmm0 = [18446744073709551612,18446744065119617022,18446744073709551612,18446744065119617022,18446744073709551612,18446744065119617022,18446744073709551612,18446744065119617022]
853; AVX512-NEXT:    vpternlogq $202, (%rdi), %zmm1, %zmm0
854; AVX512-NEXT:    retq
855  %3 = load <8 x i64>, ptr %0
856  %4 = load <8 x i64>, ptr %1
857  %5 = and <8 x i64> %3, <i64 3, i64 8589934593, i64 3, i64 8589934593, i64 3, i64 8589934593, i64 3, i64 8589934593>
858  %6 = and <8 x i64> %4, <i64 -4, i64 -8589934594, i64 -4, i64 -8589934594, i64 -4, i64 -8589934594, i64 -4, i64 -8589934594>
859  %7 = or <8 x i64> %6, %5
860  ret <8 x i64> %7
861}
862
863define <8 x i64> @bitselect_v8i64_broadcast_rrr(<8 x i64> %a0, <8 x i64> %a1, i64 %a2) {
864; SSE-LABEL: bitselect_v8i64_broadcast_rrr:
865; SSE:       # %bb.0:
866; SSE-NEXT:    movq %rdi, %xmm8
867; SSE-NEXT:    pshufd {{.*#+}} xmm8 = xmm8[0,1,0,1]
868; SSE-NEXT:    pand %xmm8, %xmm3
869; SSE-NEXT:    pand %xmm8, %xmm2
870; SSE-NEXT:    pand %xmm8, %xmm1
871; SSE-NEXT:    pand %xmm8, %xmm0
872; SSE-NEXT:    movdqa %xmm8, %xmm9
873; SSE-NEXT:    pandn %xmm7, %xmm9
874; SSE-NEXT:    por %xmm9, %xmm3
875; SSE-NEXT:    movdqa %xmm8, %xmm7
876; SSE-NEXT:    pandn %xmm6, %xmm7
877; SSE-NEXT:    por %xmm7, %xmm2
878; SSE-NEXT:    movdqa %xmm8, %xmm6
879; SSE-NEXT:    pandn %xmm5, %xmm6
880; SSE-NEXT:    por %xmm6, %xmm1
881; SSE-NEXT:    pandn %xmm4, %xmm8
882; SSE-NEXT:    por %xmm8, %xmm0
883; SSE-NEXT:    retq
884;
885; XOP-LABEL: bitselect_v8i64_broadcast_rrr:
886; XOP:       # %bb.0:
887; XOP-NEXT:    vmovq %rdi, %xmm4
888; XOP-NEXT:    vpshufd {{.*#+}} xmm4 = xmm4[0,1,0,1]
889; XOP-NEXT:    vinsertf128 $1, %xmm4, %ymm4, %ymm4
890; XOP-NEXT:    vpcmov %ymm4, %ymm2, %ymm0, %ymm0
891; XOP-NEXT:    vpcmov %ymm4, %ymm3, %ymm1, %ymm1
892; XOP-NEXT:    retq
893;
894; AVX1-LABEL: bitselect_v8i64_broadcast_rrr:
895; AVX1:       # %bb.0:
896; AVX1-NEXT:    vmovq %rdi, %xmm4
897; AVX1-NEXT:    vpshufd {{.*#+}} xmm4 = xmm4[0,1,0,1]
898; AVX1-NEXT:    vinsertf128 $1, %xmm4, %ymm4, %ymm4
899; AVX1-NEXT:    vandps %ymm4, %ymm1, %ymm1
900; AVX1-NEXT:    vandps %ymm4, %ymm0, %ymm0
901; AVX1-NEXT:    vandnps %ymm3, %ymm4, %ymm3
902; AVX1-NEXT:    vorps %ymm3, %ymm1, %ymm1
903; AVX1-NEXT:    vandnps %ymm2, %ymm4, %ymm2
904; AVX1-NEXT:    vorps %ymm2, %ymm0, %ymm0
905; AVX1-NEXT:    retq
906;
907; AVX2-LABEL: bitselect_v8i64_broadcast_rrr:
908; AVX2:       # %bb.0:
909; AVX2-NEXT:    vmovq %rdi, %xmm4
910; AVX2-NEXT:    vpbroadcastq %xmm4, %ymm4
911; AVX2-NEXT:    vpand %ymm4, %ymm1, %ymm1
912; AVX2-NEXT:    vpand %ymm4, %ymm0, %ymm0
913; AVX2-NEXT:    vpandn %ymm3, %ymm4, %ymm3
914; AVX2-NEXT:    vpor %ymm3, %ymm1, %ymm1
915; AVX2-NEXT:    vpandn %ymm2, %ymm4, %ymm2
916; AVX2-NEXT:    vpor %ymm2, %ymm0, %ymm0
917; AVX2-NEXT:    retq
918;
919; AVX512-LABEL: bitselect_v8i64_broadcast_rrr:
920; AVX512:       # %bb.0:
921; AVX512-NEXT:    vpbroadcastq %rdi, %zmm2
922; AVX512-NEXT:    vpternlogq $226, %zmm1, %zmm2, %zmm0
923; AVX512-NEXT:    retq
924  %1 = insertelement <8 x i64> undef, i64 %a2, i32 0
925  %2 = shufflevector <8 x i64> %1, <8 x i64> undef, <8 x i32> zeroinitializer
926  %3 = xor <8 x i64> %1, <i64 -1, i64 undef, i64 undef, i64 undef, i64 undef, i64 undef, i64 undef, i64 undef>
927  %4 = shufflevector <8 x i64> %3, <8 x i64> undef, <8 x i32> zeroinitializer
928  %5 = and <8 x i64> %a0, %2
929  %6 = and <8 x i64> %a1, %4
930  %7 = or <8 x i64> %5, %6
931  ret <8 x i64> %7
932}
933
934define <8 x i64> @bitselect_v8i64_broadcast_rrm(<8 x i64> %a0, <8 x i64> %a1, ptr %p2) {
935; SSE-LABEL: bitselect_v8i64_broadcast_rrm:
936; SSE:       # %bb.0:
937; SSE-NEXT:    movq {{.*#+}} xmm8 = mem[0],zero
938; SSE-NEXT:    pshufd {{.*#+}} xmm8 = xmm8[0,1,0,1]
939; SSE-NEXT:    pand %xmm8, %xmm3
940; SSE-NEXT:    pand %xmm8, %xmm2
941; SSE-NEXT:    pand %xmm8, %xmm1
942; SSE-NEXT:    pand %xmm8, %xmm0
943; SSE-NEXT:    movdqa %xmm8, %xmm9
944; SSE-NEXT:    pandn %xmm7, %xmm9
945; SSE-NEXT:    por %xmm9, %xmm3
946; SSE-NEXT:    movdqa %xmm8, %xmm7
947; SSE-NEXT:    pandn %xmm6, %xmm7
948; SSE-NEXT:    por %xmm7, %xmm2
949; SSE-NEXT:    movdqa %xmm8, %xmm6
950; SSE-NEXT:    pandn %xmm5, %xmm6
951; SSE-NEXT:    por %xmm6, %xmm1
952; SSE-NEXT:    pandn %xmm4, %xmm8
953; SSE-NEXT:    por %xmm8, %xmm0
954; SSE-NEXT:    retq
955;
956; XOP-LABEL: bitselect_v8i64_broadcast_rrm:
957; XOP:       # %bb.0:
958; XOP-NEXT:    vbroadcastsd (%rdi), %ymm4
959; XOP-NEXT:    vpcmov %ymm4, %ymm2, %ymm0, %ymm0
960; XOP-NEXT:    vpcmov %ymm4, %ymm3, %ymm1, %ymm1
961; XOP-NEXT:    retq
962;
963; AVX-LABEL: bitselect_v8i64_broadcast_rrm:
964; AVX:       # %bb.0:
965; AVX-NEXT:    vbroadcastsd (%rdi), %ymm4
966; AVX-NEXT:    vandps %ymm4, %ymm1, %ymm1
967; AVX-NEXT:    vandps %ymm4, %ymm0, %ymm0
968; AVX-NEXT:    vandnps %ymm3, %ymm4, %ymm3
969; AVX-NEXT:    vorps %ymm3, %ymm1, %ymm1
970; AVX-NEXT:    vandnps %ymm2, %ymm4, %ymm2
971; AVX-NEXT:    vorps %ymm2, %ymm0, %ymm0
972; AVX-NEXT:    retq
973;
974; AVX512-LABEL: bitselect_v8i64_broadcast_rrm:
975; AVX512:       # %bb.0:
976; AVX512-NEXT:    vpternlogq $228, (%rdi){1to8}, %zmm1, %zmm0
977; AVX512-NEXT:    retq
978  %a2 = load i64, ptr %p2
979  %1 = insertelement <8 x i64> undef, i64 %a2, i32 0
980  %2 = shufflevector <8 x i64> %1, <8 x i64> undef, <8 x i32> zeroinitializer
981  %3 = xor <8 x i64> %1, <i64 -1, i64 undef, i64 undef, i64 undef, i64 undef, i64 undef, i64 undef, i64 undef>
982  %4 = shufflevector <8 x i64> %3, <8 x i64> undef, <8 x i32> zeroinitializer
983  %5 = and <8 x i64> %a0, %2
984  %6 = and <8 x i64> %a1, %4
985  %7 = or <8 x i64> %5, %6
986  ret <8 x i64> %7
987}
988
989; Check that mask registers don't get canonicalized.
990define <4 x i1> @bitselect_v4i1_loop(<4 x i32> %a0, <4 x i32> %a1) {
991; SSE-LABEL: bitselect_v4i1_loop:
992; SSE:       # %bb.0: # %bb
993; SSE-NEXT:    pxor %xmm2, %xmm2
994; SSE-NEXT:    pcmpeqd %xmm2, %xmm0
995; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [12,12,12,12]
996; SSE-NEXT:    pcmpeqd %xmm1, %xmm2
997; SSE-NEXT:    pcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
998; SSE-NEXT:    pand %xmm0, %xmm1
999; SSE-NEXT:    pandn %xmm2, %xmm0
1000; SSE-NEXT:    por %xmm1, %xmm0
1001; SSE-NEXT:    retq
1002;
1003; XOP-LABEL: bitselect_v4i1_loop:
1004; XOP:       # %bb.0: # %bb
1005; XOP-NEXT:    vpxor %xmm2, %xmm2, %xmm2
1006; XOP-NEXT:    vpcomneqd %xmm2, %xmm0, %xmm0
1007; XOP-NEXT:    vpcomeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm2
1008; XOP-NEXT:    vpcomeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1
1009; XOP-NEXT:    vblendvps %xmm0, %xmm2, %xmm1, %xmm0
1010; XOP-NEXT:    retq
1011;
1012; AVX1-LABEL: bitselect_v4i1_loop:
1013; AVX1:       # %bb.0: # %bb
1014; AVX1-NEXT:    vpxor %xmm2, %xmm2, %xmm2
1015; AVX1-NEXT:    vpcmpeqd %xmm2, %xmm0, %xmm0
1016; AVX1-NEXT:    vpcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm2
1017; AVX1-NEXT:    vpcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1
1018; AVX1-NEXT:    vblendvps %xmm0, %xmm1, %xmm2, %xmm0
1019; AVX1-NEXT:    retq
1020;
1021; AVX2-LABEL: bitselect_v4i1_loop:
1022; AVX2:       # %bb.0: # %bb
1023; AVX2-NEXT:    vpxor %xmm2, %xmm2, %xmm2
1024; AVX2-NEXT:    vpcmpeqd %xmm2, %xmm0, %xmm0
1025; AVX2-NEXT:    vpbroadcastd {{.*#+}} xmm2 = [12,12,12,12]
1026; AVX2-NEXT:    vpcmpeqd %xmm2, %xmm1, %xmm2
1027; AVX2-NEXT:    vpbroadcastd {{.*#+}} xmm3 = [15,15,15,15]
1028; AVX2-NEXT:    vpcmpeqd %xmm3, %xmm1, %xmm1
1029; AVX2-NEXT:    vblendvps %xmm0, %xmm1, %xmm2, %xmm0
1030; AVX2-NEXT:    retq
1031;
1032; AVX512F-LABEL: bitselect_v4i1_loop:
1033; AVX512F:       # %bb.0: # %bb
1034; AVX512F-NEXT:    # kill: def $xmm1 killed $xmm1 def $zmm1
1035; AVX512F-NEXT:    # kill: def $xmm0 killed $xmm0 def $zmm0
1036; AVX512F-NEXT:    vpcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to16}, %zmm1, %k1
1037; AVX512F-NEXT:    vpcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to16}, %zmm1, %k2
1038; AVX512F-NEXT:    vptestnmd %zmm0, %zmm0, %k0 {%k2}
1039; AVX512F-NEXT:    vptestmd %zmm0, %zmm0, %k1 {%k1}
1040; AVX512F-NEXT:    korw %k0, %k1, %k1
1041; AVX512F-NEXT:    vpternlogd $255, %zmm0, %zmm0, %zmm0 {%k1} {z}
1042; AVX512F-NEXT:    # kill: def $xmm0 killed $xmm0 killed $zmm0
1043; AVX512F-NEXT:    vzeroupper
1044; AVX512F-NEXT:    retq
1045;
1046; AVX512VL-LABEL: bitselect_v4i1_loop:
1047; AVX512VL:       # %bb.0: # %bb
1048; AVX512VL-NEXT:    vpcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm1, %k1
1049; AVX512VL-NEXT:    vpcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm1, %k2
1050; AVX512VL-NEXT:    vptestnmd %xmm0, %xmm0, %k0 {%k2}
1051; AVX512VL-NEXT:    vptestmd %xmm0, %xmm0, %k1 {%k1}
1052; AVX512VL-NEXT:    korw %k0, %k1, %k1
1053; AVX512VL-NEXT:    vpcmpeqd %xmm0, %xmm0, %xmm0
1054; AVX512VL-NEXT:    vmovdqa32 %xmm0, %xmm0 {%k1} {z}
1055; AVX512VL-NEXT:    retq
1056bb:
1057  %tmp = icmp ne <4 x i32> %a0, zeroinitializer
1058  %tmp2 = icmp eq <4 x i32> %a1, <i32 12, i32 12, i32 12, i32 12>
1059  %tmp3 = icmp eq <4 x i32> %a1, <i32 15, i32 15, i32 15, i32 15>
1060  %tmp4 = select <4 x i1> %tmp, <4 x i1> %tmp2, <4 x i1> %tmp3
1061  ret <4 x i1> %tmp4
1062}
1063
1064