; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=i686-linux -mattr=+avx10.2 | FileCheck %s --check-prefixes=CHECK,X86
; RUN: llc < %s -mtriple=x86_64-linux -mattr=+avx10.2 | FileCheck %s --check-prefixes=CHECK,X64

;
; 32-bit float to signed integer
;

declare  i32 @llvm.fptosi.sat.i32.f32 (float)
declare  i64 @llvm.fptosi.sat.i64.f32 (float)

define i32 @test_signed_i32_f32(float %f) nounwind {
; X86-LABEL: test_signed_i32_f32:
; X86:       # %bb.0:
; X86-NEXT:    vcvttss2sis {{[0-9]+}}(%esp), %eax
; X86-NEXT:    retl
;
; X64-LABEL: test_signed_i32_f32:
; X64:       # %bb.0:
; X64-NEXT:    vcvttss2sis %xmm0, %eax
; X64-NEXT:    retq
    %x = call i32 @llvm.fptosi.sat.i32.f32(float %f)
    ret i32 %x
}

define i64 @test_signed_i64_f32(float %f) nounwind {
; X86-LABEL: test_signed_i64_f32:
; X86:       # %bb.0:
; X86-NEXT:    pushl %edi
; X86-NEXT:    pushl %esi
; X86-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; X86-NEXT:    vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero
; X86-NEXT:    vcvttps2qq %xmm1, %xmm1
; X86-NEXT:    vmovd %xmm1, %esi
; X86-NEXT:    xorl %ecx, %ecx
; X86-NEXT:    vucomiss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
; X86-NEXT:    cmovbl %ecx, %esi
; X86-NEXT:    vpextrd $1, %xmm1, %eax
; X86-NEXT:    movl $-2147483648, %edi # imm = 0x80000000
; X86-NEXT:    cmovael %eax, %edi
; X86-NEXT:    vucomiss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
; X86-NEXT:    movl $2147483647, %edx # imm = 0x7FFFFFFF
; X86-NEXT:    cmovbel %edi, %edx
; X86-NEXT:    movl $-1, %eax
; X86-NEXT:    cmovbel %esi, %eax
; X86-NEXT:    vucomiss %xmm0, %xmm0
; X86-NEXT:    cmovpl %ecx, %eax
; X86-NEXT:    cmovpl %ecx, %edx
; X86-NEXT:    popl %esi
; X86-NEXT:    popl %edi
; X86-NEXT:    retl
;
; X64-LABEL: test_signed_i64_f32:
; X64:       # %bb.0:
; X64-NEXT:    vcvttss2sis %xmm0, %rax
; X64-NEXT:    retq
    %x = call i64 @llvm.fptosi.sat.i64.f32(float %f)
    ret i64 %x
}

;
; 64-bit float to signed integer
;

declare  i32 @llvm.fptosi.sat.i32.f64 (double)
declare  i64 @llvm.fptosi.sat.i64.f64 (double)

define i32 @test_signed_i32_f64(double %f) nounwind {
; X86-LABEL: test_signed_i32_f64:
; X86:       # %bb.0:
; X86-NEXT:    vcvttsd2sis {{[0-9]+}}(%esp), %eax
; X86-NEXT:    retl
;
; X64-LABEL: test_signed_i32_f64:
; X64:       # %bb.0:
; X64-NEXT:    vcvttsd2sis %xmm0, %eax
; X64-NEXT:    retq
    %x = call i32 @llvm.fptosi.sat.i32.f64(double %f)
    ret i32 %x
}

define i64 @test_signed_i64_f64(double %f) nounwind {
; X86-LABEL: test_signed_i64_f64:
; X86:       # %bb.0:
; X86-NEXT:    pushl %edi
; X86-NEXT:    pushl %esi
; X86-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
; X86-NEXT:    vcvttpd2qq %xmm0, %xmm1
; X86-NEXT:    vmovd %xmm1, %esi
; X86-NEXT:    xorl %ecx, %ecx
; X86-NEXT:    vucomisd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
; X86-NEXT:    cmovbl %ecx, %esi
; X86-NEXT:    vpextrd $1, %xmm1, %eax
; X86-NEXT:    movl $-2147483648, %edi # imm = 0x80000000
; X86-NEXT:    cmovael %eax, %edi
; X86-NEXT:    vucomisd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
; X86-NEXT:    movl $2147483647, %edx # imm = 0x7FFFFFFF
; X86-NEXT:    cmovbel %edi, %edx
; X86-NEXT:    movl $-1, %eax
; X86-NEXT:    cmovbel %esi, %eax
; X86-NEXT:    vucomisd %xmm0, %xmm0
; X86-NEXT:    cmovpl %ecx, %eax
; X86-NEXT:    cmovpl %ecx, %edx
; X86-NEXT:    popl %esi
; X86-NEXT:    popl %edi
; X86-NEXT:    retl
;
; X64-LABEL: test_signed_i64_f64:
; X64:       # %bb.0:
; X64-NEXT:    vcvttsd2sis %xmm0, %rax
; X64-NEXT:    retq
    %x = call i64 @llvm.fptosi.sat.i64.f64(double %f)
    ret i64 %x
}

; VCVTTPD2DQS
define <2 x i32> @test_signed_v2i32_v2f64(<2 x double> %d) nounwind {
; CHECK-LABEL: test_signed_v2i32_v2f64:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttpd2dqs %xmm0, %xmm0
; CHECK-NEXT:    ret{{[l|q]}}
  %x = call  <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> %d)
  ret <2 x i32> %x
}

define <4 x i32> @test_signed_v4i32_v4f64(<4 x double> %f) nounwind {
; CHECK-LABEL: test_signed_v4i32_v4f64:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttpd2dqs %ymm0, %xmm0
; CHECK-NEXT:    vzeroupper
; CHECK-NEXT:    ret{{[l|q]}}
  %x = call  <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> %f)
  ret <4 x i32> %x
}

; VCVTTPD2QQS
define <2 x i64> @test_signed_v2i64_v2f64(<2 x double> %f) nounwind {
; CHECK-LABEL: test_signed_v2i64_v2f64:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttpd2qqs %xmm0, %xmm0
; CHECK-NEXT:    ret{{[l|q]}}
    %x = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f64(<2 x double> %f)
    ret <2 x i64> %x
}

define <4 x i64> @test_signed_v4i64_v4f64(<4 x double> %f) nounwind {
; CHECK-LABEL: test_signed_v4i64_v4f64:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttpd2qqs %ymm0, %ymm0
; CHECK-NEXT:    ret{{[l|q]}}
  %x = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f64(<4 x double> %f)
  ret <4 x i64> %x
}

; VCVTTPD2UDQS
define <2 x i32> @test_unsigned_v2i32_v2f64(<2 x double> %d) nounwind {
; CHECK-LABEL: test_unsigned_v2i32_v2f64:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttpd2udqs %xmm0, %xmm0
; CHECK-NEXT:    ret{{[l|q]}}
  %x = call  <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> %d)
  ret <2 x i32> %x
}

define <4 x i32> @test_unsigned_v4i32_v4f64(<4 x double> %f) nounwind {
; CHECK-LABEL: test_unsigned_v4i32_v4f64:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttpd2udqs %ymm0, %xmm0
; CHECK-NEXT:    vzeroupper
; CHECK-NEXT:    ret{{[l|q]}}
  %x = call  <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> %f)
  ret <4 x i32> %x
}

; VCVTTPD2UQQS
define <2 x i64> @test_unsigned_v2i64_v2f64(<2 x double> %f) nounwind {
; CHECK-LABEL: test_unsigned_v2i64_v2f64:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttpd2uqqs %xmm0, %xmm0
; CHECK-NEXT:    ret{{[l|q]}}
  %x = call  <2 x i64> @llvm.fptoui.sat.v2i64.v2f64(<2 x double> %f)
  ret <2 x i64> %x
}

define <4 x i64> @test_unsigned_v4i64_v4f64(<4 x double> %f) nounwind {
; CHECK-LABEL: test_unsigned_v4i64_v4f64:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttpd2uqqs %ymm0, %ymm0
; CHECK-NEXT:    ret{{[l|q]}}
  %x = call  <4 x i64> @llvm.fptoui.sat.v4i64.v4f64(<4 x double> %f)
  ret <4 x i64> %x
}

; VCVTTPS2DQS
define <4 x i32> @test_signed_v4i32_v4f32(<4 x float> %f) nounwind {
; CHECK-LABEL: test_signed_v4i32_v4f32:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttps2dqs %xmm0, %xmm0
; CHECK-NEXT:    ret{{[l|q]}}
  %x = call  <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> %f)
  ret <4 x i32> %x
}

define <8 x i32> @test_signed_v8i32_v8f32(<8 x float> %f) nounwind {
; CHECK-LABEL: test_signed_v8i32_v8f32:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttps2dqs %ymm0, %ymm0
; CHECK-NEXT:    ret{{[l|q]}}
  %x = call  <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> %f)
  ret <8 x i32> %x
}

; VCVTTPS2UDQS
define <4 x i32> @test_unsigned_v4i32_v4f32(<4 x float> %f) nounwind {
; CHECK-LABEL: test_unsigned_v4i32_v4f32:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttps2udqs %xmm0, %xmm0
; CHECK-NEXT:    ret{{[l|q]}}
  %x = call  <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> %f)
  ret <4 x i32> %x
}

define <8 x i32> @test_unsigned_v8i32_v8f32(<8 x float> %f) nounwind {
; CHECK-LABEL: test_unsigned_v8i32_v8f32:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttps2udqs %ymm0, %ymm0
; CHECK-NEXT:    ret{{[l|q]}}
  %x = call  <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> %f)
  ret <8 x i32> %x
}

; VCVTTPS2QQS
define <2 x i64> @test_signed_v2i64_v2f32(<2 x float> %f) nounwind {
; CHECK-LABEL: test_signed_v2i64_v2f32:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttps2qqs %xmm0, %xmm0
; CHECK-NEXT:    ret{{[l|q]}}
  %x = call  <2 x i64> @llvm.fptosi.sat.v2i64.v2f32(<2 x float> %f)
  ret <2 x i64> %x
}

define <4 x i64> @test_signed_v4i64_v4f32(<4 x float> %f) nounwind {
; CHECK-LABEL: test_signed_v4i64_v4f32:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttps2qqs %xmm0, %ymm0
; CHECK-NEXT:    ret{{[l|q]}}
  %x = call  <4 x i64> @llvm.fptosi.sat.v4i64.v4f32(<4 x float> %f)
  ret <4 x i64> %x
}

; VCVTTPS2UQQS
define <2 x i64> @test_unsigned_v2i64_v2f32(<2 x float> %f) nounwind {
; CHECK-LABEL: test_unsigned_v2i64_v2f32:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttps2uqqs %xmm0, %xmm0
; CHECK-NEXT:    ret{{[l|q]}}
  %x = call  <2 x i64> @llvm.fptoui.sat.v2i64.v2f32(<2 x float> %f)
  ret <2 x i64> %x
}

define <4 x i64> @test_unsigned_v4i64_v4f32(<4 x float> %f) nounwind {
; CHECK-LABEL: test_unsigned_v4i64_v4f32:
; CHECK:       # %bb.0:
; CHECK-NEXT:    vcvttps2uqqs %xmm0, %ymm0
; CHECK-NEXT:    ret{{[l|q]}}
  %x = call  <4 x i64> @llvm.fptoui.sat.v4i64.v4f32(<4 x float> %f)
  ret <4 x i64> %x
}
