| ; 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) |