[llvm] 185ff0c - [X86] Fix i64-to-bf16 conversion crash on 32-bit targets (#222934)

via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 11 08:05:01 PDT 2026


Author: Tim Besard
Date: 2026-09-11T23:04:55+08:00
New Revision: 185ff0c972cbdf0f221fbf1f45b8554810da79eb

URL: https://github.com/llvm/llvm-project/commit/185ff0c972cbdf0f221fbf1f45b8554810da79eb
DIFF: https://github.com/llvm/llvm-project/commit/185ff0c972cbdf0f221fbf1f45b8554810da79eb.diff

LOG: [X86] Fix i64-to-bf16 conversion crash on 32-bit targets (#222934)

Converting a loaded `i64` to `bfloat` can crash instruction selection on
i686:

```llvm
define bfloat @convert(ptr %p) {
  %value = load i64, ptr %p
  %result = sitofp i64 %value to bfloat
  ret bfloat %result
}
```

With `llc -mtriple=i686-linux-gnu`, this hits:

```text
Do not know how to custom type legalize this operation!
```

The X86 DAG combine folds the load and conversion into an x87 `FILD`
node
before type legalization. It already excludes `f16` and `f128`, but was
missing
`bf16`, leaving the legalizer with an unsupported result type.

Add `bf16` to that exclusion. This lets the existing legalization
promote the
conversion through `f32` and then round to bf16. The change also covers
the
constrained signed conversion, which uses the same combine.

Assisted by: Fable 5.1, Astra 6

Added: 
    llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll

Modified: 
    llvm/lib/Target/X86/X86ISelLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index a41cb2914660c..11dbec24adb33 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -59522,8 +59522,8 @@ static SDValue combineSIntToFP(SDNode *N, SelectionDAG &DAG,
       Op0.getOpcode() == ISD::LOAD) {
     LoadSDNode *Ld = cast<LoadSDNode>(Op0.getNode());
 
-    // This transformation is not supported if the result type is f16 or f128.
-    if (VT == MVT::f16 || VT == MVT::f128)
+    // FILD does not support f16, bf16, or f128 results.
+    if (VT == MVT::f16 || VT == MVT::bf16 || VT == MVT::f128)
       return SDValue();
 
     // If we have AVX512DQ we can use packed conversion instructions unless

diff  --git a/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll b/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll
new file mode 100644
index 0000000000000..9236951501a5f
--- /dev/null
+++ b/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll
@@ -0,0 +1,407 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=i686-linux-gnu | FileCheck %s --check-prefix=X87
+; RUN: llc < %s -mtriple=i686-linux-gnu -mattr=+sse2 | FileCheck %s --check-prefix=SSE2
+; RUN: llc < %s -mtriple=i686-linux-gnu -mattr=+avx512dq,+avx512vl | FileCheck %s --check-prefix=DQ
+; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck %s --check-prefix=X64
+
+; Do not fold an i64 load into a FILD with a bf16 result on 32-bit targets.
+; Leave the conversion to be promoted through f32.
+
+define bfloat @sitofp_i64_to_bf16(i64 %a) nounwind {
+; X87-LABEL: sitofp_i64_to_bf16:
+; X87:       # %bb.0:
+; X87-NEXT:    subl $28, %esp
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    calll __truncsfbf2
+; X87-NEXT:    # kill: def $ax killed $ax def $eax
+; X87-NEXT:    shll $16, %eax
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    addl $28, %esp
+; X87-NEXT:    retl
+;
+; SSE2-LABEL: sitofp_i64_to_bf16:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    subl $28, %esp
+; SSE2-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; SSE2-NEXT:    movlps %xmm0, {{[0-9]+}}(%esp)
+; SSE2-NEXT:    fildll {{[0-9]+}}(%esp)
+; SSE2-NEXT:    fstps {{[0-9]+}}(%esp)
+; SSE2-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; SSE2-NEXT:    movss %xmm0, (%esp)
+; SSE2-NEXT:    calll __truncsfbf2
+; SSE2-NEXT:    addl $28, %esp
+; SSE2-NEXT:    retl
+;
+; DQ-LABEL: sitofp_i64_to_bf16:
+; DQ:       # %bb.0:
+; DQ-NEXT:    subl $12, %esp
+; DQ-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
+; DQ-NEXT:    vcvtqq2ps %ymm0, %xmm0
+; DQ-NEXT:    vmovss %xmm0, (%esp)
+; DQ-NEXT:    vzeroupper
+; DQ-NEXT:    calll __truncsfbf2
+; DQ-NEXT:    addl $12, %esp
+; DQ-NEXT:    retl
+;
+; X64-LABEL: sitofp_i64_to_bf16:
+; X64:       # %bb.0:
+; X64-NEXT:    pushq %rax
+; X64-NEXT:    cvtsi2ss %rdi, %xmm0
+; X64-NEXT:    callq __truncsfbf2 at PLT
+; X64-NEXT:    popq %rax
+; X64-NEXT:    retq
+  %cvt = sitofp i64 %a to bfloat
+  ret bfloat %cvt
+}
+
+define bfloat @sitofp_load_i64_to_bf16(ptr %p) nounwind {
+; X87-LABEL: sitofp_load_i64_to_bf16:
+; X87:       # %bb.0:
+; X87-NEXT:    subl $28, %esp
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    movl (%eax), %ecx
+; X87-NEXT:    movl 4(%eax), %eax
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    calll __truncsfbf2
+; X87-NEXT:    # kill: def $ax killed $ax def $eax
+; X87-NEXT:    shll $16, %eax
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    addl $28, %esp
+; X87-NEXT:    retl
+;
+; SSE2-LABEL: sitofp_load_i64_to_bf16:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    subl $28, %esp
+; SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SSE2-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; SSE2-NEXT:    movlps %xmm0, {{[0-9]+}}(%esp)
+; SSE2-NEXT:    fildll {{[0-9]+}}(%esp)
+; SSE2-NEXT:    fstps {{[0-9]+}}(%esp)
+; SSE2-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; SSE2-NEXT:    movss %xmm0, (%esp)
+; SSE2-NEXT:    calll __truncsfbf2
+; SSE2-NEXT:    addl $28, %esp
+; SSE2-NEXT:    retl
+;
+; DQ-LABEL: sitofp_load_i64_to_bf16:
+; DQ:       # %bb.0:
+; DQ-NEXT:    subl $12, %esp
+; DQ-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; DQ-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
+; DQ-NEXT:    vcvtqq2ps %ymm0, %xmm0
+; DQ-NEXT:    vmovss %xmm0, (%esp)
+; DQ-NEXT:    vzeroupper
+; DQ-NEXT:    calll __truncsfbf2
+; DQ-NEXT:    addl $12, %esp
+; DQ-NEXT:    retl
+;
+; X64-LABEL: sitofp_load_i64_to_bf16:
+; X64:       # %bb.0:
+; X64-NEXT:    pushq %rax
+; X64-NEXT:    cvtsi2ssq (%rdi), %xmm0
+; X64-NEXT:    callq __truncsfbf2 at PLT
+; X64-NEXT:    popq %rax
+; X64-NEXT:    retq
+  %a = load i64, ptr %p
+  %cvt = sitofp i64 %a to bfloat
+  ret bfloat %cvt
+}
+
+define bfloat @uitofp_i64_to_bf16(i64 %a) nounwind {
+; X87-LABEL: uitofp_i64_to_bf16:
+; X87:       # %bb.0:
+; X87-NEXT:    subl $28, %esp
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    shrl $31, %ecx
+; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%ecx,4)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    calll __truncsfbf2
+; X87-NEXT:    # kill: def $ax killed $ax def $eax
+; X87-NEXT:    shll $16, %eax
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    addl $28, %esp
+; X87-NEXT:    retl
+;
+; SSE2-LABEL: uitofp_i64_to_bf16:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    subl $28, %esp
+; SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SSE2-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; SSE2-NEXT:    movlps %xmm0, {{[0-9]+}}(%esp)
+; SSE2-NEXT:    shrl $31, %eax
+; SSE2-NEXT:    fildll {{[0-9]+}}(%esp)
+; SSE2-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
+; SSE2-NEXT:    fstps (%esp)
+; SSE2-NEXT:    calll __truncsfbf2
+; SSE2-NEXT:    addl $28, %esp
+; SSE2-NEXT:    retl
+;
+; DQ-LABEL: uitofp_i64_to_bf16:
+; DQ:       # %bb.0:
+; DQ-NEXT:    subl $12, %esp
+; DQ-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
+; DQ-NEXT:    vcvtuqq2ps %ymm0, %xmm0
+; DQ-NEXT:    vmovss %xmm0, (%esp)
+; DQ-NEXT:    vzeroupper
+; DQ-NEXT:    calll __truncsfbf2
+; DQ-NEXT:    addl $12, %esp
+; DQ-NEXT:    retl
+;
+; X64-LABEL: uitofp_i64_to_bf16:
+; X64:       # %bb.0:
+; X64-NEXT:    testq %rdi, %rdi
+; X64-NEXT:    js .LBB2_1
+; X64-NEXT:  # %bb.2:
+; X64-NEXT:    cvtsi2ss %rdi, %xmm0
+; X64-NEXT:    jmp .LBB2_3
+; X64-NEXT:  .LBB2_1:
+; X64-NEXT:    movq %rdi, %rax
+; X64-NEXT:    shrq %rax
+; X64-NEXT:    andl $1, %edi
+; X64-NEXT:    orq %rax, %rdi
+; X64-NEXT:    cvtsi2ss %rdi, %xmm0
+; X64-NEXT:    addss %xmm0, %xmm0
+; X64-NEXT:  .LBB2_3:
+; X64-NEXT:    pushq %rax
+; X64-NEXT:    callq __truncsfbf2 at PLT
+; X64-NEXT:    popq %rax
+; X64-NEXT:    retq
+  %cvt = uitofp i64 %a to bfloat
+  ret bfloat %cvt
+}
+
+define bfloat @uitofp_load_i64_to_bf16(ptr %p) nounwind {
+; X87-LABEL: uitofp_load_i64_to_bf16:
+; X87:       # %bb.0:
+; X87-NEXT:    subl $28, %esp
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    movl (%eax), %ecx
+; X87-NEXT:    movl 4(%eax), %eax
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; X87-NEXT:    shrl $31, %eax
+; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    calll __truncsfbf2
+; X87-NEXT:    # kill: def $ax killed $ax def $eax
+; X87-NEXT:    shll $16, %eax
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    addl $28, %esp
+; X87-NEXT:    retl
+;
+; SSE2-LABEL: uitofp_load_i64_to_bf16:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    subl $28, %esp
+; SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SSE2-NEXT:    movl 4(%eax), %ecx
+; SSE2-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; SSE2-NEXT:    movlps %xmm0, {{[0-9]+}}(%esp)
+; SSE2-NEXT:    shrl $31, %ecx
+; SSE2-NEXT:    fildll {{[0-9]+}}(%esp)
+; SSE2-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%ecx,4)
+; SSE2-NEXT:    fstps (%esp)
+; SSE2-NEXT:    calll __truncsfbf2
+; SSE2-NEXT:    addl $28, %esp
+; SSE2-NEXT:    retl
+;
+; DQ-LABEL: uitofp_load_i64_to_bf16:
+; DQ:       # %bb.0:
+; DQ-NEXT:    subl $12, %esp
+; DQ-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; DQ-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
+; DQ-NEXT:    vcvtuqq2ps %ymm0, %xmm0
+; DQ-NEXT:    vmovss %xmm0, (%esp)
+; DQ-NEXT:    vzeroupper
+; DQ-NEXT:    calll __truncsfbf2
+; DQ-NEXT:    addl $12, %esp
+; DQ-NEXT:    retl
+;
+; X64-LABEL: uitofp_load_i64_to_bf16:
+; X64:       # %bb.0:
+; X64-NEXT:    movq (%rdi), %rax
+; X64-NEXT:    testq %rax, %rax
+; X64-NEXT:    js .LBB3_1
+; X64-NEXT:  # %bb.2:
+; X64-NEXT:    cvtsi2ss %rax, %xmm0
+; X64-NEXT:    jmp .LBB3_3
+; X64-NEXT:  .LBB3_1:
+; X64-NEXT:    movq %rax, %rcx
+; X64-NEXT:    shrq %rcx
+; X64-NEXT:    andl $1, %eax
+; X64-NEXT:    orq %rcx, %rax
+; X64-NEXT:    cvtsi2ss %rax, %xmm0
+; X64-NEXT:    addss %xmm0, %xmm0
+; X64-NEXT:  .LBB3_3:
+; X64-NEXT:    pushq %rax
+; X64-NEXT:    callq __truncsfbf2 at PLT
+; X64-NEXT:    popq %rax
+; X64-NEXT:    retq
+  %a = load i64, ptr %p
+  %cvt = uitofp i64 %a to bfloat
+  ret bfloat %cvt
+}
+
+define bfloat @strict_sitofp_load_i64_to_bf16(ptr %p) strictfp nounwind {
+; X87-LABEL: strict_sitofp_load_i64_to_bf16:
+; X87:       # %bb.0:
+; X87-NEXT:    subl $28, %esp
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    movl (%eax), %ecx
+; X87-NEXT:    movl 4(%eax), %eax
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    wait
+; X87-NEXT:    calll __truncsfbf2
+; X87-NEXT:    # kill: def $ax killed $ax def $eax
+; X87-NEXT:    shll $16, %eax
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    wait
+; X87-NEXT:    addl $28, %esp
+; X87-NEXT:    retl
+;
+; SSE2-LABEL: strict_sitofp_load_i64_to_bf16:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    subl $28, %esp
+; SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SSE2-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; SSE2-NEXT:    movlps %xmm0, {{[0-9]+}}(%esp)
+; SSE2-NEXT:    fildll {{[0-9]+}}(%esp)
+; SSE2-NEXT:    fstps {{[0-9]+}}(%esp)
+; SSE2-NEXT:    wait
+; 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 $28, %esp
+; SSE2-NEXT:    retl
+;
+; DQ-LABEL: strict_sitofp_load_i64_to_bf16:
+; DQ:       # %bb.0:
+; DQ-NEXT:    subl $12, %esp
+; DQ-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; DQ-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
+; DQ-NEXT:    vcvtqq2ps %ymm0, %xmm0
+; DQ-NEXT:    vmovd %xmm0, (%esp)
+; DQ-NEXT:    vzeroupper
+; DQ-NEXT:    calll __truncsfbf2
+; DQ-NEXT:    # kill: def $ax killed $ax def $eax
+; DQ-NEXT:    vpinsrw $0, %eax, %xmm0, %xmm0
+; DQ-NEXT:    addl $12, %esp
+; DQ-NEXT:    retl
+;
+; X64-LABEL: strict_sitofp_load_i64_to_bf16:
+; X64:       # %bb.0:
+; X64-NEXT:    pushq %rax
+; X64-NEXT:    cvtsi2ssq (%rdi), %xmm0
+; X64-NEXT:    callq __truncsfbf2 at PLT
+; X64-NEXT:    # kill: def $ax killed $ax def $eax
+; X64-NEXT:    pinsrw $0, %eax, %xmm0
+; X64-NEXT:    popq %rax
+; X64-NEXT:    retq
+  %a = load i64, ptr %p
+  %cvt = call bfloat @llvm.experimental.constrained.sitofp.bf16.i64(i64 %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
+  ret bfloat %cvt
+}
+
+define bfloat @strict_uitofp_i64_to_bf16(i64 %a) strictfp nounwind {
+; X87-LABEL: strict_uitofp_i64_to_bf16:
+; X87:       # %bb.0:
+; X87-NEXT:    subl $28, %esp
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    shrl $31, %ecx
+; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%ecx,4)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    wait
+; X87-NEXT:    calll __truncsfbf2
+; X87-NEXT:    # kill: def $ax killed $ax def $eax
+; X87-NEXT:    shll $16, %eax
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    wait
+; X87-NEXT:    addl $28, %esp
+; X87-NEXT:    retl
+;
+; SSE2-LABEL: strict_uitofp_i64_to_bf16:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    subl $28, %esp
+; SSE2-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SSE2-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; SSE2-NEXT:    movlps %xmm0, {{[0-9]+}}(%esp)
+; SSE2-NEXT:    shrl $31, %eax
+; SSE2-NEXT:    fildll {{[0-9]+}}(%esp)
+; SSE2-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
+; SSE2-NEXT:    fstps {{[0-9]+}}(%esp)
+; SSE2-NEXT:    wait
+; 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 $28, %esp
+; SSE2-NEXT:    retl
+;
+; DQ-LABEL: strict_uitofp_i64_to_bf16:
+; DQ:       # %bb.0:
+; DQ-NEXT:    subl $12, %esp
+; DQ-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
+; DQ-NEXT:    vcvtuqq2ps %ymm0, %xmm0
+; DQ-NEXT:    vmovd %xmm0, (%esp)
+; DQ-NEXT:    vzeroupper
+; DQ-NEXT:    calll __truncsfbf2
+; DQ-NEXT:    # kill: def $ax killed $ax def $eax
+; DQ-NEXT:    vpinsrw $0, %eax, %xmm0, %xmm0
+; DQ-NEXT:    addl $12, %esp
+; DQ-NEXT:    retl
+;
+; X64-LABEL: strict_uitofp_i64_to_bf16:
+; X64:       # %bb.0:
+; X64-NEXT:    movq %rdi, %rax
+; X64-NEXT:    shrq %rax
+; X64-NEXT:    movl %edi, %ecx
+; X64-NEXT:    andl $1, %ecx
+; X64-NEXT:    orq %rax, %rcx
+; X64-NEXT:    testq %rdi, %rdi
+; X64-NEXT:    cmovnsq %rdi, %rcx
+; X64-NEXT:    cvtsi2ss %rcx, %xmm1
+; X64-NEXT:    movaps %xmm1, %xmm0
+; X64-NEXT:    addss %xmm1, %xmm0
+; X64-NEXT:    js .LBB5_2
+; X64-NEXT:  # %bb.1:
+; X64-NEXT:    movaps %xmm1, %xmm0
+; X64-NEXT:  .LBB5_2:
+; X64-NEXT:    pushq %rax
+; X64-NEXT:    callq __truncsfbf2 at PLT
+; X64-NEXT:    # kill: def $ax killed $ax def $eax
+; X64-NEXT:    pinsrw $0, %eax, %xmm0
+; X64-NEXT:    popq %rax
+; X64-NEXT:    retq
+  %cvt = call bfloat @llvm.experimental.constrained.uitofp.bf16.i64(i64 %a, metadata !"round.dynamic", metadata !"fpexcept.strict")
+  ret bfloat %cvt
+}


        


More information about the llvm-commits mailing list