1 ; Check that scalar FP conversions to signed and unsigned int64 are using
2 ; reasonable sequences, across platforms and target switches.
4 ; The signed case is straight forward, and the tests here basically
5 ; ensure successful compilation (f80 with avx512 was broken at one point).
7 ; For the unsigned case there are many possible sequences, so to avoid
8 ; a fragile test we just check for the presence of a few key instructions.
9 ; AVX512 on Intel64 can use vcvtts[ds]2usi directly for float and double.
10 ; Otherwise the sequence will involve an FP subtract (fsub, subss or subsd),
11 ; and a truncating conversion (cvtts[ds]2si, fisttp, or fnstcw+fist). When
12 ; both a subtract and fnstcw are needed, they can occur in either order.
14 ; The interesting subtargets are AVX512F (vcvtts[ds]2usi), SSE3 (fisttp),
15 ; SSE2 (cvtts[ds]2si) and vanilla X87 (fnstcw+fist, 32-bit only).
17 ; RUN: llc < %s -mtriple=i386-pc-windows-msvc -mattr=+avx512f | FileCheck %s --check-prefix=CHECK --check-prefix=AVX512_32
18 ; RUN: llc < %s -mtriple=i386-unknown-linux-gnu -mattr=+avx512f | FileCheck %s --check-prefix=CHECK --check-prefix=AVX512_32
19 ; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc -mattr=+avx512f | FileCheck %s --check-prefix=CHECK --check-prefix=AVX512_64
20 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+avx512f | FileCheck %s --check-prefix=CHECK --check-prefix=AVX512_64
21 ; RUN: llc < %s -mtriple=i386-pc-windows-msvc -mattr=+sse3 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE3_32
22 ; RUN: llc < %s -mtriple=i386-unknown-linux-gnu -mattr=+sse3 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE3_32
23 ; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc -mattr=+sse3 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE3_64
24 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+sse3 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE3_64
25 ; RUN: llc < %s -mtriple=i386-pc-windows-msvc -mattr=+sse2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE2_32
26 ; RUN: llc < %s -mtriple=i386-unknown-linux-gnu -mattr=+sse2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE2_32
27 ; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc -mattr=+sse2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE2_64
28 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+sse2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE2_64
29 ; RUN: llc < %s -mtriple=i386-pc-windows-msvc -mattr=-sse | FileCheck %s --check-prefix=CHECK --check-prefix=X87
30 ; RUN: llc < %s -mtriple=i386-unknown-linux-gnu -mattr=-sse | FileCheck %s --check-prefix=CHECK --check-prefix=X87
32 ; CHECK-LABEL: f_to_u64
36 ; SSE2_32-DAG: {{subss|fsub}}
41 ; SSE3_32: {{subss|fsub}}
45 ; AVX512_32: {{subss|fsub}}
47 ; AVX512_64: vcvttss2usi
49 define i64 @f_to_u64(float %a) nounwind {
50 %r = fptoui float %a to i64
54 ; CHECK-LABEL: f_to_s64
63 ; AVX512_64: vcvttss2si
65 define i64 @f_to_s64(float %a) nounwind {
66 %r = fptosi float %a to i64
70 ; CHECK-LABEL: d_to_u64
74 ; SSE2_32-DAG: {{subsd|fsub}}
79 ; SSE3_32: {{subsd|fsub}}
83 ; AVX512_32: {{subsd|fsub}}
85 ; AVX512_64: vcvttsd2usi
87 define i64 @d_to_u64(double %a) nounwind {
88 %r = fptoui double %a to i64
92 ; CHECK-LABEL: d_to_s64
101 ; AVX512_64: vcvttsd2si
103 define i64 @d_to_s64(double %a) nounwind {
104 %r = fptosi double %a to i64
108 ; CHECK-LABEL: x_to_u64
111 ; SSE2_32-DAG: fnstcw
112 ; SSE2_64-DAG: fnstcw
115 define i64 @x_to_u64(x86_fp80 %a) nounwind {
116 %r = fptoui x86_fp80 %a to i64
120 ; CHECK-LABEL: x_to_s64
132 define i64 @x_to_s64(x86_fp80 %a) nounwind {
133 %r = fptosi x86_fp80 %a to i64
137 ; CHECK-LABEL: t_to_u64
138 ; CHECK: __fixunstfdi
140 define i64 @t_to_u64(fp128 %a) nounwind {
141 %r = fptoui fp128 %a to i64
145 ; CHECK-LABEL: t_to_s64
148 define i64 @t_to_s64(fp128 %a) nounwind {
149 %r = fptosi fp128 %a to i64