1; Verify that scalar integer conversions to FP compile successfully
2; (at one time long double failed with avx512f), and that reasonable
3; instruction sequences are selected based on subtarget features.
4; Due to the plethora of reasonable sequences we just check for
5; one key instruction, usually a cvt or fild, allowing the test
6; to be relatively easily updated when sequences are improved.
7;
8; RUN: llc < %s -mtriple=i386-unknown-unknown     -mattr=+avx512f | FileCheck %s --check-prefix=CHECK --check-prefix=AVX512_32
9; RUN: llc < %s -mtriple=x86_64-unknown-unknown   -mattr=+avx512f | FileCheck %s --check-prefix=CHECK --check-prefix=AVX512_64
10; RUN: llc < %s -mtriple=i386-unknown-unknown     -mattr=+sse2    | FileCheck %s --check-prefix=CHECK --check-prefix=SSE2_32
11; RUN: llc < %s -mtriple=x86_64-unknown-unknown   -mattr=+sse2    | FileCheck %s --check-prefix=CHECK --check-prefix=SSE2_64
12; RUN: llc < %s -mtriple=i386-unknown-unknown     -mattr=-sse     | FileCheck %s --check-prefix=CHECK --check-prefix=X87
13
14; CHECK-LABEL: u32_to_f
15; AVX512_32: vcvtusi2ssl
16; AVX512_64: vcvtusi2ssl
17; SSE2_32: cvtsd2ss
18; SSE2_64: cvtsi2ssq
19; X87: fildll
20define float @u32_to_f(i32 %a) nounwind {
21  %r = uitofp i32 %a to float
22  ret float %r
23}
24
25; CHECK-LABEL: s32_to_f
26; AVX512_32: vcvtsi2ssl
27; AVX512_64: vcvtsi2ssl
28; SSE2_32: cvtsi2ssl
29; SSE2_64: cvtsi2ssl
30; X87: fildl
31define float @s32_to_f(i32 %a) nounwind {
32  %r = sitofp i32 %a to float
33  ret float %r
34}
35
36; CHECK-LABEL: u32_to_d
37; AVX512_32: vcvtusi2sdl
38; AVX512_64: vcvtusi2sdl
39; SSE2_32: subsd
40; SSE2_64: cvtsi2sdq
41; X87: fildll
42define double @u32_to_d(i32 %a) nounwind {
43  %r = uitofp i32 %a to double
44  ret double %r
45}
46
47; CHECK-LABEL: s32_to_d
48; AVX512_32: vcvtsi2sdl
49; AVX512_64: vcvtsi2sdl
50; SSE2_32: cvtsi2sdl
51; SSE2_64: cvtsi2sdl
52; X87: fildl
53define double @s32_to_d(i32 %a) nounwind {
54  %r = sitofp i32 %a to double
55  ret double %r
56}
57
58; CHECK-LABEL: u32_to_x
59; AVX512_32: vsubsd
60; AVX512_64: vsubsd
61; SSE2_32: subsd
62; SSE2_64: fildll
63; X87: fildll
64define x86_fp80 @u32_to_x(i32 %a) nounwind {
65  %r = uitofp i32 %a to x86_fp80
66  ret x86_fp80 %r
67}
68
69; CHECK-LABEL: s32_to_x
70; CHECK: fildl
71define x86_fp80 @s32_to_x(i32 %a) nounwind {
72  %r = sitofp i32 %a to x86_fp80
73  ret x86_fp80 %r
74}
75
76; CHECK-LABEL: u64_to_f
77; AVX512_32: vmovq {{.*#+}} xmm0 = mem[0],zero
78; AVX512_32: vmovlpd %xmm0, {{[0-9]+}}(%esp)
79; AVX512_32: fildll
80
81; AVX512_64: vcvtusi2ssq
82
83; SSE2_32: movq {{.*#+}} xmm0 = mem[0],zero
84; SSE2_32: movq %xmm0, {{[0-9]+}}(%esp)
85; SSE2_32: fildll
86
87; SSE2_64: cvtsi2ssq
88; X87: fildll
89define float @u64_to_f(i64 %a) nounwind {
90  %r = uitofp i64 %a to float
91  ret float %r
92}
93
94; CHECK-LABEL: s64_to_f
95; AVX512_32: fildll
96; AVX512_64: vcvtsi2ssq
97; SSE2_32: fildll
98; SSE2_64: cvtsi2ssq
99; X87: fildll
100define float @s64_to_f(i64 %a) nounwind {
101  %r = sitofp i64 %a to float
102  ret float %r
103}
104
105; CHECK-LABEL: s64_to_f_2
106; SSE2_32:    movd %ecx, %xmm0
107; SSE2_32:    movd %eax, %xmm1
108; SSE2_32:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
109; SSE2_32:    movq %xmm1, {{[0-9]+}}(%esp)
110; SSE2_32:    fildll {{[0-9]+}}(%esp)
111
112; AVX512_32:    vmovd %eax, %xmm0
113; AVX512_32:    vpinsrd $1, %ecx, %xmm0, %xmm0
114; AVX512_32:    vmovlpd %xmm0, {{[0-9]+}}(%esp)
115; AVX512_32:    fildll {{[0-9]+}}(%esp)
116
117define float @s64_to_f_2(i64 %a) nounwind {
118  %a1 = add i64 %a, 5
119  %r = sitofp i64 %a1 to float
120  ret float %r
121}
122
123; CHECK-LABEL: u64_to_d
124; AVX512_32: vpunpckldq
125; AVX512_64: vcvtusi2sdq
126; SSE2_32: punpckldq
127; SSE2_64: punpckldq
128; X87: fildll
129define double @u64_to_d(i64 %a) nounwind {
130  %r = uitofp i64 %a to double
131  ret double %r
132}
133
134; CHECK-LABEL: s64_to_d
135; AVX512_32: fildll
136; AVX512_64: vcvtsi2sdq
137; SSE2_32: fildll
138; SSE2_64: cvtsi2sdq
139; X87: fildll
140define double @s64_to_d(i64 %a) nounwind {
141  %r = sitofp i64 %a to double
142  ret double %r
143}
144
145; CHECK-LABEL: s64_to_d_2
146; SSE2_32: movd %ecx, %xmm0
147; SSE2_32: movd %eax, %xmm1
148; SSE2_32: punpckldq %xmm0, %xmm1
149; SSE2_32: movq %xmm1, {{[0-9]+}}(%esp)
150; SSE2_32: fildll
151
152; AVX512_32:    vmovd %eax, %xmm0
153; AVX512_32:    vpinsrd $1, %ecx, %xmm0, %xmm0
154; AVX512_32:    vmovlpd %xmm0, {{[0-9]+}}(%esp)
155; AVX512_32: fildll
156
157define double @s64_to_d_2(i64 %a) nounwind {
158  %b = add i64 %a, 5
159  %f = sitofp i64 %b to double
160  ret double %f
161}
162
163; CHECK-LABEL: u64_to_x
164; CHECK: fildll
165define x86_fp80 @u64_to_x(i64 %a) nounwind {
166  %r = uitofp i64 %a to x86_fp80
167  ret x86_fp80 %r
168}
169
170; CHECK-LABEL: s64_to_x
171; CHECK: fildll
172define x86_fp80 @s64_to_x(i64 %a) nounwind {
173  %r = sitofp i64 %a to x86_fp80
174  ret x86_fp80 %r
175}
176