[llvm-branch-commits] [llvm] release/23.x: [X86] Fix miscompile of fptosi.sat.iN.f16 for NaN under avx512fp16 (#210556) (PR #215049)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat Aug 8 19:51:01 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: llvmbot

<details>
<summary>Changes</summary>

Backport e1823e8b1778997d12ba947350190af5ee845ca9

Requested by: @<!-- -->phoebewang

---

Patch is 116.16 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/215049.diff


3 Files Affected:

- (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+8-4) 
- (added) llvm/test/CodeGen/X86/fptosi-sat-scalar-f16.ll (+1298) 
- (modified) llvm/test/CodeGen/X86/fptosi-sat-scalar.ll (+103-1263) 


``````````diff
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 76a474c496fe7..7ccfc5acc0cea 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22658,10 +22658,14 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
   // result type of the fptoi instructions, INDVAL coincides with integer
   // minimum, so we don't need to explicitly check it.
   if (!IsSigned || SatWidth != TmpVT.getScalarSizeInBits()) {
-    // If Src ULT MinFloat, select MinInt. In particular, this also selects
-    // MinInt if Src is NaN.
-    Select = DAG.getSelectCC(
-      dl, Src, MinFloatNode, MinIntNode, Select, ISD::CondCode::SETULT);
+    // If Src is less than MinFloat, select MinInt. An unordered comparison
+    // also selects MinInt for NaN, which is correct except when signed and
+    // promoted to a wider TmpVT: there MinInt != 0, but the earlier
+    // truncation already mapped NaN to the correct 0, so use an ordered
+    // comparison to leave it alone.
+    ISD::CondCode MinCC = (IsSigned && DstVT != TmpVT) ? ISD::CondCode::SETOLT
+                                                       : ISD::CondCode::SETULT;
+    Select = DAG.getSelectCC(dl, Src, MinFloatNode, MinIntNode, Select, MinCC);
   }
 
   // If Src OGT MaxFloat, select MaxInt.
diff --git a/llvm/test/CodeGen/X86/fptosi-sat-scalar-f16.ll b/llvm/test/CodeGen/X86/fptosi-sat-scalar-f16.ll
new file mode 100644
index 0000000000000..1079a7baab2b9
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fptosi-sat-scalar-f16.ll
@@ -0,0 +1,1298 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=i686-linux | FileCheck %s --check-prefix=X86-X87
+; RUN: llc < %s -mtriple=i686-linux -mattr=+sse2 | FileCheck %s --check-prefix=X86-SSE
+; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefix=X64
+; RUN: llc < %s -mtriple=x86_64-linux -mattr=+avx512fp16 | FileCheck %s --check-prefix=X64-AVX512FP16
+
+;
+; 16-bit float to signed integer
+;
+
+; FIXME: Can be optimizated with maxss + minss
+define i1 @test_signed_i1_f16(half %f) nounwind {
+; X86-X87-LABEL: test_signed_i1_f16:
+; X86-X87:       # %bb.0:
+; X86-X87-NEXT:    pushl %ebx
+; X86-X87-NEXT:    subl $24, %esp
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X86-X87-NEXT:    movl %eax, (%esp)
+; X86-X87-NEXT:    calll __extendhfsf2
+; X86-X87-NEXT:    fnstcw {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X86-X87-NEXT:    orl $3072, %eax # imm = 0xC00
+; X86-X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fists {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fld1
+; X86-X87-NEXT:    fchs
+; X86-X87-NEXT:    fxch %st(1)
+; X86-X87-NEXT:    fucom %st(1)
+; X86-X87-NEXT:    fstp %st(1)
+; X86-X87-NEXT:    fnstsw %ax
+; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X86-X87-NEXT:    sahf
+; X86-X87-NEXT:    movb $-1, %dl
+; X86-X87-NEXT:    jb .LBB0_2
+; X86-X87-NEXT:  # %bb.1:
+; X86-X87-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-X87-NEXT:  .LBB0_2:
+; X86-X87-NEXT:    fldz
+; X86-X87-NEXT:    fxch %st(1)
+; X86-X87-NEXT:    fucom %st(1)
+; X86-X87-NEXT:    fstp %st(1)
+; X86-X87-NEXT:    fnstsw %ax
+; X86-X87-NEXT:    xorl %ecx, %ecx
+; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X86-X87-NEXT:    sahf
+; X86-X87-NEXT:    movl $0, %ebx
+; X86-X87-NEXT:    ja .LBB0_4
+; X86-X87-NEXT:  # %bb.3:
+; X86-X87-NEXT:    movl %edx, %ebx
+; X86-X87-NEXT:  .LBB0_4:
+; X86-X87-NEXT:    fucomp %st(0)
+; X86-X87-NEXT:    fnstsw %ax
+; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X86-X87-NEXT:    sahf
+; X86-X87-NEXT:    jp .LBB0_6
+; X86-X87-NEXT:  # %bb.5:
+; X86-X87-NEXT:    movl %ebx, %ecx
+; X86-X87-NEXT:  .LBB0_6:
+; X86-X87-NEXT:    movl %ecx, %eax
+; X86-X87-NEXT:    addl $24, %esp
+; X86-X87-NEXT:    popl %ebx
+; X86-X87-NEXT:    retl
+;
+; X86-SSE-LABEL: test_signed_i1_f16:
+; X86-SSE:       # %bb.0:
+; X86-SSE-NEXT:    subl $12, %esp
+; X86-SSE-NEXT:    pinsrw $0, {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    pextrw $0, %xmm0, %eax
+; X86-SSE-NEXT:    movw %ax, (%esp)
+; X86-SSE-NEXT:    calll __extendhfsf2
+; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    xorl %eax, %eax
+; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
+; X86-SSE-NEXT:    maxss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
+; X86-SSE-NEXT:    xorps %xmm1, %xmm1
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %ecx
+; X86-SSE-NEXT:    cmovnpl %ecx, %eax
+; X86-SSE-NEXT:    # kill: def $al killed $al killed $eax
+; X86-SSE-NEXT:    addl $12, %esp
+; X86-SSE-NEXT:    retl
+;
+; X64-LABEL: test_signed_i1_f16:
+; X64:       # %bb.0:
+; X64-NEXT:    pushq %rax
+; X64-NEXT:    callq __extendhfsf2 at PLT
+; X64-NEXT:    xorl %eax, %eax
+; X64-NEXT:    ucomiss %xmm0, %xmm0
+; X64-NEXT:    maxss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT:    xorps %xmm1, %xmm1
+; X64-NEXT:    minss %xmm0, %xmm1
+; X64-NEXT:    cvttss2si %xmm1, %ecx
+; X64-NEXT:    cmovnpl %ecx, %eax
+; X64-NEXT:    # kill: def $al killed $al killed $eax
+; X64-NEXT:    popq %rcx
+; X64-NEXT:    retq
+;
+; X64-AVX512FP16-LABEL: test_signed_i1_f16:
+; X64-AVX512FP16:       # %bb.0:
+; X64-AVX512FP16-NEXT:    vmovsh {{.*#+}} xmm1 = [-1.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0]
+; X64-AVX512FP16-NEXT:    vmaxsh %xmm0, %xmm1, %xmm0
+; X64-AVX512FP16-NEXT:    vxorps %xmm1, %xmm1, %xmm1
+; X64-AVX512FP16-NEXT:    vminsh %xmm0, %xmm1, %xmm0
+; X64-AVX512FP16-NEXT:    vcvttsh2si %xmm0, %eax
+; X64-AVX512FP16-NEXT:    # kill: def $al killed $al killed $eax
+; X64-AVX512FP16-NEXT:    retq
+    %x = call i1 @llvm.fptosi.sat.i1.f16(half %f)
+    ret i1 %x
+}
+
+; FIXME: Can be optimizated with maxss + minss
+define i8 @test_signed_i8_f16(half %f) nounwind {
+; X86-X87-LABEL: test_signed_i8_f16:
+; X86-X87:       # %bb.0:
+; X86-X87-NEXT:    subl $12, %esp
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X86-X87-NEXT:    movl %eax, (%esp)
+; X86-X87-NEXT:    calll __extendhfsf2
+; X86-X87-NEXT:    fnstcw {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X86-X87-NEXT:    orl $3072, %eax # imm = 0xC00
+; X86-X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fists {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-X87-NEXT:    fxch %st(1)
+; X86-X87-NEXT:    fucom %st(1)
+; X86-X87-NEXT:    fstp %st(1)
+; X86-X87-NEXT:    fnstsw %ax
+; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X86-X87-NEXT:    sahf
+; X86-X87-NEXT:    movb $-128, %dl
+; X86-X87-NEXT:    jb .LBB1_2
+; X86-X87-NEXT:  # %bb.1:
+; X86-X87-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
+; X86-X87-NEXT:  .LBB1_2:
+; X86-X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-X87-NEXT:    fxch %st(1)
+; X86-X87-NEXT:    fucom %st(1)
+; X86-X87-NEXT:    fstp %st(1)
+; X86-X87-NEXT:    fnstsw %ax
+; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X86-X87-NEXT:    sahf
+; X86-X87-NEXT:    movb $127, %cl
+; X86-X87-NEXT:    ja .LBB1_4
+; X86-X87-NEXT:  # %bb.3:
+; X86-X87-NEXT:    movl %edx, %ecx
+; X86-X87-NEXT:  .LBB1_4:
+; X86-X87-NEXT:    fucomp %st(0)
+; X86-X87-NEXT:    fnstsw %ax
+; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X86-X87-NEXT:    sahf
+; X86-X87-NEXT:    jnp .LBB1_6
+; X86-X87-NEXT:  # %bb.5:
+; X86-X87-NEXT:    xorl %ecx, %ecx
+; X86-X87-NEXT:  .LBB1_6:
+; X86-X87-NEXT:    movl %ecx, %eax
+; X86-X87-NEXT:    addl $12, %esp
+; X86-X87-NEXT:    retl
+;
+; X86-SSE-LABEL: test_signed_i8_f16:
+; X86-SSE:       # %bb.0:
+; X86-SSE-NEXT:    subl $12, %esp
+; X86-SSE-NEXT:    pinsrw $0, {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    pextrw $0, %xmm0, %eax
+; X86-SSE-NEXT:    movw %ax, (%esp)
+; X86-SSE-NEXT:    calll __extendhfsf2
+; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    xorl %eax, %eax
+; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
+; X86-SSE-NEXT:    maxss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
+; X86-SSE-NEXT:    minss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
+; X86-SSE-NEXT:    cvttss2si %xmm0, %ecx
+; X86-SSE-NEXT:    cmovnpl %ecx, %eax
+; X86-SSE-NEXT:    # kill: def $al killed $al killed $eax
+; X86-SSE-NEXT:    addl $12, %esp
+; X86-SSE-NEXT:    retl
+;
+; X64-LABEL: test_signed_i8_f16:
+; X64:       # %bb.0:
+; X64-NEXT:    pushq %rax
+; X64-NEXT:    callq __extendhfsf2 at PLT
+; X64-NEXT:    xorl %eax, %eax
+; X64-NEXT:    ucomiss %xmm0, %xmm0
+; X64-NEXT:    maxss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT:    minss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %ecx
+; X64-NEXT:    cmovnpl %ecx, %eax
+; X64-NEXT:    # kill: def $al killed $al killed $eax
+; X64-NEXT:    popq %rcx
+; X64-NEXT:    retq
+;
+; X64-AVX512FP16-LABEL: test_signed_i8_f16:
+; X64-AVX512FP16:       # %bb.0:
+; X64-AVX512FP16-NEXT:    vmovsh {{.*#+}} xmm1 = [-1.28E+2,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0]
+; X64-AVX512FP16-NEXT:    vmaxsh %xmm0, %xmm1, %xmm0
+; X64-AVX512FP16-NEXT:    vmovsh {{.*#+}} xmm1 = [1.27E+2,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0]
+; X64-AVX512FP16-NEXT:    vminsh %xmm0, %xmm1, %xmm0
+; X64-AVX512FP16-NEXT:    vcvttsh2si %xmm0, %eax
+; X64-AVX512FP16-NEXT:    # kill: def $al killed $al killed $eax
+; X64-AVX512FP16-NEXT:    retq
+    %x = call i8 @llvm.fptosi.sat.i8.f16(half %f)
+    ret i8 %x
+}
+
+; FIXME: Can be optimizated with maxss + minss
+define i13 @test_signed_i13_f16(half %f) nounwind {
+; X86-X87-LABEL: test_signed_i13_f16:
+; X86-X87:       # %bb.0:
+; X86-X87-NEXT:    subl $12, %esp
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X86-X87-NEXT:    movl %eax, (%esp)
+; X86-X87-NEXT:    calll __extendhfsf2
+; X86-X87-NEXT:    fnstcw {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X86-X87-NEXT:    orl $3072, %eax # imm = 0xC00
+; X86-X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fists {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-X87-NEXT:    fxch %st(1)
+; X86-X87-NEXT:    fucom %st(1)
+; X86-X87-NEXT:    fstp %st(1)
+; X86-X87-NEXT:    fnstsw %ax
+; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X86-X87-NEXT:    sahf
+; X86-X87-NEXT:    movl $61440, %ecx # imm = 0xF000
+; X86-X87-NEXT:    jb .LBB2_2
+; X86-X87-NEXT:  # %bb.1:
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; X86-X87-NEXT:  .LBB2_2:
+; X86-X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-X87-NEXT:    fxch %st(1)
+; X86-X87-NEXT:    fucom %st(1)
+; X86-X87-NEXT:    fstp %st(1)
+; X86-X87-NEXT:    fnstsw %ax
+; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X86-X87-NEXT:    sahf
+; X86-X87-NEXT:    movl $4095, %edx # imm = 0xFFF
+; X86-X87-NEXT:    ja .LBB2_4
+; X86-X87-NEXT:  # %bb.3:
+; X86-X87-NEXT:    movl %ecx, %edx
+; X86-X87-NEXT:  .LBB2_4:
+; X86-X87-NEXT:    fucomp %st(0)
+; X86-X87-NEXT:    fnstsw %ax
+; X86-X87-NEXT:    xorl %ecx, %ecx
+; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X86-X87-NEXT:    sahf
+; X86-X87-NEXT:    jp .LBB2_6
+; X86-X87-NEXT:  # %bb.5:
+; X86-X87-NEXT:    movl %edx, %ecx
+; X86-X87-NEXT:  .LBB2_6:
+; X86-X87-NEXT:    movl %ecx, %eax
+; X86-X87-NEXT:    addl $12, %esp
+; X86-X87-NEXT:    retl
+;
+; X86-SSE-LABEL: test_signed_i13_f16:
+; X86-SSE:       # %bb.0:
+; X86-SSE-NEXT:    subl $12, %esp
+; X86-SSE-NEXT:    pinsrw $0, {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    pextrw $0, %xmm0, %eax
+; X86-SSE-NEXT:    movw %ax, (%esp)
+; X86-SSE-NEXT:    calll __extendhfsf2
+; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    xorl %eax, %eax
+; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
+; X86-SSE-NEXT:    maxss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
+; X86-SSE-NEXT:    minss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
+; X86-SSE-NEXT:    cvttss2si %xmm0, %ecx
+; X86-SSE-NEXT:    cmovnpl %ecx, %eax
+; X86-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
+; X86-SSE-NEXT:    addl $12, %esp
+; X86-SSE-NEXT:    retl
+;
+; X64-LABEL: test_signed_i13_f16:
+; X64:       # %bb.0:
+; X64-NEXT:    pushq %rax
+; X64-NEXT:    callq __extendhfsf2 at PLT
+; X64-NEXT:    xorl %eax, %eax
+; X64-NEXT:    ucomiss %xmm0, %xmm0
+; X64-NEXT:    maxss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT:    minss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %ecx
+; X64-NEXT:    cmovnpl %ecx, %eax
+; X64-NEXT:    # kill: def $ax killed $ax killed $eax
+; X64-NEXT:    popq %rcx
+; X64-NEXT:    retq
+;
+; X64-AVX512FP16-LABEL: test_signed_i13_f16:
+; X64-AVX512FP16:       # %bb.0:
+; X64-AVX512FP16-NEXT:    vcvttsh2si %xmm0, %eax
+; X64-AVX512FP16-NEXT:    vmovsh {{.*#+}} xmm1 = [-4.096E+3,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0]
+; X64-AVX512FP16-NEXT:    vucomish %xmm0, %xmm1
+; X64-AVX512FP16-NEXT:    movl $61440, %ecx # imm = 0xF000
+; X64-AVX512FP16-NEXT:    cmovbel %eax, %ecx
+; X64-AVX512FP16-NEXT:    vucomish {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-AVX512FP16-NEXT:    movl $4095, %eax # imm = 0xFFF
+; X64-AVX512FP16-NEXT:    cmovbel %ecx, %eax
+; X64-AVX512FP16-NEXT:    # kill: def $ax killed $ax killed $eax
+; X64-AVX512FP16-NEXT:    retq
+    %x = call i13 @llvm.fptosi.sat.i13.f16(half %f)
+    ret i13 %x
+}
+
+; FIXME: Can be optimizated with maxss + minss
+define i16 @test_signed_i16_f16(half %f) nounwind {
+; X86-X87-LABEL: test_signed_i16_f16:
+; X86-X87:       # %bb.0:
+; X86-X87-NEXT:    subl $12, %esp
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X86-X87-NEXT:    movl %eax, (%esp)
+; X86-X87-NEXT:    calll __extendhfsf2
+; X86-X87-NEXT:    fnstcw {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X86-X87-NEXT:    orl $3072, %eax # imm = 0xC00
+; X86-X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fists {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-X87-NEXT:    fxch %st(1)
+; X86-X87-NEXT:    fucom %st(1)
+; X86-X87-NEXT:    fstp %st(1)
+; X86-X87-NEXT:    fnstsw %ax
+; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X86-X87-NEXT:    sahf
+; X86-X87-NEXT:    movl $32768, %ecx # imm = 0x8000
+; X86-X87-NEXT:    jb .LBB3_2
+; X86-X87-NEXT:  # %bb.1:
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; X86-X87-NEXT:  .LBB3_2:
+; X86-X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-X87-NEXT:    fxch %st(1)
+; X86-X87-NEXT:    fucom %st(1)
+; X86-X87-NEXT:    fstp %st(1)
+; X86-X87-NEXT:    fnstsw %ax
+; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X86-X87-NEXT:    sahf
+; X86-X87-NEXT:    movl $32767, %edx # imm = 0x7FFF
+; X86-X87-NEXT:    ja .LBB3_4
+; X86-X87-NEXT:  # %bb.3:
+; X86-X87-NEXT:    movl %ecx, %edx
+; X86-X87-NEXT:  .LBB3_4:
+; X86-X87-NEXT:    fucomp %st(0)
+; X86-X87-NEXT:    fnstsw %ax
+; X86-X87-NEXT:    xorl %ecx, %ecx
+; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X86-X87-NEXT:    sahf
+; X86-X87-NEXT:    jp .LBB3_6
+; X86-X87-NEXT:  # %bb.5:
+; X86-X87-NEXT:    movl %edx, %ecx
+; X86-X87-NEXT:  .LBB3_6:
+; X86-X87-NEXT:    movl %ecx, %eax
+; X86-X87-NEXT:    addl $12, %esp
+; X86-X87-NEXT:    retl
+;
+; X86-SSE-LABEL: test_signed_i16_f16:
+; X86-SSE:       # %bb.0:
+; X86-SSE-NEXT:    subl $12, %esp
+; X86-SSE-NEXT:    pinsrw $0, {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    pextrw $0, %xmm0, %eax
+; X86-SSE-NEXT:    movw %ax, (%esp)
+; X86-SSE-NEXT:    calll __extendhfsf2
+; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    xorl %eax, %eax
+; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
+; X86-SSE-NEXT:    maxss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
+; X86-SSE-NEXT:    minss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
+; X86-SSE-NEXT:    cvttss2si %xmm0, %ecx
+; X86-SSE-NEXT:    cmovnpl %ecx, %eax
+; X86-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
+; X86-SSE-NEXT:    addl $12, %esp
+; X86-SSE-NEXT:    retl
+;
+; X64-LABEL: test_signed_i16_f16:
+; X64:       # %bb.0:
+; X64-NEXT:    pushq %rax
+; X64-NEXT:    callq __extendhfsf2 at PLT
+; X64-NEXT:    xorl %eax, %eax
+; X64-NEXT:    ucomiss %xmm0, %xmm0
+; X64-NEXT:    maxss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT:    minss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %ecx
+; X64-NEXT:    cmovnpl %ecx, %eax
+; X64-NEXT:    # kill: def $ax killed $ax killed $eax
+; X64-NEXT:    popq %rcx
+; X64-NEXT:    retq
+;
+; X64-AVX512FP16-LABEL: test_signed_i16_f16:
+; X64-AVX512FP16:       # %bb.0:
+; X64-AVX512FP16-NEXT:    vcvttsh2si %xmm0, %eax
+; X64-AVX512FP16-NEXT:    vmovsh {{.*#+}} xmm1 = [-3.2768E+4,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0,0.0E+0]
+; X64-AVX512FP16-NEXT:    vucomish %xmm0, %xmm1
+; X64-AVX512FP16-NEXT:    movl $32768, %ecx # imm = 0x8000
+; X64-AVX512FP16-NEXT:    cmovbel %eax, %ecx
+; X64-AVX512FP16-NEXT:    vucomish {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-AVX512FP16-NEXT:    movl $32767, %eax # imm = 0x7FFF
+; X64-AVX512FP16-NEXT:    cmovbel %ecx, %eax
+; X64-AVX512FP16-NEXT:    # kill: def $ax killed $ax killed $eax
+; X64-AVX512FP16-NEXT:    retq
+    %x = call i16 @llvm.fptosi.sat.i16.f16(half %f)
+    ret i16 %x
+}
+
+; FIXME: Can be optimizated with maxss + minss
+define i19 @test_signed_i19_f16(half %f) nounwind {
+; X86-X87-LABEL: test_signed_i19_f16:
+; X86-X87:       # %bb.0:
+; X86-X87-NEXT:    subl $12, %esp
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X86-X87-NEXT:    movl %eax, (%esp)
+; X86-X87-NEXT:    calll __extendhfsf2
+; X86-X87-NEXT:    fnstcw {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X86-X87-NEXT:    orl $3072, %eax # imm = 0xC00
+; X86-X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fistl {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-X87-NEXT:    fxch %st(1)
+; X86-X87-NEXT:    fucom %st(1)
+; X86-X87-NEXT:    fstp %st(1)
+; X86-X87-NEXT:    fnstsw %ax
+; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X86-X87-NEXT:    sahf
+; X86-X87-NEXT:    movl $-262144, %ecx # imm = 0xFFFC0000
+; X86-X87-NEXT:    jb .LBB4_2
+; X86-X87-NEXT:  # %bb.1:
+; X86-X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-X87-NEXT:  .LBB4_2:
+; X86-X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-X87-NEXT:    fxch %st(1)
+; X86-X87-NEXT:    fucom %st(1)
+; X86-X87-NEXT:    fstp %st(1)
+; X86-X87-NEXT:    fnstsw %ax
+; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X86-X87-NEXT:    sahf
+; X86-X87-NEXT:    movl $262143, %edx # imm = 0x3FFFF
+; X86-X87-NEXT:    ja .LBB4_4
+; X86-X87-NEXT:  # %bb.3:
+; X86-X87-NEXT:    movl %ecx, %edx
+; X86-X87-NEXT:  .LBB4_4:
+; X86-X87-NEXT:    fucomp %st(0)
+; X86-X87-NEXT:    fnstsw %ax
+; X86-X87-NEXT:    xorl %ecx, %ecx
+; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X86-X87-NEXT:    sahf
+; X86-X87-NEXT:    jp .LBB4_6
+; X86-X87-NEXT:  # %bb.5:
+; X86-X87-NEXT:    movl %edx, %ecx
+; X86-X87-NEXT:  .LBB4_6:
+; X86-X87-NEXT:    movl %ecx, %eax
+; X86-X87-NEXT:    addl $12, %esp
+; X86-X87-NEXT:    retl
+;
+; X86-SSE-LABEL: test_signed_i19_f16:
+; X86-SSE:       # %bb.0:
+; X86-SSE-NEXT:    subl $12, %esp
+; X86-SSE-NEXT:    pinsrw $0, {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    pextrw $0, %xmm0, %eax
+; X86-SSE-NEXT:    movw %ax, (%esp)
+; X86-SSE-NEXT:    calll __extendhfsf2
+; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    xorl %eax, %eax
+; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
+; X86-SSE-NEXT:    maxss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
+; X86-SSE-NEXT:    minss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
+; X86-SSE-NEXT:    cvttss2si %xmm0, %ecx
+; X86-SSE-NEXT:    cmovnpl %ecx, %eax
+; X86-SSE-NEXT:    addl $12, %esp
+; X86-SSE-NEXT:    retl
+;
+; X64-LABEL: test_signed_i19_f16:
+; X64:       # %bb.0:
+; X64-NEXT:    pushq %rax
+; X64-NEXT:    callq __extendhfsf2 at PLT
+; X64-NEXT:    xorl %eax, %eax
+; X64-NEXT:    ucomiss %xmm0, %xmm0
+; X64-NEXT:    maxss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; X64-NEXT: ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/215049


More information about the llvm-branch-commits mailing list