[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