blob: a4386d453b91b8d43ed283e3214d2f25f047f501 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
; RUN: llc < %s -mtriple=i686-linux-gnu -mattr=-sse2 -verify-machineinstrs | FileCheck %s --check-prefix=NO-SSE2
; RUN: llc < %s -mtriple=i686-linux-gnu -mattr=+sse2 -verify-machineinstrs | FileCheck %s --check-prefix=SSE2
; RUN: llc < %s -mtriple=x86_64-linux-gnu -mattr=+soft-float -verify-machineinstrs | FileCheck %s --check-prefix=SOFT-FLOAT
define bfloat @fptrunc_f32(float %x) nounwind {
; NO-SSE2-LABEL: fptrunc_f32:
; NO-SSE2: # %bb.0:
; NO-SSE2-NEXT: subl $12, %esp
; NO-SSE2-NEXT: flds {{[0-9]+}}(%esp)
; NO-SSE2-NEXT: fstps (%esp)
; NO-SSE2-NEXT: calll __truncsfbf2
; NO-SSE2-NEXT: # kill: def $ax killed $ax def $eax
; NO-SSE2-NEXT: shll $16, %eax
; NO-SSE2-NEXT: movl %eax, {{[0-9]+}}(%esp)
; NO-SSE2-NEXT: flds {{[0-9]+}}(%esp)
; NO-SSE2-NEXT: addl $12, %esp
; NO-SSE2-NEXT: retl
;
; SSE2-LABEL: fptrunc_f32:
; SSE2: # %bb.0:
; SSE2-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
; SSE2-NEXT: movd %xmm0, %eax
; SSE2-NEXT: btl $16, %eax
; SSE2-NEXT: movl %eax, %ecx
; SSE2-NEXT: adcl $32767, %ecx # imm = 0x7FFF
; SSE2-NEXT: orl $4194304, %eax # imm = 0x400000
; SSE2-NEXT: ucomiss %xmm0, %xmm0
; SSE2-NEXT: cmovnpl %ecx, %eax
; SSE2-NEXT: shrl $16, %eax
; SSE2-NEXT: pinsrw $0, %eax, %xmm0
; SSE2-NEXT: retl
;
; SOFT-FLOAT-LABEL: fptrunc_f32:
; SOFT-FLOAT: # %bb.0:
; SOFT-FLOAT-NEXT: pushq %rax
; SOFT-FLOAT-NEXT: callq __truncsfbf2@PLT
; SOFT-FLOAT-NEXT: popq %rcx
; SOFT-FLOAT-NEXT: retq
%r = fptrunc float %x to bfloat
ret bfloat %r
}
define bfloat @fptrunc_f64(double %x) nounwind {
; NO-SSE2-LABEL: fptrunc_f64:
; NO-SSE2: # %bb.0:
; NO-SSE2-NEXT: subl $12, %esp
; NO-SSE2-NEXT: fldl {{[0-9]+}}(%esp)
; NO-SSE2-NEXT: fstpl (%esp)
; NO-SSE2-NEXT: calll __truncdfbf2
; NO-SSE2-NEXT: # kill: def $ax killed $ax def $eax
; NO-SSE2-NEXT: shll $16, %eax
; NO-SSE2-NEXT: movl %eax, {{[0-9]+}}(%esp)
; NO-SSE2-NEXT: flds {{[0-9]+}}(%esp)
; NO-SSE2-NEXT: addl $12, %esp
; NO-SSE2-NEXT: retl
;
; SSE2-LABEL: fptrunc_f64:
; SSE2: # %bb.0:
; SSE2-NEXT: subl $12, %esp
; SSE2-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero
; SSE2-NEXT: movsd %xmm0, (%esp)
; SSE2-NEXT: calll __truncdfbf2
; SSE2-NEXT: addl $12, %esp
; SSE2-NEXT: retl
;
; SOFT-FLOAT-LABEL: fptrunc_f64:
; SOFT-FLOAT: # %bb.0:
; SOFT-FLOAT-NEXT: pushq %rax
; SOFT-FLOAT-NEXT: callq __truncdfbf2@PLT
; SOFT-FLOAT-NEXT: popq %rcx
; SOFT-FLOAT-NEXT: retq
%r = fptrunc double %x to bfloat
ret bfloat %r
}
define bfloat @fptrunc_f32_strict(float %x) strictfp {
; NO-SSE2-LABEL: fptrunc_f32_strict:
; NO-SSE2: # %bb.0:
; NO-SSE2-NEXT: subl $12, %esp
; NO-SSE2-NEXT: .cfi_def_cfa_offset 16
; NO-SSE2-NEXT: flds {{[0-9]+}}(%esp)
; NO-SSE2-NEXT: fstps (%esp)
; NO-SSE2-NEXT: wait
; NO-SSE2-NEXT: calll __truncsfbf2
; NO-SSE2-NEXT: # kill: def $ax killed $ax def $eax
; NO-SSE2-NEXT: shll $16, %eax
; NO-SSE2-NEXT: movl %eax, {{[0-9]+}}(%esp)
; NO-SSE2-NEXT: flds {{[0-9]+}}(%esp)
; NO-SSE2-NEXT: wait
; NO-SSE2-NEXT: addl $12, %esp
; NO-SSE2-NEXT: .cfi_def_cfa_offset 4
; NO-SSE2-NEXT: retl
;
; SSE2-LABEL: fptrunc_f32_strict:
; SSE2: # %bb.0:
; SSE2-NEXT: subl $12, %esp
; SSE2-NEXT: .cfi_def_cfa_offset 16
; SSE2-NEXT: movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
; SSE2-NEXT: movd %xmm0, (%esp)
; SSE2-NEXT: calll __truncsfbf2
; SSE2-NEXT: # kill: def $ax killed $ax def $eax
; SSE2-NEXT: pinsrw $0, %eax, %xmm0
; SSE2-NEXT: addl $12, %esp
; SSE2-NEXT: .cfi_def_cfa_offset 4
; SSE2-NEXT: retl
;
; SOFT-FLOAT-LABEL: fptrunc_f32_strict:
; SOFT-FLOAT: # %bb.0:
; SOFT-FLOAT-NEXT: pushq %rax
; SOFT-FLOAT-NEXT: .cfi_def_cfa_offset 16
; SOFT-FLOAT-NEXT: callq __truncsfbf2@PLT
; SOFT-FLOAT-NEXT: popq %rcx
; SOFT-FLOAT-NEXT: .cfi_def_cfa_offset 8
; SOFT-FLOAT-NEXT: retq
%r = call bfloat @llvm.experimental.constrained.fptrunc.bf16.f32(
float %x, metadata !"round.tonearest", metadata !"fpexcept.strict")
ret bfloat %r
}
declare bfloat @llvm.experimental.constrained.fptrunc.bf16.f32(float, metadata,
metadata)