152 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			LLVM
		
	
	
	
; Check that scalar FP conversions to signed and unsigned int64 are using
 | 
						|
; reasonable sequences, across platforms and target switches.
 | 
						|
;
 | 
						|
; The signed case is straight forward, and the tests here basically
 | 
						|
; ensure successful compilation (f80 with avx512 was broken at one point).
 | 
						|
;
 | 
						|
; For the unsigned case there are many possible sequences, so to avoid
 | 
						|
; a fragile test we just check for the presence of a few key instructions.
 | 
						|
; AVX512 on Intel64 can use vcvtts[ds]2usi directly for float and double.
 | 
						|
; Otherwise the sequence will involve an FP subtract (fsub, subss or subsd),
 | 
						|
; and a truncating conversion (cvtts[ds]2si, fisttp, or fnstcw+fist).  When
 | 
						|
; both a subtract and fnstcw are needed, they can occur in either order.
 | 
						|
;
 | 
						|
; The interesting subtargets are AVX512F (vcvtts[ds]2usi), SSE3 (fisttp),
 | 
						|
; SSE2 (cvtts[ds]2si) and vanilla X87 (fnstcw+fist, 32-bit only).
 | 
						|
;
 | 
						|
; RUN: llc < %s -mtriple=i386-pc-windows-msvc     -mattr=+avx512f | FileCheck %s --check-prefix=CHECK --check-prefix=AVX512_32
 | 
						|
; RUN: llc < %s -mtriple=i386-unknown-linux-gnu   -mattr=+avx512f | FileCheck %s --check-prefix=CHECK --check-prefix=AVX512_32
 | 
						|
; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc   -mattr=+avx512f | FileCheck %s --check-prefix=CHECK --check-prefix=AVX512_64
 | 
						|
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+avx512f | FileCheck %s --check-prefix=CHECK --check-prefix=AVX512_64
 | 
						|
; RUN: llc < %s -mtriple=i386-pc-windows-msvc     -mattr=+sse3 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE3_32
 | 
						|
; RUN: llc < %s -mtriple=i386-unknown-linux-gnu   -mattr=+sse3 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE3_32
 | 
						|
; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc   -mattr=+sse3 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE3_64
 | 
						|
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+sse3 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE3_64
 | 
						|
; RUN: llc < %s -mtriple=i386-pc-windows-msvc     -mattr=+sse2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE2_32
 | 
						|
; RUN: llc < %s -mtriple=i386-unknown-linux-gnu   -mattr=+sse2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE2_32
 | 
						|
; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc   -mattr=+sse2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE2_64
 | 
						|
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+sse2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE2_64
 | 
						|
; RUN: llc < %s -mtriple=i386-pc-windows-msvc     -mattr=-sse  | FileCheck %s --check-prefix=CHECK --check-prefix=X87
 | 
						|
; RUN: llc < %s -mtriple=i386-unknown-linux-gnu   -mattr=-sse  | FileCheck %s --check-prefix=CHECK --check-prefix=X87
 | 
						|
 | 
						|
; CHECK-LABEL: f_to_u64
 | 
						|
; X87-DAG: fsub
 | 
						|
; X87-DAG: fnstcw
 | 
						|
; X87: fist
 | 
						|
; SSE2_32-DAG: {{subss|fsub}}
 | 
						|
; SSE2_32-DAG: fnstcw
 | 
						|
; SSE2_32: fist
 | 
						|
; SSE2_64: subss
 | 
						|
; SSE2_64: cvttss2si
 | 
						|
; SSE3_32: {{subss|fsub}}
 | 
						|
; SSE3_32: fistt
 | 
						|
; SSE3_64: subss
 | 
						|
; SSE3_64: cvttss2si
 | 
						|
; AVX512_32: {{subss|fsub}}
 | 
						|
; AVX512_32: fistt
 | 
						|
; AVX512_64: vcvttss2usi
 | 
						|
; CHECK: ret
 | 
						|
define i64 @f_to_u64(float %a) nounwind {
 | 
						|
  %r = fptoui float %a to i64
 | 
						|
  ret i64 %r
 | 
						|
}
 | 
						|
 | 
						|
; CHECK-LABEL: f_to_s64
 | 
						|
; X87: fnstcw
 | 
						|
; X87: fist
 | 
						|
; SSE2_32: fnstcw
 | 
						|
; SSE2_32: fist
 | 
						|
; SSE2_64: cvttss2si
 | 
						|
; SSE3_32: fistt
 | 
						|
; SSE3_64: cvttss2si
 | 
						|
; AVX512_32: fistt
 | 
						|
; AVX512_64: vcvttss2si
 | 
						|
; CHECK: ret
 | 
						|
define i64 @f_to_s64(float %a) nounwind {
 | 
						|
  %r = fptosi float %a to i64
 | 
						|
  ret i64 %r
 | 
						|
}
 | 
						|
 | 
						|
; CHECK-LABEL: d_to_u64
 | 
						|
; X87-DAG: fsub
 | 
						|
; X87-DAG: fnstcw
 | 
						|
; X87: fist
 | 
						|
; SSE2_32-DAG: {{subsd|fsub}}
 | 
						|
; SSE2_32-DAG: fnstcw
 | 
						|
; SSE2_32: fist
 | 
						|
; SSE2_64: subsd
 | 
						|
; SSE2_64: cvttsd2si
 | 
						|
; SSE3_32: {{subsd|fsub}}
 | 
						|
; SSE3_32: fistt
 | 
						|
; SSE3_64: subsd
 | 
						|
; SSE3_64: cvttsd2si
 | 
						|
; AVX512_32: {{subsd|fsub}}
 | 
						|
; AVX512_32: fistt
 | 
						|
; AVX512_64: vcvttsd2usi
 | 
						|
; CHECK: ret
 | 
						|
define i64 @d_to_u64(double %a) nounwind {
 | 
						|
  %r = fptoui double %a to i64
 | 
						|
  ret i64 %r
 | 
						|
}
 | 
						|
 | 
						|
; CHECK-LABEL: d_to_s64
 | 
						|
; X87: fnstcw
 | 
						|
; X87: fist
 | 
						|
; SSE2_32: fnstcw
 | 
						|
; SSE2_32: fist
 | 
						|
; SSE2_64: cvttsd2si
 | 
						|
; SSE3_32: fistt
 | 
						|
; SSE3_64: cvttsd2si
 | 
						|
; AVX512_32: fistt
 | 
						|
; AVX512_64: vcvttsd2si
 | 
						|
; CHECK: ret
 | 
						|
define i64 @d_to_s64(double %a) nounwind {
 | 
						|
  %r = fptosi double %a to i64
 | 
						|
  ret i64 %r
 | 
						|
}
 | 
						|
 | 
						|
; CHECK-LABEL: x_to_u64
 | 
						|
; CHECK-DAG: fsub
 | 
						|
; X87-DAG: fnstcw
 | 
						|
; SSE2_32-DAG: fnstcw
 | 
						|
; SSE2_64-DAG: fnstcw
 | 
						|
; CHECK: fist
 | 
						|
; CHECK: ret
 | 
						|
define i64 @x_to_u64(x86_fp80 %a) nounwind {
 | 
						|
  %r = fptoui x86_fp80 %a to i64
 | 
						|
  ret i64 %r
 | 
						|
}
 | 
						|
 | 
						|
; CHECK-LABEL: x_to_s64
 | 
						|
; X87: fnstcw
 | 
						|
; X87: fist
 | 
						|
; SSE2_32: fnstcw
 | 
						|
; SSE2_32: fist
 | 
						|
; SSE2_64: fnstcw
 | 
						|
; SSE2_64: fist
 | 
						|
; SSE3_32: fistt
 | 
						|
; SSE3_64: fistt
 | 
						|
; AVX512_32: fistt
 | 
						|
; AVX512_64: fistt
 | 
						|
; CHECK: ret
 | 
						|
define i64 @x_to_s64(x86_fp80 %a) nounwind {
 | 
						|
  %r = fptosi x86_fp80 %a to i64
 | 
						|
  ret i64 %r
 | 
						|
}
 | 
						|
 | 
						|
; CHECK-LABEL: t_to_u64
 | 
						|
; CHECK: __fixunstfdi
 | 
						|
; CHECK: ret
 | 
						|
define i64 @t_to_u64(fp128 %a) nounwind {
 | 
						|
  %r = fptoui fp128 %a to i64
 | 
						|
  ret i64 %r
 | 
						|
}
 | 
						|
 | 
						|
; CHECK-LABEL: t_to_s64
 | 
						|
; CHECK: __fixtfdi
 | 
						|
; CHECK: ret
 | 
						|
define i64 @t_to_s64(fp128 %a) nounwind {
 | 
						|
  %r = fptosi fp128 %a to i64
 | 
						|
  ret i64 %r
 | 
						|
}
 |