1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=X32
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=X64
4
5define i32 @knownbits_mask_extract_sext(<8 x i16> %a0) nounwind {
6; X32-LABEL: knownbits_mask_extract_sext:
7; X32:       # %bb.0:
8; X32-NEXT:    vmovd %xmm0, %eax
9; X32-NEXT:    andl $15, %eax
10; X32-NEXT:    retl
11;
12; X64-LABEL: knownbits_mask_extract_sext:
13; X64:       # %bb.0:
14; X64-NEXT:    vmovd %xmm0, %eax
15; X64-NEXT:    andl $15, %eax
16; X64-NEXT:    retq
17  %1 = and <8 x i16> %a0, <i16 15, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
18  %2 = extractelement <8 x i16> %1, i32 0
19  %3 = sext i16 %2 to i32
20  ret i32 %3
21}
22
23define float @knownbits_mask_extract_uitofp(<2 x i64> %a0) nounwind {
24; X32-LABEL: knownbits_mask_extract_uitofp:
25; X32:       # %bb.0:
26; X32-NEXT:    pushl %eax
27; X32-NEXT:    vpmovzxwq {{.*#+}} xmm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero
28; X32-NEXT:    vcvtdq2ps %xmm0, %xmm0
29; X32-NEXT:    vmovss %xmm0, (%esp)
30; X32-NEXT:    flds (%esp)
31; X32-NEXT:    popl %eax
32; X32-NEXT:    retl
33;
34; X64-LABEL: knownbits_mask_extract_uitofp:
35; X64:       # %bb.0:
36; X64-NEXT:    vmovq %xmm0, %rax
37; X64-NEXT:    movzwl %ax, %eax
38; X64-NEXT:    vcvtsi2ssl %eax, %xmm1, %xmm0
39; X64-NEXT:    retq
40  %1 = and <2 x i64> %a0, <i64 65535, i64 -1>
41  %2 = extractelement <2 x i64> %1, i32 0
42  %3 = uitofp i64 %2 to float
43  ret float %3
44}
45
46define <4 x float> @knownbits_insert_uitofp(<4 x i32> %a0, i16 %a1, i16 %a2) nounwind {
47; X32-LABEL: knownbits_insert_uitofp:
48; X32:       # %bb.0:
49; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
50; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
51; X32-NEXT:    vmovd %ecx, %xmm0
52; X32-NEXT:    vpinsrd $2, %eax, %xmm0, %xmm0
53; X32-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,0,2,2]
54; X32-NEXT:    vcvtdq2ps %xmm0, %xmm0
55; X32-NEXT:    retl
56;
57; X64-LABEL: knownbits_insert_uitofp:
58; X64:       # %bb.0:
59; X64-NEXT:    movzwl %di, %eax
60; X64-NEXT:    movzwl %si, %ecx
61; X64-NEXT:    vmovd %eax, %xmm0
62; X64-NEXT:    vpinsrd $2, %ecx, %xmm0, %xmm0
63; X64-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,0,2,2]
64; X64-NEXT:    vcvtdq2ps %xmm0, %xmm0
65; X64-NEXT:    retq
66  %1 = zext i16 %a1 to i32
67  %2 = zext i16 %a2 to i32
68  %3 = insertelement <4 x i32> %a0, i32 %1, i32 0
69  %4 = insertelement <4 x i32>  %3, i32 %2, i32 2
70  %5 = shufflevector <4 x i32> %4, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 2, i32 2>
71  %6 = uitofp <4 x i32> %5 to <4 x float>
72  ret <4 x float> %6
73}
74
75define <4 x i32> @knownbits_mask_shuffle_sext(<8 x i16> %a0) nounwind {
76; X32-LABEL: knownbits_mask_shuffle_sext:
77; X32:       # %bb.0:
78; X32-NEXT:    vpand {{\.LCPI.*}}, %xmm0, %xmm0
79; X32-NEXT:    vpxor %xmm1, %xmm1, %xmm1
80; X32-NEXT:    vpunpckhwd {{.*#+}} xmm0 = xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
81; X32-NEXT:    retl
82;
83; X64-LABEL: knownbits_mask_shuffle_sext:
84; X64:       # %bb.0:
85; X64-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
86; X64-NEXT:    vpxor %xmm1, %xmm1, %xmm1
87; X64-NEXT:    vpunpckhwd {{.*#+}} xmm0 = xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
88; X64-NEXT:    retq
89  %1 = and <8 x i16> %a0, <i16 -1, i16 -1, i16 -1, i16 -1, i16 15, i16 15, i16 15, i16 15>
90  %2 = shufflevector <8 x i16> %1, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
91  %3 = sext <4 x i16> %2 to <4 x i32>
92  ret <4 x i32> %3
93}
94
95define <4 x i32> @knownbits_mask_shuffle_shuffle_sext(<8 x i16> %a0) nounwind {
96; X32-LABEL: knownbits_mask_shuffle_shuffle_sext:
97; X32:       # %bb.0:
98; X32-NEXT:    vpand {{\.LCPI.*}}, %xmm0, %xmm0
99; X32-NEXT:    vpxor %xmm1, %xmm1, %xmm1
100; X32-NEXT:    vpunpckhwd {{.*#+}} xmm0 = xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
101; X32-NEXT:    retl
102;
103; X64-LABEL: knownbits_mask_shuffle_shuffle_sext:
104; X64:       # %bb.0:
105; X64-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
106; X64-NEXT:    vpxor %xmm1, %xmm1, %xmm1
107; X64-NEXT:    vpunpckhwd {{.*#+}} xmm0 = xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
108; X64-NEXT:    retq
109  %1 = and <8 x i16> %a0, <i16 -1, i16 -1, i16 -1, i16 -1, i16 15, i16 15, i16 15, i16 15>
110  %2 = shufflevector <8 x i16> %1, <8 x i16> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 undef, i32 undef, i32 undef, i32 undef>
111  %3 = shufflevector <8 x i16> %2, <8 x i16> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
112  %4 = sext <4 x i16> %3 to <4 x i32>
113  ret <4 x i32> %4
114}
115
116define <4 x i32> @knownbits_mask_shuffle_shuffle_undef_sext(<8 x i16> %a0) nounwind {
117; X32-LABEL: knownbits_mask_shuffle_shuffle_undef_sext:
118; X32:       # %bb.0:
119; X32-NEXT:    vpand {{\.LCPI.*}}, %xmm0, %xmm0
120; X32-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
121; X32-NEXT:    vpmovsxwd %xmm0, %xmm0
122; X32-NEXT:    retl
123;
124; X64-LABEL: knownbits_mask_shuffle_shuffle_undef_sext:
125; X64:       # %bb.0:
126; X64-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
127; X64-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
128; X64-NEXT:    vpmovsxwd %xmm0, %xmm0
129; X64-NEXT:    retq
130  %1 = and <8 x i16> %a0, <i16 -1, i16 -1, i16 -1, i16 -1, i16 15, i16 15, i16 15, i16 15>
131  %2 = shufflevector <8 x i16> %1, <8 x i16> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
132  %3 = shufflevector <8 x i16> %2, <8 x i16> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
133  %4 = sext <4 x i16> %3 to <4 x i32>
134  ret <4 x i32> %4
135}
136
137define <4 x float> @knownbits_mask_shuffle_uitofp(<4 x i32> %a0) nounwind {
138; X32-LABEL: knownbits_mask_shuffle_uitofp:
139; X32:       # %bb.0:
140; X32-NEXT:    vandps {{\.LCPI.*}}, %xmm0, %xmm0
141; X32-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[2,2,3,3]
142; X32-NEXT:    vcvtdq2ps %xmm0, %xmm0
143; X32-NEXT:    retl
144;
145; X64-LABEL: knownbits_mask_shuffle_uitofp:
146; X64:       # %bb.0:
147; X64-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
148; X64-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[2,2,3,3]
149; X64-NEXT:    vcvtdq2ps %xmm0, %xmm0
150; X64-NEXT:    retq
151  %1 = and <4 x i32> %a0, <i32 -1, i32 -1, i32 255, i32 4085>
152  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 2, i32 3, i32 3>
153  %3 = uitofp <4 x i32> %2 to <4 x float>
154  ret <4 x float> %3
155}
156
157define <4 x float> @knownbits_mask_or_shuffle_uitofp(<4 x i32> %a0) nounwind {
158; X32-LABEL: knownbits_mask_or_shuffle_uitofp:
159; X32:       # %bb.0:
160; X32-NEXT:    vmovaps {{.*#+}} xmm0 = [6.5535E+4,6.5535E+4,6.5535E+4,6.5535E+4]
161; X32-NEXT:    retl
162;
163; X64-LABEL: knownbits_mask_or_shuffle_uitofp:
164; X64:       # %bb.0:
165; X64-NEXT:    vmovaps {{.*#+}} xmm0 = [6.5535E+4,6.5535E+4,6.5535E+4,6.5535E+4]
166; X64-NEXT:    retq
167  %1 = and <4 x i32> %a0, <i32 -1, i32 -1, i32 255, i32 4085>
168  %2 = or <4 x i32> %1, <i32 65535, i32 65535, i32 65535, i32 65535>
169  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 2, i32 2, i32 3, i32 3>
170  %4 = uitofp <4 x i32> %3 to <4 x float>
171  ret <4 x float> %4
172}
173
174define <4 x float> @knownbits_mask_xor_shuffle_uitofp(<4 x i32> %a0) nounwind {
175; X32-LABEL: knownbits_mask_xor_shuffle_uitofp:
176; X32:       # %bb.0:
177; X32-NEXT:    vandps {{\.LCPI.*}}, %xmm0, %xmm0
178; X32-NEXT:    vxorps {{\.LCPI.*}}, %xmm0, %xmm0
179; X32-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[2,2,3,3]
180; X32-NEXT:    vcvtdq2ps %xmm0, %xmm0
181; X32-NEXT:    retl
182;
183; X64-LABEL: knownbits_mask_xor_shuffle_uitofp:
184; X64:       # %bb.0:
185; X64-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
186; X64-NEXT:    vxorps {{.*}}(%rip), %xmm0, %xmm0
187; X64-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[2,2,3,3]
188; X64-NEXT:    vcvtdq2ps %xmm0, %xmm0
189; X64-NEXT:    retq
190  %1 = and <4 x i32> %a0, <i32 -1, i32 -1, i32 255, i32 4085>
191  %2 = xor <4 x i32> %1, <i32 65535, i32 65535, i32 65535, i32 65535>
192  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 2, i32 2, i32 3, i32 3>
193  %4 = uitofp <4 x i32> %3 to <4 x float>
194  ret <4 x float> %4
195}
196
197define <4 x i32> @knownbits_mask_shl_shuffle_lshr(<4 x i32> %a0) nounwind {
198; X32-LABEL: knownbits_mask_shl_shuffle_lshr:
199; X32:       # %bb.0:
200; X32-NEXT:    vxorps %xmm0, %xmm0, %xmm0
201; X32-NEXT:    retl
202;
203; X64-LABEL: knownbits_mask_shl_shuffle_lshr:
204; X64:       # %bb.0:
205; X64-NEXT:    vxorps %xmm0, %xmm0, %xmm0
206; X64-NEXT:    retq
207  %1 = and <4 x i32> %a0, <i32 -65536, i32 -7, i32 -7, i32 -65536>
208  %2 = shl <4 x i32> %1, <i32 17, i32 17, i32 17, i32 17>
209  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>
210  %4 = lshr <4 x i32> %3, <i32 15, i32 15, i32 15, i32 15>
211  ret <4 x i32> %4
212}
213
214define <4 x i32> @knownbits_mask_ashr_shuffle_lshr(<4 x i32> %a0) nounwind {
215; X32-LABEL: knownbits_mask_ashr_shuffle_lshr:
216; X32:       # %bb.0:
217; X32-NEXT:    vxorps %xmm0, %xmm0, %xmm0
218; X32-NEXT:    retl
219;
220; X64-LABEL: knownbits_mask_ashr_shuffle_lshr:
221; X64:       # %bb.0:
222; X64-NEXT:    vxorps %xmm0, %xmm0, %xmm0
223; X64-NEXT:    retq
224  %1 = and <4 x i32> %a0, <i32 131071, i32 -1, i32 -1, i32 131071>
225  %2 = ashr <4 x i32> %1, <i32 15, i32 15, i32 15, i32 15>
226  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>
227  %4 = lshr <4 x i32> %3, <i32 30, i32 30, i32 30, i32 30>
228  ret <4 x i32> %4
229}
230
231define <4 x i32> @knownbits_mask_mul_shuffle_shl(<4 x i32> %a0, <4 x i32> %a1) nounwind {
232; X32-LABEL: knownbits_mask_mul_shuffle_shl:
233; X32:       # %bb.0:
234; X32-NEXT:    vxorps %xmm0, %xmm0, %xmm0
235; X32-NEXT:    retl
236;
237; X64-LABEL: knownbits_mask_mul_shuffle_shl:
238; X64:       # %bb.0:
239; X64-NEXT:    vxorps %xmm0, %xmm0, %xmm0
240; X64-NEXT:    retq
241  %1 = and <4 x i32> %a0, <i32 -65536, i32 -7, i32 -7, i32 -65536>
242  %2 = mul <4 x i32> %a1, %1
243  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>
244  %4 = shl <4 x i32> %3, <i32 22, i32 22, i32 22, i32 22>
245  ret <4 x i32> %4
246}
247
248define <4 x i32> @knownbits_mask_trunc_shuffle_shl(<4 x i64> %a0) nounwind {
249; X32-LABEL: knownbits_mask_trunc_shuffle_shl:
250; X32:       # %bb.0:
251; X32-NEXT:    vxorps %xmm0, %xmm0, %xmm0
252; X32-NEXT:    retl
253;
254; X64-LABEL: knownbits_mask_trunc_shuffle_shl:
255; X64:       # %bb.0:
256; X64-NEXT:    vxorps %xmm0, %xmm0, %xmm0
257; X64-NEXT:    retq
258  %1 = and <4 x i64> %a0, <i64 -65536, i64 -7, i64 7, i64 -65536>
259  %2 = trunc <4 x i64> %1 to <4 x i32>
260  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>
261  %4 = shl <4 x i32> %3, <i32 22, i32 22, i32 22, i32 22>
262  ret <4 x i32> %4
263}
264
265define <4 x i32> @knownbits_mask_add_shuffle_lshr(<4 x i32> %a0, <4 x i32> %a1) nounwind {
266; X32-LABEL: knownbits_mask_add_shuffle_lshr:
267; X32:       # %bb.0:
268; X32-NEXT:    vxorps %xmm0, %xmm0, %xmm0
269; X32-NEXT:    retl
270;
271; X64-LABEL: knownbits_mask_add_shuffle_lshr:
272; X64:       # %bb.0:
273; X64-NEXT:    vxorps %xmm0, %xmm0, %xmm0
274; X64-NEXT:    retq
275  %1 = and <4 x i32> %a0, <i32 32767, i32 -1, i32 -1, i32 32767>
276  %2 = and <4 x i32> %a1, <i32 32767, i32 -1, i32 -1, i32 32767>
277  %3 = add <4 x i32> %1, %2
278  %4 = shufflevector <4 x i32> %3, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>
279  %5 = lshr <4 x i32> %4, <i32 17, i32 17, i32 17, i32 17>
280  ret <4 x i32> %5
281}
282
283define <4 x i32> @knownbits_mask_sub_shuffle_lshr(<4 x i32> %a0) nounwind {
284; X32-LABEL: knownbits_mask_sub_shuffle_lshr:
285; X32:       # %bb.0:
286; X32-NEXT:    vxorps %xmm0, %xmm0, %xmm0
287; X32-NEXT:    retl
288;
289; X64-LABEL: knownbits_mask_sub_shuffle_lshr:
290; X64:       # %bb.0:
291; X64-NEXT:    vxorps %xmm0, %xmm0, %xmm0
292; X64-NEXT:    retq
293  %1 = and <4 x i32> %a0, <i32 15, i32 -1, i32 -1, i32 15>
294  %2 = sub <4 x i32> <i32 255, i32 255, i32 255, i32 255>, %1
295  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>
296  %4 = lshr <4 x i32> %3, <i32 22, i32 22, i32 22, i32 22>
297  ret <4 x i32> %4
298}
299
300define <4 x i32> @knownbits_mask_udiv_shuffle_lshr(<4 x i32> %a0, <4 x i32> %a1) nounwind {
301; X32-LABEL: knownbits_mask_udiv_shuffle_lshr:
302; X32:       # %bb.0:
303; X32-NEXT:    vxorps %xmm0, %xmm0, %xmm0
304; X32-NEXT:    retl
305;
306; X64-LABEL: knownbits_mask_udiv_shuffle_lshr:
307; X64:       # %bb.0:
308; X64-NEXT:    vxorps %xmm0, %xmm0, %xmm0
309; X64-NEXT:    retq
310  %1 = and <4 x i32> %a0, <i32 32767, i32 -1, i32 -1, i32 32767>
311  %2 = udiv <4 x i32> %1, %a1
312  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>
313  %4 = lshr <4 x i32> %3, <i32 22, i32 22, i32 22, i32 22>
314  ret <4 x i32> %4
315}
316
317define <4 x i32> @knownbits_urem_lshr(<4 x i32> %a0) nounwind {
318; X32-LABEL: knownbits_urem_lshr:
319; X32:       # %bb.0:
320; X32-NEXT:    vxorps %xmm0, %xmm0, %xmm0
321; X32-NEXT:    retl
322;
323; X64-LABEL: knownbits_urem_lshr:
324; X64:       # %bb.0:
325; X64-NEXT:    vxorps %xmm0, %xmm0, %xmm0
326; X64-NEXT:    retq
327  %1 = urem <4 x i32> %a0, <i32 16, i32 16, i32 16, i32 16>
328  %2 = lshr <4 x i32> %1, <i32 22, i32 22, i32 22, i32 22>
329  ret <4 x i32> %2
330}
331
332define <4 x i32> @knownbits_mask_urem_shuffle_lshr(<4 x i32> %a0, <4 x i32> %a1) nounwind {
333; X32-LABEL: knownbits_mask_urem_shuffle_lshr:
334; X32:       # %bb.0:
335; X32-NEXT:    vxorps %xmm0, %xmm0, %xmm0
336; X32-NEXT:    retl
337;
338; X64-LABEL: knownbits_mask_urem_shuffle_lshr:
339; X64:       # %bb.0:
340; X64-NEXT:    vxorps %xmm0, %xmm0, %xmm0
341; X64-NEXT:    retq
342  %1 = and <4 x i32> %a0, <i32 32767, i32 -1, i32 -1, i32 32767>
343  %2 = and <4 x i32> %a1, <i32 32767, i32 -1, i32 -1, i32 32767>
344  %3 = urem <4 x i32> %1, %2
345  %4 = shufflevector <4 x i32> %3, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>
346  %5 = lshr <4 x i32> %4, <i32 22, i32 22, i32 22, i32 22>
347  ret <4 x i32> %5
348}
349
350define <4 x i32> @knownbits_mask_srem_shuffle_lshr(<4 x i32> %a0) nounwind {
351; X32-LABEL: knownbits_mask_srem_shuffle_lshr:
352; X32:       # %bb.0:
353; X32-NEXT:    vxorps %xmm0, %xmm0, %xmm0
354; X32-NEXT:    retl
355;
356; X64-LABEL: knownbits_mask_srem_shuffle_lshr:
357; X64:       # %bb.0:
358; X64-NEXT:    vxorps %xmm0, %xmm0, %xmm0
359; X64-NEXT:    retq
360  %1 = and <4 x i32> %a0, <i32 -32768, i32 -1, i32 -1, i32 -32768>
361  %2 = srem <4 x i32> %1, <i32 16, i32 16, i32 16, i32 16>
362  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>
363  %4 = lshr <4 x i32> %3, <i32 22, i32 22, i32 22, i32 22>
364  ret <4 x i32> %4
365}
366
367define <4 x i32> @knownbits_mask_bswap_shuffle_shl(<4 x i32> %a0) nounwind {
368; X32-LABEL: knownbits_mask_bswap_shuffle_shl:
369; X32:       # %bb.0:
370; X32-NEXT:    vxorps %xmm0, %xmm0, %xmm0
371; X32-NEXT:    retl
372;
373; X64-LABEL: knownbits_mask_bswap_shuffle_shl:
374; X64:       # %bb.0:
375; X64-NEXT:    vxorps %xmm0, %xmm0, %xmm0
376; X64-NEXT:    retq
377  %1 = and <4 x i32> %a0, <i32 32767, i32 -1, i32 -1, i32 32767>
378  %2 = call <4 x i32> @llvm.bswap.v4i32(<4 x i32> %1)
379  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>
380  %4 = shl <4 x i32> %3, <i32 22, i32 22, i32 22, i32 22>
381  ret <4 x i32> %4
382}
383declare <4 x i32> @llvm.bswap.v4i32(<4 x i32>)
384
385define <8 x float> @knownbits_mask_concat_uitofp(<4 x i32> %a0, <4 x i32> %a1) nounwind {
386; X32-LABEL: knownbits_mask_concat_uitofp:
387; X32:       # %bb.0:
388; X32-NEXT:    vandps {{\.LCPI.*}}, %xmm0, %xmm0
389; X32-NEXT:    vandps {{\.LCPI.*}}, %xmm1, %xmm1
390; X32-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[0,2,0,2]
391; X32-NEXT:    vpermilps {{.*#+}} xmm1 = xmm1[1,3,1,3]
392; X32-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
393; X32-NEXT:    vcvtdq2ps %ymm0, %ymm0
394; X32-NEXT:    retl
395;
396; X64-LABEL: knownbits_mask_concat_uitofp:
397; X64:       # %bb.0:
398; X64-NEXT:    vandps {{.*}}(%rip), %xmm0, %xmm0
399; X64-NEXT:    vandps {{.*}}(%rip), %xmm1, %xmm1
400; X64-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[0,2,0,2]
401; X64-NEXT:    vpermilps {{.*#+}} xmm1 = xmm1[1,3,1,3]
402; X64-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
403; X64-NEXT:    vcvtdq2ps %ymm0, %ymm0
404; X64-NEXT:    retq
405  %1 = and <4 x i32> %a0, <i32 131071, i32 -1, i32 131071, i32 -1>
406  %2 = and <4 x i32> %a1, <i32 -1, i32 131071, i32 -1, i32 131071>
407  %3 = shufflevector <4 x i32> %1, <4 x i32> %2, <8 x i32> <i32 0, i32 2, i32 0, i32 2, i32 5, i32 7, i32 5, i32 7>
408  %4 = uitofp <8 x i32> %3 to <8 x float>
409  ret <8 x float> %4
410}
411
412define <4 x float> @knownbits_lshr_bitcast_shuffle_uitofp(<2 x i64> %a0, <4 x i32> %a1) nounwind {
413; X32-LABEL: knownbits_lshr_bitcast_shuffle_uitofp:
414; X32:       # %bb.0:
415; X32-NEXT:    vpsrlq $1, %xmm0, %xmm0
416; X32-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
417; X32-NEXT:    vcvtdq2ps %xmm0, %xmm0
418; X32-NEXT:    retl
419;
420; X64-LABEL: knownbits_lshr_bitcast_shuffle_uitofp:
421; X64:       # %bb.0:
422; X64-NEXT:    vpsrlq $1, %xmm0, %xmm0
423; X64-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
424; X64-NEXT:    vcvtdq2ps %xmm0, %xmm0
425; X64-NEXT:    retq
426  %1 = lshr <2 x i64> %a0, <i64 1, i64 1>
427  %2 = bitcast <2 x i64> %1 to <4 x i32>
428  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 3, i32 3>
429  %4 = uitofp <4 x i32> %3 to <4 x float>
430  ret <4 x float> %4
431}
432
433define <4 x float> @knownbits_smax_smin_shuffle_uitofp(<4 x i32> %a0) {
434; X32-LABEL: knownbits_smax_smin_shuffle_uitofp:
435; X32:       # %bb.0:
436; X32-NEXT:    vpminsd {{\.LCPI.*}}, %xmm0, %xmm0
437; X32-NEXT:    vpmaxsd {{\.LCPI.*}}, %xmm0, %xmm0
438; X32-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,0,3,3]
439; X32-NEXT:    vpblendw {{.*#+}} xmm1 = xmm0[0],mem[1],xmm0[2],mem[3],xmm0[4],mem[5],xmm0[6],mem[7]
440; X32-NEXT:    vpsrld $16, %xmm0, %xmm0
441; X32-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],mem[1],xmm0[2],mem[3],xmm0[4],mem[5],xmm0[6],mem[7]
442; X32-NEXT:    vaddps {{\.LCPI.*}}, %xmm0, %xmm0
443; X32-NEXT:    vaddps %xmm0, %xmm1, %xmm0
444; X32-NEXT:    retl
445;
446; X64-LABEL: knownbits_smax_smin_shuffle_uitofp:
447; X64:       # %bb.0:
448; X64-NEXT:    vpminsd {{.*}}(%rip), %xmm0, %xmm0
449; X64-NEXT:    vpmaxsd {{.*}}(%rip), %xmm0, %xmm0
450; X64-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,0,3,3]
451; X64-NEXT:    vpblendw {{.*#+}} xmm1 = xmm0[0],mem[1],xmm0[2],mem[3],xmm0[4],mem[5],xmm0[6],mem[7]
452; X64-NEXT:    vpsrld $16, %xmm0, %xmm0
453; X64-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],mem[1],xmm0[2],mem[3],xmm0[4],mem[5],xmm0[6],mem[7]
454; X64-NEXT:    vaddps {{.*}}(%rip), %xmm0, %xmm0
455; X64-NEXT:    vaddps %xmm0, %xmm1, %xmm0
456; X64-NEXT:    retq
457  %1 = call <4 x i32> @llvm.x86.sse41.pminsd(<4 x i32> %a0, <4 x i32> <i32 0, i32 -65535, i32 -65535, i32 0>)
458  %2 = call <4 x i32> @llvm.x86.sse41.pmaxsd(<4 x i32> %1, <4 x i32> <i32 65535, i32 -1, i32 -1, i32 131071>)
459  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>
460  %4 = uitofp <4 x i32> %3 to <4 x float>
461  ret <4 x float> %4
462}
463declare <4 x i32> @llvm.x86.sse41.pmaxsd(<4 x i32>, <4 x i32>) nounwind readnone
464declare <4 x i32> @llvm.x86.sse41.pminsd(<4 x i32>, <4 x i32>) nounwind readnone
465
466define <4 x float> @knownbits_umin_shuffle_uitofp(<4 x i32> %a0) {
467; X32-LABEL: knownbits_umin_shuffle_uitofp:
468; X32:       # %bb.0:
469; X32-NEXT:    vpminud {{\.LCPI.*}}, %xmm0, %xmm0
470; X32-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,0,3,3]
471; X32-NEXT:    vcvtdq2ps %xmm0, %xmm0
472; X32-NEXT:    retl
473;
474; X64-LABEL: knownbits_umin_shuffle_uitofp:
475; X64:       # %bb.0:
476; X64-NEXT:    vpminud {{.*}}(%rip), %xmm0, %xmm0
477; X64-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,0,3,3]
478; X64-NEXT:    vcvtdq2ps %xmm0, %xmm0
479; X64-NEXT:    retq
480  %1 = call <4 x i32> @llvm.x86.sse41.pminud(<4 x i32> %a0, <4 x i32> <i32 65535, i32 -1, i32 -1, i32 262143>)
481  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>
482  %3 = uitofp <4 x i32> %2 to <4 x float>
483  ret <4 x float> %3
484}
485declare <4 x i32> @llvm.x86.sse41.pmaxud(<4 x i32>, <4 x i32>) nounwind readnone
486declare <4 x i32> @llvm.x86.sse41.pminud(<4 x i32>, <4 x i32>) nounwind readnone
487
488define <4 x i32> @knownbits_umax_shuffle_ashr(<4 x i32> %a0) {
489; X32-LABEL: knownbits_umax_shuffle_ashr:
490; X32:       # %bb.0:
491; X32-NEXT:    vpcmpeqd %xmm0, %xmm0, %xmm0
492; X32-NEXT:    retl
493;
494; X64-LABEL: knownbits_umax_shuffle_ashr:
495; X64:       # %bb.0:
496; X64-NEXT:    vpcmpeqd %xmm0, %xmm0, %xmm0
497; X64-NEXT:    retq
498  %1 = call <4 x i32> @llvm.x86.sse41.pmaxud(<4 x i32> %a0, <4 x i32> <i32 65535, i32 -1, i32 -1, i32 262143>)
499  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 2, i32 2>
500  %3 = ashr <4 x i32> %2, <i32 31, i32 31, i32 31, i32 31>
501  ret <4 x i32> %3
502}
503
504define <4 x float> @knownbits_mask_umax_shuffle_uitofp(<4 x i32> %a0) {
505; X32-LABEL: knownbits_mask_umax_shuffle_uitofp:
506; X32:       # %bb.0:
507; X32-NEXT:    vpand {{\.LCPI.*}}, %xmm0, %xmm0
508; X32-NEXT:    vpmaxud {{\.LCPI.*}}, %xmm0, %xmm0
509; X32-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,0,3,3]
510; X32-NEXT:    vcvtdq2ps %xmm0, %xmm0
511; X32-NEXT:    retl
512;
513; X64-LABEL: knownbits_mask_umax_shuffle_uitofp:
514; X64:       # %bb.0:
515; X64-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
516; X64-NEXT:    vpmaxud {{.*}}(%rip), %xmm0, %xmm0
517; X64-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,0,3,3]
518; X64-NEXT:    vcvtdq2ps %xmm0, %xmm0
519; X64-NEXT:    retq
520  %1 = and <4 x i32> %a0, <i32 65535, i32 -1, i32 -1, i32 262143>
521  %2 = call <4 x i32> @llvm.x86.sse41.pmaxud(<4 x i32> %1, <4 x i32> <i32 255, i32 -1, i32 -1, i32 1023>)
522  %3 = shufflevector <4 x i32> %2, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 3, i32 3>
523  %4 = uitofp <4 x i32> %3 to <4 x float>
524  ret <4 x float> %4
525}
526
527define <4 x i32> @knownbits_mask_bitreverse_ashr(<4 x i32> %a0) {
528; X32-LABEL: knownbits_mask_bitreverse_ashr:
529; X32:       # %bb.0:
530; X32-NEXT:    vxorps %xmm0, %xmm0, %xmm0
531; X32-NEXT:    retl
532;
533; X64-LABEL: knownbits_mask_bitreverse_ashr:
534; X64:       # %bb.0:
535; X64-NEXT:    vxorps %xmm0, %xmm0, %xmm0
536; X64-NEXT:    retq
537  %1 = and <4 x i32> %a0, <i32 -2, i32 -2, i32 -2, i32 -2>
538  %2 = call <4 x i32> @llvm.bitreverse.v4i32(<4 x i32> %1)
539  %3 = ashr <4 x i32> %2, <i32 31, i32 31, i32 31, i32 31>
540  ret <4 x i32> %3
541}
542declare <4 x i32> @llvm.bitreverse.v4i32(<4 x i32>) nounwind readnone
543
544; If we don't know that the input isn't INT_MIN we can't combine to sitofp
545define <4 x float> @knownbits_abs_uitofp(<4 x i32> %a0) {
546; X32-LABEL: knownbits_abs_uitofp:
547; X32:       # %bb.0:
548; X32-NEXT:    vpabsd %xmm0, %xmm0
549; X32-NEXT:    vpblendw {{.*#+}} xmm1 = xmm0[0],mem[1],xmm0[2],mem[3],xmm0[4],mem[5],xmm0[6],mem[7]
550; X32-NEXT:    vpsrld $16, %xmm0, %xmm0
551; X32-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],mem[1],xmm0[2],mem[3],xmm0[4],mem[5],xmm0[6],mem[7]
552; X32-NEXT:    vaddps {{\.LCPI.*}}, %xmm0, %xmm0
553; X32-NEXT:    vaddps %xmm0, %xmm1, %xmm0
554; X32-NEXT:    retl
555;
556; X64-LABEL: knownbits_abs_uitofp:
557; X64:       # %bb.0:
558; X64-NEXT:    vpabsd %xmm0, %xmm0
559; X64-NEXT:    vpblendw {{.*#+}} xmm1 = xmm0[0],mem[1],xmm0[2],mem[3],xmm0[4],mem[5],xmm0[6],mem[7]
560; X64-NEXT:    vpsrld $16, %xmm0, %xmm0
561; X64-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],mem[1],xmm0[2],mem[3],xmm0[4],mem[5],xmm0[6],mem[7]
562; X64-NEXT:    vaddps {{.*}}(%rip), %xmm0, %xmm0
563; X64-NEXT:    vaddps %xmm0, %xmm1, %xmm0
564; X64-NEXT:    retq
565  %1 = sub <4 x i32> zeroinitializer, %a0
566  %2 = icmp slt <4 x i32> %a0, zeroinitializer
567  %3 = select <4 x i1> %2, <4 x i32> %1, <4 x i32> %a0
568  %4 = uitofp <4 x i32> %3 to <4 x float>
569  ret <4 x float> %4
570}
571
572define <4 x float> @knownbits_or_abs_uitofp(<4 x i32> %a0) {
573; X32-LABEL: knownbits_or_abs_uitofp:
574; X32:       # %bb.0:
575; X32-NEXT:    vpor {{\.LCPI.*}}, %xmm0, %xmm0
576; X32-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,0,2]
577; X32-NEXT:    vpabsd %xmm0, %xmm0
578; X32-NEXT:    vcvtdq2ps %xmm0, %xmm0
579; X32-NEXT:    retl
580;
581; X64-LABEL: knownbits_or_abs_uitofp:
582; X64:       # %bb.0:
583; X64-NEXT:    vpor {{.*}}(%rip), %xmm0, %xmm0
584; X64-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,0,2]
585; X64-NEXT:    vpabsd %xmm0, %xmm0
586; X64-NEXT:    vcvtdq2ps %xmm0, %xmm0
587; X64-NEXT:    retq
588  %1 = or <4 x i32> %a0, <i32 1, i32 0, i32 3, i32 0>
589  %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 2, i32 0, i32 2>
590  %3 = sub <4 x i32> zeroinitializer, %2
591  %4 = icmp slt <4 x i32> %2, zeroinitializer
592  %5 = select <4 x i1> %4, <4 x i32> %3, <4 x i32> %2
593  %6 = uitofp <4 x i32> %5 to <4 x float>
594  ret <4 x float> %6
595}
596
597define <4 x float> @knownbits_and_select_shuffle_uitofp(<4 x i32> %a0, <4 x i32> %a1, <4 x i32> %a2, <4 x i32> %a3) nounwind {
598; X32-LABEL: knownbits_and_select_shuffle_uitofp:
599; X32:       # %bb.0:
600; X32-NEXT:    pushl %ebp
601; X32-NEXT:    movl %esp, %ebp
602; X32-NEXT:    andl $-16, %esp
603; X32-NEXT:    subl $16, %esp
604; X32-NEXT:    vmovaps 8(%ebp), %xmm3
605; X32-NEXT:    vandps {{\.LCPI.*}}, %xmm2, %xmm2
606; X32-NEXT:    vandps {{\.LCPI.*}}, %xmm3, %xmm3
607; X32-NEXT:    vpcmpeqd %xmm1, %xmm0, %xmm0
608; X32-NEXT:    vblendvps %xmm0, %xmm2, %xmm3, %xmm0
609; X32-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[0,0,2,2]
610; X32-NEXT:    vcvtdq2ps %xmm0, %xmm0
611; X32-NEXT:    movl %ebp, %esp
612; X32-NEXT:    popl %ebp
613; X32-NEXT:    retl
614;
615; X64-LABEL: knownbits_and_select_shuffle_uitofp:
616; X64:       # %bb.0:
617; X64-NEXT:    vandps {{.*}}(%rip), %xmm2, %xmm2
618; X64-NEXT:    vandps {{.*}}(%rip), %xmm3, %xmm3
619; X64-NEXT:    vpcmpeqd %xmm1, %xmm0, %xmm0
620; X64-NEXT:    vblendvps %xmm0, %xmm2, %xmm3, %xmm0
621; X64-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[0,0,2,2]
622; X64-NEXT:    vcvtdq2ps %xmm0, %xmm0
623; X64-NEXT:    retq
624  %1 = and <4 x i32> %a2, <i32 65535, i32 -1, i32 255, i32 -1>
625  %2 = and <4 x i32> %a3, <i32 255, i32 -1, i32 65535, i32 -1>
626  %3 = icmp eq <4 x i32> %a0, %a1
627  %4 = select <4 x i1> %3, <4 x i32> %1, <4 x i32> %2
628  %5 = shufflevector <4 x i32> %4, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 2, i32 2>
629  %6 = uitofp <4 x i32> %5 to <4 x float>
630  ret <4 x float> %6
631}
632
633define <4 x float> @knownbits_lshr_and_select_shuffle_uitofp(<4 x i32> %a0, <4 x i32> %a1, <4 x i32> %a2, <4 x i32> %a3) nounwind {
634; X32-LABEL: knownbits_lshr_and_select_shuffle_uitofp:
635; X32:       # %bb.0:
636; X32-NEXT:    pushl %ebp
637; X32-NEXT:    movl %esp, %ebp
638; X32-NEXT:    andl $-16, %esp
639; X32-NEXT:    subl $16, %esp
640; X32-NEXT:    vmovaps 8(%ebp), %xmm3
641; X32-NEXT:    vpsrld $5, %xmm2, %xmm2
642; X32-NEXT:    vandps {{\.LCPI.*}}, %xmm3, %xmm3
643; X32-NEXT:    vpcmpeqd %xmm1, %xmm0, %xmm0
644; X32-NEXT:    vblendvps %xmm0, %xmm2, %xmm3, %xmm0
645; X32-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[0,0,2,2]
646; X32-NEXT:    vcvtdq2ps %xmm0, %xmm0
647; X32-NEXT:    movl %ebp, %esp
648; X32-NEXT:    popl %ebp
649; X32-NEXT:    retl
650;
651; X64-LABEL: knownbits_lshr_and_select_shuffle_uitofp:
652; X64:       # %bb.0:
653; X64-NEXT:    vpsrld $5, %xmm2, %xmm2
654; X64-NEXT:    vandps {{.*}}(%rip), %xmm3, %xmm3
655; X64-NEXT:    vpcmpeqd %xmm1, %xmm0, %xmm0
656; X64-NEXT:    vblendvps %xmm0, %xmm2, %xmm3, %xmm0
657; X64-NEXT:    vpermilps {{.*#+}} xmm0 = xmm0[0,0,2,2]
658; X64-NEXT:    vcvtdq2ps %xmm0, %xmm0
659; X64-NEXT:    retq
660  %1 = lshr <4 x i32> %a2, <i32 5, i32 1, i32 5, i32 1>
661  %2 = and <4 x i32> %a3, <i32 255, i32 -1, i32 65535, i32 -1>
662  %3 = icmp eq <4 x i32> %a0, %a1
663  %4 = select <4 x i1> %3, <4 x i32> %1, <4 x i32> %2
664  %5 = shufflevector <4 x i32> %4, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 2, i32 2>
665  %6 = uitofp <4 x i32> %5 to <4 x float>
666  ret <4 x float> %6
667}
668