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