[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