; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s ; i32 saturate define i32 @stest_f64i32(double %x) { ; CHECK-LABEL: stest_f64i32: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: ucomisd %xmm0, %xmm0 ; CHECK-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: cvttsd2si %xmm0, %ecx ; CHECK-NEXT: cmovnpl %ecx, %eax ; CHECK-NEXT: retq entry: %conv = fptosi double %x to i64 %0 = icmp slt i64 %conv, 2147483647 %spec.store.select = select i1 %0, i64 %conv, i64 2147483647 %1 = icmp sgt i64 %spec.store.select, -2147483648 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 -2147483648 %conv6 = trunc i64 %spec.store.select7 to i32 ret i32 %conv6 } define i32 @utest_f64i32(double %x) { ; CHECK-LABEL: utest_f64i32: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttsd2si %xmm0, %rax ; CHECK-NEXT: movq %rax, %rcx ; CHECK-NEXT: sarq $63, %rcx ; CHECK-NEXT: subsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: cvttsd2si %xmm0, %rdx ; CHECK-NEXT: andq %rcx, %rdx ; CHECK-NEXT: orq %rax, %rdx ; CHECK-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF ; CHECK-NEXT: cmpq %rax, %rdx ; CHECK-NEXT: movl $-1, %eax ; CHECK-NEXT: cmovbl %edx, %eax ; CHECK-NEXT: retq entry: %conv = fptoui double %x to i64 %0 = icmp ult i64 %conv, 4294967295 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 %conv6 = trunc i64 %spec.store.select to i32 ret i32 %conv6 } define i32 @ustest_f64i32(double %x) { ; CHECK-LABEL: ustest_f64i32: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttsd2si %xmm0, %rcx ; CHECK-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF ; CHECK-NEXT: cmpq %rax, %rcx ; CHECK-NEXT: cmovlq %rcx, %rax ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: testq %rax, %rax ; CHECK-NEXT: cmovlel %ecx, %eax ; CHECK-NEXT: # kill: def $eax killed $eax killed $rax ; CHECK-NEXT: retq entry: %conv = fptosi double %x to i64 %0 = icmp slt i64 %conv, 4294967295 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 %1 = icmp sgt i64 %spec.store.select, 0 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 0 %conv6 = trunc i64 %spec.store.select7 to i32 ret i32 %conv6 } define i32 @stest_f32i32(float %x) { ; CHECK-LABEL: stest_f32i32: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttss2si %xmm0, %eax ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movl $2147483647, %ecx # imm = 0x7FFFFFFF ; CHECK-NEXT: cmovbel %eax, %ecx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: ucomiss %xmm0, %xmm0 ; CHECK-NEXT: cmovnpl %ecx, %eax ; CHECK-NEXT: retq entry: %conv = fptosi float %x to i64 %0 = icmp slt i64 %conv, 2147483647 %spec.store.select = select i1 %0, i64 %conv, i64 2147483647 %1 = icmp sgt i64 %spec.store.select, -2147483648 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 -2147483648 %conv6 = trunc i64 %spec.store.select7 to i32 ret i32 %conv6 } define i32 @utest_f32i32(float %x) { ; CHECK-LABEL: utest_f32i32: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttss2si %xmm0, %rax ; CHECK-NEXT: movq %rax, %rcx ; CHECK-NEXT: sarq $63, %rcx ; CHECK-NEXT: subss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: cvttss2si %xmm0, %rdx ; CHECK-NEXT: andq %rcx, %rdx ; CHECK-NEXT: orq %rax, %rdx ; CHECK-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF ; CHECK-NEXT: cmpq %rax, %rdx ; CHECK-NEXT: movl $-1, %eax ; CHECK-NEXT: cmovbl %edx, %eax ; CHECK-NEXT: retq entry: %conv = fptoui float %x to i64 %0 = icmp ult i64 %conv, 4294967295 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 %conv6 = trunc i64 %spec.store.select to i32 ret i32 %conv6 } define i32 @ustest_f32i32(float %x) { ; CHECK-LABEL: ustest_f32i32: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttss2si %xmm0, %rcx ; CHECK-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF ; CHECK-NEXT: cmpq %rax, %rcx ; CHECK-NEXT: cmovlq %rcx, %rax ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: testq %rax, %rax ; CHECK-NEXT: cmovlel %ecx, %eax ; CHECK-NEXT: # kill: def $eax killed $eax killed $rax ; CHECK-NEXT: retq entry: %conv = fptosi float %x to i64 %0 = icmp slt i64 %conv, 4294967295 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 %1 = icmp sgt i64 %spec.store.select, 0 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 0 %conv6 = trunc i64 %spec.store.select7 to i32 ret i32 %conv6 } define i32 @stest_f16i32(half %x) { ; CHECK-LABEL: stest_f16i32: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: cvttss2si %xmm0, %eax ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movl $-2147483648, %ecx # imm = 0x80000000 ; CHECK-NEXT: cmovael %eax, %ecx ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movl $2147483647, %edx # imm = 0x7FFFFFFF ; CHECK-NEXT: cmovbel %ecx, %edx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: ucomiss %xmm0, %xmm0 ; CHECK-NEXT: cmovnpl %edx, %eax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi half %x to i64 %0 = icmp slt i64 %conv, 2147483647 %spec.store.select = select i1 %0, i64 %conv, i64 2147483647 %1 = icmp sgt i64 %spec.store.select, -2147483648 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 -2147483648 %conv6 = trunc i64 %spec.store.select7 to i32 ret i32 %conv6 } define i32 @utesth_f16i32(half %x) { ; CHECK-LABEL: utesth_f16i32: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: cvttss2si %xmm0, %rax ; CHECK-NEXT: movq %rax, %rcx ; CHECK-NEXT: sarq $63, %rcx ; CHECK-NEXT: subss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: cvttss2si %xmm0, %rdx ; CHECK-NEXT: andq %rcx, %rdx ; CHECK-NEXT: orq %rax, %rdx ; CHECK-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF ; CHECK-NEXT: cmpq %rax, %rdx ; CHECK-NEXT: movl $-1, %eax ; CHECK-NEXT: cmovbl %edx, %eax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptoui half %x to i64 %0 = icmp ult i64 %conv, 4294967295 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 %conv6 = trunc i64 %spec.store.select to i32 ret i32 %conv6 } define i32 @ustest_f16i32(half %x) { ; CHECK-LABEL: ustest_f16i32: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: cvttss2si %xmm0, %rcx ; CHECK-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF ; CHECK-NEXT: cmpq %rax, %rcx ; CHECK-NEXT: cmovlq %rcx, %rax ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: testq %rax, %rax ; CHECK-NEXT: cmovlel %ecx, %eax ; CHECK-NEXT: # kill: def $eax killed $eax killed $rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi half %x to i64 %0 = icmp slt i64 %conv, 4294967295 %spec.store.select = select i1 %0, i64 %conv, i64 4294967295 %1 = icmp sgt i64 %spec.store.select, 0 %spec.store.select7 = select i1 %1, i64 %spec.store.select, i64 0 %conv6 = trunc i64 %spec.store.select7 to i32 ret i32 %conv6 } ; i16 saturate define i16 @stest_f64i16(double %x) { ; CHECK-LABEL: stest_f64i16: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero ; CHECK-NEXT: maxsd %xmm0, %xmm1 ; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero ; CHECK-NEXT: minsd %xmm1, %xmm0 ; CHECK-NEXT: cvttsd2si %xmm0, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: retq entry: %conv = fptosi double %x to i32 %0 = icmp slt i32 %conv, 32767 %spec.store.select = select i1 %0, i32 %conv, i32 32767 %1 = icmp sgt i32 %spec.store.select, -32768 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 -32768 %conv6 = trunc i32 %spec.store.select7 to i16 ret i16 %conv6 } define i16 @utest_f64i16(double %x) { ; CHECK-LABEL: utest_f64i16: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttsd2si %xmm0, %rcx ; CHECK-NEXT: cmpl $65535, %ecx # imm = 0xFFFF ; CHECK-NEXT: movl $65535, %eax # imm = 0xFFFF ; CHECK-NEXT: cmovbl %ecx, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: retq entry: %conv = fptoui double %x to i32 %0 = icmp ult i32 %conv, 65535 %spec.store.select = select i1 %0, i32 %conv, i32 65535 %conv6 = trunc i32 %spec.store.select to i16 ret i16 %conv6 } define i16 @ustest_f64i16(double %x) { ; CHECK-LABEL: ustest_f64i16: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttsd2si %xmm0, %eax ; CHECK-NEXT: cmpl $65535, %eax # imm = 0xFFFF ; CHECK-NEXT: movl $65535, %ecx # imm = 0xFFFF ; CHECK-NEXT: cmovll %eax, %ecx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: testl %ecx, %ecx ; CHECK-NEXT: cmovgl %ecx, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: retq entry: %conv = fptosi double %x to i32 %0 = icmp slt i32 %conv, 65535 %spec.store.select = select i1 %0, i32 %conv, i32 65535 %1 = icmp sgt i32 %spec.store.select, 0 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 0 %conv6 = trunc i32 %spec.store.select7 to i16 ret i16 %conv6 } define i16 @stest_f32i16(float %x) { ; CHECK-LABEL: stest_f32i16: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero ; CHECK-NEXT: maxss %xmm0, %xmm1 ; CHECK-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero ; CHECK-NEXT: minss %xmm1, %xmm0 ; CHECK-NEXT: cvttss2si %xmm0, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: retq entry: %conv = fptosi float %x to i32 %0 = icmp slt i32 %conv, 32767 %spec.store.select = select i1 %0, i32 %conv, i32 32767 %1 = icmp sgt i32 %spec.store.select, -32768 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 -32768 %conv6 = trunc i32 %spec.store.select7 to i16 ret i16 %conv6 } define i16 @utest_f32i16(float %x) { ; CHECK-LABEL: utest_f32i16: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttss2si %xmm0, %rcx ; CHECK-NEXT: cmpl $65535, %ecx # imm = 0xFFFF ; CHECK-NEXT: movl $65535, %eax # imm = 0xFFFF ; CHECK-NEXT: cmovbl %ecx, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: retq entry: %conv = fptoui float %x to i32 %0 = icmp ult i32 %conv, 65535 %spec.store.select = select i1 %0, i32 %conv, i32 65535 %conv6 = trunc i32 %spec.store.select to i16 ret i16 %conv6 } define i16 @ustest_f32i16(float %x) { ; CHECK-LABEL: ustest_f32i16: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttss2si %xmm0, %eax ; CHECK-NEXT: cmpl $65535, %eax # imm = 0xFFFF ; CHECK-NEXT: movl $65535, %ecx # imm = 0xFFFF ; CHECK-NEXT: cmovll %eax, %ecx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: testl %ecx, %ecx ; CHECK-NEXT: cmovgl %ecx, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: retq entry: %conv = fptosi float %x to i32 %0 = icmp slt i32 %conv, 65535 %spec.store.select = select i1 %0, i32 %conv, i32 65535 %1 = icmp sgt i32 %spec.store.select, 0 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 0 %conv6 = trunc i32 %spec.store.select7 to i16 ret i16 %conv6 } define i16 @stest_f16i16(half %x) { ; CHECK-LABEL: stest_f16i16: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: cvttss2si %xmm0, %eax ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movl $32768, %ecx # imm = 0x8000 ; CHECK-NEXT: cmovael %eax, %ecx ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movl $32767, %edx # imm = 0x7FFF ; CHECK-NEXT: cmovbel %ecx, %edx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: ucomiss %xmm0, %xmm0 ; CHECK-NEXT: cmovnpl %edx, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi half %x to i32 %0 = icmp slt i32 %conv, 32767 %spec.store.select = select i1 %0, i32 %conv, i32 32767 %1 = icmp sgt i32 %spec.store.select, -32768 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 -32768 %conv6 = trunc i32 %spec.store.select7 to i16 ret i16 %conv6 } define i16 @utesth_f16i16(half %x) { ; CHECK-LABEL: utesth_f16i16: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: cvttss2si %xmm0, %rcx ; CHECK-NEXT: cmpl $65535, %ecx # imm = 0xFFFF ; CHECK-NEXT: movl $65535, %eax # imm = 0xFFFF ; CHECK-NEXT: cmovbl %ecx, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptoui half %x to i32 %0 = icmp ult i32 %conv, 65535 %spec.store.select = select i1 %0, i32 %conv, i32 65535 %conv6 = trunc i32 %spec.store.select to i16 ret i16 %conv6 } define i16 @ustest_f16i16(half %x) { ; CHECK-LABEL: ustest_f16i16: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: cvttss2si %xmm0, %eax ; CHECK-NEXT: cmpl $65535, %eax # imm = 0xFFFF ; CHECK-NEXT: movl $65535, %ecx # imm = 0xFFFF ; CHECK-NEXT: cmovll %eax, %ecx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: testl %ecx, %ecx ; CHECK-NEXT: cmovgl %ecx, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi half %x to i32 %0 = icmp slt i32 %conv, 65535 %spec.store.select = select i1 %0, i32 %conv, i32 65535 %1 = icmp sgt i32 %spec.store.select, 0 %spec.store.select7 = select i1 %1, i32 %spec.store.select, i32 0 %conv6 = trunc i32 %spec.store.select7 to i16 ret i16 %conv6 } ; i64 saturate define i64 @stest_f64i64(double %x) { ; CHECK-LABEL: stest_f64i64: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttsd2si %xmm0, %rax ; CHECK-NEXT: ucomisd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movabsq $9223372036854775807, %rcx # imm = 0x7FFFFFFFFFFFFFFF ; CHECK-NEXT: cmovbeq %rax, %rcx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: ucomisd %xmm0, %xmm0 ; CHECK-NEXT: cmovnpq %rcx, %rax ; CHECK-NEXT: retq entry: %conv = fptosi double %x to i128 %0 = icmp slt i128 %conv, 9223372036854775807 %spec.store.select = select i1 %0, i128 %conv, i128 9223372036854775807 %1 = icmp sgt i128 %spec.store.select, -9223372036854775808 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 -9223372036854775808 %conv6 = trunc i128 %spec.store.select7 to i64 ret i64 %conv6 } define i64 @utest_f64i64(double %x) { ; CHECK-LABEL: utest_f64i64: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __fixunsdfti@PLT ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: testq %rdx, %rdx ; CHECK-NEXT: cmovneq %rcx, %rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptoui double %x to i128 %0 = icmp ult i128 %conv, 18446744073709551616 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 %conv6 = trunc i128 %spec.store.select to i64 ret i64 %conv6 } define i64 @ustest_f64i64(double %x) { ; CHECK-LABEL: ustest_f64i64: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __fixdfti@PLT ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: testq %rdx, %rdx ; CHECK-NEXT: movl $1, %esi ; CHECK-NEXT: cmovleq %rdx, %rsi ; CHECK-NEXT: cmovgq %rcx, %rax ; CHECK-NEXT: movq %rax, %rdx ; CHECK-NEXT: negq %rdx ; CHECK-NEXT: movl $0, %edx ; CHECK-NEXT: sbbq %rsi, %rdx ; CHECK-NEXT: cmovgeq %rcx, %rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi double %x to i128 %0 = icmp slt i128 %conv, 18446744073709551616 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 %1 = icmp sgt i128 %spec.store.select, 0 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 0 %conv6 = trunc i128 %spec.store.select7 to i64 ret i64 %conv6 } define i64 @stest_f32i64(float %x) { ; CHECK-LABEL: stest_f32i64: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttss2si %xmm0, %rax ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movabsq $9223372036854775807, %rcx # imm = 0x7FFFFFFFFFFFFFFF ; CHECK-NEXT: cmovbeq %rax, %rcx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: ucomiss %xmm0, %xmm0 ; CHECK-NEXT: cmovnpq %rcx, %rax ; CHECK-NEXT: retq entry: %conv = fptosi float %x to i128 %0 = icmp slt i128 %conv, 9223372036854775807 %spec.store.select = select i1 %0, i128 %conv, i128 9223372036854775807 %1 = icmp sgt i128 %spec.store.select, -9223372036854775808 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 -9223372036854775808 %conv6 = trunc i128 %spec.store.select7 to i64 ret i64 %conv6 } define i64 @utest_f32i64(float %x) { ; CHECK-LABEL: utest_f32i64: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __fixunssfti@PLT ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: testq %rdx, %rdx ; CHECK-NEXT: cmovneq %rcx, %rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptoui float %x to i128 %0 = icmp ult i128 %conv, 18446744073709551616 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 %conv6 = trunc i128 %spec.store.select to i64 ret i64 %conv6 } define i64 @ustest_f32i64(float %x) { ; CHECK-LABEL: ustest_f32i64: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __fixsfti@PLT ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: testq %rdx, %rdx ; CHECK-NEXT: movl $1, %esi ; CHECK-NEXT: cmovleq %rdx, %rsi ; CHECK-NEXT: cmovgq %rcx, %rax ; CHECK-NEXT: movq %rax, %rdx ; CHECK-NEXT: negq %rdx ; CHECK-NEXT: movl $0, %edx ; CHECK-NEXT: sbbq %rsi, %rdx ; CHECK-NEXT: cmovgeq %rcx, %rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi float %x to i128 %0 = icmp slt i128 %conv, 18446744073709551616 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 %1 = icmp sgt i128 %spec.store.select, 0 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 0 %conv6 = trunc i128 %spec.store.select7 to i64 ret i64 %conv6 } define i64 @stest_f16i64(half %x) { ; CHECK-LABEL: stest_f16i64: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: cvttss2si %xmm0, %rax ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000 ; CHECK-NEXT: cmovaeq %rax, %rcx ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movabsq $9223372036854775807, %rdx # imm = 0x7FFFFFFFFFFFFFFF ; CHECK-NEXT: cmovbeq %rcx, %rdx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: ucomiss %xmm0, %xmm0 ; CHECK-NEXT: cmovnpq %rdx, %rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi half %x to i128 %0 = icmp slt i128 %conv, 9223372036854775807 %spec.store.select = select i1 %0, i128 %conv, i128 9223372036854775807 %1 = icmp sgt i128 %spec.store.select, -9223372036854775808 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 -9223372036854775808 %conv6 = trunc i128 %spec.store.select7 to i64 ret i64 %conv6 } define i64 @utesth_f16i64(half %x) { ; CHECK-LABEL: utesth_f16i64: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __fixunshfti@PLT ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: testq %rdx, %rdx ; CHECK-NEXT: cmovneq %rcx, %rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptoui half %x to i128 %0 = icmp ult i128 %conv, 18446744073709551616 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 %conv6 = trunc i128 %spec.store.select to i64 ret i64 %conv6 } define i64 @ustest_f16i64(half %x) { ; CHECK-LABEL: ustest_f16i64: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __fixhfti@PLT ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: testq %rdx, %rdx ; CHECK-NEXT: movl $1, %esi ; CHECK-NEXT: cmovleq %rdx, %rsi ; CHECK-NEXT: cmovgq %rcx, %rax ; CHECK-NEXT: movq %rax, %rdx ; CHECK-NEXT: negq %rdx ; CHECK-NEXT: movl $0, %edx ; CHECK-NEXT: sbbq %rsi, %rdx ; CHECK-NEXT: cmovgeq %rcx, %rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi half %x to i128 %0 = icmp slt i128 %conv, 18446744073709551616 %spec.store.select = select i1 %0, i128 %conv, i128 18446744073709551616 %1 = icmp sgt i128 %spec.store.select, 0 %spec.store.select7 = select i1 %1, i128 %spec.store.select, i128 0 %conv6 = trunc i128 %spec.store.select7 to i64 ret i64 %conv6 } ; i32 saturate define i32 @stest_f64i32_mm(double %x) { ; CHECK-LABEL: stest_f64i32_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: ucomisd %xmm0, %xmm0 ; CHECK-NEXT: maxsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: minsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: cvttsd2si %xmm0, %ecx ; CHECK-NEXT: cmovnpl %ecx, %eax ; CHECK-NEXT: retq entry: %conv = fptosi double %x to i64 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648) %conv6 = trunc i64 %spec.store.select7 to i32 ret i32 %conv6 } define i32 @utest_f64i32_mm(double %x) { ; CHECK-LABEL: utest_f64i32_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttsd2si %xmm0, %rcx ; CHECK-NEXT: movq %rcx, %rdx ; CHECK-NEXT: sarq $63, %rdx ; CHECK-NEXT: subsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: cvttsd2si %xmm0, %rax ; CHECK-NEXT: andq %rdx, %rax ; CHECK-NEXT: orq %rcx, %rax ; CHECK-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF ; CHECK-NEXT: cmpq %rcx, %rax ; CHECK-NEXT: cmovaeq %rcx, %rax ; CHECK-NEXT: # kill: def $eax killed $eax killed $rax ; CHECK-NEXT: retq entry: %conv = fptoui double %x to i64 %spec.store.select = call i64 @llvm.umin.i64(i64 %conv, i64 4294967295) %conv6 = trunc i64 %spec.store.select to i32 ret i32 %conv6 } define i32 @ustest_f64i32_mm(double %x) { ; CHECK-LABEL: ustest_f64i32_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttsd2si %xmm0, %rax ; CHECK-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF ; CHECK-NEXT: cmpq %rcx, %rax ; CHECK-NEXT: cmovlq %rax, %rcx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: testq %rcx, %rcx ; CHECK-NEXT: cmovgq %rcx, %rax ; CHECK-NEXT: # kill: def $eax killed $eax killed $rax ; CHECK-NEXT: retq entry: %conv = fptosi double %x to i64 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 4294967295) %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 0) %conv6 = trunc i64 %spec.store.select7 to i32 ret i32 %conv6 } define i32 @stest_f32i32_mm(float %x) { ; CHECK-LABEL: stest_f32i32_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttss2si %xmm0, %eax ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movl $2147483647, %ecx # imm = 0x7FFFFFFF ; CHECK-NEXT: cmovbel %eax, %ecx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: ucomiss %xmm0, %xmm0 ; CHECK-NEXT: cmovnpl %ecx, %eax ; CHECK-NEXT: retq entry: %conv = fptosi float %x to i64 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648) %conv6 = trunc i64 %spec.store.select7 to i32 ret i32 %conv6 } define i32 @utest_f32i32_mm(float %x) { ; CHECK-LABEL: utest_f32i32_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttss2si %xmm0, %rcx ; CHECK-NEXT: movq %rcx, %rdx ; CHECK-NEXT: sarq $63, %rdx ; CHECK-NEXT: subss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: cvttss2si %xmm0, %rax ; CHECK-NEXT: andq %rdx, %rax ; CHECK-NEXT: orq %rcx, %rax ; CHECK-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF ; CHECK-NEXT: cmpq %rcx, %rax ; CHECK-NEXT: cmovaeq %rcx, %rax ; CHECK-NEXT: # kill: def $eax killed $eax killed $rax ; CHECK-NEXT: retq entry: %conv = fptoui float %x to i64 %spec.store.select = call i64 @llvm.umin.i64(i64 %conv, i64 4294967295) %conv6 = trunc i64 %spec.store.select to i32 ret i32 %conv6 } define i32 @ustest_f32i32_mm(float %x) { ; CHECK-LABEL: ustest_f32i32_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttss2si %xmm0, %rax ; CHECK-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF ; CHECK-NEXT: cmpq %rcx, %rax ; CHECK-NEXT: cmovlq %rax, %rcx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: testq %rcx, %rcx ; CHECK-NEXT: cmovgq %rcx, %rax ; CHECK-NEXT: # kill: def $eax killed $eax killed $rax ; CHECK-NEXT: retq entry: %conv = fptosi float %x to i64 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 4294967295) %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 0) %conv6 = trunc i64 %spec.store.select7 to i32 ret i32 %conv6 } define i32 @stest_f16i32_mm(half %x) { ; CHECK-LABEL: stest_f16i32_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: cvttss2si %xmm0, %eax ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movl $-2147483648, %ecx # imm = 0x80000000 ; CHECK-NEXT: cmovael %eax, %ecx ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movl $2147483647, %edx # imm = 0x7FFFFFFF ; CHECK-NEXT: cmovbel %ecx, %edx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: ucomiss %xmm0, %xmm0 ; CHECK-NEXT: cmovnpl %edx, %eax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi half %x to i64 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 2147483647) %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 -2147483648) %conv6 = trunc i64 %spec.store.select7 to i32 ret i32 %conv6 } define i32 @utesth_f16i32_mm(half %x) { ; CHECK-LABEL: utesth_f16i32_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: cvttss2si %xmm0, %rcx ; CHECK-NEXT: movq %rcx, %rdx ; CHECK-NEXT: sarq $63, %rdx ; CHECK-NEXT: subss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: cvttss2si %xmm0, %rax ; CHECK-NEXT: andq %rdx, %rax ; CHECK-NEXT: orq %rcx, %rax ; CHECK-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF ; CHECK-NEXT: cmpq %rcx, %rax ; CHECK-NEXT: cmovaeq %rcx, %rax ; CHECK-NEXT: # kill: def $eax killed $eax killed $rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptoui half %x to i64 %spec.store.select = call i64 @llvm.umin.i64(i64 %conv, i64 4294967295) %conv6 = trunc i64 %spec.store.select to i32 ret i32 %conv6 } define i32 @ustest_f16i32_mm(half %x) { ; CHECK-LABEL: ustest_f16i32_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: cvttss2si %xmm0, %rax ; CHECK-NEXT: movl $4294967295, %ecx # imm = 0xFFFFFFFF ; CHECK-NEXT: cmpq %rcx, %rax ; CHECK-NEXT: cmovlq %rax, %rcx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: testq %rcx, %rcx ; CHECK-NEXT: cmovgq %rcx, %rax ; CHECK-NEXT: # kill: def $eax killed $eax killed $rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi half %x to i64 %spec.store.select = call i64 @llvm.smin.i64(i64 %conv, i64 4294967295) %spec.store.select7 = call i64 @llvm.smax.i64(i64 %spec.store.select, i64 0) %conv6 = trunc i64 %spec.store.select7 to i32 ret i32 %conv6 } ; i16 saturate define i16 @stest_f64i16_mm(double %x) { ; CHECK-LABEL: stest_f64i16_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero ; CHECK-NEXT: maxsd %xmm0, %xmm1 ; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero ; CHECK-NEXT: minsd %xmm1, %xmm0 ; CHECK-NEXT: cvttsd2si %xmm0, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: retq entry: %conv = fptosi double %x to i32 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 32767) %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768) %conv6 = trunc i32 %spec.store.select7 to i16 ret i16 %conv6 } define i16 @utest_f64i16_mm(double %x) { ; CHECK-LABEL: utest_f64i16_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttsd2si %xmm0, %rcx ; CHECK-NEXT: cmpl $65535, %ecx # imm = 0xFFFF ; CHECK-NEXT: movl $65535, %eax # imm = 0xFFFF ; CHECK-NEXT: cmovbl %ecx, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: retq entry: %conv = fptoui double %x to i32 %spec.store.select = call i32 @llvm.umin.i32(i32 %conv, i32 65535) %conv6 = trunc i32 %spec.store.select to i16 ret i16 %conv6 } define i16 @ustest_f64i16_mm(double %x) { ; CHECK-LABEL: ustest_f64i16_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttsd2si %xmm0, %eax ; CHECK-NEXT: cmpl $65535, %eax # imm = 0xFFFF ; CHECK-NEXT: movl $65535, %ecx # imm = 0xFFFF ; CHECK-NEXT: cmovll %eax, %ecx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: testl %ecx, %ecx ; CHECK-NEXT: cmovgl %ecx, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: retq entry: %conv = fptosi double %x to i32 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 65535) %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 0) %conv6 = trunc i32 %spec.store.select7 to i16 ret i16 %conv6 } define i16 @stest_f32i16_mm(float %x) { ; CHECK-LABEL: stest_f32i16_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero ; CHECK-NEXT: maxss %xmm0, %xmm1 ; CHECK-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero ; CHECK-NEXT: minss %xmm1, %xmm0 ; CHECK-NEXT: cvttss2si %xmm0, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: retq entry: %conv = fptosi float %x to i32 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 32767) %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768) %conv6 = trunc i32 %spec.store.select7 to i16 ret i16 %conv6 } define i16 @utest_f32i16_mm(float %x) { ; CHECK-LABEL: utest_f32i16_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttss2si %xmm0, %rcx ; CHECK-NEXT: cmpl $65535, %ecx # imm = 0xFFFF ; CHECK-NEXT: movl $65535, %eax # imm = 0xFFFF ; CHECK-NEXT: cmovbl %ecx, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: retq entry: %conv = fptoui float %x to i32 %spec.store.select = call i32 @llvm.umin.i32(i32 %conv, i32 65535) %conv6 = trunc i32 %spec.store.select to i16 ret i16 %conv6 } define i16 @ustest_f32i16_mm(float %x) { ; CHECK-LABEL: ustest_f32i16_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttss2si %xmm0, %eax ; CHECK-NEXT: cmpl $65535, %eax # imm = 0xFFFF ; CHECK-NEXT: movl $65535, %ecx # imm = 0xFFFF ; CHECK-NEXT: cmovll %eax, %ecx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: testl %ecx, %ecx ; CHECK-NEXT: cmovgl %ecx, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: retq entry: %conv = fptosi float %x to i32 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 65535) %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 0) %conv6 = trunc i32 %spec.store.select7 to i16 ret i16 %conv6 } define i16 @stest_f16i16_mm(half %x) { ; CHECK-LABEL: stest_f16i16_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: cvttss2si %xmm0, %eax ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movl $32768, %ecx # imm = 0x8000 ; CHECK-NEXT: cmovael %eax, %ecx ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movl $32767, %edx # imm = 0x7FFF ; CHECK-NEXT: cmovbel %ecx, %edx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: ucomiss %xmm0, %xmm0 ; CHECK-NEXT: cmovnpl %edx, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi half %x to i32 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 32767) %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 -32768) %conv6 = trunc i32 %spec.store.select7 to i16 ret i16 %conv6 } define i16 @utesth_f16i16_mm(half %x) { ; CHECK-LABEL: utesth_f16i16_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: cvttss2si %xmm0, %rcx ; CHECK-NEXT: cmpl $65535, %ecx # imm = 0xFFFF ; CHECK-NEXT: movl $65535, %eax # imm = 0xFFFF ; CHECK-NEXT: cmovbl %ecx, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptoui half %x to i32 %spec.store.select = call i32 @llvm.umin.i32(i32 %conv, i32 65535) %conv6 = trunc i32 %spec.store.select to i16 ret i16 %conv6 } define i16 @ustest_f16i16_mm(half %x) { ; CHECK-LABEL: ustest_f16i16_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: cvttss2si %xmm0, %eax ; CHECK-NEXT: cmpl $65535, %eax # imm = 0xFFFF ; CHECK-NEXT: movl $65535, %ecx # imm = 0xFFFF ; CHECK-NEXT: cmovll %eax, %ecx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: testl %ecx, %ecx ; CHECK-NEXT: cmovgl %ecx, %eax ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi half %x to i32 %spec.store.select = call i32 @llvm.smin.i32(i32 %conv, i32 65535) %spec.store.select7 = call i32 @llvm.smax.i32(i32 %spec.store.select, i32 0) %conv6 = trunc i32 %spec.store.select7 to i16 ret i16 %conv6 } ; i64 saturate define i64 @stest_f64i64_mm(double %x) { ; CHECK-LABEL: stest_f64i64_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttsd2si %xmm0, %rax ; CHECK-NEXT: ucomisd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movabsq $9223372036854775807, %rcx # imm = 0x7FFFFFFFFFFFFFFF ; CHECK-NEXT: cmovbeq %rax, %rcx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: ucomisd %xmm0, %xmm0 ; CHECK-NEXT: cmovnpq %rcx, %rax ; CHECK-NEXT: retq entry: %conv = fptosi double %x to i128 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807) %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808) %conv6 = trunc i128 %spec.store.select7 to i64 ret i64 %conv6 } define i64 @utest_f64i64_mm(double %x) { ; CHECK-LABEL: utest_f64i64_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __fixunsdfti@PLT ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: testq %rdx, %rdx ; CHECK-NEXT: cmovneq %rcx, %rax ; CHECK-NEXT: cmpq $1, %rdx ; CHECK-NEXT: cmoveq %rcx, %rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptoui double %x to i128 %spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616) %conv6 = trunc i128 %spec.store.select to i64 ret i64 %conv6 } define i64 @ustest_f64i64_mm(double %x) { ; CHECK-LABEL: ustest_f64i64_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __fixdfti@PLT ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: testq %rdx, %rdx ; CHECK-NEXT: movl $1, %esi ; CHECK-NEXT: cmovleq %rdx, %rsi ; CHECK-NEXT: cmovgq %rcx, %rax ; CHECK-NEXT: cmpq $1, %rdx ; CHECK-NEXT: cmoveq %rcx, %rax ; CHECK-NEXT: testq %rsi, %rsi ; CHECK-NEXT: cmovsq %rcx, %rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi double %x to i128 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616) %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0) %conv6 = trunc i128 %spec.store.select7 to i64 ret i64 %conv6 } define i64 @stest_f32i64_mm(float %x) { ; CHECK-LABEL: stest_f32i64_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cvttss2si %xmm0, %rax ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movabsq $9223372036854775807, %rcx # imm = 0x7FFFFFFFFFFFFFFF ; CHECK-NEXT: cmovbeq %rax, %rcx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: ucomiss %xmm0, %xmm0 ; CHECK-NEXT: cmovnpq %rcx, %rax ; CHECK-NEXT: retq entry: %conv = fptosi float %x to i128 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807) %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808) %conv6 = trunc i128 %spec.store.select7 to i64 ret i64 %conv6 } define i64 @utest_f32i64_mm(float %x) { ; CHECK-LABEL: utest_f32i64_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __fixunssfti@PLT ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: testq %rdx, %rdx ; CHECK-NEXT: cmovneq %rcx, %rax ; CHECK-NEXT: cmpq $1, %rdx ; CHECK-NEXT: cmoveq %rcx, %rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptoui float %x to i128 %spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616) %conv6 = trunc i128 %spec.store.select to i64 ret i64 %conv6 } define i64 @ustest_f32i64_mm(float %x) { ; CHECK-LABEL: ustest_f32i64_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __fixsfti@PLT ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: testq %rdx, %rdx ; CHECK-NEXT: movl $1, %esi ; CHECK-NEXT: cmovleq %rdx, %rsi ; CHECK-NEXT: cmovgq %rcx, %rax ; CHECK-NEXT: cmpq $1, %rdx ; CHECK-NEXT: cmoveq %rcx, %rax ; CHECK-NEXT: testq %rsi, %rsi ; CHECK-NEXT: cmovsq %rcx, %rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi float %x to i128 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616) %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0) %conv6 = trunc i128 %spec.store.select7 to i64 ret i64 %conv6 } define i64 @stest_f16i64_mm(half %x) { ; CHECK-LABEL: stest_f16i64_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: cvttss2si %xmm0, %rax ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000 ; CHECK-NEXT: cmovaeq %rax, %rcx ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: movabsq $9223372036854775807, %rdx # imm = 0x7FFFFFFFFFFFFFFF ; CHECK-NEXT: cmovbeq %rcx, %rdx ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: ucomiss %xmm0, %xmm0 ; CHECK-NEXT: cmovnpq %rdx, %rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi half %x to i128 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 9223372036854775807) %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 -9223372036854775808) %conv6 = trunc i128 %spec.store.select7 to i64 ret i64 %conv6 } define i64 @utesth_f16i64_mm(half %x) { ; CHECK-LABEL: utesth_f16i64_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __fixunshfti@PLT ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: testq %rdx, %rdx ; CHECK-NEXT: cmovneq %rcx, %rax ; CHECK-NEXT: cmpq $1, %rdx ; CHECK-NEXT: cmoveq %rcx, %rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptoui half %x to i128 %spec.store.select = call i128 @llvm.umin.i128(i128 %conv, i128 18446744073709551616) %conv6 = trunc i128 %spec.store.select to i64 ret i64 %conv6 } define i64 @ustest_f16i64_mm(half %x) { ; CHECK-LABEL: ustest_f16i64_mm: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq __fixhfti@PLT ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: testq %rdx, %rdx ; CHECK-NEXT: movl $1, %esi ; CHECK-NEXT: cmovleq %rdx, %rsi ; CHECK-NEXT: cmovgq %rcx, %rax ; CHECK-NEXT: cmpq $1, %rdx ; CHECK-NEXT: cmoveq %rcx, %rax ; CHECK-NEXT: testq %rsi, %rsi ; CHECK-NEXT: cmovsq %rcx, %rax ; CHECK-NEXT: popq %rcx ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: retq entry: %conv = fptosi half %x to i128 %spec.store.select = call i128 @llvm.smin.i128(i128 %conv, i128 18446744073709551616) %spec.store.select7 = call i128 @llvm.smax.i128(i128 %spec.store.select, i128 0) %conv6 = trunc i128 %spec.store.select7 to i64 ret i64 %conv6 } declare i32 @llvm.smin.i32(i32, i32) declare i32 @llvm.smax.i32(i32, i32) declare i32 @llvm.umin.i32(i32, i32) declare i64 @llvm.smin.i64(i64, i64) declare i64 @llvm.smax.i64(i64, i64) declare i64 @llvm.umin.i64(i64, i64) declare i128 @llvm.smin.i128(i128, i128) declare i128 @llvm.smax.i128(i128, i128) declare i128 @llvm.umin.i128(i128, i128)