1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx,+f16c -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,AVX1
3; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx2,+f16c -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,AVX2
4; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx2,+f16c,+fast-variable-crosslane-shuffle,+fast-variable-perlane-shuffle -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,AVX2
5; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx2,+f16c,+fast-variable-perlane-shuffle -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,AVX2
6; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx512f -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,AVX512
7; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx512f,+avx512vl,+fast-variable-crosslane-shuffle,+fast-variable-perlane-shuffle -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,AVX512
8; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx512f,+avx512vl,+fast-variable-perlane-shuffle -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,AVX512
9
10;
11; Half to Float
12;
13
14define float @cvt_i16_to_f32(i16 %a0) nounwind {
15; ALL-LABEL: cvt_i16_to_f32:
16; ALL:       # %bb.0:
17; ALL-NEXT:    movzwl %di, %eax
18; ALL-NEXT:    vmovd %eax, %xmm0
19; ALL-NEXT:    vcvtph2ps %xmm0, %xmm0
20; ALL-NEXT:    retq
21  %1 = bitcast i16 %a0 to half
22  %2 = fpext half %1 to float
23  ret float %2
24}
25
26define <4 x float> @cvt_4i16_to_4f32(<4 x i16> %a0) nounwind {
27; ALL-LABEL: cvt_4i16_to_4f32:
28; ALL:       # %bb.0:
29; ALL-NEXT:    vcvtph2ps %xmm0, %xmm0
30; ALL-NEXT:    retq
31  %1 = bitcast <4 x i16> %a0 to <4 x half>
32  %2 = fpext <4 x half> %1 to <4 x float>
33  ret <4 x float> %2
34}
35
36define <4 x float> @cvt_8i16_to_4f32(<8 x i16> %a0) nounwind {
37; ALL-LABEL: cvt_8i16_to_4f32:
38; ALL:       # %bb.0:
39; ALL-NEXT:    vcvtph2ps %xmm0, %xmm0
40; ALL-NEXT:    retq
41  %1 = shufflevector <8 x i16> %a0, <8 x i16> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
42  %2 = bitcast <4 x i16> %1 to <4 x half>
43  %3 = fpext <4 x half> %2 to <4 x float>
44  ret <4 x float> %3
45}
46
47define <8 x float> @cvt_8i16_to_8f32(<8 x i16> %a0) nounwind {
48; ALL-LABEL: cvt_8i16_to_8f32:
49; ALL:       # %bb.0:
50; ALL-NEXT:    vcvtph2ps %xmm0, %ymm0
51; ALL-NEXT:    retq
52  %1 = bitcast <8 x i16> %a0 to <8 x half>
53  %2 = fpext <8 x half> %1 to <8 x float>
54  ret <8 x float> %2
55}
56
57define <16 x float> @cvt_16i16_to_16f32(<16 x i16> %a0) nounwind {
58; AVX1-LABEL: cvt_16i16_to_16f32:
59; AVX1:       # %bb.0:
60; AVX1-NEXT:    vcvtph2ps %xmm0, %ymm2
61; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
62; AVX1-NEXT:    vcvtph2ps %xmm0, %ymm1
63; AVX1-NEXT:    vmovaps %ymm2, %ymm0
64; AVX1-NEXT:    retq
65;
66; AVX2-LABEL: cvt_16i16_to_16f32:
67; AVX2:       # %bb.0:
68; AVX2-NEXT:    vcvtph2ps %xmm0, %ymm2
69; AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm0
70; AVX2-NEXT:    vcvtph2ps %xmm0, %ymm1
71; AVX2-NEXT:    vmovaps %ymm2, %ymm0
72; AVX2-NEXT:    retq
73;
74; AVX512-LABEL: cvt_16i16_to_16f32:
75; AVX512:       # %bb.0:
76; AVX512-NEXT:    vcvtph2ps %ymm0, %zmm0
77; AVX512-NEXT:    retq
78  %1 = bitcast <16 x i16> %a0 to <16 x half>
79  %2 = fpext <16 x half> %1 to <16 x float>
80  ret <16 x float> %2
81}
82
83define <2 x float> @cvt_2i16_to_2f32_constrained(<2 x i16> %a0) nounwind strictfp {
84; ALL-LABEL: cvt_2i16_to_2f32_constrained:
85; ALL:       # %bb.0:
86; ALL-NEXT:    vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero
87; ALL-NEXT:    vcvtph2ps %xmm0, %xmm0
88; ALL-NEXT:    retq
89  %1 = bitcast <2 x i16> %a0 to <2 x half>
90  %2 = call <2 x float> @llvm.experimental.constrained.fpext.v2f32.v2f16(<2 x half> %1, metadata !"fpexcept.strict") strictfp
91  ret <2 x float> %2
92}
93declare <2 x float> @llvm.experimental.constrained.fpext.v2f32.v2f16(<2 x half>, metadata) strictfp
94
95define <4 x float> @cvt_4i16_to_4f32_constrained(<4 x i16> %a0) nounwind strictfp {
96; ALL-LABEL: cvt_4i16_to_4f32_constrained:
97; ALL:       # %bb.0:
98; ALL-NEXT:    vcvtph2ps %xmm0, %xmm0
99; ALL-NEXT:    retq
100  %1 = bitcast <4 x i16> %a0 to <4 x half>
101  %2 = call <4 x float> @llvm.experimental.constrained.fpext.v4f32.v4f16(<4 x half> %1, metadata !"fpexcept.strict") strictfp
102  ret <4 x float> %2
103}
104declare <4 x float> @llvm.experimental.constrained.fpext.v4f32.v4f16(<4 x half>, metadata) strictfp
105
106define <8 x float> @cvt_8i16_to_8f32_constrained(<8 x i16> %a0) nounwind strictfp {
107; ALL-LABEL: cvt_8i16_to_8f32_constrained:
108; ALL:       # %bb.0:
109; ALL-NEXT:    vcvtph2ps %xmm0, %ymm0
110; ALL-NEXT:    retq
111  %1 = bitcast <8 x i16> %a0 to <8 x half>
112  %2 = call <8 x float> @llvm.experimental.constrained.fpext.v8f32.v8f16(<8 x half> %1, metadata !"fpexcept.strict") strictfp
113  ret <8 x float> %2
114}
115declare <8 x float> @llvm.experimental.constrained.fpext.v8f32.v8f16(<8 x half>, metadata) strictfp
116
117define <16 x float> @cvt_16i16_to_16f32_constrained(<16 x i16> %a0) nounwind strictfp {
118; AVX1-LABEL: cvt_16i16_to_16f32_constrained:
119; AVX1:       # %bb.0:
120; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
121; AVX1-NEXT:    vcvtph2ps %xmm1, %ymm1
122; AVX1-NEXT:    vcvtph2ps %xmm0, %ymm0
123; AVX1-NEXT:    retq
124;
125; AVX2-LABEL: cvt_16i16_to_16f32_constrained:
126; AVX2:       # %bb.0:
127; AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm1
128; AVX2-NEXT:    vcvtph2ps %xmm1, %ymm1
129; AVX2-NEXT:    vcvtph2ps %xmm0, %ymm0
130; AVX2-NEXT:    retq
131;
132; AVX512-LABEL: cvt_16i16_to_16f32_constrained:
133; AVX512:       # %bb.0:
134; AVX512-NEXT:    vcvtph2ps %ymm0, %zmm0
135; AVX512-NEXT:    retq
136  %1 = bitcast <16 x i16> %a0 to <16 x half>
137  %2 = call <16 x float> @llvm.experimental.constrained.fpext.v16f32.v16f16(<16 x half> %1, metadata !"fpexcept.strict") strictfp
138  ret <16 x float> %2
139}
140declare <16 x float> @llvm.experimental.constrained.fpext.v16f32.v16f16(<16 x half>, metadata) strictfp
141
142;
143; Half to Float (Load)
144;
145
146define float @load_cvt_i16_to_f32(ptr %a0) nounwind {
147; ALL-LABEL: load_cvt_i16_to_f32:
148; ALL:       # %bb.0:
149; ALL-NEXT:    movzwl (%rdi), %eax
150; ALL-NEXT:    vmovd %eax, %xmm0
151; ALL-NEXT:    vcvtph2ps %xmm0, %xmm0
152; ALL-NEXT:    retq
153  %1 = load i16, ptr %a0
154  %2 = bitcast i16 %1 to half
155  %3 = fpext half %2 to float
156  ret float %3
157}
158
159define <4 x float> @load_cvt_4i16_to_4f32(ptr %a0) nounwind {
160; ALL-LABEL: load_cvt_4i16_to_4f32:
161; ALL:       # %bb.0:
162; ALL-NEXT:    vcvtph2ps (%rdi), %xmm0
163; ALL-NEXT:    retq
164  %1 = load <4 x i16>, ptr %a0
165  %2 = bitcast <4 x i16> %1 to <4 x half>
166  %3 = fpext <4 x half> %2 to <4 x float>
167  ret <4 x float> %3
168}
169
170define <4 x float> @load_cvt_8i16_to_4f32(ptr %a0) nounwind {
171; ALL-LABEL: load_cvt_8i16_to_4f32:
172; ALL:       # %bb.0:
173; ALL-NEXT:    vcvtph2ps (%rdi), %xmm0
174; ALL-NEXT:    retq
175  %1 = load <8 x i16>, ptr %a0
176  %2 = shufflevector <8 x i16> %1, <8 x i16> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
177  %3 = bitcast <4 x i16> %2 to <4 x half>
178  %4 = fpext <4 x half> %3 to <4 x float>
179  ret <4 x float> %4
180}
181
182define <8 x float> @load_cvt_8i16_to_8f32(ptr %a0) nounwind {
183; ALL-LABEL: load_cvt_8i16_to_8f32:
184; ALL:       # %bb.0:
185; ALL-NEXT:    vcvtph2ps (%rdi), %ymm0
186; ALL-NEXT:    retq
187  %1 = load <8 x i16>, ptr %a0
188  %2 = bitcast <8 x i16> %1 to <8 x half>
189  %3 = fpext <8 x half> %2 to <8 x float>
190  ret <8 x float> %3
191}
192
193define <16 x float> @load_cvt_16i16_to_16f32(ptr %a0) nounwind {
194; AVX1-LABEL: load_cvt_16i16_to_16f32:
195; AVX1:       # %bb.0:
196; AVX1-NEXT:    vcvtph2ps (%rdi), %ymm0
197; AVX1-NEXT:    vcvtph2ps 16(%rdi), %ymm1
198; AVX1-NEXT:    retq
199;
200; AVX2-LABEL: load_cvt_16i16_to_16f32:
201; AVX2:       # %bb.0:
202; AVX2-NEXT:    vcvtph2ps (%rdi), %ymm0
203; AVX2-NEXT:    vcvtph2ps 16(%rdi), %ymm1
204; AVX2-NEXT:    retq
205;
206; AVX512-LABEL: load_cvt_16i16_to_16f32:
207; AVX512:       # %bb.0:
208; AVX512-NEXT:    vcvtph2ps (%rdi), %zmm0
209; AVX512-NEXT:    retq
210  %1 = load <16 x i16>, ptr %a0
211  %2 = bitcast <16 x i16> %1 to <16 x half>
212  %3 = fpext <16 x half> %2 to <16 x float>
213  ret <16 x float> %3
214}
215
216define <4 x float> @load_cvt_4i16_to_4f32_constrained(ptr %a0) nounwind strictfp {
217; ALL-LABEL: load_cvt_4i16_to_4f32_constrained:
218; ALL:       # %bb.0:
219; ALL-NEXT:    vcvtph2ps (%rdi), %xmm0
220; ALL-NEXT:    retq
221  %1 = load <4 x i16>, ptr %a0
222  %2 = bitcast <4 x i16> %1 to <4 x half>
223  %3 = call <4 x float> @llvm.experimental.constrained.fpext.v4f32.v4f16(<4 x half> %2, metadata !"fpexcept.strict") strictfp
224  ret <4 x float> %3
225}
226
227define <4 x float> @load_cvt_8i16_to_4f32_constrained(ptr %a0) nounwind strictfp {
228; ALL-LABEL: load_cvt_8i16_to_4f32_constrained:
229; ALL:       # %bb.0:
230; ALL-NEXT:    vcvtph2ps (%rdi), %xmm0
231; ALL-NEXT:    retq
232  %1 = load <8 x i16>, ptr %a0
233  %2 = shufflevector <8 x i16> %1, <8 x i16> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
234  %3 = bitcast <4 x i16> %2 to <4 x half>
235  %4 = call <4 x float> @llvm.experimental.constrained.fpext.v4f32.v4f16(<4 x half> %3, metadata !"fpexcept.strict") strictfp
236  ret <4 x float> %4
237}
238
239;
240; Half to Double
241;
242
243define double @cvt_i16_to_f64(i16 %a0) nounwind {
244; ALL-LABEL: cvt_i16_to_f64:
245; ALL:       # %bb.0:
246; ALL-NEXT:    movzwl %di, %eax
247; ALL-NEXT:    vmovd %eax, %xmm0
248; ALL-NEXT:    vcvtph2ps %xmm0, %xmm0
249; ALL-NEXT:    vcvtss2sd %xmm0, %xmm0, %xmm0
250; ALL-NEXT:    retq
251  %1 = bitcast i16 %a0 to half
252  %2 = fpext half %1 to double
253  ret double %2
254}
255
256define <2 x double> @cvt_2i16_to_2f64(<2 x i16> %a0) nounwind {
257; ALL-LABEL: cvt_2i16_to_2f64:
258; ALL:       # %bb.0:
259; ALL-NEXT:    vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero
260; ALL-NEXT:    vcvtph2ps %xmm0, %xmm0
261; ALL-NEXT:    vcvtps2pd %xmm0, %xmm0
262; ALL-NEXT:    retq
263  %1 = bitcast <2 x i16> %a0 to <2 x half>
264  %2 = fpext <2 x half> %1 to <2 x double>
265  ret <2 x double> %2
266}
267
268define <4 x double> @cvt_4i16_to_4f64(<4 x i16> %a0) nounwind {
269; ALL-LABEL: cvt_4i16_to_4f64:
270; ALL:       # %bb.0:
271; ALL-NEXT:    vcvtph2ps %xmm0, %xmm0
272; ALL-NEXT:    vcvtps2pd %xmm0, %ymm0
273; ALL-NEXT:    retq
274  %1 = bitcast <4 x i16> %a0 to <4 x half>
275  %2 = fpext <4 x half> %1 to <4 x double>
276  ret <4 x double> %2
277}
278
279define <2 x double> @cvt_8i16_to_2f64(<8 x i16> %a0) nounwind {
280; ALL-LABEL: cvt_8i16_to_2f64:
281; ALL:       # %bb.0:
282; ALL-NEXT:    vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero
283; ALL-NEXT:    vcvtph2ps %xmm0, %xmm0
284; ALL-NEXT:    vcvtps2pd %xmm0, %xmm0
285; ALL-NEXT:    retq
286  %1 = shufflevector <8 x i16> %a0, <8 x i16> undef, <2 x i32> <i32 0, i32 1>
287  %2 = bitcast <2 x i16> %1 to <2 x half>
288  %3 = fpext <2 x half> %2 to <2 x double>
289  ret <2 x double> %3
290}
291
292define <4 x double> @cvt_8i16_to_4f64(<8 x i16> %a0) nounwind {
293; ALL-LABEL: cvt_8i16_to_4f64:
294; ALL:       # %bb.0:
295; ALL-NEXT:    vcvtph2ps %xmm0, %xmm0
296; ALL-NEXT:    vcvtps2pd %xmm0, %ymm0
297; ALL-NEXT:    retq
298  %1 = shufflevector <8 x i16> %a0, <8 x i16> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
299  %2 = bitcast <4 x i16> %1 to <4 x half>
300  %3 = fpext <4 x half> %2 to <4 x double>
301  ret <4 x double> %3
302}
303
304define <8 x double> @cvt_8i16_to_8f64(<8 x i16> %a0) nounwind {
305; AVX1-LABEL: cvt_8i16_to_8f64:
306; AVX1:       # %bb.0:
307; AVX1-NEXT:    vcvtph2ps %xmm0, %ymm1
308; AVX1-NEXT:    vcvtps2pd %xmm1, %ymm0
309; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
310; AVX1-NEXT:    vcvtps2pd %xmm1, %ymm1
311; AVX1-NEXT:    retq
312;
313; AVX2-LABEL: cvt_8i16_to_8f64:
314; AVX2:       # %bb.0:
315; AVX2-NEXT:    vcvtph2ps %xmm0, %ymm1
316; AVX2-NEXT:    vcvtps2pd %xmm1, %ymm0
317; AVX2-NEXT:    vextractf128 $1, %ymm1, %xmm1
318; AVX2-NEXT:    vcvtps2pd %xmm1, %ymm1
319; AVX2-NEXT:    retq
320;
321; AVX512-LABEL: cvt_8i16_to_8f64:
322; AVX512:       # %bb.0:
323; AVX512-NEXT:    vcvtph2ps %xmm0, %ymm0
324; AVX512-NEXT:    vcvtps2pd %ymm0, %zmm0
325; AVX512-NEXT:    retq
326  %1 = bitcast <8 x i16> %a0 to <8 x half>
327  %2 = fpext <8 x half> %1 to <8 x double>
328  ret <8 x double> %2
329}
330
331define <2 x double> @cvt_2i16_to_2f64_constrained(<2 x i16> %a0) nounwind strictfp {
332; ALL-LABEL: cvt_2i16_to_2f64_constrained:
333; ALL:       # %bb.0:
334; ALL-NEXT:    vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero
335; ALL-NEXT:    vcvtph2ps %xmm0, %xmm0
336; ALL-NEXT:    vcvtps2pd %xmm0, %xmm0
337; ALL-NEXT:    retq
338  %1 = bitcast <2 x i16> %a0 to <2 x half>
339  %2 = call <2 x double> @llvm.experimental.constrained.fpext.v2f64.v2f16(<2 x half> %1, metadata !"fpexcept.strict") strictfp
340  ret <2 x double> %2
341}
342declare <2 x double> @llvm.experimental.constrained.fpext.v2f64.v2f16(<2 x half>, metadata) strictfp
343
344define <4 x double> @cvt_4i16_to_4f64_constrained(<4 x i16> %a0) nounwind strictfp {
345; ALL-LABEL: cvt_4i16_to_4f64_constrained:
346; ALL:       # %bb.0:
347; ALL-NEXT:    vcvtph2ps %xmm0, %xmm0
348; ALL-NEXT:    vcvtps2pd %xmm0, %ymm0
349; ALL-NEXT:    retq
350  %1 = bitcast <4 x i16> %a0 to <4 x half>
351  %2 = call <4 x double> @llvm.experimental.constrained.fpext.v4f64.v4f16(<4 x half> %1, metadata !"fpexcept.strict") strictfp
352  ret <4 x double> %2
353}
354declare <4 x double> @llvm.experimental.constrained.fpext.v4f64.v4f16(<4 x half>, metadata) strictfp
355
356define <8 x double> @cvt_8i16_to_8f64_constrained(<8 x i16> %a0) nounwind strictfp {
357; AVX1-LABEL: cvt_8i16_to_8f64_constrained:
358; AVX1:       # %bb.0:
359; AVX1-NEXT:    vcvtph2ps %xmm0, %ymm0
360; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
361; AVX1-NEXT:    vcvtps2pd %xmm1, %ymm1
362; AVX1-NEXT:    vcvtps2pd %xmm0, %ymm0
363; AVX1-NEXT:    retq
364;
365; AVX2-LABEL: cvt_8i16_to_8f64_constrained:
366; AVX2:       # %bb.0:
367; AVX2-NEXT:    vcvtph2ps %xmm0, %ymm0
368; AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm1
369; AVX2-NEXT:    vcvtps2pd %xmm1, %ymm1
370; AVX2-NEXT:    vcvtps2pd %xmm0, %ymm0
371; AVX2-NEXT:    retq
372;
373; AVX512-LABEL: cvt_8i16_to_8f64_constrained:
374; AVX512:       # %bb.0:
375; AVX512-NEXT:    vcvtph2ps %xmm0, %ymm0
376; AVX512-NEXT:    vcvtps2pd %ymm0, %zmm0
377; AVX512-NEXT:    retq
378  %1 = bitcast <8 x i16> %a0 to <8 x half>
379  %2 = call <8 x double> @llvm.experimental.constrained.fpext.v8f64.v8f16(<8 x half> %1, metadata !"fpexcept.strict") strictfp
380  ret <8 x double> %2
381}
382declare <8 x double> @llvm.experimental.constrained.fpext.v8f64.v8f16(<8 x half>, metadata) strictfp
383
384;
385; Half to Double (Load)
386;
387
388define double @load_cvt_i16_to_f64(ptr %a0) nounwind {
389; ALL-LABEL: load_cvt_i16_to_f64:
390; ALL:       # %bb.0:
391; ALL-NEXT:    movzwl (%rdi), %eax
392; ALL-NEXT:    vmovd %eax, %xmm0
393; ALL-NEXT:    vcvtph2ps %xmm0, %xmm0
394; ALL-NEXT:    vcvtss2sd %xmm0, %xmm0, %xmm0
395; ALL-NEXT:    retq
396  %1 = load i16, ptr %a0
397  %2 = bitcast i16 %1 to half
398  %3 = fpext half %2 to double
399  ret double %3
400}
401
402define <2 x double> @load_cvt_2i16_to_2f64(ptr %a0) nounwind {
403; ALL-LABEL: load_cvt_2i16_to_2f64:
404; ALL:       # %bb.0:
405; ALL-NEXT:    vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero
406; ALL-NEXT:    vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero
407; ALL-NEXT:    vcvtph2ps %xmm0, %xmm0
408; ALL-NEXT:    vcvtps2pd %xmm0, %xmm0
409; ALL-NEXT:    retq
410  %1 = load <2 x i16>, ptr %a0
411  %2 = bitcast <2 x i16> %1 to <2 x half>
412  %3 = fpext <2 x half> %2 to <2 x double>
413  ret <2 x double> %3
414}
415
416define <4 x double> @load_cvt_4i16_to_4f64(ptr %a0) nounwind {
417; ALL-LABEL: load_cvt_4i16_to_4f64:
418; ALL:       # %bb.0:
419; ALL-NEXT:    vcvtph2ps (%rdi), %xmm0
420; ALL-NEXT:    vcvtps2pd %xmm0, %ymm0
421; ALL-NEXT:    retq
422  %1 = load <4 x i16>, ptr %a0
423  %2 = bitcast <4 x i16> %1 to <4 x half>
424  %3 = fpext <4 x half> %2 to <4 x double>
425  ret <4 x double> %3
426}
427
428define <4 x double> @load_cvt_8i16_to_4f64(ptr %a0) nounwind {
429; ALL-LABEL: load_cvt_8i16_to_4f64:
430; ALL:       # %bb.0:
431; ALL-NEXT:    vcvtph2ps (%rdi), %xmm0
432; ALL-NEXT:    vcvtps2pd %xmm0, %ymm0
433; ALL-NEXT:    retq
434  %1 = load <8 x i16>, ptr %a0
435  %2 = shufflevector <8 x i16> %1, <8 x i16> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
436  %3 = bitcast <4 x i16> %2 to <4 x half>
437  %4 = fpext <4 x half> %3 to <4 x double>
438  ret <4 x double> %4
439}
440
441define <8 x double> @load_cvt_8i16_to_8f64(ptr %a0) nounwind {
442; AVX1-LABEL: load_cvt_8i16_to_8f64:
443; AVX1:       # %bb.0:
444; AVX1-NEXT:    vcvtph2ps (%rdi), %ymm1
445; AVX1-NEXT:    vcvtps2pd %xmm1, %ymm0
446; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm1
447; AVX1-NEXT:    vcvtps2pd %xmm1, %ymm1
448; AVX1-NEXT:    retq
449;
450; AVX2-LABEL: load_cvt_8i16_to_8f64:
451; AVX2:       # %bb.0:
452; AVX2-NEXT:    vcvtph2ps (%rdi), %ymm1
453; AVX2-NEXT:    vcvtps2pd %xmm1, %ymm0
454; AVX2-NEXT:    vextractf128 $1, %ymm1, %xmm1
455; AVX2-NEXT:    vcvtps2pd %xmm1, %ymm1
456; AVX2-NEXT:    retq
457;
458; AVX512-LABEL: load_cvt_8i16_to_8f64:
459; AVX512:       # %bb.0:
460; AVX512-NEXT:    vcvtph2ps (%rdi), %ymm0
461; AVX512-NEXT:    vcvtps2pd %ymm0, %zmm0
462; AVX512-NEXT:    retq
463  %1 = load <8 x i16>, ptr %a0
464  %2 = bitcast <8 x i16> %1 to <8 x half>
465  %3 = fpext <8 x half> %2 to <8 x double>
466  ret <8 x double> %3
467}
468
469;
470; Float to Half
471;
472
473define i16 @cvt_f32_to_i16(float %a0) nounwind {
474; ALL-LABEL: cvt_f32_to_i16:
475; ALL:       # %bb.0:
476; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
477; ALL-NEXT:    vmovd %xmm0, %eax
478; ALL-NEXT:    # kill: def $ax killed $ax killed $eax
479; ALL-NEXT:    retq
480  %1 = fptrunc float %a0 to half
481  %2 = bitcast half %1 to i16
482  ret i16 %2
483}
484
485define <4 x i16> @cvt_4f32_to_4i16(<4 x float> %a0) nounwind {
486; ALL-LABEL: cvt_4f32_to_4i16:
487; ALL:       # %bb.0:
488; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
489; ALL-NEXT:    retq
490  %1 = fptrunc <4 x float> %a0 to <4 x half>
491  %2 = bitcast <4 x half> %1 to <4 x i16>
492  ret <4 x i16> %2
493}
494
495define <8 x i16> @cvt_4f32_to_8i16_undef(<4 x float> %a0) nounwind {
496; ALL-LABEL: cvt_4f32_to_8i16_undef:
497; ALL:       # %bb.0:
498; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
499; ALL-NEXT:    retq
500  %1 = fptrunc <4 x float> %a0 to <4 x half>
501  %2 = bitcast <4 x half> %1 to <4 x i16>
502  %3 = shufflevector <4 x i16> %2, <4 x i16> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
503  ret <8 x i16> %3
504}
505
506define <8 x i16> @cvt_4f32_to_8i16_zero(<4 x float> %a0) nounwind {
507; ALL-LABEL: cvt_4f32_to_8i16_zero:
508; ALL:       # %bb.0:
509; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
510; ALL-NEXT:    retq
511  %1 = fptrunc <4 x float> %a0 to <4 x half>
512  %2 = bitcast <4 x half> %1 to <4 x i16>
513  %3 = shufflevector <4 x i16> %2, <4 x i16> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
514  ret <8 x i16> %3
515}
516
517define <8 x i16> @cvt_8f32_to_8i16(<8 x float> %a0) nounwind {
518; ALL-LABEL: cvt_8f32_to_8i16:
519; ALL:       # %bb.0:
520; ALL-NEXT:    vcvtps2ph $4, %ymm0, %xmm0
521; ALL-NEXT:    vzeroupper
522; ALL-NEXT:    retq
523  %1 = fptrunc <8 x float> %a0 to <8 x half>
524  %2 = bitcast <8 x half> %1 to <8 x i16>
525  ret <8 x i16> %2
526}
527
528define <16 x i16> @cvt_16f32_to_16i16(<16 x float> %a0) nounwind {
529; AVX1-LABEL: cvt_16f32_to_16i16:
530; AVX1:       # %bb.0:
531; AVX1-NEXT:    vcvtps2ph $4, %ymm0, %xmm0
532; AVX1-NEXT:    vcvtps2ph $4, %ymm1, %xmm1
533; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
534; AVX1-NEXT:    retq
535;
536; AVX2-LABEL: cvt_16f32_to_16i16:
537; AVX2:       # %bb.0:
538; AVX2-NEXT:    vcvtps2ph $4, %ymm0, %xmm0
539; AVX2-NEXT:    vcvtps2ph $4, %ymm1, %xmm1
540; AVX2-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
541; AVX2-NEXT:    retq
542;
543; AVX512-LABEL: cvt_16f32_to_16i16:
544; AVX512:       # %bb.0:
545; AVX512-NEXT:    vcvtps2ph $4, %zmm0, %ymm0
546; AVX512-NEXT:    retq
547  %1 = fptrunc <16 x float> %a0 to <16 x half>
548  %2 = bitcast <16 x half> %1 to <16 x i16>
549  ret <16 x i16> %2
550}
551
552;
553; Float to Half (Store)
554;
555
556define void @store_cvt_f32_to_i16(float %a0, ptr %a1) nounwind {
557; ALL-LABEL: store_cvt_f32_to_i16:
558; ALL:       # %bb.0:
559; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
560; ALL-NEXT:    vmovd %xmm0, %eax
561; ALL-NEXT:    movw %ax, (%rdi)
562; ALL-NEXT:    retq
563  %1 = fptrunc float %a0 to half
564  %2 = bitcast half %1 to i16
565  store i16 %2, ptr %a1
566  ret void
567}
568
569define void @store_cvt_4f32_to_4i16(<4 x float> %a0, ptr %a1) nounwind {
570; ALL-LABEL: store_cvt_4f32_to_4i16:
571; ALL:       # %bb.0:
572; ALL-NEXT:    vcvtps2ph $4, %xmm0, (%rdi)
573; ALL-NEXT:    retq
574  %1 = fptrunc <4 x float> %a0 to <4 x half>
575  %2 = bitcast <4 x half> %1 to <4 x i16>
576  store <4 x i16> %2, ptr %a1
577  ret void
578}
579
580define void @store_cvt_4f32_to_8i16_undef(<4 x float> %a0, ptr %a1) nounwind {
581; ALL-LABEL: store_cvt_4f32_to_8i16_undef:
582; ALL:       # %bb.0:
583; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
584; ALL-NEXT:    vmovaps %xmm0, (%rdi)
585; ALL-NEXT:    retq
586  %1 = fptrunc <4 x float> %a0 to <4 x half>
587  %2 = bitcast <4 x half> %1 to <4 x i16>
588  %3 = shufflevector <4 x i16> %2, <4 x i16> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
589  store <8 x i16> %3, ptr %a1
590  ret void
591}
592
593define void @store_cvt_4f32_to_8i16_zero(<4 x float> %a0, ptr %a1) nounwind {
594; ALL-LABEL: store_cvt_4f32_to_8i16_zero:
595; ALL:       # %bb.0:
596; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
597; ALL-NEXT:    vmovaps %xmm0, (%rdi)
598; ALL-NEXT:    retq
599  %1 = fptrunc <4 x float> %a0 to <4 x half>
600  %2 = bitcast <4 x half> %1 to <4 x i16>
601  %3 = shufflevector <4 x i16> %2, <4 x i16> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
602  store <8 x i16> %3, ptr %a1
603  ret void
604}
605
606define void @store_cvt_8f32_to_8i16(<8 x float> %a0, ptr %a1) nounwind {
607; ALL-LABEL: store_cvt_8f32_to_8i16:
608; ALL:       # %bb.0:
609; ALL-NEXT:    vcvtps2ph $4, %ymm0, (%rdi)
610; ALL-NEXT:    vzeroupper
611; ALL-NEXT:    retq
612  %1 = fptrunc <8 x float> %a0 to <8 x half>
613  %2 = bitcast <8 x half> %1 to <8 x i16>
614  store <8 x i16> %2, ptr %a1
615  ret void
616}
617
618define void @store_cvt_16f32_to_16i16(<16 x float> %a0, ptr %a1) nounwind {
619; AVX1-LABEL: store_cvt_16f32_to_16i16:
620; AVX1:       # %bb.0:
621; AVX1-NEXT:    vcvtps2ph $4, %ymm1, 16(%rdi)
622; AVX1-NEXT:    vcvtps2ph $4, %ymm0, (%rdi)
623; AVX1-NEXT:    vzeroupper
624; AVX1-NEXT:    retq
625;
626; AVX2-LABEL: store_cvt_16f32_to_16i16:
627; AVX2:       # %bb.0:
628; AVX2-NEXT:    vcvtps2ph $4, %ymm1, 16(%rdi)
629; AVX2-NEXT:    vcvtps2ph $4, %ymm0, (%rdi)
630; AVX2-NEXT:    vzeroupper
631; AVX2-NEXT:    retq
632;
633; AVX512-LABEL: store_cvt_16f32_to_16i16:
634; AVX512:       # %bb.0:
635; AVX512-NEXT:    vcvtps2ph $4, %zmm0, (%rdi)
636; AVX512-NEXT:    vzeroupper
637; AVX512-NEXT:    retq
638  %1 = fptrunc <16 x float> %a0 to <16 x half>
639  %2 = bitcast <16 x half> %1 to <16 x i16>
640  store <16 x i16> %2, ptr %a1
641  ret void
642}
643
644;
645; Double to Half
646;
647
648define i16 @cvt_f64_to_i16(double %a0) nounwind {
649; ALL-LABEL: cvt_f64_to_i16:
650; ALL:       # %bb.0:
651; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
652; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
653; ALL-NEXT:    vmovd %xmm0, %eax
654; ALL-NEXT:    # kill: def $ax killed $ax killed $eax
655; ALL-NEXT:    retq
656  %1 = fptrunc double %a0 to half
657  %2 = bitcast half %1 to i16
658  ret i16 %2
659}
660
661define <2 x i16> @cvt_2f64_to_2i16(<2 x double> %a0) nounwind {
662; ALL-LABEL: cvt_2f64_to_2i16:
663; ALL:       # %bb.0:
664; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm1
665; ALL-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
666; ALL-NEXT:    vmovd %xmm1, %eax
667; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
668; ALL-NEXT:    vpermilpd {{.*#+}} xmm0 = xmm0[1,0]
669; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
670; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
671; ALL-NEXT:    vmovd %xmm0, %eax
672; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
673; ALL-NEXT:    vmovaps -{{[0-9]+}}(%rsp), %xmm0
674; ALL-NEXT:    retq
675  %1 = fptrunc <2 x double> %a0 to <2 x half>
676  %2 = bitcast <2 x half> %1 to <2 x i16>
677  ret <2 x i16> %2
678}
679
680define <4 x i16> @cvt_4f64_to_4i16(<4 x double> %a0) nounwind {
681; ALL-LABEL: cvt_4f64_to_4i16:
682; ALL:       # %bb.0:
683; ALL-NEXT:    vextractf128 $1, %ymm0, %xmm1
684; ALL-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm2
685; ALL-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
686; ALL-NEXT:    vmovd %xmm2, %eax
687; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
688; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm2
689; ALL-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
690; ALL-NEXT:    vmovd %xmm2, %eax
691; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
692; ALL-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm1[1,0]
693; ALL-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm1
694; ALL-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
695; ALL-NEXT:    vmovd %xmm1, %eax
696; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
697; ALL-NEXT:    vpermilpd {{.*#+}} xmm0 = xmm0[1,0]
698; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
699; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
700; ALL-NEXT:    vmovd %xmm0, %eax
701; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
702; ALL-NEXT:    vmovaps -{{[0-9]+}}(%rsp), %xmm0
703; ALL-NEXT:    vzeroupper
704; ALL-NEXT:    retq
705  %1 = fptrunc <4 x double> %a0 to <4 x half>
706  %2 = bitcast <4 x half> %1 to <4 x i16>
707  ret <4 x i16> %2
708}
709
710define <8 x i16> @cvt_4f64_to_8i16_undef(<4 x double> %a0) nounwind {
711; ALL-LABEL: cvt_4f64_to_8i16_undef:
712; ALL:       # %bb.0:
713; ALL-NEXT:    vextractf128 $1, %ymm0, %xmm1
714; ALL-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm2
715; ALL-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
716; ALL-NEXT:    vmovd %xmm2, %eax
717; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
718; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm2
719; ALL-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
720; ALL-NEXT:    vmovd %xmm2, %eax
721; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
722; ALL-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm1[1,0]
723; ALL-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm1
724; ALL-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
725; ALL-NEXT:    vmovd %xmm1, %eax
726; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
727; ALL-NEXT:    vpermilpd {{.*#+}} xmm0 = xmm0[1,0]
728; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
729; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
730; ALL-NEXT:    vmovd %xmm0, %eax
731; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
732; ALL-NEXT:    vmovaps -{{[0-9]+}}(%rsp), %xmm0
733; ALL-NEXT:    vzeroupper
734; ALL-NEXT:    retq
735  %1 = fptrunc <4 x double> %a0 to <4 x half>
736  %2 = bitcast <4 x half> %1 to <4 x i16>
737  %3 = shufflevector <4 x i16> %2, <4 x i16> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
738  ret <8 x i16> %3
739}
740
741define <8 x i16> @cvt_4f64_to_8i16_zero(<4 x double> %a0) nounwind {
742; ALL-LABEL: cvt_4f64_to_8i16_zero:
743; ALL:       # %bb.0:
744; ALL-NEXT:    vextractf128 $1, %ymm0, %xmm1
745; ALL-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm2
746; ALL-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
747; ALL-NEXT:    vmovd %xmm2, %eax
748; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
749; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm2
750; ALL-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
751; ALL-NEXT:    vmovd %xmm2, %eax
752; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
753; ALL-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm1[1,0]
754; ALL-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm1
755; ALL-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
756; ALL-NEXT:    vmovd %xmm1, %eax
757; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
758; ALL-NEXT:    vpermilpd {{.*#+}} xmm0 = xmm0[1,0]
759; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
760; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
761; ALL-NEXT:    vmovd %xmm0, %eax
762; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
763; ALL-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
764; ALL-NEXT:    vzeroupper
765; ALL-NEXT:    retq
766  %1 = fptrunc <4 x double> %a0 to <4 x half>
767  %2 = bitcast <4 x half> %1 to <4 x i16>
768  %3 = shufflevector <4 x i16> %2, <4 x i16> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
769  ret <8 x i16> %3
770}
771
772define <8 x i16> @cvt_8f64_to_8i16(<8 x double> %a0) nounwind {
773; AVX1-LABEL: cvt_8f64_to_8i16:
774; AVX1:       # %bb.0:
775; AVX1-NEXT:    vpermilpd {{.*#+}} xmm2 = xmm0[1,0]
776; AVX1-NEXT:    vcvtsd2ss %xmm2, %xmm2, %xmm2
777; AVX1-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
778; AVX1-NEXT:    vmovd %xmm2, %eax
779; AVX1-NEXT:    shll $16, %eax
780; AVX1-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm2
781; AVX1-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
782; AVX1-NEXT:    vmovd %xmm2, %ecx
783; AVX1-NEXT:    movzwl %cx, %ecx
784; AVX1-NEXT:    orl %eax, %ecx
785; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
786; AVX1-NEXT:    vpermilpd {{.*#+}} xmm2 = xmm0[1,0]
787; AVX1-NEXT:    vcvtsd2ss %xmm2, %xmm2, %xmm2
788; AVX1-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
789; AVX1-NEXT:    vmovd %xmm2, %edx
790; AVX1-NEXT:    shll $16, %edx
791; AVX1-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
792; AVX1-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
793; AVX1-NEXT:    vmovd %xmm0, %eax
794; AVX1-NEXT:    movzwl %ax, %eax
795; AVX1-NEXT:    orl %edx, %eax
796; AVX1-NEXT:    shlq $32, %rax
797; AVX1-NEXT:    orq %rcx, %rax
798; AVX1-NEXT:    vpermilpd {{.*#+}} xmm0 = xmm1[1,0]
799; AVX1-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
800; AVX1-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
801; AVX1-NEXT:    vmovd %xmm0, %ecx
802; AVX1-NEXT:    shll $16, %ecx
803; AVX1-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm0
804; AVX1-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
805; AVX1-NEXT:    vmovd %xmm0, %edx
806; AVX1-NEXT:    movzwl %dx, %edx
807; AVX1-NEXT:    orl %ecx, %edx
808; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm0
809; AVX1-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
810; AVX1-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm1
811; AVX1-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
812; AVX1-NEXT:    vmovd %xmm1, %ecx
813; AVX1-NEXT:    shll $16, %ecx
814; AVX1-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
815; AVX1-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
816; AVX1-NEXT:    vmovd %xmm0, %esi
817; AVX1-NEXT:    movzwl %si, %esi
818; AVX1-NEXT:    orl %ecx, %esi
819; AVX1-NEXT:    shlq $32, %rsi
820; AVX1-NEXT:    orq %rdx, %rsi
821; AVX1-NEXT:    vmovq %rsi, %xmm0
822; AVX1-NEXT:    vmovq %rax, %xmm1
823; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
824; AVX1-NEXT:    vzeroupper
825; AVX1-NEXT:    retq
826;
827; AVX2-LABEL: cvt_8f64_to_8i16:
828; AVX2:       # %bb.0:
829; AVX2-NEXT:    vpermilpd {{.*#+}} xmm2 = xmm0[1,0]
830; AVX2-NEXT:    vcvtsd2ss %xmm2, %xmm2, %xmm2
831; AVX2-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
832; AVX2-NEXT:    vmovd %xmm2, %eax
833; AVX2-NEXT:    shll $16, %eax
834; AVX2-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm2
835; AVX2-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
836; AVX2-NEXT:    vmovd %xmm2, %ecx
837; AVX2-NEXT:    movzwl %cx, %ecx
838; AVX2-NEXT:    orl %eax, %ecx
839; AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm0
840; AVX2-NEXT:    vpermilpd {{.*#+}} xmm2 = xmm0[1,0]
841; AVX2-NEXT:    vcvtsd2ss %xmm2, %xmm2, %xmm2
842; AVX2-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
843; AVX2-NEXT:    vmovd %xmm2, %edx
844; AVX2-NEXT:    shll $16, %edx
845; AVX2-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
846; AVX2-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
847; AVX2-NEXT:    vmovd %xmm0, %eax
848; AVX2-NEXT:    movzwl %ax, %eax
849; AVX2-NEXT:    orl %edx, %eax
850; AVX2-NEXT:    shlq $32, %rax
851; AVX2-NEXT:    orq %rcx, %rax
852; AVX2-NEXT:    vpermilpd {{.*#+}} xmm0 = xmm1[1,0]
853; AVX2-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
854; AVX2-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
855; AVX2-NEXT:    vmovd %xmm0, %ecx
856; AVX2-NEXT:    shll $16, %ecx
857; AVX2-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm0
858; AVX2-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
859; AVX2-NEXT:    vmovd %xmm0, %edx
860; AVX2-NEXT:    movzwl %dx, %edx
861; AVX2-NEXT:    orl %ecx, %edx
862; AVX2-NEXT:    vextractf128 $1, %ymm1, %xmm0
863; AVX2-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
864; AVX2-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm1
865; AVX2-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
866; AVX2-NEXT:    vmovd %xmm1, %ecx
867; AVX2-NEXT:    shll $16, %ecx
868; AVX2-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
869; AVX2-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
870; AVX2-NEXT:    vmovd %xmm0, %esi
871; AVX2-NEXT:    movzwl %si, %esi
872; AVX2-NEXT:    orl %ecx, %esi
873; AVX2-NEXT:    shlq $32, %rsi
874; AVX2-NEXT:    orq %rdx, %rsi
875; AVX2-NEXT:    vmovq %rsi, %xmm0
876; AVX2-NEXT:    vmovq %rax, %xmm1
877; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
878; AVX2-NEXT:    vzeroupper
879; AVX2-NEXT:    retq
880;
881; AVX512-LABEL: cvt_8f64_to_8i16:
882; AVX512:       # %bb.0:
883; AVX512-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
884; AVX512-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm1
885; AVX512-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
886; AVX512-NEXT:    vmovd %xmm1, %eax
887; AVX512-NEXT:    shll $16, %eax
888; AVX512-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm1
889; AVX512-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
890; AVX512-NEXT:    vmovd %xmm1, %ecx
891; AVX512-NEXT:    movzwl %cx, %ecx
892; AVX512-NEXT:    orl %eax, %ecx
893; AVX512-NEXT:    vextractf128 $1, %ymm0, %xmm1
894; AVX512-NEXT:    vpermilpd {{.*#+}} xmm2 = xmm1[1,0]
895; AVX512-NEXT:    vcvtsd2ss %xmm2, %xmm2, %xmm2
896; AVX512-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
897; AVX512-NEXT:    vmovd %xmm2, %edx
898; AVX512-NEXT:    shll $16, %edx
899; AVX512-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm1
900; AVX512-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
901; AVX512-NEXT:    vmovd %xmm1, %eax
902; AVX512-NEXT:    movzwl %ax, %eax
903; AVX512-NEXT:    orl %edx, %eax
904; AVX512-NEXT:    shlq $32, %rax
905; AVX512-NEXT:    orq %rcx, %rax
906; AVX512-NEXT:    vextractf64x4 $1, %zmm0, %ymm0
907; AVX512-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
908; AVX512-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm1
909; AVX512-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
910; AVX512-NEXT:    vmovd %xmm1, %ecx
911; AVX512-NEXT:    shll $16, %ecx
912; AVX512-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm1
913; AVX512-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
914; AVX512-NEXT:    vmovd %xmm1, %edx
915; AVX512-NEXT:    movzwl %dx, %edx
916; AVX512-NEXT:    orl %ecx, %edx
917; AVX512-NEXT:    vextractf128 $1, %ymm0, %xmm0
918; AVX512-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
919; AVX512-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm1
920; AVX512-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
921; AVX512-NEXT:    vmovd %xmm1, %ecx
922; AVX512-NEXT:    shll $16, %ecx
923; AVX512-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
924; AVX512-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
925; AVX512-NEXT:    vmovd %xmm0, %esi
926; AVX512-NEXT:    movzwl %si, %esi
927; AVX512-NEXT:    orl %ecx, %esi
928; AVX512-NEXT:    shlq $32, %rsi
929; AVX512-NEXT:    orq %rdx, %rsi
930; AVX512-NEXT:    vmovq %rsi, %xmm0
931; AVX512-NEXT:    vmovq %rax, %xmm1
932; AVX512-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
933; AVX512-NEXT:    vzeroupper
934; AVX512-NEXT:    retq
935  %1 = fptrunc <8 x double> %a0 to <8 x half>
936  %2 = bitcast <8 x half> %1 to <8 x i16>
937  ret <8 x i16> %2
938}
939
940;
941; Double to Half (Store)
942;
943
944define void @store_cvt_f64_to_i16(double %a0, ptr %a1) nounwind {
945; ALL-LABEL: store_cvt_f64_to_i16:
946; ALL:       # %bb.0:
947; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
948; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
949; ALL-NEXT:    vmovd %xmm0, %eax
950; ALL-NEXT:    movw %ax, (%rdi)
951; ALL-NEXT:    retq
952  %1 = fptrunc double %a0 to half
953  %2 = bitcast half %1 to i16
954  store i16 %2, ptr %a1
955  ret void
956}
957
958define void @store_cvt_2f64_to_2i16(<2 x double> %a0, ptr %a1) nounwind {
959; ALL-LABEL: store_cvt_2f64_to_2i16:
960; ALL:       # %bb.0:
961; ALL-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
962; ALL-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm1
963; ALL-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
964; ALL-NEXT:    vmovd %xmm1, %eax
965; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
966; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
967; ALL-NEXT:    vmovd %xmm0, %ecx
968; ALL-NEXT:    movw %cx, (%rdi)
969; ALL-NEXT:    movw %ax, 2(%rdi)
970; ALL-NEXT:    retq
971  %1 = fptrunc <2 x double> %a0 to <2 x half>
972  %2 = bitcast <2 x half> %1 to <2 x i16>
973  store <2 x i16> %2, ptr %a1
974  ret void
975}
976
977define void @store_cvt_4f64_to_4i16(<4 x double> %a0, ptr %a1) nounwind {
978; ALL-LABEL: store_cvt_4f64_to_4i16:
979; ALL:       # %bb.0:
980; ALL-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
981; ALL-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm1
982; ALL-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
983; ALL-NEXT:    vmovd %xmm1, %eax
984; ALL-NEXT:    vextractf128 $1, %ymm0, %xmm1
985; ALL-NEXT:    vpermilpd {{.*#+}} xmm2 = xmm1[1,0]
986; ALL-NEXT:    vcvtsd2ss %xmm2, %xmm2, %xmm2
987; ALL-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
988; ALL-NEXT:    vmovd %xmm2, %ecx
989; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
990; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
991; ALL-NEXT:    vmovd %xmm0, %edx
992; ALL-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm0
993; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
994; ALL-NEXT:    vmovd %xmm0, %esi
995; ALL-NEXT:    movw %si, 4(%rdi)
996; ALL-NEXT:    movw %dx, (%rdi)
997; ALL-NEXT:    movw %cx, 6(%rdi)
998; ALL-NEXT:    movw %ax, 2(%rdi)
999; ALL-NEXT:    vzeroupper
1000; ALL-NEXT:    retq
1001  %1 = fptrunc <4 x double> %a0 to <4 x half>
1002  %2 = bitcast <4 x half> %1 to <4 x i16>
1003  store <4 x i16> %2, ptr %a1
1004  ret void
1005}
1006
1007define void @store_cvt_4f64_to_8i16_undef(<4 x double> %a0, ptr %a1) nounwind {
1008; ALL-LABEL: store_cvt_4f64_to_8i16_undef:
1009; ALL:       # %bb.0:
1010; ALL-NEXT:    vextractf128 $1, %ymm0, %xmm1
1011; ALL-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm2
1012; ALL-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
1013; ALL-NEXT:    vmovd %xmm2, %eax
1014; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
1015; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm2
1016; ALL-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
1017; ALL-NEXT:    vmovd %xmm2, %eax
1018; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
1019; ALL-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm1[1,0]
1020; ALL-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm1
1021; ALL-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
1022; ALL-NEXT:    vmovd %xmm1, %eax
1023; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
1024; ALL-NEXT:    vpermilpd {{.*#+}} xmm0 = xmm0[1,0]
1025; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
1026; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1027; ALL-NEXT:    vmovd %xmm0, %eax
1028; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
1029; ALL-NEXT:    vmovaps -{{[0-9]+}}(%rsp), %xmm0
1030; ALL-NEXT:    vmovaps %xmm0, (%rdi)
1031; ALL-NEXT:    vzeroupper
1032; ALL-NEXT:    retq
1033  %1 = fptrunc <4 x double> %a0 to <4 x half>
1034  %2 = bitcast <4 x half> %1 to <4 x i16>
1035  %3 = shufflevector <4 x i16> %2, <4 x i16> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
1036  store <8 x i16> %3, ptr %a1
1037  ret void
1038}
1039
1040define void @store_cvt_4f64_to_8i16_zero(<4 x double> %a0, ptr %a1) nounwind {
1041; ALL-LABEL: store_cvt_4f64_to_8i16_zero:
1042; ALL:       # %bb.0:
1043; ALL-NEXT:    vextractf128 $1, %ymm0, %xmm1
1044; ALL-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm2
1045; ALL-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
1046; ALL-NEXT:    vmovd %xmm2, %eax
1047; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
1048; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm2
1049; ALL-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
1050; ALL-NEXT:    vmovd %xmm2, %eax
1051; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
1052; ALL-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm1[1,0]
1053; ALL-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm1
1054; ALL-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
1055; ALL-NEXT:    vmovd %xmm1, %eax
1056; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
1057; ALL-NEXT:    vpermilpd {{.*#+}} xmm0 = xmm0[1,0]
1058; ALL-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
1059; ALL-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1060; ALL-NEXT:    vmovd %xmm0, %eax
1061; ALL-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
1062; ALL-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
1063; ALL-NEXT:    vmovaps %xmm0, (%rdi)
1064; ALL-NEXT:    vzeroupper
1065; ALL-NEXT:    retq
1066  %1 = fptrunc <4 x double> %a0 to <4 x half>
1067  %2 = bitcast <4 x half> %1 to <4 x i16>
1068  %3 = shufflevector <4 x i16> %2, <4 x i16> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
1069  store <8 x i16> %3, ptr %a1
1070  ret void
1071}
1072
1073define void @store_cvt_8f64_to_8i16(<8 x double> %a0, ptr %a1) nounwind {
1074; AVX1-LABEL: store_cvt_8f64_to_8i16:
1075; AVX1:       # %bb.0:
1076; AVX1-NEXT:    vpermilpd {{.*#+}} xmm2 = xmm0[1,0]
1077; AVX1-NEXT:    vcvtsd2ss %xmm2, %xmm2, %xmm2
1078; AVX1-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
1079; AVX1-NEXT:    vmovd %xmm2, %r8d
1080; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm2
1081; AVX1-NEXT:    vpermilpd {{.*#+}} xmm3 = xmm2[1,0]
1082; AVX1-NEXT:    vcvtsd2ss %xmm3, %xmm3, %xmm3
1083; AVX1-NEXT:    vcvtps2ph $4, %xmm3, %xmm3
1084; AVX1-NEXT:    vmovd %xmm3, %r9d
1085; AVX1-NEXT:    vpermilpd {{.*#+}} xmm3 = xmm1[1,0]
1086; AVX1-NEXT:    vcvtsd2ss %xmm3, %xmm3, %xmm3
1087; AVX1-NEXT:    vcvtps2ph $4, %xmm3, %xmm3
1088; AVX1-NEXT:    vmovd %xmm3, %r10d
1089; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm3
1090; AVX1-NEXT:    vpermilpd {{.*#+}} xmm4 = xmm3[1,0]
1091; AVX1-NEXT:    vcvtsd2ss %xmm4, %xmm4, %xmm4
1092; AVX1-NEXT:    vcvtps2ph $4, %xmm4, %xmm4
1093; AVX1-NEXT:    vmovd %xmm4, %r11d
1094; AVX1-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
1095; AVX1-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1096; AVX1-NEXT:    vmovd %xmm0, %eax
1097; AVX1-NEXT:    vcvtsd2ss %xmm2, %xmm2, %xmm0
1098; AVX1-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1099; AVX1-NEXT:    vmovd %xmm0, %ecx
1100; AVX1-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm0
1101; AVX1-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1102; AVX1-NEXT:    vmovd %xmm0, %edx
1103; AVX1-NEXT:    vcvtsd2ss %xmm3, %xmm3, %xmm0
1104; AVX1-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1105; AVX1-NEXT:    vmovd %xmm0, %esi
1106; AVX1-NEXT:    movw %si, 12(%rdi)
1107; AVX1-NEXT:    movw %dx, 8(%rdi)
1108; AVX1-NEXT:    movw %cx, 4(%rdi)
1109; AVX1-NEXT:    movw %ax, (%rdi)
1110; AVX1-NEXT:    movw %r11w, 14(%rdi)
1111; AVX1-NEXT:    movw %r10w, 10(%rdi)
1112; AVX1-NEXT:    movw %r9w, 6(%rdi)
1113; AVX1-NEXT:    movw %r8w, 2(%rdi)
1114; AVX1-NEXT:    vzeroupper
1115; AVX1-NEXT:    retq
1116;
1117; AVX2-LABEL: store_cvt_8f64_to_8i16:
1118; AVX2:       # %bb.0:
1119; AVX2-NEXT:    vpermilpd {{.*#+}} xmm2 = xmm0[1,0]
1120; AVX2-NEXT:    vcvtsd2ss %xmm2, %xmm2, %xmm2
1121; AVX2-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
1122; AVX2-NEXT:    vmovd %xmm2, %r8d
1123; AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm2
1124; AVX2-NEXT:    vpermilpd {{.*#+}} xmm3 = xmm2[1,0]
1125; AVX2-NEXT:    vcvtsd2ss %xmm3, %xmm3, %xmm3
1126; AVX2-NEXT:    vcvtps2ph $4, %xmm3, %xmm3
1127; AVX2-NEXT:    vmovd %xmm3, %r9d
1128; AVX2-NEXT:    vpermilpd {{.*#+}} xmm3 = xmm1[1,0]
1129; AVX2-NEXT:    vcvtsd2ss %xmm3, %xmm3, %xmm3
1130; AVX2-NEXT:    vcvtps2ph $4, %xmm3, %xmm3
1131; AVX2-NEXT:    vmovd %xmm3, %r10d
1132; AVX2-NEXT:    vextractf128 $1, %ymm1, %xmm3
1133; AVX2-NEXT:    vpermilpd {{.*#+}} xmm4 = xmm3[1,0]
1134; AVX2-NEXT:    vcvtsd2ss %xmm4, %xmm4, %xmm4
1135; AVX2-NEXT:    vcvtps2ph $4, %xmm4, %xmm4
1136; AVX2-NEXT:    vmovd %xmm4, %r11d
1137; AVX2-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
1138; AVX2-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1139; AVX2-NEXT:    vmovd %xmm0, %eax
1140; AVX2-NEXT:    vcvtsd2ss %xmm2, %xmm2, %xmm0
1141; AVX2-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1142; AVX2-NEXT:    vmovd %xmm0, %ecx
1143; AVX2-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm0
1144; AVX2-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1145; AVX2-NEXT:    vmovd %xmm0, %edx
1146; AVX2-NEXT:    vcvtsd2ss %xmm3, %xmm3, %xmm0
1147; AVX2-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1148; AVX2-NEXT:    vmovd %xmm0, %esi
1149; AVX2-NEXT:    movw %si, 12(%rdi)
1150; AVX2-NEXT:    movw %dx, 8(%rdi)
1151; AVX2-NEXT:    movw %cx, 4(%rdi)
1152; AVX2-NEXT:    movw %ax, (%rdi)
1153; AVX2-NEXT:    movw %r11w, 14(%rdi)
1154; AVX2-NEXT:    movw %r10w, 10(%rdi)
1155; AVX2-NEXT:    movw %r9w, 6(%rdi)
1156; AVX2-NEXT:    movw %r8w, 2(%rdi)
1157; AVX2-NEXT:    vzeroupper
1158; AVX2-NEXT:    retq
1159;
1160; AVX512-LABEL: store_cvt_8f64_to_8i16:
1161; AVX512:       # %bb.0:
1162; AVX512-NEXT:    vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
1163; AVX512-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm1
1164; AVX512-NEXT:    vcvtps2ph $4, %xmm1, %xmm1
1165; AVX512-NEXT:    vmovd %xmm1, %r8d
1166; AVX512-NEXT:    vextractf128 $1, %ymm0, %xmm1
1167; AVX512-NEXT:    vpermilpd {{.*#+}} xmm2 = xmm1[1,0]
1168; AVX512-NEXT:    vcvtsd2ss %xmm2, %xmm2, %xmm2
1169; AVX512-NEXT:    vcvtps2ph $4, %xmm2, %xmm2
1170; AVX512-NEXT:    vmovd %xmm2, %r9d
1171; AVX512-NEXT:    vextractf64x4 $1, %zmm0, %ymm2
1172; AVX512-NEXT:    vpermilpd {{.*#+}} xmm3 = xmm2[1,0]
1173; AVX512-NEXT:    vcvtsd2ss %xmm3, %xmm3, %xmm3
1174; AVX512-NEXT:    vcvtps2ph $4, %xmm3, %xmm3
1175; AVX512-NEXT:    vmovd %xmm3, %r10d
1176; AVX512-NEXT:    vextractf128 $1, %ymm2, %xmm3
1177; AVX512-NEXT:    vpermilpd {{.*#+}} xmm4 = xmm3[1,0]
1178; AVX512-NEXT:    vcvtsd2ss %xmm4, %xmm4, %xmm4
1179; AVX512-NEXT:    vcvtps2ph $4, %xmm4, %xmm4
1180; AVX512-NEXT:    vmovd %xmm4, %r11d
1181; AVX512-NEXT:    vcvtsd2ss %xmm0, %xmm0, %xmm0
1182; AVX512-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1183; AVX512-NEXT:    vmovd %xmm0, %eax
1184; AVX512-NEXT:    vcvtsd2ss %xmm1, %xmm1, %xmm0
1185; AVX512-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1186; AVX512-NEXT:    vmovd %xmm0, %ecx
1187; AVX512-NEXT:    vcvtsd2ss %xmm2, %xmm2, %xmm0
1188; AVX512-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1189; AVX512-NEXT:    vmovd %xmm0, %edx
1190; AVX512-NEXT:    vcvtsd2ss %xmm3, %xmm3, %xmm0
1191; AVX512-NEXT:    vcvtps2ph $4, %xmm0, %xmm0
1192; AVX512-NEXT:    vmovd %xmm0, %esi
1193; AVX512-NEXT:    movw %si, 12(%rdi)
1194; AVX512-NEXT:    movw %dx, 8(%rdi)
1195; AVX512-NEXT:    movw %cx, 4(%rdi)
1196; AVX512-NEXT:    movw %ax, (%rdi)
1197; AVX512-NEXT:    movw %r11w, 14(%rdi)
1198; AVX512-NEXT:    movw %r10w, 10(%rdi)
1199; AVX512-NEXT:    movw %r9w, 6(%rdi)
1200; AVX512-NEXT:    movw %r8w, 2(%rdi)
1201; AVX512-NEXT:    vzeroupper
1202; AVX512-NEXT:    retq
1203  %1 = fptrunc <8 x double> %a0 to <8 x half>
1204  %2 = bitcast <8 x half> %1 to <8 x i16>
1205  store <8 x i16> %2, ptr %a1
1206  ret void
1207}
1208
1209define void @store_cvt_32f32_to_32f16(<32 x float> %a0, ptr %a1) nounwind {
1210; AVX1-LABEL: store_cvt_32f32_to_32f16:
1211; AVX1:       # %bb.0:
1212; AVX1-NEXT:    vcvtps2ph $4, %ymm3, 48(%rdi)
1213; AVX1-NEXT:    vcvtps2ph $4, %ymm2, 32(%rdi)
1214; AVX1-NEXT:    vcvtps2ph $4, %ymm1, 16(%rdi)
1215; AVX1-NEXT:    vcvtps2ph $4, %ymm0, (%rdi)
1216; AVX1-NEXT:    vzeroupper
1217; AVX1-NEXT:    retq
1218;
1219; AVX2-LABEL: store_cvt_32f32_to_32f16:
1220; AVX2:       # %bb.0:
1221; AVX2-NEXT:    vcvtps2ph $4, %ymm3, 48(%rdi)
1222; AVX2-NEXT:    vcvtps2ph $4, %ymm2, 32(%rdi)
1223; AVX2-NEXT:    vcvtps2ph $4, %ymm1, 16(%rdi)
1224; AVX2-NEXT:    vcvtps2ph $4, %ymm0, (%rdi)
1225; AVX2-NEXT:    vzeroupper
1226; AVX2-NEXT:    retq
1227;
1228; AVX512-LABEL: store_cvt_32f32_to_32f16:
1229; AVX512:       # %bb.0:
1230; AVX512-NEXT:    vcvtps2ph $4, %zmm1, 32(%rdi)
1231; AVX512-NEXT:    vcvtps2ph $4, %zmm0, (%rdi)
1232; AVX512-NEXT:    vzeroupper
1233; AVX512-NEXT:    retq
1234  %1 = fptrunc <32 x float> %a0 to <32 x half>
1235  store <32 x half> %1, ptr %a1
1236  ret void
1237}
1238