[llvm] [X86][SSE] Improve ISD::FP_TO_*INT_SAT vector lowering (PR #199416)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 5 00:08:09 PDT 2026


https://github.com/Panadulek updated https://github.com/llvm/llvm-project/pull/199416

>From 7574914e79364f1954f8253e1557d82fa1c749e3 Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Sun, 24 May 2026 03:20:27 +0200
Subject: [PATCH 01/18] Fix #51923

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index dfda1157a720e..720697ef512a1 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -319,6 +319,8 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
       setOperationAction(ISD::FP_TO_UINT_SAT, MVT::i64, Custom);
       setOperationAction(ISD::FP_TO_SINT_SAT, MVT::i64, Custom);
     }
+    setOperationAction(ISD::FP_TO_UINT_SAT, MVT::v4i32, Custom);
+    setOperationAction(ISD::FP_TO_SINT_SAT, MVT::v4i32, Custom);
   }
   if (Subtarget.hasAVX10_2()) {
     for (MVT VT : {MVT::v8i8, MVT::v16i8, MVT::v32i8}) {
@@ -22433,7 +22435,22 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
                               dl, VecI16VT, Src);
     return DAG.getNode(ISD::TRUNCATE, dl, DstVT, Res);
   }
+  else if(DstVT == MVT::v4i32 && Subtarget.hasSSE2())
+  {
+    const bool isSigned = Op.getOpcode() == ISD::FP_TO_SINT_SAT;
+    SDValue src = Op.getOperand(0);
+    EVT SrcVT = Src.getValueType();
+    SDLoc dl(Op);
+    double MaxVal = IsSigned ? 2147483520.0 : 4294967040.0;
+    double MinVal = IsSigned ? -2147483648.0 : 0.0;
+    SDValue MaxC = DAG.getConstantFP(MaxVal, dl, SrcVT);
+    SDValue MinC = DAG.getConstantFP(MinVal, dl, SrcVT);
 
+    SDValue ClampedBottom = DAG.getNode(X86ISD::FMAX, dl, SrcVT, Src, MinC);
+    SDValue ClampedTop = DAG.getNode(X86ISD::FMIN, dl, SrcVT, ClampedBottom, MaxC);
+    unsigned CastOpc = IsSigned ? ISD::FP_TO_SINT : ISD::FP_TO_UINT;
+    return DAG.getNode(CastOpc, dl, DstVT, ClampedTop);
+  }
   // This code is only for floats and doubles. Fall back to generic code for
   // anything else.
   if (!isScalarFPTypeInSSEReg(SrcVT) || isBF16orSoftF16(SrcVT, Subtarget))

>From ec2f80c040b91e7917e9ea8b376372633308d393 Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Sun, 24 May 2026 03:49:34 +0200
Subject: [PATCH 02/18] code clean

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 29 ++++++++++++++-----------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 720697ef512a1..66664f113ad14 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22434,22 +22434,25 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
     SDValue Res = DAG.getNode(IsSigned ? X86ISD::CVTTP2IBS : X86ISD::CVTTP2IUBS,
                               dl, VecI16VT, Src);
     return DAG.getNode(ISD::TRUNCATE, dl, DstVT, Res);
-  }
-  else if(DstVT == MVT::v4i32 && Subtarget.hasSSE2())
-  {
-    const bool isSigned = Op.getOpcode() == ISD::FP_TO_SINT_SAT;
-    SDValue src = Op.getOperand(0);
-    EVT SrcVT = Src.getValueType();
-    SDLoc dl(Op);
-    double MaxVal = IsSigned ? 2147483520.0 : 4294967040.0;
-    double MinVal = IsSigned ? -2147483648.0 : 0.0;
-    SDValue MaxC = DAG.getConstantFP(MaxVal, dl, SrcVT);
-    SDValue MinC = DAG.getConstantFP(MinVal, dl, SrcVT);
+  } else if (DstVT == MVT::v4i32 && Subtarget.hasSSE2()) {
+    unsigned SatWidth = SatVT.getScalarSizeInBits();
+    APInt MinInt = IsSigned ? APInt::getSignedMinValue(SatWidth)
+                            : APInt::getMinValue(SatWidth);
+    APInt MaxInt = IsSigned ? APInt::getSignedMaxValue(SatWidth)
+                            : APInt::getMaxValue(SatWidth);
+
+    const fltSemantics &Sem = SrcVT.getFltSemantics();
+    APFloat MinFloat(Sem);
+    MinFloat.convertFromAPInt(MinInt, IsSigned, APFloat::rmTowardZero);
+    APFloat MaxFloat(Sem);
+    MaxFloat.convertFromAPInt(MaxInt, IsSigned, APFloat::rmTowardZero);
+
+    SDValue MaxC = DAG.getConstantFP(MaxFloat, dl, SrcVT);
+    SDValue MinC = DAG.getConstantFP(MinFloat, dl, SrcVT);
 
     SDValue ClampedBottom = DAG.getNode(X86ISD::FMAX, dl, SrcVT, Src, MinC);
     SDValue ClampedTop = DAG.getNode(X86ISD::FMIN, dl, SrcVT, ClampedBottom, MaxC);
-    unsigned CastOpc = IsSigned ? ISD::FP_TO_SINT : ISD::FP_TO_UINT;
-    return DAG.getNode(CastOpc, dl, DstVT, ClampedTop);
+    return DAG.getNode(FpToIntOpcode, dl, DstVT, ClampedTop);
   }
   // This code is only for floats and doubles. Fall back to generic code for
   // anything else.

>From 3ca136d3cbc98c5cc853696713db9bb39d92714d Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Sun, 24 May 2026 05:11:07 +0200
Subject: [PATCH 03/18] [X86] Optimize vector FP_TO_INT_SAT lowering for v4i32
 on SSE2.

    This replaces the costly scalarization fallback with precise vectorized boundary clamping and native
   conversions.
---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  66 +-
 .../CodeGen/X86/fp-to-int-sat-vector-sse2.ll  | 113 ++++
 llvm/test/CodeGen/X86/fpclamptosat_vec.ll     | 630 +++++++-----------
 3 files changed, 402 insertions(+), 407 deletions(-)
 create mode 100644 llvm/test/CodeGen/X86/fp-to-int-sat-vector-sse2.ll

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 66664f113ad14..495f58f3bc004 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22436,6 +22436,45 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
     return DAG.getNode(ISD::TRUNCATE, dl, DstVT, Res);
   } else if (DstVT == MVT::v4i32 && Subtarget.hasSSE2()) {
     unsigned SatWidth = SatVT.getScalarSizeInBits();
+    assert(SatWidth <= 32 && "Expected saturation width no wider than result element");
+
+    if (SatWidth == 32) {
+      if (IsSigned) {
+        // Direct conversion handles in-range and negative overflow correctly.
+        SDValue Cvt = DAG.getNode(ISD::FP_TO_SINT, dl, DstVT, Src);
+
+        // Detect positive overflow (src >= 2^31) and saturate to INT_MAX.
+        APFloat PosOvfBoundFlt(SrcVT.getScalarType().getFltSemantics());
+        PosOvfBoundFlt.convertFromAPInt(APInt::getSignedMinValue(32), /*IsSigned=*/true, APFloat::rmTowardZero);
+        PosOvfBoundFlt.changeSign(); // Flips -2^31 to +2^31
+        SDValue PosOvfBound = DAG.getConstantFP(PosOvfBoundFlt, dl, SrcVT);
+        SDValue PosOvf = DAG.getSetCC(dl, DstVT, Src, PosOvfBound, ISD::SETOGE);
+        SDValue IntMax = DAG.getConstant(APInt::getSignedMaxValue(32), dl, DstVT);
+        SDValue Fixed = DAG.getSelect(dl, DstVT, PosOvf, IntMax, Cvt);
+
+        // Detect NaN and map to 0.
+        SDValue IsNaN = DAG.getSetCC(dl, DstVT, Src, Src, ISD::SETUO);
+        SDValue Zero = DAG.getConstant(0, dl, DstVT);
+        return DAG.getSelect(dl, DstVT, IsNaN, Zero, Fixed);
+      } else {
+        // Clamp negative values and NaN to 0. FMAX maps NaN to 0.0.
+        SDValue ZeroFP = DAG.getConstantFP(0.0, dl, SrcVT);
+        SDValue Clamped = DAG.getNode(X86ISD::FMAX, dl, SrcVT, Src, ZeroFP);
+
+        // Detect overflow (src >= 2^32) to saturate to UINT_MAX.
+        APFloat OvfBoundFlt(SrcVT.getScalarType().getFltSemantics());
+        OvfBoundFlt.convertFromAPInt(APInt::getOneBitSet(33, 32), /*IsSigned=*/false, APFloat::rmTowardZero);
+        SDValue OvfBound = DAG.getConstantFP(OvfBoundFlt, dl, SrcVT);
+        SDValue IsOvf = DAG.getSetCC(dl, DstVT, Clamped, OvfBound, ISD::SETOGE);
+
+        SDValue Cvt = DAG.getNode(ISD::FP_TO_UINT, dl, DstVT, Clamped);
+        SDValue UintMax = DAG.getConstant(APInt::getMaxValue(32), dl, DstVT);
+
+        // Apply saturation for overflow.
+        return DAG.getSelect(dl, DstVT, IsOvf, UintMax, Cvt);
+      }
+    }
+
     APInt MinInt = IsSigned ? APInt::getSignedMinValue(SatWidth)
                             : APInt::getMinValue(SatWidth);
     APInt MaxInt = IsSigned ? APInt::getSignedMaxValue(SatWidth)
@@ -22443,16 +22482,37 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
 
     const fltSemantics &Sem = SrcVT.getFltSemantics();
     APFloat MinFloat(Sem);
-    MinFloat.convertFromAPInt(MinInt, IsSigned, APFloat::rmTowardZero);
     APFloat MaxFloat(Sem);
-    MaxFloat.convertFromAPInt(MaxInt, IsSigned, APFloat::rmTowardZero);
+    // Only use the FMAX/FMIN clamp path when both bounds are exactly
+    // representable in the source float type. If either is inexact, fall back
+    // to generic lowering.
+    bool AreExactFloatBounds =
+        !(MinFloat.convertFromAPInt(MinInt, IsSigned, APFloat::rmTowardZero) &
+          APFloat::opInexact) &&
+        !(MaxFloat.convertFromAPInt(MaxInt, IsSigned, APFloat::rmTowardZero) &
+          APFloat::opInexact);
+    if (!AreExactFloatBounds)
+      return SDValue();
 
     SDValue MaxC = DAG.getConstantFP(MaxFloat, dl, SrcVT);
     SDValue MinC = DAG.getConstantFP(MinFloat, dl, SrcVT);
 
+    // Clamp from below. X86ISD::FMAX returns the second operand when either
+    // input is NaN, so NaN maps to MinC here.
     SDValue ClampedBottom = DAG.getNode(X86ISD::FMAX, dl, SrcVT, Src, MinC);
+    // Clamp from above. NaN (now MinC) is already in range and passes through.
     SDValue ClampedTop = DAG.getNode(X86ISD::FMIN, dl, SrcVT, ClampedBottom, MaxC);
-    return DAG.getNode(FpToIntOpcode, dl, DstVT, ClampedTop);
+    SDValue Result = DAG.getNode(FpToIntOpcode, dl, DstVT, ClampedTop);
+
+    // For signed saturation, NaN was mapped to MinC, so FP_TO_SINT produces
+    // INT_MIN. ISD::FP_TO_SINT_SAT requires NaN -> 0; fix with a zero-select.
+    // For unsigned saturation, MinC == 0.0, so NaN -> 0.0 -> 0: already correct.
+    if (IsSigned) {
+      SDValue Zero = DAG.getConstant(0, dl, DstVT);
+      SDValue IsNaN = DAG.getSetCC(dl, DstVT, Src, Src, ISD::SETUO);
+      return DAG.getSelect(dl, DstVT, IsNaN, Zero, Result);
+    }
+    return Result;
   }
   // This code is only for floats and doubles. Fall back to generic code for
   // anything else.
diff --git a/llvm/test/CodeGen/X86/fp-to-int-sat-vector-sse2.ll b/llvm/test/CodeGen/X86/fp-to-int-sat-vector-sse2.ll
new file mode 100644
index 0000000000000..b9ae1157f991f
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fp-to-int-sat-vector-sse2.ll
@@ -0,0 +1,113 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64 -mattr=+sse2,-avx | FileCheck %s --check-prefix=SSE2
+
+declare <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float>)
+declare <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float>)
+
+; 1. Base case variables
+define <4 x i32> @test_signed_var(<4 x float> %f) {
+; SSE2-LABEL: test_signed_var:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
+; SSE2-NEXT:    cmpleps %xmm0, %xmm1
+; SSE2-NEXT:    cvttps2dq %xmm0, %xmm2
+; SSE2-NEXT:    movaps %xmm1, %xmm3
+; SSE2-NEXT:    andnps %xmm2, %xmm3
+; SSE2-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE2-NEXT:    orps %xmm3, %xmm1
+; SSE2-NEXT:    cmpunordps %xmm0, %xmm0
+; SSE2-NEXT:    andnps %xmm1, %xmm0
+; SSE2-NEXT:    retq
+  %x = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> %f)
+  ret <4 x i32> %x
+}
+
+define <4 x i32> @test_unsigned_var(<4 x float> %f) {
+; SSE2-LABEL: test_unsigned_var:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    xorps %xmm1, %xmm1
+; SSE2-NEXT:    maxps %xmm1, %xmm0
+; SSE2-NEXT:    cvttps2dq %xmm0, %xmm2
+; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
+; SSE2-NEXT:    cmpleps %xmm0, %xmm1
+; SSE2-NEXT:    orps %xmm2, %xmm1
+; SSE2-NEXT:    psrad $31, %xmm2
+; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE2-NEXT:    cvttps2dq %xmm0, %xmm0
+; SSE2-NEXT:    pand %xmm2, %xmm0
+; SSE2-NEXT:    orps %xmm0, %xmm1
+; SSE2-NEXT:    movaps %xmm1, %xmm0
+; SSE2-NEXT:    retq
+  %x = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> %f)
+  ret <4 x i32> %x
+}
+
+; 2. Signed edge cases
+define <4 x i32> @test_signed_edge1() {
+  ; NaN, +Inf, -Inf, 0.0
+; SSE2-LABEL: test_signed_edge1:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    cvttps2dq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE2-NEXT:    movaps {{.*#+}} xmm0 = [u,u,NaN,u]
+; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[2,3]
+; SSE2-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE2-NEXT:    retq
+  %x = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> <float 0x7FF8000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000, float 0.0>)
+  ret <4 x i32> %x
+}
+
+define <4 x i32> @test_signed_edge2() {
+  ; exact limits and slight overflow
+  ; 2^31, < -2^31, max f32 < 2^31, -2^31
+; SSE2-LABEL: test_signed_edge2:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [2147483647,2147483647,2147483647,2147483647]
+; SSE2-NEXT:    cvttps2dq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE2-NEXT:    movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]
+; SSE2-NEXT:    retq
+  %x = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> <float 2147483648.0, float -2147483904.0, float 2147483520.0, float -2147483648.0>)
+  ret <4 x i32> %x
+}
+
+; 3. Unsigned edge cases
+define <4 x i32> @test_unsigned_edge1() {
+  ; NaN, -1.0, +Inf, 0.0
+; SSE2-LABEL: test_unsigned_edge1:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    xorps %xmm0, %xmm0
+; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [NaN,-1.0E+0,+Inf,0.0E+0]
+; SSE2-NEXT:    maxps %xmm0, %xmm1
+; SSE2-NEXT:    cvttps2dq %xmm1, %xmm2
+; SSE2-NEXT:    movaps {{.*#+}} xmm0 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
+; SSE2-NEXT:    cmpleps %xmm1, %xmm0
+; SSE2-NEXT:    orps %xmm2, %xmm0
+; SSE2-NEXT:    psrad $31, %xmm2
+; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE2-NEXT:    cvttps2dq %xmm1, %xmm1
+; SSE2-NEXT:    pand %xmm2, %xmm1
+; SSE2-NEXT:    orps %xmm1, %xmm0
+; SSE2-NEXT:    retq
+  %x = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> <float 0x7FF8000000000000, float -1.0, float 0x7FF0000000000000, float 0.0>)
+  ret <4 x i32> %x
+}
+
+define <4 x i32> @test_unsigned_edge2() {
+  ; slight below zero, > 2^32, max f32 < 2^32, 2^32 exact
+; SSE2-LABEL: test_unsigned_edge2:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    xorps %xmm0, %xmm0
+; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [-5.0E-1,4.2949673E+9,4.29496704E+9,4.2949673E+9]
+; SSE2-NEXT:    maxps %xmm0, %xmm1
+; SSE2-NEXT:    cvttps2dq %xmm1, %xmm2
+; SSE2-NEXT:    movaps {{.*#+}} xmm0 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
+; SSE2-NEXT:    cmpleps %xmm1, %xmm0
+; SSE2-NEXT:    orps %xmm2, %xmm0
+; SSE2-NEXT:    psrad $31, %xmm2
+; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE2-NEXT:    cvttps2dq %xmm1, %xmm1
+; SSE2-NEXT:    pand %xmm2, %xmm1
+; SSE2-NEXT:    orps %xmm1, %xmm0
+; SSE2-NEXT:    retq
+  %x = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> <float -0.5, float 4294967296.0, float 4294967040.0, float 4294967296.0>)
+  ret <4 x i32> %x
+}
diff --git a/llvm/test/CodeGen/X86/fpclamptosat_vec.ll b/llvm/test/CodeGen/X86/fpclamptosat_vec.ll
index 991ce33e58b4c..f8d7eece7c70c 100644
--- a/llvm/test/CodeGen/X86/fpclamptosat_vec.ll
+++ b/llvm/test/CodeGen/X86/fpclamptosat_vec.ll
@@ -227,106 +227,26 @@ entry:
 define <4 x i32> @stest_f32i32(<4 x float> %x) nounwind {
 ; SSE-LABEL: stest_f32i32:
 ; SSE:       # %bb.0: # %entry
-; SSE-NEXT:    movaps %xmm0, %xmm1
-; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[3,3],xmm0[3,3]
-; SSE-NEXT:    cvttss2si %xmm1, %rax
-; SSE-NEXT:    movq %rax, %xmm1
-; SSE-NEXT:    movaps %xmm0, %xmm2
-; SSE-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1],xmm0[1]
-; SSE-NEXT:    cvttss2si %xmm2, %rax
-; SSE-NEXT:    movq %rax, %xmm2
-; SSE-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm1[0]
-; SSE-NEXT:    cvttss2si %xmm0, %rax
-; SSE-NEXT:    movq %rax, %xmm4
-; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE-NEXT:    cvttss2si %xmm0, %rax
-; SSE-NEXT:    movq %rax, %xmm0
-; SSE-NEXT:    punpcklqdq {{.*#+}} xmm4 = xmm4[0],xmm0[0]
-; SSE-NEXT:    movdqa {{.*#+}} xmm3 = [2147483647,2147483647]
-; SSE-NEXT:    movdqa {{.*#+}} xmm0 = [2147483648,2147483648]
-; SSE-NEXT:    movdqa %xmm4, %xmm1
-; SSE-NEXT:    pxor %xmm0, %xmm1
-; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm1[1,1,3,3]
-; SSE-NEXT:    pxor %xmm6, %xmm6
-; SSE-NEXT:    pcmpeqd %xmm6, %xmm5
-; SSE-NEXT:    movdqa {{.*#+}} xmm7 = [4294967295,4294967295]
-; SSE-NEXT:    movdqa %xmm7, %xmm8
-; SSE-NEXT:    pcmpgtd %xmm1, %xmm8
-; SSE-NEXT:    pshufd {{.*#+}} xmm9 = xmm8[0,0,2,2]
-; SSE-NEXT:    pand %xmm5, %xmm9
-; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm8[1,1,3,3]
-; SSE-NEXT:    por %xmm9, %xmm1
-; SSE-NEXT:    pand %xmm1, %xmm4
-; SSE-NEXT:    pandn %xmm3, %xmm1
-; SSE-NEXT:    por %xmm4, %xmm1
-; SSE-NEXT:    movdqa %xmm2, %xmm4
-; SSE-NEXT:    pxor %xmm0, %xmm4
-; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm4[1,1,3,3]
-; SSE-NEXT:    pcmpeqd %xmm6, %xmm5
-; SSE-NEXT:    pcmpgtd %xmm4, %xmm7
-; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm7[0,0,2,2]
-; SSE-NEXT:    pand %xmm5, %xmm4
-; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm7[1,1,3,3]
-; SSE-NEXT:    por %xmm4, %xmm5
-; SSE-NEXT:    pand %xmm5, %xmm2
-; SSE-NEXT:    pandn %xmm3, %xmm5
-; SSE-NEXT:    por %xmm2, %xmm5
-; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [18446744071562067968,18446744071562067968]
-; SSE-NEXT:    movdqa %xmm5, %xmm3
-; SSE-NEXT:    pxor %xmm0, %xmm3
-; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm3[1,1,3,3]
-; SSE-NEXT:    pcmpeqd %xmm6, %xmm6
-; SSE-NEXT:    pcmpeqd %xmm6, %xmm4
-; SSE-NEXT:    movdqa {{.*#+}} xmm7 = [18446744069414584320,18446744069414584320]
-; SSE-NEXT:    pcmpgtd %xmm7, %xmm3
-; SSE-NEXT:    pshufd {{.*#+}} xmm8 = xmm3[0,0,2,2]
-; SSE-NEXT:    pand %xmm4, %xmm8
-; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,3,3]
-; SSE-NEXT:    por %xmm8, %xmm3
-; SSE-NEXT:    pand %xmm3, %xmm5
-; SSE-NEXT:    pandn %xmm2, %xmm3
-; SSE-NEXT:    por %xmm5, %xmm3
-; SSE-NEXT:    pxor %xmm1, %xmm0
-; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm0[1,1,3,3]
-; SSE-NEXT:    pcmpeqd %xmm6, %xmm4
-; SSE-NEXT:    pcmpgtd %xmm7, %xmm0
-; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm0[0,0,2,2]
-; SSE-NEXT:    pand %xmm4, %xmm5
-; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
-; SSE-NEXT:    por %xmm5, %xmm0
-; SSE-NEXT:    pand %xmm0, %xmm1
-; SSE-NEXT:    pandn %xmm2, %xmm0
-; SSE-NEXT:    por %xmm1, %xmm0
-; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm3[0,2]
+; SSE-NEXT:    movaps {{.*#+}} xmm1 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
+; SSE-NEXT:    cmpleps %xmm0, %xmm1
+; SSE-NEXT:    cvttps2dq %xmm0, %xmm2
+; SSE-NEXT:    movaps %xmm1, %xmm3
+; SSE-NEXT:    andnps %xmm2, %xmm3
+; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE-NEXT:    orps %xmm3, %xmm1
+; SSE-NEXT:    cmpunordps %xmm0, %xmm0
+; SSE-NEXT:    andnps %xmm1, %xmm0
 ; SSE-NEXT:    retq
 ;
 ; AVX2-LABEL: stest_f32i32:
 ; AVX2:       # %bb.0: # %entry
-; AVX2-NEXT:    vshufps {{.*#+}} xmm1 = xmm0[3,3,3,3]
-; AVX2-NEXT:    vcvttss2si %xmm1, %rax
-; AVX2-NEXT:    vmovq %rax, %xmm1
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm2 = xmm0[1,0]
-; AVX2-NEXT:    vcvttss2si %xmm2, %rax
-; AVX2-NEXT:    vmovq %rax, %xmm2
-; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
-; AVX2-NEXT:    vcvttss2si %xmm0, %rax
-; AVX2-NEXT:    vmovq %rax, %xmm2
-; AVX2-NEXT:    vmovshdup {{.*#+}} xmm0 = xmm0[1,1,3,3]
-; AVX2-NEXT:    vcvttss2si %xmm0, %rax
-; AVX2-NEXT:    vmovq %rax, %xmm0
-; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm2[0],xmm0[0]
-; AVX2-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
-; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm1 = [2147483647,2147483647,2147483647,2147483647]
-; AVX2-NEXT:    vpcmpgtq %ymm0, %ymm1, %ymm2
-; AVX2-NEXT:    vblendvpd %ymm2, %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm1 = [18446744071562067968,18446744071562067968,18446744071562067968,18446744071562067968]
-; AVX2-NEXT:    vpcmpgtq %ymm1, %ymm0, %ymm2
-; AVX2-NEXT:    vblendvpd %ymm2, %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vbroadcastf128 {{.*#+}} ymm1 = [0,2,4,6,0,2,4,6]
-; AVX2-NEXT:    # ymm1 = mem[0,1,0,1]
-; AVX2-NEXT:    vpermps %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
-; AVX2-NEXT:    vzeroupper
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm1 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
+; AVX2-NEXT:    vcmpleps %xmm0, %xmm1, %xmm1
+; AVX2-NEXT:    vcvttps2dq %xmm0, %xmm2
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm3 = [2147483647,2147483647,2147483647,2147483647]
+; AVX2-NEXT:    vblendvps %xmm1, %xmm3, %xmm2, %xmm1
+; AVX2-NEXT:    vcmpunordps %xmm0, %xmm0, %xmm0
+; AVX2-NEXT:    vandnps %xmm1, %xmm0, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: stest_f32i32:
@@ -604,130 +524,121 @@ entry:
 define <4 x i32> @stest_f16i32(<4 x half> %x) nounwind {
 ; SSE-LABEL: stest_f16i32:
 ; SSE:       # %bb.0: # %entry
-; SSE-NEXT:    subq $72, %rsp
-; SSE-NEXT:    movdqa %xmm0, (%rsp) # 16-byte Spill
+; SSE-NEXT:    pushq %rbp
+; SSE-NEXT:    pushq %r14
+; SSE-NEXT:    pushq %rbx
+; SSE-NEXT:    subq $64, %rsp
+; SSE-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; SSE-NEXT:    movdqa %xmm0, %xmm1
 ; SSE-NEXT:    psrld $16, %xmm1
 ; SSE-NEXT:    movdqa %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; SSE-NEXT:    movdqa %xmm0, %xmm1
 ; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[1,1],xmm0[1,1]
-; SSE-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; SSE-NEXT:    movaps %xmm1, (%rsp) # 16-byte Spill
 ; SSE-NEXT:    psrlq $48, %xmm0
 ; SSE-NEXT:    callq __extendhfsf2 at PLT
-; SSE-NEXT:    cvttss2si %xmm0, %rax
-; SSE-NEXT:    movq %rax, %xmm0
-; SSE-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE-NEXT:    callq __extendhfsf2 at PLT
-; SSE-NEXT:    cvttss2si %xmm0, %rax
-; SSE-NEXT:    movq %rax, %xmm0
-; SSE-NEXT:    punpcklqdq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload
-; SSE-NEXT:    # xmm0 = xmm0[0],mem[0]
+; SSE-NEXT:    cvttss2si %xmm0, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    movl $-2147483648, %ebx # imm = 0x80000000
+; SSE-NEXT:    cmovbl %ebx, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    movl $2147483647, %ebp # imm = 0x7FFFFFFF
+; SSE-NEXT:    cmoval %ebp, %eax
+; SSE-NEXT:    xorl %r14d, %r14d
+; SSE-NEXT:    ucomiss %xmm0, %xmm0
+; SSE-NEXT:    cmovpl %r14d, %eax
+; SSE-NEXT:    movd %eax, %xmm0
 ; SSE-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; SSE-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
 ; SSE-NEXT:    callq __extendhfsf2 at PLT
-; SSE-NEXT:    cvttss2si %xmm0, %rax
-; SSE-NEXT:    movq %rax, %xmm0
+; SSE-NEXT:    cvttss2si %xmm0, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    cmovbl %ebx, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    cmoval %ebp, %eax
+; SSE-NEXT:    ucomiss %xmm0, %xmm0
+; SSE-NEXT:    cmovpl %r14d, %eax
+; SSE-NEXT:    movd %eax, %xmm0
+; SSE-NEXT:    punpckldq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload
+; SSE-NEXT:    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
 ; SSE-NEXT:    movdqa %xmm0, (%rsp) # 16-byte Spill
 ; SSE-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; SSE-NEXT:    callq __extendhfsf2 at PLT
-; SSE-NEXT:    cvttss2si %xmm0, %rax
-; SSE-NEXT:    movq %rax, %xmm0
-; SSE-NEXT:    movdqa (%rsp), %xmm3 # 16-byte Reload
-; SSE-NEXT:    punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm0[0]
-; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [2147483647,2147483647]
-; SSE-NEXT:    movdqa {{.*#+}} xmm0 = [2147483648,2147483648]
-; SSE-NEXT:    movdqa %xmm3, %xmm1
-; SSE-NEXT:    movdqa %xmm3, %xmm8
-; SSE-NEXT:    pxor %xmm0, %xmm1
-; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm1[1,1,3,3]
-; SSE-NEXT:    pxor %xmm4, %xmm4
-; SSE-NEXT:    pcmpeqd %xmm4, %xmm3
-; SSE-NEXT:    movdqa {{.*#+}} xmm5 = [4294967295,4294967295]
-; SSE-NEXT:    movdqa %xmm5, %xmm6
-; SSE-NEXT:    pcmpgtd %xmm1, %xmm6
-; SSE-NEXT:    pshufd {{.*#+}} xmm7 = xmm6[0,0,2,2]
-; SSE-NEXT:    pand %xmm3, %xmm7
-; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm6[1,1,3,3]
-; SSE-NEXT:    por %xmm7, %xmm1
-; SSE-NEXT:    pand %xmm1, %xmm8
-; SSE-NEXT:    pandn %xmm2, %xmm1
-; SSE-NEXT:    por %xmm8, %xmm1
-; SSE-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
-; SSE-NEXT:    movdqa %xmm7, %xmm3
-; SSE-NEXT:    pxor %xmm0, %xmm3
-; SSE-NEXT:    pshufd {{.*#+}} xmm6 = xmm3[1,1,3,3]
-; SSE-NEXT:    pcmpeqd %xmm4, %xmm6
-; SSE-NEXT:    pcmpgtd %xmm3, %xmm5
-; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm5[0,0,2,2]
-; SSE-NEXT:    pand %xmm6, %xmm3
-; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm5[1,1,3,3]
-; SSE-NEXT:    por %xmm3, %xmm4
-; SSE-NEXT:    movdqa %xmm7, %xmm3
-; SSE-NEXT:    pand %xmm4, %xmm3
-; SSE-NEXT:    pandn %xmm2, %xmm4
-; SSE-NEXT:    por %xmm3, %xmm4
-; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [18446744071562067968,18446744071562067968]
-; SSE-NEXT:    movdqa %xmm4, %xmm3
-; SSE-NEXT:    pxor %xmm0, %xmm3
-; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm3[1,1,3,3]
-; SSE-NEXT:    pcmpeqd %xmm6, %xmm6
-; SSE-NEXT:    pcmpeqd %xmm6, %xmm5
-; SSE-NEXT:    movdqa {{.*#+}} xmm7 = [18446744069414584320,18446744069414584320]
-; SSE-NEXT:    pcmpgtd %xmm7, %xmm3
-; SSE-NEXT:    pshufd {{.*#+}} xmm8 = xmm3[0,0,2,2]
-; SSE-NEXT:    pand %xmm5, %xmm8
-; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,3,3]
-; SSE-NEXT:    por %xmm8, %xmm3
-; SSE-NEXT:    pand %xmm3, %xmm4
-; SSE-NEXT:    pandn %xmm2, %xmm3
-; SSE-NEXT:    por %xmm4, %xmm3
-; SSE-NEXT:    pxor %xmm1, %xmm0
-; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm0[1,1,3,3]
-; SSE-NEXT:    pcmpeqd %xmm6, %xmm4
-; SSE-NEXT:    pcmpgtd %xmm7, %xmm0
-; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm0[0,0,2,2]
-; SSE-NEXT:    pand %xmm4, %xmm5
-; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
-; SSE-NEXT:    por %xmm5, %xmm0
-; SSE-NEXT:    pand %xmm0, %xmm1
-; SSE-NEXT:    pandn %xmm2, %xmm0
-; SSE-NEXT:    por %xmm1, %xmm0
-; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm3[0,2]
-; SSE-NEXT:    addq $72, %rsp
+; SSE-NEXT:    cvttss2si %xmm0, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    cmovbl %ebx, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    cmoval %ebp, %eax
+; SSE-NEXT:    ucomiss %xmm0, %xmm0
+; SSE-NEXT:    cmovpl %r14d, %eax
+; SSE-NEXT:    movd %eax, %xmm0
+; SSE-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; SSE-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; SSE-NEXT:    callq __extendhfsf2 at PLT
+; SSE-NEXT:    cvttss2si %xmm0, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    cmovbl %ebx, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    cmoval %ebp, %eax
+; SSE-NEXT:    ucomiss %xmm0, %xmm0
+; SSE-NEXT:    cmovpl %r14d, %eax
+; SSE-NEXT:    movd %eax, %xmm1
+; SSE-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
+; SSE-NEXT:    punpcklqdq (%rsp), %xmm0 # 16-byte Folded Reload
+; SSE-NEXT:    # xmm0 = xmm0[0],mem[0]
+; SSE-NEXT:    addq $64, %rsp
+; SSE-NEXT:    popq %rbx
+; SSE-NEXT:    popq %r14
+; SSE-NEXT:    popq %rbp
 ; SSE-NEXT:    retq
 ;
 ; AVX2-LABEL: stest_f16i32:
 ; AVX2:       # %bb.0: # %entry
-; AVX2-NEXT:    vpsrlq $48, %xmm0, %xmm1
-; AVX2-NEXT:    vcvtph2ps %xmm1, %xmm1
-; AVX2-NEXT:    vcvttss2si %xmm1, %rax
-; AVX2-NEXT:    vmovshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; AVX2-NEXT:    vcvtph2ps %xmm1, %xmm1
-; AVX2-NEXT:    vcvttss2si %xmm1, %rcx
-; AVX2-NEXT:    vcvtph2ps %xmm0, %xmm1
-; AVX2-NEXT:    vmovq %rax, %xmm2
-; AVX2-NEXT:    vcvttss2si %xmm1, %rax
-; AVX2-NEXT:    vmovq %rcx, %xmm1
-; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
-; AVX2-NEXT:    vpsrld $16, %xmm0, %xmm0
+; AVX2-NEXT:    vpsrld $16, %xmm0, %xmm1
+; AVX2-NEXT:    vcvtph2ps %xmm1, %xmm3
+; AVX2-NEXT:    vcvttss2si %xmm3, %esi
+; AVX2-NEXT:    vmovss {{.*#+}} xmm1 = [-2.14748365E+9,0.0E+0,0.0E+0,0.0E+0]
+; AVX2-NEXT:    vucomiss %xmm1, %xmm3
+; AVX2-NEXT:    movl $-2147483648, %eax # imm = 0x80000000
+; AVX2-NEXT:    cmovbl %eax, %esi
+; AVX2-NEXT:    vmovss {{.*#+}} xmm2 = [2.14748352E+9,0.0E+0,0.0E+0,0.0E+0]
+; AVX2-NEXT:    vucomiss %xmm2, %xmm3
+; AVX2-NEXT:    movl $2147483647, %ecx # imm = 0x7FFFFFFF
+; AVX2-NEXT:    cmoval %ecx, %esi
+; AVX2-NEXT:    xorl %edx, %edx
+; AVX2-NEXT:    vucomiss %xmm3, %xmm3
+; AVX2-NEXT:    cmovpl %edx, %esi
+; AVX2-NEXT:    vcvtph2ps %xmm0, %xmm3
+; AVX2-NEXT:    vcvttss2si %xmm3, %edi
+; AVX2-NEXT:    vucomiss %xmm1, %xmm3
+; AVX2-NEXT:    cmovbl %eax, %edi
+; AVX2-NEXT:    vucomiss %xmm2, %xmm3
+; AVX2-NEXT:    cmoval %ecx, %edi
+; AVX2-NEXT:    vucomiss %xmm3, %xmm3
+; AVX2-NEXT:    cmovpl %edx, %edi
+; AVX2-NEXT:    vmovd %edi, %xmm3
+; AVX2-NEXT:    vpinsrd $1, %esi, %xmm3, %xmm3
+; AVX2-NEXT:    vmovshdup {{.*#+}} xmm4 = xmm0[1,1,3,3]
+; AVX2-NEXT:    vcvtph2ps %xmm4, %xmm4
+; AVX2-NEXT:    vcvttss2si %xmm4, %esi
+; AVX2-NEXT:    vucomiss %xmm1, %xmm4
+; AVX2-NEXT:    cmovbl %eax, %esi
+; AVX2-NEXT:    vucomiss %xmm2, %xmm4
+; AVX2-NEXT:    cmoval %ecx, %esi
+; AVX2-NEXT:    vucomiss %xmm4, %xmm4
+; AVX2-NEXT:    cmovpl %edx, %esi
+; AVX2-NEXT:    vpinsrd $2, %esi, %xmm3, %xmm3
+; AVX2-NEXT:    vpsrlq $48, %xmm0, %xmm0
 ; AVX2-NEXT:    vcvtph2ps %xmm0, %xmm0
-; AVX2-NEXT:    vmovq %rax, %xmm2
-; AVX2-NEXT:    vcvttss2si %xmm0, %rax
-; AVX2-NEXT:    vmovq %rax, %xmm0
-; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm2[0],xmm0[0]
-; AVX2-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
-; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm1 = [2147483647,2147483647,2147483647,2147483647]
-; AVX2-NEXT:    vpcmpgtq %ymm0, %ymm1, %ymm2
-; AVX2-NEXT:    vblendvpd %ymm2, %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm1 = [18446744071562067968,18446744071562067968,18446744071562067968,18446744071562067968]
-; AVX2-NEXT:    vpcmpgtq %ymm1, %ymm0, %ymm2
-; AVX2-NEXT:    vblendvpd %ymm2, %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vbroadcastf128 {{.*#+}} ymm1 = [0,2,4,6,0,2,4,6]
-; AVX2-NEXT:    # ymm1 = mem[0,1,0,1]
-; AVX2-NEXT:    vpermps %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
-; AVX2-NEXT:    vzeroupper
+; AVX2-NEXT:    vcvttss2si %xmm0, %esi
+; AVX2-NEXT:    vucomiss %xmm1, %xmm0
+; AVX2-NEXT:    cmovbl %eax, %esi
+; AVX2-NEXT:    vucomiss %xmm2, %xmm0
+; AVX2-NEXT:    cmoval %ecx, %esi
+; AVX2-NEXT:    vucomiss %xmm0, %xmm0
+; AVX2-NEXT:    cmovpl %edx, %esi
+; AVX2-NEXT:    vpinsrd $3, %esi, %xmm3, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: stest_f16i32:
@@ -2846,106 +2757,26 @@ entry:
 define <4 x i32> @stest_f32i32_mm(<4 x float> %x) nounwind {
 ; SSE-LABEL: stest_f32i32_mm:
 ; SSE:       # %bb.0: # %entry
-; SSE-NEXT:    movaps %xmm0, %xmm1
-; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[3,3],xmm0[3,3]
-; SSE-NEXT:    cvttss2si %xmm1, %rax
-; SSE-NEXT:    movq %rax, %xmm1
-; SSE-NEXT:    movaps %xmm0, %xmm2
-; SSE-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1],xmm0[1]
-; SSE-NEXT:    cvttss2si %xmm2, %rax
-; SSE-NEXT:    movq %rax, %xmm2
-; SSE-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm1[0]
-; SSE-NEXT:    cvttss2si %xmm0, %rax
-; SSE-NEXT:    movq %rax, %xmm3
-; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE-NEXT:    cvttss2si %xmm0, %rax
-; SSE-NEXT:    movq %rax, %xmm0
-; SSE-NEXT:    punpcklqdq {{.*#+}} xmm3 = xmm3[0],xmm0[0]
-; SSE-NEXT:    movdqa {{.*#+}} xmm0 = [2147483648,2147483648]
-; SSE-NEXT:    movdqa %xmm3, %xmm1
-; SSE-NEXT:    pxor %xmm0, %xmm1
-; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm1[1,1,3,3]
-; SSE-NEXT:    pxor %xmm5, %xmm5
-; SSE-NEXT:    pcmpeqd %xmm5, %xmm4
-; SSE-NEXT:    movdqa {{.*#+}} xmm6 = [4294967295,4294967295]
-; SSE-NEXT:    movdqa %xmm6, %xmm7
-; SSE-NEXT:    pcmpgtd %xmm1, %xmm7
-; SSE-NEXT:    pshufd {{.*#+}} xmm8 = xmm7[0,0,2,2]
-; SSE-NEXT:    pand %xmm4, %xmm8
-; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm7[1,1,3,3]
-; SSE-NEXT:    por %xmm8, %xmm1
-; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [2147483647,2147483647]
-; SSE-NEXT:    pand %xmm1, %xmm3
-; SSE-NEXT:    pandn %xmm4, %xmm1
-; SSE-NEXT:    por %xmm3, %xmm1
-; SSE-NEXT:    movdqa %xmm2, %xmm3
-; SSE-NEXT:    pxor %xmm0, %xmm3
-; SSE-NEXT:    pshufd {{.*#+}} xmm7 = xmm3[1,1,3,3]
-; SSE-NEXT:    pcmpeqd %xmm5, %xmm7
-; SSE-NEXT:    pcmpgtd %xmm3, %xmm6
-; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm6[0,0,2,2]
-; SSE-NEXT:    pand %xmm7, %xmm3
-; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm6[1,1,3,3]
-; SSE-NEXT:    por %xmm3, %xmm5
-; SSE-NEXT:    pand %xmm5, %xmm2
-; SSE-NEXT:    pandn %xmm4, %xmm5
-; SSE-NEXT:    por %xmm2, %xmm5
-; SSE-NEXT:    movdqa %xmm5, %xmm2
-; SSE-NEXT:    pxor %xmm0, %xmm2
-; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm2[1,1,3,3]
-; SSE-NEXT:    pcmpeqd %xmm4, %xmm4
-; SSE-NEXT:    pcmpeqd %xmm4, %xmm3
-; SSE-NEXT:    movdqa {{.*#+}} xmm6 = [18446744069414584320,18446744069414584320]
-; SSE-NEXT:    pcmpgtd %xmm6, %xmm2
-; SSE-NEXT:    pshufd {{.*#+}} xmm7 = xmm2[0,0,2,2]
-; SSE-NEXT:    pand %xmm3, %xmm7
-; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
-; SSE-NEXT:    por %xmm7, %xmm2
-; SSE-NEXT:    movdqa {{.*#+}} xmm3 = [18446744071562067968,18446744071562067968]
-; SSE-NEXT:    pand %xmm2, %xmm5
-; SSE-NEXT:    pandn %xmm3, %xmm2
-; SSE-NEXT:    por %xmm5, %xmm2
-; SSE-NEXT:    pxor %xmm1, %xmm0
-; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm0[1,1,3,3]
-; SSE-NEXT:    pcmpeqd %xmm4, %xmm5
-; SSE-NEXT:    pcmpgtd %xmm6, %xmm0
-; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm0[0,0,2,2]
-; SSE-NEXT:    pand %xmm5, %xmm4
-; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
-; SSE-NEXT:    por %xmm4, %xmm0
-; SSE-NEXT:    pand %xmm0, %xmm1
-; SSE-NEXT:    pandn %xmm3, %xmm0
-; SSE-NEXT:    por %xmm1, %xmm0
-; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[0,2]
+; SSE-NEXT:    movaps {{.*#+}} xmm1 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
+; SSE-NEXT:    cmpleps %xmm0, %xmm1
+; SSE-NEXT:    cvttps2dq %xmm0, %xmm2
+; SSE-NEXT:    movaps %xmm1, %xmm3
+; SSE-NEXT:    andnps %xmm2, %xmm3
+; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE-NEXT:    orps %xmm3, %xmm1
+; SSE-NEXT:    cmpunordps %xmm0, %xmm0
+; SSE-NEXT:    andnps %xmm1, %xmm0
 ; SSE-NEXT:    retq
 ;
 ; AVX2-LABEL: stest_f32i32_mm:
 ; AVX2:       # %bb.0: # %entry
-; AVX2-NEXT:    vshufps {{.*#+}} xmm1 = xmm0[3,3,3,3]
-; AVX2-NEXT:    vcvttss2si %xmm1, %rax
-; AVX2-NEXT:    vmovq %rax, %xmm1
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm2 = xmm0[1,0]
-; AVX2-NEXT:    vcvttss2si %xmm2, %rax
-; AVX2-NEXT:    vmovq %rax, %xmm2
-; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
-; AVX2-NEXT:    vcvttss2si %xmm0, %rax
-; AVX2-NEXT:    vmovq %rax, %xmm2
-; AVX2-NEXT:    vmovshdup {{.*#+}} xmm0 = xmm0[1,1,3,3]
-; AVX2-NEXT:    vcvttss2si %xmm0, %rax
-; AVX2-NEXT:    vmovq %rax, %xmm0
-; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm2[0],xmm0[0]
-; AVX2-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
-; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm1 = [2147483647,2147483647,2147483647,2147483647]
-; AVX2-NEXT:    vpcmpgtq %ymm0, %ymm1, %ymm2
-; AVX2-NEXT:    vblendvpd %ymm2, %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm1 = [18446744071562067968,18446744071562067968,18446744071562067968,18446744071562067968]
-; AVX2-NEXT:    vpcmpgtq %ymm1, %ymm0, %ymm2
-; AVX2-NEXT:    vblendvpd %ymm2, %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vbroadcastf128 {{.*#+}} ymm1 = [0,2,4,6,0,2,4,6]
-; AVX2-NEXT:    # ymm1 = mem[0,1,0,1]
-; AVX2-NEXT:    vpermps %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
-; AVX2-NEXT:    vzeroupper
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm1 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
+; AVX2-NEXT:    vcmpleps %xmm0, %xmm1, %xmm1
+; AVX2-NEXT:    vcvttps2dq %xmm0, %xmm2
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm3 = [2147483647,2147483647,2147483647,2147483647]
+; AVX2-NEXT:    vblendvps %xmm1, %xmm3, %xmm2, %xmm1
+; AVX2-NEXT:    vcmpunordps %xmm0, %xmm0, %xmm0
+; AVX2-NEXT:    vandnps %xmm1, %xmm0, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: stest_f32i32_mm:
@@ -3218,130 +3049,121 @@ entry:
 define <4 x i32> @stest_f16i32_mm(<4 x half> %x) nounwind {
 ; SSE-LABEL: stest_f16i32_mm:
 ; SSE:       # %bb.0: # %entry
-; SSE-NEXT:    subq $72, %rsp
-; SSE-NEXT:    movdqa %xmm0, (%rsp) # 16-byte Spill
+; SSE-NEXT:    pushq %rbp
+; SSE-NEXT:    pushq %r14
+; SSE-NEXT:    pushq %rbx
+; SSE-NEXT:    subq $64, %rsp
+; SSE-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; SSE-NEXT:    movdqa %xmm0, %xmm1
 ; SSE-NEXT:    psrld $16, %xmm1
 ; SSE-NEXT:    movdqa %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; SSE-NEXT:    movdqa %xmm0, %xmm1
 ; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[1,1],xmm0[1,1]
-; SSE-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; SSE-NEXT:    movaps %xmm1, (%rsp) # 16-byte Spill
 ; SSE-NEXT:    psrlq $48, %xmm0
 ; SSE-NEXT:    callq __extendhfsf2 at PLT
-; SSE-NEXT:    cvttss2si %xmm0, %rax
-; SSE-NEXT:    movq %rax, %xmm0
-; SSE-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE-NEXT:    callq __extendhfsf2 at PLT
-; SSE-NEXT:    cvttss2si %xmm0, %rax
-; SSE-NEXT:    movq %rax, %xmm0
-; SSE-NEXT:    punpcklqdq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload
-; SSE-NEXT:    # xmm0 = xmm0[0],mem[0]
+; SSE-NEXT:    cvttss2si %xmm0, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    movl $-2147483648, %ebx # imm = 0x80000000
+; SSE-NEXT:    cmovbl %ebx, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    movl $2147483647, %ebp # imm = 0x7FFFFFFF
+; SSE-NEXT:    cmoval %ebp, %eax
+; SSE-NEXT:    xorl %r14d, %r14d
+; SSE-NEXT:    ucomiss %xmm0, %xmm0
+; SSE-NEXT:    cmovpl %r14d, %eax
+; SSE-NEXT:    movd %eax, %xmm0
 ; SSE-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; SSE-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
 ; SSE-NEXT:    callq __extendhfsf2 at PLT
-; SSE-NEXT:    cvttss2si %xmm0, %rax
-; SSE-NEXT:    movq %rax, %xmm0
+; SSE-NEXT:    cvttss2si %xmm0, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    cmovbl %ebx, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    cmoval %ebp, %eax
+; SSE-NEXT:    ucomiss %xmm0, %xmm0
+; SSE-NEXT:    cmovpl %r14d, %eax
+; SSE-NEXT:    movd %eax, %xmm0
+; SSE-NEXT:    punpckldq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload
+; SSE-NEXT:    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
 ; SSE-NEXT:    movdqa %xmm0, (%rsp) # 16-byte Spill
 ; SSE-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; SSE-NEXT:    callq __extendhfsf2 at PLT
-; SSE-NEXT:    cvttss2si %xmm0, %rax
-; SSE-NEXT:    movq %rax, %xmm0
-; SSE-NEXT:    movdqa (%rsp), %xmm2 # 16-byte Reload
-; SSE-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm0[0]
-; SSE-NEXT:    movdqa {{.*#+}} xmm0 = [2147483648,2147483648]
-; SSE-NEXT:    movdqa %xmm2, %xmm1
-; SSE-NEXT:    movdqa %xmm2, %xmm7
-; SSE-NEXT:    pxor %xmm0, %xmm1
-; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[1,1,3,3]
-; SSE-NEXT:    pxor %xmm3, %xmm3
-; SSE-NEXT:    pcmpeqd %xmm3, %xmm2
-; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [4294967295,4294967295]
-; SSE-NEXT:    movdqa %xmm4, %xmm5
-; SSE-NEXT:    pcmpgtd %xmm1, %xmm5
-; SSE-NEXT:    pshufd {{.*#+}} xmm6 = xmm5[0,0,2,2]
-; SSE-NEXT:    pand %xmm2, %xmm6
-; SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm5[1,1,3,3]
-; SSE-NEXT:    por %xmm6, %xmm1
-; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [2147483647,2147483647]
-; SSE-NEXT:    pand %xmm1, %xmm7
-; SSE-NEXT:    pandn %xmm2, %xmm1
-; SSE-NEXT:    por %xmm7, %xmm1
-; SSE-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
-; SSE-NEXT:    movdqa %xmm7, %xmm5
-; SSE-NEXT:    pxor %xmm0, %xmm5
-; SSE-NEXT:    pshufd {{.*#+}} xmm6 = xmm5[1,1,3,3]
-; SSE-NEXT:    pcmpeqd %xmm3, %xmm6
-; SSE-NEXT:    pcmpgtd %xmm5, %xmm4
-; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm4[0,0,2,2]
-; SSE-NEXT:    pand %xmm6, %xmm3
-; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm4[1,1,3,3]
-; SSE-NEXT:    por %xmm3, %xmm4
-; SSE-NEXT:    movdqa %xmm7, %xmm3
-; SSE-NEXT:    pand %xmm4, %xmm3
-; SSE-NEXT:    pandn %xmm2, %xmm4
-; SSE-NEXT:    por %xmm3, %xmm4
-; SSE-NEXT:    movdqa %xmm4, %xmm2
-; SSE-NEXT:    pxor %xmm0, %xmm2
-; SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm2[1,1,3,3]
-; SSE-NEXT:    pcmpeqd %xmm5, %xmm5
-; SSE-NEXT:    pcmpeqd %xmm5, %xmm3
-; SSE-NEXT:    movdqa {{.*#+}} xmm6 = [18446744069414584320,18446744069414584320]
-; SSE-NEXT:    pcmpgtd %xmm6, %xmm2
-; SSE-NEXT:    pshufd {{.*#+}} xmm7 = xmm2[0,0,2,2]
-; SSE-NEXT:    pand %xmm3, %xmm7
-; SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
-; SSE-NEXT:    por %xmm7, %xmm2
-; SSE-NEXT:    movdqa {{.*#+}} xmm3 = [18446744071562067968,18446744071562067968]
-; SSE-NEXT:    pand %xmm2, %xmm4
-; SSE-NEXT:    pandn %xmm3, %xmm2
-; SSE-NEXT:    por %xmm4, %xmm2
-; SSE-NEXT:    pxor %xmm1, %xmm0
-; SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm0[1,1,3,3]
-; SSE-NEXT:    pcmpeqd %xmm5, %xmm4
-; SSE-NEXT:    pcmpgtd %xmm6, %xmm0
-; SSE-NEXT:    pshufd {{.*#+}} xmm5 = xmm0[0,0,2,2]
-; SSE-NEXT:    pand %xmm4, %xmm5
-; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
-; SSE-NEXT:    por %xmm5, %xmm0
-; SSE-NEXT:    pand %xmm0, %xmm1
-; SSE-NEXT:    pandn %xmm3, %xmm0
-; SSE-NEXT:    por %xmm1, %xmm0
-; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm2[0,2]
-; SSE-NEXT:    addq $72, %rsp
+; SSE-NEXT:    cvttss2si %xmm0, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    cmovbl %ebx, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    cmoval %ebp, %eax
+; SSE-NEXT:    ucomiss %xmm0, %xmm0
+; SSE-NEXT:    cmovpl %r14d, %eax
+; SSE-NEXT:    movd %eax, %xmm0
+; SSE-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; SSE-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; SSE-NEXT:    callq __extendhfsf2 at PLT
+; SSE-NEXT:    cvttss2si %xmm0, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    cmovbl %ebx, %eax
+; SSE-NEXT:    ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    cmoval %ebp, %eax
+; SSE-NEXT:    ucomiss %xmm0, %xmm0
+; SSE-NEXT:    cmovpl %r14d, %eax
+; SSE-NEXT:    movd %eax, %xmm1
+; SSE-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
+; SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
+; SSE-NEXT:    punpcklqdq (%rsp), %xmm0 # 16-byte Folded Reload
+; SSE-NEXT:    # xmm0 = xmm0[0],mem[0]
+; SSE-NEXT:    addq $64, %rsp
+; SSE-NEXT:    popq %rbx
+; SSE-NEXT:    popq %r14
+; SSE-NEXT:    popq %rbp
 ; SSE-NEXT:    retq
 ;
 ; AVX2-LABEL: stest_f16i32_mm:
 ; AVX2:       # %bb.0: # %entry
-; AVX2-NEXT:    vpsrlq $48, %xmm0, %xmm1
-; AVX2-NEXT:    vcvtph2ps %xmm1, %xmm1
-; AVX2-NEXT:    vcvttss2si %xmm1, %rax
-; AVX2-NEXT:    vmovshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; AVX2-NEXT:    vcvtph2ps %xmm1, %xmm1
-; AVX2-NEXT:    vcvttss2si %xmm1, %rcx
-; AVX2-NEXT:    vcvtph2ps %xmm0, %xmm1
-; AVX2-NEXT:    vmovq %rax, %xmm2
-; AVX2-NEXT:    vcvttss2si %xmm1, %rax
-; AVX2-NEXT:    vmovq %rcx, %xmm1
-; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
-; AVX2-NEXT:    vpsrld $16, %xmm0, %xmm0
+; AVX2-NEXT:    vpsrld $16, %xmm0, %xmm1
+; AVX2-NEXT:    vcvtph2ps %xmm1, %xmm3
+; AVX2-NEXT:    vcvttss2si %xmm3, %esi
+; AVX2-NEXT:    vmovss {{.*#+}} xmm1 = [-2.14748365E+9,0.0E+0,0.0E+0,0.0E+0]
+; AVX2-NEXT:    vucomiss %xmm1, %xmm3
+; AVX2-NEXT:    movl $-2147483648, %eax # imm = 0x80000000
+; AVX2-NEXT:    cmovbl %eax, %esi
+; AVX2-NEXT:    vmovss {{.*#+}} xmm2 = [2.14748352E+9,0.0E+0,0.0E+0,0.0E+0]
+; AVX2-NEXT:    vucomiss %xmm2, %xmm3
+; AVX2-NEXT:    movl $2147483647, %ecx # imm = 0x7FFFFFFF
+; AVX2-NEXT:    cmoval %ecx, %esi
+; AVX2-NEXT:    xorl %edx, %edx
+; AVX2-NEXT:    vucomiss %xmm3, %xmm3
+; AVX2-NEXT:    cmovpl %edx, %esi
+; AVX2-NEXT:    vcvtph2ps %xmm0, %xmm3
+; AVX2-NEXT:    vcvttss2si %xmm3, %edi
+; AVX2-NEXT:    vucomiss %xmm1, %xmm3
+; AVX2-NEXT:    cmovbl %eax, %edi
+; AVX2-NEXT:    vucomiss %xmm2, %xmm3
+; AVX2-NEXT:    cmoval %ecx, %edi
+; AVX2-NEXT:    vucomiss %xmm3, %xmm3
+; AVX2-NEXT:    cmovpl %edx, %edi
+; AVX2-NEXT:    vmovd %edi, %xmm3
+; AVX2-NEXT:    vpinsrd $1, %esi, %xmm3, %xmm3
+; AVX2-NEXT:    vmovshdup {{.*#+}} xmm4 = xmm0[1,1,3,3]
+; AVX2-NEXT:    vcvtph2ps %xmm4, %xmm4
+; AVX2-NEXT:    vcvttss2si %xmm4, %esi
+; AVX2-NEXT:    vucomiss %xmm1, %xmm4
+; AVX2-NEXT:    cmovbl %eax, %esi
+; AVX2-NEXT:    vucomiss %xmm2, %xmm4
+; AVX2-NEXT:    cmoval %ecx, %esi
+; AVX2-NEXT:    vucomiss %xmm4, %xmm4
+; AVX2-NEXT:    cmovpl %edx, %esi
+; AVX2-NEXT:    vpinsrd $2, %esi, %xmm3, %xmm3
+; AVX2-NEXT:    vpsrlq $48, %xmm0, %xmm0
 ; AVX2-NEXT:    vcvtph2ps %xmm0, %xmm0
-; AVX2-NEXT:    vmovq %rax, %xmm2
-; AVX2-NEXT:    vcvttss2si %xmm0, %rax
-; AVX2-NEXT:    vmovq %rax, %xmm0
-; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm2[0],xmm0[0]
-; AVX2-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
-; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm1 = [2147483647,2147483647,2147483647,2147483647]
-; AVX2-NEXT:    vpcmpgtq %ymm0, %ymm1, %ymm2
-; AVX2-NEXT:    vblendvpd %ymm2, %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vpbroadcastq {{.*#+}} ymm1 = [18446744071562067968,18446744071562067968,18446744071562067968,18446744071562067968]
-; AVX2-NEXT:    vpcmpgtq %ymm1, %ymm0, %ymm2
-; AVX2-NEXT:    vblendvpd %ymm2, %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    vbroadcastf128 {{.*#+}} ymm1 = [0,2,4,6,0,2,4,6]
-; AVX2-NEXT:    # ymm1 = mem[0,1,0,1]
-; AVX2-NEXT:    vpermps %ymm0, %ymm1, %ymm0
-; AVX2-NEXT:    # kill: def $xmm0 killed $xmm0 killed $ymm0
-; AVX2-NEXT:    vzeroupper
+; AVX2-NEXT:    vcvttss2si %xmm0, %esi
+; AVX2-NEXT:    vucomiss %xmm1, %xmm0
+; AVX2-NEXT:    cmovbl %eax, %esi
+; AVX2-NEXT:    vucomiss %xmm2, %xmm0
+; AVX2-NEXT:    cmoval %ecx, %esi
+; AVX2-NEXT:    vucomiss %xmm0, %xmm0
+; AVX2-NEXT:    cmovpl %edx, %esi
+; AVX2-NEXT:    vpinsrd $3, %esi, %xmm3, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: stest_f16i32_mm:

>From c6ca4031b5e9da929820c6a9097137de16e0222d Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Sun, 24 May 2026 14:43:17 +0200
Subject: [PATCH 04/18] Remove unecessary comments

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 495f58f3bc004..239aced34ce7d 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22440,37 +22440,26 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
 
     if (SatWidth == 32) {
       if (IsSigned) {
-        // Direct conversion handles in-range and negative overflow correctly.
         SDValue Cvt = DAG.getNode(ISD::FP_TO_SINT, dl, DstVT, Src);
-
-        // Detect positive overflow (src >= 2^31) and saturate to INT_MAX.
         APFloat PosOvfBoundFlt(SrcVT.getScalarType().getFltSemantics());
         PosOvfBoundFlt.convertFromAPInt(APInt::getSignedMinValue(32), /*IsSigned=*/true, APFloat::rmTowardZero);
-        PosOvfBoundFlt.changeSign(); // Flips -2^31 to +2^31
+        PosOvfBoundFlt.changeSign();
         SDValue PosOvfBound = DAG.getConstantFP(PosOvfBoundFlt, dl, SrcVT);
         SDValue PosOvf = DAG.getSetCC(dl, DstVT, Src, PosOvfBound, ISD::SETOGE);
         SDValue IntMax = DAG.getConstant(APInt::getSignedMaxValue(32), dl, DstVT);
         SDValue Fixed = DAG.getSelect(dl, DstVT, PosOvf, IntMax, Cvt);
-
-        // Detect NaN and map to 0.
         SDValue IsNaN = DAG.getSetCC(dl, DstVT, Src, Src, ISD::SETUO);
         SDValue Zero = DAG.getConstant(0, dl, DstVT);
         return DAG.getSelect(dl, DstVT, IsNaN, Zero, Fixed);
       } else {
-        // Clamp negative values and NaN to 0. FMAX maps NaN to 0.0.
         SDValue ZeroFP = DAG.getConstantFP(0.0, dl, SrcVT);
         SDValue Clamped = DAG.getNode(X86ISD::FMAX, dl, SrcVT, Src, ZeroFP);
-
-        // Detect overflow (src >= 2^32) to saturate to UINT_MAX.
         APFloat OvfBoundFlt(SrcVT.getScalarType().getFltSemantics());
         OvfBoundFlt.convertFromAPInt(APInt::getOneBitSet(33, 32), /*IsSigned=*/false, APFloat::rmTowardZero);
         SDValue OvfBound = DAG.getConstantFP(OvfBoundFlt, dl, SrcVT);
         SDValue IsOvf = DAG.getSetCC(dl, DstVT, Clamped, OvfBound, ISD::SETOGE);
-
         SDValue Cvt = DAG.getNode(ISD::FP_TO_UINT, dl, DstVT, Clamped);
         SDValue UintMax = DAG.getConstant(APInt::getMaxValue(32), dl, DstVT);
-
-        // Apply saturation for overflow.
         return DAG.getSelect(dl, DstVT, IsOvf, UintMax, Cvt);
       }
     }

>From 105afc276af1c9dcfef0c5e3c2228d81341ae613 Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Mon, 25 May 2026 16:55:56 +0200
Subject: [PATCH 05/18] fix test

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 239aced34ce7d..1438c8a5a4adc 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22491,7 +22491,14 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
     SDValue ClampedBottom = DAG.getNode(X86ISD::FMAX, dl, SrcVT, Src, MinC);
     // Clamp from above. NaN (now MinC) is already in range and passes through.
     SDValue ClampedTop = DAG.getNode(X86ISD::FMIN, dl, SrcVT, ClampedBottom, MaxC);
-    SDValue Result = DAG.getNode(FpToIntOpcode, dl, DstVT, ClampedTop);
+    
+    // For smaller widths, the max unsigned value fits in a signed 32-bit int.
+    // Use FP_TO_SINT instead of FP_TO_UINT to avoid expensive legalization.
+    unsigned CastOpc = FpToIntOpcode;
+    if (!IsSigned && SatWidth < 32)
+      CastOpc = ISD::FP_TO_SINT;
+
+    SDValue Result = DAG.getNode(CastOpc, dl, DstVT, ClampedTop);
 
     // For signed saturation, NaN was mapped to MinC, so FP_TO_SINT produces
     // INT_MIN. ISD::FP_TO_SINT_SAT requires NaN -> 0; fix with a zero-select.

>From f12a1b785627b964cea07d9cdb1f19d1f912a12c Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Mon, 25 May 2026 17:25:46 +0200
Subject: [PATCH 06/18] git format

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 1438c8a5a4adc..8bcb3ee15fef7 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22436,17 +22436,21 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
     return DAG.getNode(ISD::TRUNCATE, dl, DstVT, Res);
   } else if (DstVT == MVT::v4i32 && Subtarget.hasSSE2()) {
     unsigned SatWidth = SatVT.getScalarSizeInBits();
-    assert(SatWidth <= 32 && "Expected saturation width no wider than result element");
+    assert(SatWidth <= 32 &&
+           "Expected saturation width no wider than result element");
 
     if (SatWidth == 32) {
       if (IsSigned) {
         SDValue Cvt = DAG.getNode(ISD::FP_TO_SINT, dl, DstVT, Src);
         APFloat PosOvfBoundFlt(SrcVT.getScalarType().getFltSemantics());
-        PosOvfBoundFlt.convertFromAPInt(APInt::getSignedMinValue(32), /*IsSigned=*/true, APFloat::rmTowardZero);
+        PosOvfBoundFlt.convertFromAPInt(APInt::getSignedMinValue(32),
+                                        /*IsSigned=*/true,
+                                        APFloat::rmTowardZero);
         PosOvfBoundFlt.changeSign();
         SDValue PosOvfBound = DAG.getConstantFP(PosOvfBoundFlt, dl, SrcVT);
         SDValue PosOvf = DAG.getSetCC(dl, DstVT, Src, PosOvfBound, ISD::SETOGE);
-        SDValue IntMax = DAG.getConstant(APInt::getSignedMaxValue(32), dl, DstVT);
+        SDValue IntMax =
+            DAG.getConstant(APInt::getSignedMaxValue(32), dl, DstVT);
         SDValue Fixed = DAG.getSelect(dl, DstVT, PosOvf, IntMax, Cvt);
         SDValue IsNaN = DAG.getSetCC(dl, DstVT, Src, Src, ISD::SETUO);
         SDValue Zero = DAG.getConstant(0, dl, DstVT);
@@ -22455,7 +22459,8 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
         SDValue ZeroFP = DAG.getConstantFP(0.0, dl, SrcVT);
         SDValue Clamped = DAG.getNode(X86ISD::FMAX, dl, SrcVT, Src, ZeroFP);
         APFloat OvfBoundFlt(SrcVT.getScalarType().getFltSemantics());
-        OvfBoundFlt.convertFromAPInt(APInt::getOneBitSet(33, 32), /*IsSigned=*/false, APFloat::rmTowardZero);
+        OvfBoundFlt.convertFromAPInt(APInt::getOneBitSet(33, 32),
+                                     /*IsSigned=*/false, APFloat::rmTowardZero);
         SDValue OvfBound = DAG.getConstantFP(OvfBoundFlt, dl, SrcVT);
         SDValue IsOvf = DAG.getSetCC(dl, DstVT, Clamped, OvfBound, ISD::SETOGE);
         SDValue Cvt = DAG.getNode(ISD::FP_TO_UINT, dl, DstVT, Clamped);
@@ -22490,8 +22495,9 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
     // input is NaN, so NaN maps to MinC here.
     SDValue ClampedBottom = DAG.getNode(X86ISD::FMAX, dl, SrcVT, Src, MinC);
     // Clamp from above. NaN (now MinC) is already in range and passes through.
-    SDValue ClampedTop = DAG.getNode(X86ISD::FMIN, dl, SrcVT, ClampedBottom, MaxC);
-    
+    SDValue ClampedTop =
+        DAG.getNode(X86ISD::FMIN, dl, SrcVT, ClampedBottom, MaxC);
+
     // For smaller widths, the max unsigned value fits in a signed 32-bit int.
     // Use FP_TO_SINT instead of FP_TO_UINT to avoid expensive legalization.
     unsigned CastOpc = FpToIntOpcode;
@@ -22502,7 +22508,8 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
 
     // For signed saturation, NaN was mapped to MinC, so FP_TO_SINT produces
     // INT_MIN. ISD::FP_TO_SINT_SAT requires NaN -> 0; fix with a zero-select.
-    // For unsigned saturation, MinC == 0.0, so NaN -> 0.0 -> 0: already correct.
+    // For unsigned saturation, MinC == 0.0, so NaN -> 0.0 -> 0: already
+    // correct.
     if (IsSigned) {
       SDValue Zero = DAG.getConstant(0, dl, DstVT);
       SDValue IsNaN = DAG.getSetCC(dl, DstVT, Src, Src, ISD::SETUO);

>From 8db402f09ae2e28a99e7ca3c063dd64e5fc59f30 Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Tue, 9 Jun 2026 20:39:54 +0200
Subject: [PATCH 07/18] implement suggestions from review

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 8bcb3ee15fef7..e2a7d672d12d6 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22434,14 +22434,19 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
     SDValue Res = DAG.getNode(IsSigned ? X86ISD::CVTTP2IBS : X86ISD::CVTTP2IUBS,
                               dl, VecI16VT, Src);
     return DAG.getNode(ISD::TRUNCATE, dl, DstVT, Res);
-  } else if (DstVT == MVT::v4i32 && Subtarget.hasSSE2()) {
+  } 
+  if ((DstVT == MVT::v4i32 && Subtarget.hasSSE2()) ||
+             (DstVT == MVT::v8i32 && Subtarget.hasAVX()) ||
+             (DstVT == MVT::v16i32 && Subtarget.hasAVX512())) {
     unsigned SatWidth = SatVT.getScalarSizeInBits();
     assert(SatWidth <= 32 &&
            "Expected saturation width no wider than result element");
 
     if (SatWidth == 32) {
       if (IsSigned) {
-        SDValue Cvt = DAG.getNode(ISD::FP_TO_SINT, dl, DstVT, Src);
+        // Use X86ISD::CVTTP2SI (CVTTPS2DQ/CVTTPD2DQ) which has defined
+        // out-of-range behavior: maps overflow and NaN to 0x80000000 (INT_MIN).
+        SDValue Cvt = DAG.getNode(X86ISD::CVTTP2SI, dl, DstVT, Src);
         APFloat PosOvfBoundFlt(SrcVT.getScalarType().getFltSemantics());
         PosOvfBoundFlt.convertFromAPInt(APInt::getSignedMinValue(32),
                                         /*IsSigned=*/true,
@@ -22463,7 +22468,16 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
                                      /*IsSigned=*/false, APFloat::rmTowardZero);
         SDValue OvfBound = DAG.getConstantFP(OvfBoundFlt, dl, SrcVT);
         SDValue IsOvf = DAG.getSetCC(dl, DstVT, Clamped, OvfBound, ISD::SETOGE);
-        SDValue Cvt = DAG.getNode(ISD::FP_TO_UINT, dl, DstVT, Clamped);
+        // v16i32 (512-bit, AVX512): use X86ISD::CVTTP2UI (VCVTTPS2UDQZ).
+        // v4i32 (128-bit, SSE) and v8i32 (256-bit, AVX) are already covered
+        // by CVTTPS2DQ/VCVTTPS2DQ via expandFP_TO_UINT_SSE — no AVX512VL
+        // needed.
+        SDValue Cvt;
+        if (DstVT == MVT::v16i32)
+          Cvt = DAG.getNode(X86ISD::CVTTP2UI, dl, DstVT, Clamped);
+        else
+          Cvt = expandFP_TO_UINT_SSE(DstVT.getSimpleVT(), Clamped, dl, DAG,
+                                     Subtarget);
         SDValue UintMax = DAG.getConstant(APInt::getMaxValue(32), dl, DstVT);
         return DAG.getSelect(dl, DstVT, IsOvf, UintMax, Cvt);
       }

>From 12c194c5d1dfa4523a6382a6b866efdf364037da Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Sun, 14 Jun 2026 00:29:44 +0200
Subject: [PATCH 08/18] Enable support for avx and avx512, and use CVTTP2SI

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index e2a7d672d12d6..d724b3ec21ad8 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -322,6 +322,14 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
     setOperationAction(ISD::FP_TO_UINT_SAT, MVT::v4i32, Custom);
     setOperationAction(ISD::FP_TO_SINT_SAT, MVT::v4i32, Custom);
   }
+  if (Subtarget.hasAVX()) {
+    setOperationAction(ISD::FP_TO_UINT_SAT, MVT::v8i32, Custom);
+    setOperationAction(ISD::FP_TO_SINT_SAT, MVT::v8i32, Custom);
+  }
+  if (Subtarget.hasAVX512()) {
+    setOperationAction(ISD::FP_TO_UINT_SAT, MVT::v16i32, Custom);
+    setOperationAction(ISD::FP_TO_SINT_SAT, MVT::v16i32, Custom);
+  }
   if (Subtarget.hasAVX10_2()) {
     for (MVT VT : {MVT::v8i8, MVT::v16i8, MVT::v32i8}) {
       setOperationAction(ISD::FP_TO_UINT_SAT, VT, Custom);
@@ -22513,12 +22521,9 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
         DAG.getNode(X86ISD::FMIN, dl, SrcVT, ClampedBottom, MaxC);
 
     // For smaller widths, the max unsigned value fits in a signed 32-bit int.
-    // Use FP_TO_SINT instead of FP_TO_UINT to avoid expensive legalization.
-    unsigned CastOpc = FpToIntOpcode;
-    if (!IsSigned && SatWidth < 32)
-      CastOpc = ISD::FP_TO_SINT;
-
-    SDValue Result = DAG.getNode(CastOpc, dl, DstVT, ClampedTop);
+    // Use X86ISD::CVTTP2SI instead of FP_TO_UINT to avoid expensive legalization
+    // and guarantee the out-of-range behavior.
+    SDValue Result = DAG.getNode(X86ISD::CVTTP2SI, dl, DstVT, ClampedTop);
 
     // For signed saturation, NaN was mapped to MinC, so FP_TO_SINT produces
     // INT_MIN. ISD::FP_TO_SINT_SAT requires NaN -> 0; fix with a zero-select.

>From 91e768c31bba485f7de6aaf12a0db43896e419dd Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Sun, 14 Jun 2026 01:18:31 +0200
Subject: [PATCH 09/18] fix some fail cases

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 48 ++++++++++++++++++-------
 1 file changed, 36 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index d724b3ec21ad8..b78fff98156e9 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22450,7 +22450,8 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
     assert(SatWidth <= 32 &&
            "Expected saturation width no wider than result element");
 
-    if (SatWidth == 32) {
+    if (SatWidth == 32 && (SrcVT.getScalarType() == MVT::f32 ||
+                           SrcVT.getScalarType() == MVT::f64)) {
       if (IsSigned) {
         // Use X86ISD::CVTTP2SI (CVTTPS2DQ/CVTTPD2DQ) which has defined
         // out-of-range behavior: maps overflow and NaN to 0x80000000 (INT_MIN).
@@ -22461,12 +22462,23 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
                                         APFloat::rmTowardZero);
         PosOvfBoundFlt.changeSign();
         SDValue PosOvfBound = DAG.getConstantFP(PosOvfBoundFlt, dl, SrcVT);
-        SDValue PosOvf = DAG.getSetCC(dl, DstVT, Src, PosOvfBound, ISD::SETOGE);
+        EVT CCVT =
+            getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), SrcVT);
+        EVT SelCCVT =
+            getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), DstVT);
+
+        SDValue PosOvf = DAG.getSetCC(dl, CCVT, Src, PosOvfBound, ISD::SETOGE);
+        SDValue IsNaN = DAG.getSetCC(dl, CCVT, Src, Src, ISD::SETUO);
+
+        if (CCVT != SelCCVT) {
+          PosOvf = DAG.getNode(ISD::TRUNCATE, dl, SelCCVT, PosOvf);
+          IsNaN = DAG.getNode(ISD::TRUNCATE, dl, SelCCVT, IsNaN);
+        }
+
         SDValue IntMax =
             DAG.getConstant(APInt::getSignedMaxValue(32), dl, DstVT);
-        SDValue Fixed = DAG.getSelect(dl, DstVT, PosOvf, IntMax, Cvt);
-        SDValue IsNaN = DAG.getSetCC(dl, DstVT, Src, Src, ISD::SETUO);
         SDValue Zero = DAG.getConstant(0, dl, DstVT);
+        SDValue Fixed = DAG.getSelect(dl, DstVT, PosOvf, IntMax, Cvt);
         return DAG.getSelect(dl, DstVT, IsNaN, Zero, Fixed);
       } else {
         SDValue ZeroFP = DAG.getConstantFP(0.0, dl, SrcVT);
@@ -22475,7 +22487,13 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
         OvfBoundFlt.convertFromAPInt(APInt::getOneBitSet(33, 32),
                                      /*IsSigned=*/false, APFloat::rmTowardZero);
         SDValue OvfBound = DAG.getConstantFP(OvfBoundFlt, dl, SrcVT);
-        SDValue IsOvf = DAG.getSetCC(dl, DstVT, Clamped, OvfBound, ISD::SETOGE);
+        EVT CCVT =
+            getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), SrcVT);
+        SDValue IsOvf = DAG.getSetCC(dl, CCVT, Clamped, OvfBound, ISD::SETOGE);
+        EVT SelCCVT =
+            getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), DstVT);
+        if (CCVT != SelCCVT)
+          IsOvf = DAG.getNode(ISD::TRUNCATE, dl, SelCCVT, IsOvf);
         // v16i32 (512-bit, AVX512): use X86ISD::CVTTP2UI (VCVTTPS2UDQZ).
         // v4i32 (128-bit, SSE) and v8i32 (256-bit, AVX) are already covered
         // by CVTTPS2DQ/VCVTTPS2DQ via expandFP_TO_UINT_SSE — no AVX512VL
@@ -22503,10 +22521,10 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
     // representable in the source float type. If either is inexact, fall back
     // to generic lowering.
     bool AreExactFloatBounds =
-        !(MinFloat.convertFromAPInt(MinInt, IsSigned, APFloat::rmTowardZero) &
-          APFloat::opInexact) &&
-        !(MaxFloat.convertFromAPInt(MaxInt, IsSigned, APFloat::rmTowardZero) &
-          APFloat::opInexact);
+        MinFloat.convertFromAPInt(MinInt, IsSigned, APFloat::rmTowardZero) ==
+            APFloat::opOK &&
+        MaxFloat.convertFromAPInt(MaxInt, IsSigned, APFloat::rmTowardZero) ==
+            APFloat::opOK;
     if (!AreExactFloatBounds)
       return SDValue();
 
@@ -22521,8 +22539,8 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
         DAG.getNode(X86ISD::FMIN, dl, SrcVT, ClampedBottom, MaxC);
 
     // For smaller widths, the max unsigned value fits in a signed 32-bit int.
-    // Use X86ISD::CVTTP2SI instead of FP_TO_UINT to avoid expensive legalization
-    // and guarantee the out-of-range behavior.
+    // Use X86ISD::CVTTP2SI instead of FP_TO_UINT to avoid expensive
+    // legalization and guarantee the out-of-range behavior.
     SDValue Result = DAG.getNode(X86ISD::CVTTP2SI, dl, DstVT, ClampedTop);
 
     // For signed saturation, NaN was mapped to MinC, so FP_TO_SINT produces
@@ -22531,7 +22549,13 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
     // correct.
     if (IsSigned) {
       SDValue Zero = DAG.getConstant(0, dl, DstVT);
-      SDValue IsNaN = DAG.getSetCC(dl, DstVT, Src, Src, ISD::SETUO);
+      EVT CCVT =
+          getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), SrcVT);
+      SDValue IsNaN = DAG.getSetCC(dl, CCVT, Src, Src, ISD::SETUO);
+      EVT SelCCVT =
+          getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), DstVT);
+      if (CCVT != SelCCVT)
+        IsNaN = DAG.getNode(ISD::TRUNCATE, dl, SelCCVT, IsNaN);
       return DAG.getSelect(dl, DstVT, IsNaN, Zero, Result);
     }
     return Result;

>From 1bacb867e4426921958691b1640a5fe008727278 Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Sun, 14 Jun 2026 02:34:51 +0200
Subject: [PATCH 10/18] improvment test

---
 llvm/test/CodeGen/X86/llc-accept-avx10-512.ll | 65 ++-----------------
 1 file changed, 6 insertions(+), 59 deletions(-)

diff --git a/llvm/test/CodeGen/X86/llc-accept-avx10-512.ll b/llvm/test/CodeGen/X86/llc-accept-avx10-512.ll
index b5c9895fefd98..1ba6392ebe11f 100644
--- a/llvm/test/CodeGen/X86/llc-accept-avx10-512.ll
+++ b/llvm/test/CodeGen/X86/llc-accept-avx10-512.ll
@@ -26,65 +26,12 @@ define <32 x bfloat> @foo_avx10.1(<16 x float> %a, <16 x float> %b) {
 define <8 x i32> @foo_avx10.2(<8 x double> %f) {
 ; CHECK-AVX10_1-LABEL: foo_avx10.2:
 ; CHECK-AVX10_1:       # %bb.0:
-; CHECK-AVX10_1-NEXT:    vextractf32x4 $2, %zmm0, %xmm1
-; CHECK-AVX10_1-NEXT:    vshufpd {{.*#+}} xmm2 = xmm1[1,0]
-; CHECK-AVX10_1-NEXT:    vmovsd {{.*#+}} xmm3 = [-2.147483648E+9,0.0E+0]
-; CHECK-AVX10_1-NEXT:    vmaxsd %xmm3, %xmm2, %xmm4
-; CHECK-AVX10_1-NEXT:    vmovsd {{.*#+}} xmm5 = [2.147483647E+9,0.0E+0]
-; CHECK-AVX10_1-NEXT:    vminsd %xmm5, %xmm4, %xmm4
-; CHECK-AVX10_1-NEXT:    vcvttsd2si %xmm4, %ecx
-; CHECK-AVX10_1-NEXT:    xorl %eax, %eax
-; CHECK-AVX10_1-NEXT:    vucomisd %xmm2, %xmm2
-; CHECK-AVX10_1-NEXT:    cmovpl %eax, %ecx
-; CHECK-AVX10_1-NEXT:    vmaxsd %xmm3, %xmm1, %xmm2
-; CHECK-AVX10_1-NEXT:    vminsd %xmm5, %xmm2, %xmm2
-; CHECK-AVX10_1-NEXT:    vcvttsd2si %xmm2, %edx
-; CHECK-AVX10_1-NEXT:    vucomisd %xmm1, %xmm1
-; CHECK-AVX10_1-NEXT:    cmovpl %eax, %edx
-; CHECK-AVX10_1-NEXT:    vmovd %edx, %xmm1
-; CHECK-AVX10_1-NEXT:    vpinsrd $1, %ecx, %xmm1, %xmm1
-; CHECK-AVX10_1-NEXT:    vextractf32x4 $3, %zmm0, %xmm2
-; CHECK-AVX10_1-NEXT:    vmaxsd %xmm3, %xmm2, %xmm4
-; CHECK-AVX10_1-NEXT:    vminsd %xmm5, %xmm4, %xmm4
-; CHECK-AVX10_1-NEXT:    vcvttsd2si %xmm4, %ecx
-; CHECK-AVX10_1-NEXT:    vucomisd %xmm2, %xmm2
-; CHECK-AVX10_1-NEXT:    cmovpl %eax, %ecx
-; CHECK-AVX10_1-NEXT:    vpinsrd $2, %ecx, %xmm1, %xmm1
-; CHECK-AVX10_1-NEXT:    vshufpd {{.*#+}} xmm2 = xmm2[1,0]
-; CHECK-AVX10_1-NEXT:    vmaxsd %xmm3, %xmm2, %xmm4
-; CHECK-AVX10_1-NEXT:    vminsd %xmm5, %xmm4, %xmm4
-; CHECK-AVX10_1-NEXT:    vcvttsd2si %xmm4, %ecx
-; CHECK-AVX10_1-NEXT:    vucomisd %xmm2, %xmm2
-; CHECK-AVX10_1-NEXT:    cmovpl %eax, %ecx
-; CHECK-AVX10_1-NEXT:    vpinsrd $3, %ecx, %xmm1, %xmm1
-; CHECK-AVX10_1-NEXT:    vshufpd {{.*#+}} xmm2 = xmm0[1,0]
-; CHECK-AVX10_1-NEXT:    vmaxsd %xmm3, %xmm2, %xmm4
-; CHECK-AVX10_1-NEXT:    vminsd %xmm5, %xmm4, %xmm4
-; CHECK-AVX10_1-NEXT:    vcvttsd2si %xmm4, %ecx
-; CHECK-AVX10_1-NEXT:    vucomisd %xmm2, %xmm2
-; CHECK-AVX10_1-NEXT:    cmovpl %eax, %ecx
-; CHECK-AVX10_1-NEXT:    vmaxsd %xmm3, %xmm0, %xmm2
-; CHECK-AVX10_1-NEXT:    vminsd %xmm5, %xmm2, %xmm2
-; CHECK-AVX10_1-NEXT:    vcvttsd2si %xmm2, %edx
-; CHECK-AVX10_1-NEXT:    vucomisd %xmm0, %xmm0
-; CHECK-AVX10_1-NEXT:    cmovpl %eax, %edx
-; CHECK-AVX10_1-NEXT:    vmovd %edx, %xmm2
-; CHECK-AVX10_1-NEXT:    vpinsrd $1, %ecx, %xmm2, %xmm2
-; CHECK-AVX10_1-NEXT:    vextractf128 $1, %ymm0, %xmm0
-; CHECK-AVX10_1-NEXT:    vmaxsd %xmm3, %xmm0, %xmm4
-; CHECK-AVX10_1-NEXT:    vminsd %xmm5, %xmm4, %xmm4
-; CHECK-AVX10_1-NEXT:    vcvttsd2si %xmm4, %ecx
-; CHECK-AVX10_1-NEXT:    vucomisd %xmm0, %xmm0
-; CHECK-AVX10_1-NEXT:    cmovpl %eax, %ecx
-; CHECK-AVX10_1-NEXT:    vpinsrd $2, %ecx, %xmm2, %xmm2
-; CHECK-AVX10_1-NEXT:    vshufpd {{.*#+}} xmm0 = xmm0[1,0]
-; CHECK-AVX10_1-NEXT:    vmaxsd %xmm3, %xmm0, %xmm3
-; CHECK-AVX10_1-NEXT:    vminsd %xmm5, %xmm3, %xmm3
-; CHECK-AVX10_1-NEXT:    vcvttsd2si %xmm3, %ecx
-; CHECK-AVX10_1-NEXT:    vucomisd %xmm0, %xmm0
-; CHECK-AVX10_1-NEXT:    cmovpl %eax, %ecx
-; CHECK-AVX10_1-NEXT:    vpinsrd $3, %ecx, %xmm2, %xmm0
-; CHECK-AVX10_1-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
+; CHECK-AVX10_1-NEXT:    vcmpgepd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %k1
+; CHECK-AVX10_1-NEXT:    vcvttpd2dq %zmm0, %ymm1
+; CHECK-AVX10_1-NEXT:    vpbroadcastd {{.*#+}} ymm1 {%k1} = [2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647]
+; CHECK-AVX10_1-NEXT:    vcmpunordpd %zmm0, %zmm0, %k0
+; CHECK-AVX10_1-NEXT:    knotb %k0, %k1
+; CHECK-AVX10_1-NEXT:    vmovdqa32 %ymm1, %ymm0 {%k1} {z}
 ; CHECK-AVX10_1-NEXT:    retq
 ;
 ; CHECK-AVX10_2-LABEL: foo_avx10.2:

>From e669955e0b72b170ba430d697d2ec6e81b7a4865 Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Sun, 14 Jun 2026 13:01:46 +0200
Subject: [PATCH 11/18] Improve comment

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index b78fff98156e9..305df43af6b83 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22442,10 +22442,10 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
     SDValue Res = DAG.getNode(IsSigned ? X86ISD::CVTTP2IBS : X86ISD::CVTTP2IUBS,
                               dl, VecI16VT, Src);
     return DAG.getNode(ISD::TRUNCATE, dl, DstVT, Res);
-  } 
+  }
   if ((DstVT == MVT::v4i32 && Subtarget.hasSSE2()) ||
-             (DstVT == MVT::v8i32 && Subtarget.hasAVX()) ||
-             (DstVT == MVT::v16i32 && Subtarget.hasAVX512())) {
+      (DstVT == MVT::v8i32 && Subtarget.hasAVX()) ||
+      (DstVT == MVT::v16i32 && Subtarget.hasAVX512())) {
     unsigned SatWidth = SatVT.getScalarSizeInBits();
     assert(SatWidth <= 32 &&
            "Expected saturation width no wider than result element");
@@ -22496,8 +22496,7 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
           IsOvf = DAG.getNode(ISD::TRUNCATE, dl, SelCCVT, IsOvf);
         // v16i32 (512-bit, AVX512): use X86ISD::CVTTP2UI (VCVTTPS2UDQZ).
         // v4i32 (128-bit, SSE) and v8i32 (256-bit, AVX) are already covered
-        // by CVTTPS2DQ/VCVTTPS2DQ via expandFP_TO_UINT_SSE — no AVX512VL
-        // needed.
+        // by CVTTPS2DQ/VCVTTPS2DQ via expandFP_TO_UINT_SSE
         SDValue Cvt;
         if (DstVT == MVT::v16i32)
           Cvt = DAG.getNode(X86ISD::CVTTP2UI, dl, DstVT, Clamped);

>From 237a9a6d507e135cb1ca44d2af1b5b779effa53d Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Sun, 14 Jun 2026 19:31:28 +0200
Subject: [PATCH 12/18] update fptoi.sat.ll

---
 llvm/test/Analysis/CostModel/X86/fptoi_sat.ll | 376 +++++++++---------
 1 file changed, 188 insertions(+), 188 deletions(-)

diff --git a/llvm/test/Analysis/CostModel/X86/fptoi_sat.ll b/llvm/test/Analysis/CostModel/X86/fptoi_sat.ll
index 41bf88b1ec316..6e464ef667503 100644
--- a/llvm/test/Analysis/CostModel/X86/fptoi_sat.ll
+++ b/llvm/test/Analysis/CostModel/X86/fptoi_sat.ll
@@ -38,8 +38,8 @@ define void @casts() {
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v2f32u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f32(<2 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 17 for instruction: %v2f32s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f32(<2 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v2f32u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f32(<2 x float> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v2f32s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v2f32u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f32s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f32u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 26 for instruction: %v2f32s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f32(<2 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 22 for instruction: %v2f32u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f32(<2 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 19 for instruction: %v2f64s1 = call <2 x i1> @llvm.fptosi.sat.v2i1.v2f64(<2 x double> undef)
@@ -48,28 +48,28 @@ define void @casts() {
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v2f64u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f64(<2 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 17 for instruction: %v2f64s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f64(<2 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v2f64u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f64(<2 x double> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v2f64s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v2f64u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f64s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f64u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 26 for instruction: %v2f64s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f64(<2 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 44 for instruction: %v2f64u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f64(<2 x double> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v4f32s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f32(<4 x float> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v4f32u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f32(<4 x float> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f32(<4 x float> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f32(<4 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v4f32s8 = call <4 x i8> @llvm.fptosi.sat.v4i8.v4f32(<4 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v4f32u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f32(<4 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 17 for instruction: %v4f32s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f32(<4 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v4f32u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f32(<4 x float> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v4f32s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v4f32u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 43 for instruction: %v4f32s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f32(<4 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 37 for instruction: %v4f32u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f32(<4 x float> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 30 for instruction: %v4f64s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f64(<4 x double> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 32 for instruction: %v4f64u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f64(<4 x double> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f64(<4 x double> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f64(<4 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 34 for instruction: %v4f64s8 = call <4 x i8> @llvm.fptosi.sat.v4i8.v4f64(<4 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 28 for instruction: %v4f64u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f64(<4 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 32 for instruction: %v4f64s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f64(<4 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 26 for instruction: %v4f64u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f64(<4 x double> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 30 for instruction: %v4f64s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 32 for instruction: %v4f64u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 52 for instruction: %v4f64s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f64(<4 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 88 for instruction: %v4f64u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f64(<4 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 32 for instruction: %v8f32s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f32(<8 x float> undef)
@@ -78,8 +78,8 @@ define void @casts() {
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 28 for instruction: %v8f32u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f32(<8 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 32 for instruction: %v8f32s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f32(<8 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 26 for instruction: %v8f32u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f32(<8 x float> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 32 for instruction: %v8f32s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 32 for instruction: %v8f32u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f32s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f32u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 86 for instruction: %v8f32s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f32(<8 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 74 for instruction: %v8f32u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f32(<8 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 62 for instruction: %v8f64s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f64(<8 x double> undef)
@@ -88,8 +88,8 @@ define void @casts() {
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 56 for instruction: %v8f64u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f64(<8 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 62 for instruction: %v8f64s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f64(<8 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 52 for instruction: %v8f64u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f64(<8 x double> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 60 for instruction: %v8f64s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f64(<8 x double> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 64 for instruction: %v8f64u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f64s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f64(<8 x double> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f64u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 104 for instruction: %v8f64s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f64(<8 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 176 for instruction: %v8f64u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f64(<8 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 66 for instruction: %v16f32s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f32(<16 x float> undef)
@@ -98,8 +98,8 @@ define void @casts() {
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 56 for instruction: %v16f32u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f32(<16 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 64 for instruction: %v16f32s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f32(<16 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 52 for instruction: %v16f32u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f32(<16 x float> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 64 for instruction: %v16f32s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f32(<16 x float> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 64 for instruction: %v16f32u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f32s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f32(<16 x float> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f32u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 172 for instruction: %v16f32s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f32(<16 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 148 for instruction: %v16f32u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f32(<16 x float> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 130 for instruction: %v16f64s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f64(<16 x double> undef)
@@ -108,8 +108,8 @@ define void @casts() {
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 112 for instruction: %v16f64u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f64(<16 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 124 for instruction: %v16f64s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f64(<16 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 104 for instruction: %v16f64u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f64(<16 x double> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 120 for instruction: %v16f64s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f64(<16 x double> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 128 for instruction: %v16f64u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f64(<16 x double> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f64s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f64(<16 x double> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f64u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f64(<16 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 208 for instruction: %v16f64s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f64(<16 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 352 for instruction: %v16f64u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f64(<16 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
@@ -141,8 +141,8 @@ define void @casts() {
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v2f32u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f32(<2 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f32s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f32(<2 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v2f32u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f32(<2 x float> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f32s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f32u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f32s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f32u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 17 for instruction: %v2f32s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f32(<2 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %v2f32u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f32(<2 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 17 for instruction: %v2f64s1 = call <2 x i1> @llvm.fptosi.sat.v2i1.v2f64(<2 x double> undef)
@@ -151,28 +151,28 @@ define void @casts() {
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v2f64u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f64(<2 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f64s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f64(<2 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v2f64u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f64(<2 x double> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f64s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f64u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f64s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f64u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 17 for instruction: %v2f64s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f64(<2 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %v2f64u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f64(<2 x double> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v4f32s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f32(<4 x float> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v4f32u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f32(<4 x float> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f32(<4 x float> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f32(<4 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v4f32s8 = call <4 x i8> @llvm.fptosi.sat.v4i8.v4f32(<4 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v4f32u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f32(<4 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v4f32s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f32(<4 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v4f32u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f32(<4 x float> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v4f32s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v4f32u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 26 for instruction: %v4f32s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f32(<4 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 33 for instruction: %v4f32u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f32(<4 x float> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 22 for instruction: %v4f64s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f64(<4 x double> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v4f64u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f64(<4 x double> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f64(<4 x double> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f64(<4 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v4f64s8 = call <4 x i8> @llvm.fptosi.sat.v4i8.v4f64(<4 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %v4f64u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f64(<4 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 22 for instruction: %v4f64s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f64(<4 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v4f64u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f64(<4 x double> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 22 for instruction: %v4f64s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v4f64u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 34 for instruction: %v4f64s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f64(<4 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 40 for instruction: %v4f64u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f64(<4 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 22 for instruction: %v8f32s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f32(<8 x float> undef)
@@ -181,8 +181,8 @@ define void @casts() {
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %v8f32u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f32(<8 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 22 for instruction: %v8f32s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f32(<8 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v8f32u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f32(<8 x float> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v8f32s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v8f32u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f32s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f32u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 52 for instruction: %v8f32s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f32(<8 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 66 for instruction: %v8f32u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f32(<8 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 42 for instruction: %v8f64s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f64(<8 x double> undef)
@@ -191,8 +191,8 @@ define void @casts() {
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 40 for instruction: %v8f64u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f64(<8 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 42 for instruction: %v8f64s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f64(<8 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 36 for instruction: %v8f64u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f64(<8 x double> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 44 for instruction: %v8f64s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f64(<8 x double> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 48 for instruction: %v8f64u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f64s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f64(<8 x double> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f64u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 68 for instruction: %v8f64s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f64(<8 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 80 for instruction: %v8f64u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f64(<8 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 46 for instruction: %v16f32s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f32(<16 x float> undef)
@@ -201,8 +201,8 @@ define void @casts() {
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 40 for instruction: %v16f32u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f32(<16 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 44 for instruction: %v16f32s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f32(<16 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 36 for instruction: %v16f32u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f32(<16 x float> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 48 for instruction: %v16f32s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f32(<16 x float> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 48 for instruction: %v16f32u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f32s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f32(<16 x float> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f32u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 104 for instruction: %v16f32s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f32(<16 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 132 for instruction: %v16f32u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f32(<16 x float> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 90 for instruction: %v16f64s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f64(<16 x double> undef)
@@ -211,8 +211,8 @@ define void @casts() {
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 80 for instruction: %v16f64u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f64(<16 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 84 for instruction: %v16f64s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f64(<16 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 72 for instruction: %v16f64u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f64(<16 x double> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 88 for instruction: %v16f64s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f64(<16 x double> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 96 for instruction: %v16f64u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f64(<16 x double> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f64s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f64(<16 x double> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f64u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f64(<16 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 136 for instruction: %v16f64s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f64(<16 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 160 for instruction: %v16f64u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f64(<16 x double> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
@@ -244,8 +244,8 @@ define void @casts() {
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v2f32u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f32(<2 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v2f32s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f32(<2 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %v2f32u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f32(<2 x float> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v2f32s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v2f32u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f32s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f32u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 15 for instruction: %v2f32s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f32(<2 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v2f32u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f32(<2 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 15 for instruction: %v2f64s1 = call <2 x i1> @llvm.fptosi.sat.v2i1.v2f64(<2 x double> undef)
@@ -254,28 +254,28 @@ define void @casts() {
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v2f64u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f64(<2 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v2f64s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f64(<2 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %v2f64u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f64(<2 x double> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v2f64s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v2f64u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f64s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f64u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 15 for instruction: %v2f64s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f64(<2 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v2f64u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f64(<2 x double> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v4f32s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f32(<4 x float> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v4f32u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f32(<4 x float> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f32(<4 x float> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f32(<4 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v4f32s8 = call <4 x i8> @llvm.fptosi.sat.v4i8.v4f32(<4 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v4f32u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f32(<4 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v4f32s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f32(<4 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %v4f32u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f32(<4 x float> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v4f32s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v4f32u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v4f32s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f32(<4 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 32 for instruction: %v4f32u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f32(<4 x float> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v4f64s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f64(<4 x double> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v4f64u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f64(<4 x double> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f64(<4 x double> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f64(<4 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v4f64s8 = call <4 x i8> @llvm.fptosi.sat.v4i8.v4f64(<4 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v4f64u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f64(<4 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v4f64s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f64(<4 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v4f64u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f64(<4 x double> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v4f64s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v4f64u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 29 for instruction: %v4f64s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f64(<4 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 36 for instruction: %v4f64u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f64(<4 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v8f32s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f32(<8 x float> undef)
@@ -284,8 +284,8 @@ define void @casts() {
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v8f32u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f32(<8 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v8f32s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f32(<8 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v8f32u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f32(<8 x float> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 17 for instruction: %v8f32s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 17 for instruction: %v8f32u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f32s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f32u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 47 for instruction: %v8f32s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f32(<8 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 63 for instruction: %v8f32u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f32(<8 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 30 for instruction: %v8f64s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f64(<8 x double> undef)
@@ -294,8 +294,8 @@ define void @casts() {
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v8f64u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f64(<8 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 30 for instruction: %v8f64s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f64(<8 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v8f64u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f64(<8 x double> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 32 for instruction: %v8f64s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f64(<8 x double> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 34 for instruction: %v8f64u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f64s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f64(<8 x double> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f64u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 58 for instruction: %v8f64s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f64(<8 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 72 for instruction: %v8f64u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f64(<8 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 30 for instruction: %v16f32s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f32(<16 x float> undef)
@@ -304,8 +304,8 @@ define void @casts() {
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v16f32u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f32(<16 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 31 for instruction: %v16f32s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f32(<16 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v16f32u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f32(<16 x float> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 34 for instruction: %v16f32s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f32(<16 x float> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 34 for instruction: %v16f32u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v16f32s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f32(<16 x float> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v16f32u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 94 for instruction: %v16f32s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f32(<16 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 126 for instruction: %v16f32u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f32(<16 x float> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 58 for instruction: %v16f64s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f64(<16 x double> undef)
@@ -314,8 +314,8 @@ define void @casts() {
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 48 for instruction: %v16f64u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f64(<16 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 59 for instruction: %v16f64s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f64(<16 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 48 for instruction: %v16f64u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f64(<16 x double> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 64 for instruction: %v16f64s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f64(<16 x double> undef)
-; AVX1-NEXT:  Cost Model: Found an estimated cost of 68 for instruction: %v16f64u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f64(<16 x double> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v16f64s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f64(<16 x double> undef)
+; AVX1-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v16f64u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f64(<16 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 116 for instruction: %v16f64s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f64(<16 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 144 for instruction: %v16f64u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f64(<16 x double> undef)
 ; AVX1-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
@@ -347,8 +347,8 @@ define void @casts() {
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 6 for instruction: %v2f32u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f32(<2 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v2f32s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f32(<2 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v2f32u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f32(<2 x float> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v2f32s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %v2f32u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f32s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f32u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v2f32s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f32(<2 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v2f32u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f32(<2 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v2f64s1 = call <2 x i1> @llvm.fptosi.sat.v2i1.v2f64(<2 x double> undef)
@@ -357,28 +357,28 @@ define void @casts() {
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 6 for instruction: %v2f64u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f64(<2 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v2f64s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f64(<2 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v2f64u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f64(<2 x double> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v2f64s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v2f64u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f64s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f64u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v2f64s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f64(<2 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v2f64u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f64(<2 x double> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v4f32s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f32(<4 x float> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %v4f32u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f32(<4 x float> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f32(<4 x float> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f32(<4 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v4f32s8 = call <4 x i8> @llvm.fptosi.sat.v4i8.v4f32(<4 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 6 for instruction: %v4f32u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f32(<4 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v4f32s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f32(<4 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v4f32u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f32(<4 x float> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v4f32s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %v4f32u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 21 for instruction: %v4f32s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f32(<4 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 26 for instruction: %v4f32u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f32(<4 x float> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v4f64s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f64(<4 x double> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v4f64u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f64(<4 x double> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f64(<4 x double> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f64(<4 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v4f64s8 = call <4 x i8> @llvm.fptosi.sat.v4i8.v4f64(<4 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v4f64u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f64(<4 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v4f64s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f64(<4 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v4f64u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f64(<4 x double> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v4f64s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v4f64u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 23 for instruction: %v4f64s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f64(<4 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 28 for instruction: %v4f64u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f64(<4 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v8f32s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f32(<8 x float> undef)
@@ -387,8 +387,8 @@ define void @casts() {
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v8f32u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f32(<8 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v8f32s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f32(<8 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v8f32u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f32(<8 x float> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v8f32s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v8f32u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f32s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f32u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 40 for instruction: %v8f32s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f32(<8 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 51 for instruction: %v8f32u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f32(<8 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %v8f64s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f64(<8 x double> undef)
@@ -397,8 +397,8 @@ define void @casts() {
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v8f64u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f64(<8 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %v8f64s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f64(<8 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v8f64u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f64(<8 x double> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 19 for instruction: %v8f64s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f64(<8 x double> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %v8f64u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f64s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f64(<8 x double> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f64u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 46 for instruction: %v8f64s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f64(<8 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 56 for instruction: %v8f64u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f64(<8 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %v16f32s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f32(<16 x float> undef)
@@ -407,8 +407,8 @@ define void @casts() {
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v16f32u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f32(<16 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v16f32s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f32(<16 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v16f32u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f32(<16 x float> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %v16f32s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f32(<16 x float> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v16f32u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v16f32s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f32(<16 x float> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v16f32u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 80 for instruction: %v16f32s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f32(<16 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 102 for instruction: %v16f32u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f32(<16 x float> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 38 for instruction: %v16f64s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f64(<16 x double> undef)
@@ -417,8 +417,8 @@ define void @casts() {
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 32 for instruction: %v16f64u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f64(<16 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 38 for instruction: %v16f64s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f64(<16 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 32 for instruction: %v16f64u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f64(<16 x double> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 38 for instruction: %v16f64s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f64(<16 x double> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 40 for instruction: %v16f64u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f64(<16 x double> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v16f64s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f64(<16 x double> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v16f64u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f64(<16 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 92 for instruction: %v16f64s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f64(<16 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 112 for instruction: %v16f64u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f64(<16 x double> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
@@ -450,8 +450,8 @@ define void @casts() {
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v2f32u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f32(<2 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v2f32s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f32(<2 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %v2f32u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f32(<2 x float> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v2f32s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %v2f32u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f32s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f32u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v2f32s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f32(<2 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v2f32u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f32(<2 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v2f64s1 = call <2 x i1> @llvm.fptosi.sat.v2i1.v2f64(<2 x double> undef)
@@ -460,8 +460,8 @@ define void @casts() {
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v2f64u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f64(<2 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v2f64s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f64(<2 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %v2f64u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f64(<2 x double> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v2f64s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %v2f64u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f64s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f64u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v2f64s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f64(<2 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v2f64u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f64(<2 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v4f32s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f32(<4 x float> undef)
@@ -470,8 +470,8 @@ define void @casts() {
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v4f32u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f32(<4 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v4f32s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f32(<4 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %v4f32u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f32(<4 x float> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v4f32s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %v4f32u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v4f32s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f32(<4 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v4f32u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f32(<4 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v4f64s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f64(<4 x double> undef)
@@ -480,8 +480,8 @@ define void @casts() {
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 6 for instruction: %v4f64u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f64(<4 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v4f64s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f64(<4 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 6 for instruction: %v4f64u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f64(<4 x double> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %v4f64s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v4f64u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %v4f64s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f64(<4 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v4f64u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f64(<4 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 22 for instruction: %v8f32s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f32(<8 x float> undef)
@@ -490,8 +490,8 @@ define void @casts() {
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 6 for instruction: %v8f32u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f32(<8 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v8f32s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f32(<8 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 6 for instruction: %v8f32u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f32(<8 x float> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %v8f32s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v8f32u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f32s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f32u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 36 for instruction: %v8f32s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f32(<8 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 34 for instruction: %v8f32u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f32(<8 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v8f64s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f64(<8 x double> undef)
@@ -500,8 +500,8 @@ define void @casts() {
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v8f64u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f64(<8 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v8f64s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f64(<8 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v8f64u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f64(<8 x double> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v8f64s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f64(<8 x double> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %v8f64u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f64s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f64(<8 x double> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f64u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 38 for instruction: %v8f64s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f64(<8 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 36 for instruction: %v8f64u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f64(<8 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 42 for instruction: %v16f32s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f32(<16 x float> undef)
@@ -510,8 +510,8 @@ define void @casts() {
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v16f32u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f32(<16 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v16f32s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f32(<16 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v16f32u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f32(<16 x float> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v16f32s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f32(<16 x float> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v16f32u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v16f32s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f32(<16 x float> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v16f32u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 72 for instruction: %v16f32s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f32(<16 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 69 for instruction: %v16f32u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f32(<16 x float> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 49 for instruction: %v16f64s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f64(<16 x double> undef)
@@ -520,8 +520,8 @@ define void @casts() {
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 17 for instruction: %v16f64u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f64(<16 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 22 for instruction: %v16f64s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f64(<16 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 17 for instruction: %v16f64u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f64(<16 x double> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v16f64s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f64(<16 x double> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 15 for instruction: %v16f64u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f64(<16 x double> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v16f64s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f64(<16 x double> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v16f64u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f64(<16 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 76 for instruction: %v16f64s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f64(<16 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 72 for instruction: %v16f64u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f64(<16 x double> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
@@ -553,8 +553,8 @@ define void @casts() {
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v2f32u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f32(<2 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v2f32s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f32(<2 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %v2f32u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f32(<2 x float> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v2f32s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %v2f32u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f32s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f32u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v2f32s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f32(<2 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %v2f32u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f32(<2 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v2f64s1 = call <2 x i1> @llvm.fptosi.sat.v2i1.v2f64(<2 x double> undef)
@@ -563,8 +563,8 @@ define void @casts() {
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v2f64u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f64(<2 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v2f64s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f64(<2 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %v2f64u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f64(<2 x double> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v2f64s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %v2f64u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f64s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f64u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v2f64s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f64(<2 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %v2f64u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f64(<2 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v4f32s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f32(<4 x float> undef)
@@ -573,8 +573,8 @@ define void @casts() {
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v4f32u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f32(<4 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v4f32s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f32(<4 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %v4f32u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f32(<4 x float> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v4f32s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %v4f32u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v4f32s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f32(<4 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 3 for instruction: %v4f32u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f32(<4 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v4f64s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f64(<4 x double> undef)
@@ -583,8 +583,8 @@ define void @casts() {
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 6 for instruction: %v4f64u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f64(<4 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v4f64s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f64(<4 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 6 for instruction: %v4f64u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f64(<4 x double> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %v4f64s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v4f64u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %v4f64s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f64(<4 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v4f64u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f64(<4 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 22 for instruction: %v8f32s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f32(<8 x float> undef)
@@ -593,8 +593,8 @@ define void @casts() {
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 6 for instruction: %v8f32u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f32(<8 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v8f32s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f32(<8 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 6 for instruction: %v8f32u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f32(<8 x float> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %v8f32s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v8f32u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f32s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f32u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %v8f32s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f32(<8 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 5 for instruction: %v8f32u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f32(<8 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v8f64s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f64(<8 x double> undef)
@@ -603,8 +603,8 @@ define void @casts() {
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v8f64u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f64(<8 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v8f64s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f64(<8 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v8f64u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f64(<8 x double> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v8f64s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f64(<8 x double> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %v8f64u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f64s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f64(<8 x double> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f64u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v8f64s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f64(<8 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 7 for instruction: %v8f64u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f64(<8 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 42 for instruction: %v16f32s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f32(<16 x float> undef)
@@ -613,8 +613,8 @@ define void @casts() {
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v16f32u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f32(<16 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v16f32s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f32(<16 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v16f32u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f32(<16 x float> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v16f32s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f32(<16 x float> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v16f32u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v16f32s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f32(<16 x float> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v16f32u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v16f32s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f32(<16 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v16f32u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f32(<16 x float> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 49 for instruction: %v16f64s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f64(<16 x double> undef)
@@ -623,8 +623,8 @@ define void @casts() {
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 17 for instruction: %v16f64u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f64(<16 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 22 for instruction: %v16f64s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f64(<16 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 17 for instruction: %v16f64u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f64(<16 x double> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v16f64s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f64(<16 x double> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 15 for instruction: %v16f64u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f64(<16 x double> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v16f64s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f64(<16 x double> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v16f64u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f64(<16 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v16f64s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f64(<16 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v16f64u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f64(<16 x double> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
@@ -656,8 +656,8 @@ define void @casts() {
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v2f32u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f32(<2 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v2f32s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f32(<2 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v2f32u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f32(<2 x float> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f32s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f32u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f32s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f32(<2 x float> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f32u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f32(<2 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 25 for instruction: %v2f32s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f32(<2 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 26 for instruction: %v2f32u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f32(<2 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 19 for instruction: %v2f64s1 = call <2 x i1> @llvm.fptosi.sat.v2i1.v2f64(<2 x double> undef)
@@ -666,28 +666,28 @@ define void @casts() {
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v2f64u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f64(<2 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v2f64s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f64(<2 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v2f64u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f64(<2 x double> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f64s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f64u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f64s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f64(<2 x double> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f64u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f64(<2 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 25 for instruction: %v2f64s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f64(<2 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 26 for instruction: %v2f64u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f64(<2 x double> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v4f32s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f32(<4 x float> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v4f32u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f32(<4 x float> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f32(<4 x float> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f32(<4 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 15 for instruction: %v4f32s8 = call <4 x i8> @llvm.fptosi.sat.v4i8.v4f32(<4 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %v4f32u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f32(<4 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v4f32s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f32(<4 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 9 for instruction: %v4f32u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f32(<4 x float> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v4f32s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v4f32u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f32u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 42 for instruction: %v4f32s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f32(<4 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 45 for instruction: %v4f32u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f32(<4 x float> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 22 for instruction: %v4f64s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f64(<4 x double> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v4f64u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f64(<4 x double> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f64(<4 x double> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f64(<4 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 26 for instruction: %v4f64s8 = call <4 x i8> @llvm.fptosi.sat.v4i8.v4f64(<4 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %v4f64u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f64(<4 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v4f64s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f64(<4 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v4f64u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f64(<4 x double> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 22 for instruction: %v4f64s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v4f64u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f64u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 50 for instruction: %v4f64s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f64(<4 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 52 for instruction: %v4f64u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f64(<4 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v8f32s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f32(<8 x float> undef)
@@ -696,8 +696,8 @@ define void @casts() {
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 20 for instruction: %v8f32u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f32(<8 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v8f32s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f32(<8 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v8f32u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f32(<8 x float> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v8f32s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v8f32u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f32s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f32u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 84 for instruction: %v8f32s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f32(<8 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 90 for instruction: %v8f32u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f32(<8 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 44 for instruction: %v8f64s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f64(<8 x double> undef)
@@ -706,8 +706,8 @@ define void @casts() {
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 40 for instruction: %v8f64u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f64(<8 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 44 for instruction: %v8f64s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f64(<8 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 36 for instruction: %v8f64u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f64(<8 x double> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 44 for instruction: %v8f64s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f64(<8 x double> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 48 for instruction: %v8f64u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f64s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f64(<8 x double> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f64u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 100 for instruction: %v8f64s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f64(<8 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 104 for instruction: %v8f64u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f64(<8 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 48 for instruction: %v16f32s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f32(<16 x float> undef)
@@ -716,8 +716,8 @@ define void @casts() {
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 40 for instruction: %v16f32u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f32(<16 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 48 for instruction: %v16f32s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f32(<16 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 36 for instruction: %v16f32u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f32(<16 x float> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 48 for instruction: %v16f32s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f32(<16 x float> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 48 for instruction: %v16f32u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f32s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f32(<16 x float> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f32u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 168 for instruction: %v16f32s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f32(<16 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 180 for instruction: %v16f32u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f32(<16 x float> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 92 for instruction: %v16f64s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f64(<16 x double> undef)
@@ -726,8 +726,8 @@ define void @casts() {
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 80 for instruction: %v16f64u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f64(<16 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 88 for instruction: %v16f64s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f64(<16 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 72 for instruction: %v16f64u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f64(<16 x double> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 88 for instruction: %v16f64s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f64(<16 x double> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 96 for instruction: %v16f64u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f64(<16 x double> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f64s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f64(<16 x double> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f64u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f64(<16 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 200 for instruction: %v16f64s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f64(<16 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 208 for instruction: %v16f64u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f64(<16 x double> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
@@ -863,18 +863,18 @@ define void @fp16() {
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v2f16u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f16(<2 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v2f16s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f16(<2 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f16u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f16(<2 x half> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 15 for instruction: %v2f16s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f16(<2 x half> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v2f16u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f16(<2 x half> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f16s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f16(<2 x half> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f16u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f16(<2 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 15 for instruction: %v2f16s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f16(<2 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v2f16u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f16(<2 x half> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 29 for instruction: %v4f16s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f16(<4 x half> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 23 for instruction: %v4f16u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f16(<4 x half> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f16(<4 x half> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f16(<4 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 32 for instruction: %v4f16s8 = call <4 x i8> @llvm.fptosi.sat.v4i8.v4f16(<4 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 26 for instruction: %v4f16u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f16(<4 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 32 for instruction: %v4f16s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f16(<4 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 26 for instruction: %v4f16u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f16(<4 x half> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 29 for instruction: %v4f16s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f16(<4 x half> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 23 for instruction: %v4f16u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f16(<4 x half> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f16(<4 x half> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f16(<4 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 30 for instruction: %v4f16s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f16(<4 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 22 for instruction: %v4f16u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f16(<4 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 99 for instruction: %v8f16s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f16(<8 x half> undef)
@@ -883,8 +883,8 @@ define void @fp16() {
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 79 for instruction: %v8f16u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f16(<8 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 95 for instruction: %v8f16s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f16(<8 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 78 for instruction: %v8f16u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f16(<8 x half> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 92 for instruction: %v8f16s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f16(<8 x half> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 73 for instruction: %v8f16u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f16(<8 x half> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f16s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f16(<8 x half> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f16u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f16(<8 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 94 for instruction: %v8f16s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f16(<8 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 71 for instruction: %v8f16u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f16(<8 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 197 for instruction: %v16f16s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f16(<16 x half> undef)
@@ -893,8 +893,8 @@ define void @fp16() {
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 153 for instruction: %v16f16u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f16(<16 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 190 for instruction: %v16f16s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f16(<16 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 156 for instruction: %v16f16u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f16(<16 x half> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 184 for instruction: %v16f16s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f16(<16 x half> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 146 for instruction: %v16f16u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f16(<16 x half> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f16s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f16(<16 x half> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f16u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f16(<16 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 188 for instruction: %v16f16s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f16(<16 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 142 for instruction: %v16f16u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f16(<16 x half> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
@@ -916,18 +916,18 @@ define void @fp16() {
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v2f16u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f16(<2 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v2f16s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f16(<2 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f16u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f16(<2 x half> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 15 for instruction: %v2f16s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f16(<2 x half> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v2f16u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f16(<2 x half> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f16s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f16(<2 x half> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f16u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f16(<2 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 15 for instruction: %v2f16s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f16(<2 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v2f16u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f16(<2 x half> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 29 for instruction: %v4f16s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f16(<4 x half> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 23 for instruction: %v4f16u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f16(<4 x half> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f16(<4 x half> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f16(<4 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 31 for instruction: %v4f16s8 = call <4 x i8> @llvm.fptosi.sat.v4i8.v4f16(<4 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 25 for instruction: %v4f16u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f16(<4 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 31 for instruction: %v4f16s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f16(<4 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 25 for instruction: %v4f16u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f16(<4 x half> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 29 for instruction: %v4f16s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f16(<4 x half> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 23 for instruction: %v4f16u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f16(<4 x half> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f16(<4 x half> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f16(<4 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 30 for instruction: %v4f16s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f16(<4 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 22 for instruction: %v4f16u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f16(<4 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 99 for instruction: %v8f16s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f16(<8 x half> undef)
@@ -936,8 +936,8 @@ define void @fp16() {
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 77 for instruction: %v8f16u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f16(<8 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 95 for instruction: %v8f16s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f16(<8 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 78 for instruction: %v8f16u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f16(<8 x half> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 92 for instruction: %v8f16s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f16(<8 x half> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 73 for instruction: %v8f16u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f16(<8 x half> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f16s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f16(<8 x half> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f16u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f16(<8 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 94 for instruction: %v8f16s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f16(<8 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 71 for instruction: %v8f16u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f16(<8 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 197 for instruction: %v16f16s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f16(<16 x half> undef)
@@ -946,8 +946,8 @@ define void @fp16() {
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 153 for instruction: %v16f16u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f16(<16 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 190 for instruction: %v16f16s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f16(<16 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 156 for instruction: %v16f16u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f16(<16 x half> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 184 for instruction: %v16f16s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f16(<16 x half> undef)
-; SSE42-NEXT:  Cost Model: Found an estimated cost of 146 for instruction: %v16f16u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f16(<16 x half> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f16s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f16(<16 x half> undef)
+; SSE42-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f16u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f16(<16 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 188 for instruction: %v16f16s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f16(<16 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 142 for instruction: %v16f16u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f16(<16 x half> undef)
 ; SSE42-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
@@ -969,18 +969,18 @@ define void @fp16() {
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f16u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f16(<2 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v2f16s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f16(<2 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f16u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f16(<2 x half> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 15 for instruction: %v2f16s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f16(<2 x half> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v2f16u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f16(<2 x half> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f16s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f16(<2 x half> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f16u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f16(<2 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 15 for instruction: %v2f16s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f16(<2 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v2f16u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f16(<2 x half> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 29 for instruction: %v4f16s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f16(<4 x half> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 23 for instruction: %v4f16u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f16(<4 x half> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f16(<4 x half> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f16(<4 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 30 for instruction: %v4f16s8 = call <4 x i8> @llvm.fptosi.sat.v4i8.v4f16(<4 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v4f16u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f16(<4 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 30 for instruction: %v4f16s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f16(<4 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 24 for instruction: %v4f16u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f16(<4 x half> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 29 for instruction: %v4f16s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f16(<4 x half> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 23 for instruction: %v4f16u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f16(<4 x half> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f16(<4 x half> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f16(<4 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 29 for instruction: %v4f16s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f16(<4 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 23 for instruction: %v4f16u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f16(<4 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 76 for instruction: %v8f16s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f16(<8 x half> undef)
@@ -989,8 +989,8 @@ define void @fp16() {
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 88 for instruction: %v8f16u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f16(<8 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 103 for instruction: %v8f16s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f16(<8 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 86 for instruction: %v8f16u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f16(<8 x half> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 101 for instruction: %v8f16s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f16(<8 x half> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 84 for instruction: %v8f16u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f16(<8 x half> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f16s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f16(<8 x half> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f16u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f16(<8 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 92 for instruction: %v8f16s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f16(<8 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 73 for instruction: %v8f16u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f16(<8 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 203 for instruction: %v16f16s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f16(<16 x half> undef)
@@ -999,8 +999,8 @@ define void @fp16() {
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 179 for instruction: %v16f16u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f16(<16 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 212 for instruction: %v16f16s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f16(<16 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 179 for instruction: %v16f16u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f16(<16 x half> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 210 for instruction: %v16f16s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f16(<16 x half> undef)
-; AVX2-NEXT:  Cost Model: Found an estimated cost of 175 for instruction: %v16f16u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f16(<16 x half> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v16f16s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f16(<16 x half> undef)
+; AVX2-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v16f16u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f16(<16 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 192 for instruction: %v16f16s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f16(<16 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 153 for instruction: %v16f16u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f16(<16 x half> undef)
 ; AVX2-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
@@ -1022,8 +1022,8 @@ define void @fp16() {
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v2f16u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f16(<2 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v2f16s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f16(<2 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f16u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f16(<2 x half> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v2f16s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f16(<2 x half> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v2f16u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f16(<2 x half> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f16s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f16(<2 x half> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f16u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f16(<2 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v2f16s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f16(<2 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 16 for instruction: %v2f16u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f16(<2 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 36 for instruction: %v4f16s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f16(<4 x half> undef)
@@ -1032,8 +1032,8 @@ define void @fp16() {
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 29 for instruction: %v4f16u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f16(<4 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 30 for instruction: %v4f16s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f16(<4 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 28 for instruction: %v4f16u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f16(<4 x half> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 29 for instruction: %v4f16s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f16(<4 x half> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 27 for instruction: %v4f16u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f16(<4 x half> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f16(<4 x half> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f16(<4 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 42 for instruction: %v4f16s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f16(<4 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 40 for instruction: %v4f16u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f16(<4 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 76 for instruction: %v8f16s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f16(<8 x half> undef)
@@ -1042,8 +1042,8 @@ define void @fp16() {
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 86 for instruction: %v8f16u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f16(<8 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 88 for instruction: %v8f16s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f16(<8 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 86 for instruction: %v8f16u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f16(<8 x half> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 86 for instruction: %v8f16s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f16(<8 x half> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 84 for instruction: %v8f16u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f16(<8 x half> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f16s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f16(<8 x half> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f16u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f16(<8 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 90 for instruction: %v8f16s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f16(<8 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 88 for instruction: %v8f16u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f16(<8 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 156 for instruction: %v16f16s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f16(<16 x half> undef)
@@ -1052,8 +1052,8 @@ define void @fp16() {
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 178 for instruction: %v16f16u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f16(<16 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 180 for instruction: %v16f16s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f16(<16 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 178 for instruction: %v16f16u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f16(<16 x half> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 178 for instruction: %v16f16s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f16(<16 x half> undef)
-; AVX512F-NEXT:  Cost Model: Found an estimated cost of 176 for instruction: %v16f16u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f16(<16 x half> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v16f16s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f16(<16 x half> undef)
+; AVX512F-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v16f16u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f16(<16 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 186 for instruction: %v16f16s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f16(<16 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 183 for instruction: %v16f16u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f16(<16 x half> undef)
 ; AVX512F-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
@@ -1075,8 +1075,8 @@ define void @fp16() {
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v2f16u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f16(<2 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 14 for instruction: %v2f16s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f16(<2 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f16u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f16(<2 x half> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v2f16s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f16(<2 x half> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v2f16u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f16(<2 x half> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f16s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f16(<2 x half> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f16u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f16(<2 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v2f16s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f16(<2 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v2f16u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f16(<2 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 36 for instruction: %v4f16s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f16(<4 x half> undef)
@@ -1085,8 +1085,8 @@ define void @fp16() {
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 29 for instruction: %v4f16u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f16(<4 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 30 for instruction: %v4f16s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f16(<4 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 28 for instruction: %v4f16u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f16(<4 x half> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 29 for instruction: %v4f16s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f16(<4 x half> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 27 for instruction: %v4f16u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f16(<4 x half> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f16(<4 x half> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f16(<4 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 42 for instruction: %v4f16s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f16(<4 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 40 for instruction: %v4f16u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f16(<4 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 76 for instruction: %v8f16s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f16(<8 x half> undef)
@@ -1095,8 +1095,8 @@ define void @fp16() {
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 86 for instruction: %v8f16u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f16(<8 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 88 for instruction: %v8f16s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f16(<8 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 86 for instruction: %v8f16u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f16(<8 x half> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 86 for instruction: %v8f16s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f16(<8 x half> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 84 for instruction: %v8f16u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f16(<8 x half> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f16s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f16(<8 x half> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v8f16u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f16(<8 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 90 for instruction: %v8f16s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f16(<8 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 88 for instruction: %v8f16u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f16(<8 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 156 for instruction: %v16f16s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f16(<16 x half> undef)
@@ -1105,8 +1105,8 @@ define void @fp16() {
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 178 for instruction: %v16f16u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f16(<16 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 180 for instruction: %v16f16s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f16(<16 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 178 for instruction: %v16f16u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f16(<16 x half> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 178 for instruction: %v16f16s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f16(<16 x half> undef)
-; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 176 for instruction: %v16f16u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f16(<16 x half> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v16f16s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f16(<16 x half> undef)
+; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v16f16u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f16(<16 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 186 for instruction: %v16f16s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f16(<16 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 183 for instruction: %v16f16u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f16(<16 x half> undef)
 ; AVX512DQ-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void
@@ -1128,18 +1128,18 @@ define void @fp16() {
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 13 for instruction: %v2f16u8 = call <2 x i8> @llvm.fptoui.sat.v2i8.v2f16(<2 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 18 for instruction: %v2f16s16 = call <2 x i16> @llvm.fptosi.sat.v2i16.v2f16(<2 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 12 for instruction: %v2f16u16 = call <2 x i16> @llvm.fptoui.sat.v2i16.v2f16(<2 x half> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 15 for instruction: %v2f16s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f16(<2 x half> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v2f16u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f16(<2 x half> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f16s32 = call <2 x i32> @llvm.fptosi.sat.v2i32.v2f16(<2 x half> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v2f16u32 = call <2 x i32> @llvm.fptoui.sat.v2i32.v2f16(<2 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 17 for instruction: %v2f16s64 = call <2 x i64> @llvm.fptosi.sat.v2i64.v2f16(<2 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 11 for instruction: %v2f16u64 = call <2 x i64> @llvm.fptoui.sat.v2i64.v2f16(<2 x half> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 29 for instruction: %v4f16s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f16(<4 x half> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 23 for instruction: %v4f16u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f16(<4 x half> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16s1 = call <4 x i1> @llvm.fptosi.sat.v4i1.v4f16(<4 x half> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16u1 = call <4 x i1> @llvm.fptoui.sat.v4i1.v4f16(<4 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 33 for instruction: %v4f16s8 = call <4 x i8> @llvm.fptosi.sat.v4i8.v4f16(<4 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 25 for instruction: %v4f16u8 = call <4 x i8> @llvm.fptoui.sat.v4i8.v4f16(<4 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 33 for instruction: %v4f16s16 = call <4 x i16> @llvm.fptosi.sat.v4i16.v4f16(<4 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 25 for instruction: %v4f16u16 = call <4 x i16> @llvm.fptoui.sat.v4i16.v4f16(<4 x half> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 29 for instruction: %v4f16s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f16(<4 x half> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 23 for instruction: %v4f16u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f16(<4 x half> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16s32 = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f16(<4 x half> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %v4f16u32 = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f16(<4 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 34 for instruction: %v4f16s64 = call <4 x i64> @llvm.fptosi.sat.v4i64.v4f16(<4 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 22 for instruction: %v4f16u64 = call <4 x i64> @llvm.fptoui.sat.v4i64.v4f16(<4 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 101 for instruction: %v8f16s1 = call <8 x i1> @llvm.fptosi.sat.v8i1.v8f16(<8 x half> undef)
@@ -1148,8 +1148,8 @@ define void @fp16() {
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 77 for instruction: %v8f16u8 = call <8 x i8> @llvm.fptoui.sat.v8i8.v8f16(<8 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 97 for instruction: %v8f16s16 = call <8 x i16> @llvm.fptosi.sat.v8i16.v8f16(<8 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 78 for instruction: %v8f16u16 = call <8 x i16> @llvm.fptoui.sat.v8i16.v8f16(<8 x half> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 92 for instruction: %v8f16s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f16(<8 x half> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 73 for instruction: %v8f16u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f16(<8 x half> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f16s32 = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f16(<8 x half> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %v8f16u32 = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f16(<8 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 102 for instruction: %v8f16s64 = call <8 x i64> @llvm.fptosi.sat.v8i64.v8f16(<8 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 71 for instruction: %v8f16u64 = call <8 x i64> @llvm.fptoui.sat.v8i64.v8f16(<8 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 199 for instruction: %v16f16s1 = call <16 x i1> @llvm.fptosi.sat.v16i1.v16f16(<16 x half> undef)
@@ -1158,8 +1158,8 @@ define void @fp16() {
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 153 for instruction: %v16f16u8 = call <16 x i8> @llvm.fptoui.sat.v16i8.v16f16(<16 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 194 for instruction: %v16f16s16 = call <16 x i16> @llvm.fptosi.sat.v16i16.v16f16(<16 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 156 for instruction: %v16f16u16 = call <16 x i16> @llvm.fptoui.sat.v16i16.v16f16(<16 x half> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 184 for instruction: %v16f16s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f16(<16 x half> undef)
-; SLM-NEXT:  Cost Model: Found an estimated cost of 146 for instruction: %v16f16u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f16(<16 x half> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f16s32 = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f16(<16 x half> undef)
+; SLM-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %v16f16u32 = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f16(<16 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 204 for instruction: %v16f16s64 = call <16 x i64> @llvm.fptosi.sat.v16i64.v16f16(<16 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 142 for instruction: %v16f16u64 = call <16 x i64> @llvm.fptoui.sat.v16i64.v16f16(<16 x half> undef)
 ; SLM-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret void

>From a0163b1f425c7bf965fd9f834561e63d662db578 Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Tue, 16 Jun 2026 14:35:04 +0200
Subject: [PATCH 13/18] [X86] Fix KNL compile crash and update test checks

---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |   6 +-
 .../test/CodeGen/X86/fptosi-sat-vector-128.ll | 406 +++---------------
 .../test/CodeGen/X86/fptosi-sat-vector-256.ll | 200 +++------
 .../test/CodeGen/X86/fptosi-sat-vector-512.ll | 333 ++------------
 .../test/CodeGen/X86/fptoui-sat-vector-128.ll | 362 +++-------------
 .../test/CodeGen/X86/fptoui-sat-vector-256.ll | 223 +++-------
 .../test/CodeGen/X86/fptoui-sat-vector-512.ll | 357 ++-------------
 7 files changed, 305 insertions(+), 1582 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 305df43af6b83..0d1d861c06820 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22471,8 +22471,8 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
         SDValue IsNaN = DAG.getSetCC(dl, CCVT, Src, Src, ISD::SETUO);
 
         if (CCVT != SelCCVT) {
-          PosOvf = DAG.getNode(ISD::TRUNCATE, dl, SelCCVT, PosOvf);
-          IsNaN = DAG.getNode(ISD::TRUNCATE, dl, SelCCVT, IsNaN);
+          PosOvf = DAG.getSExtOrTrunc(PosOvf, dl, SelCCVT);
+          IsNaN = DAG.getSExtOrTrunc(IsNaN, dl, SelCCVT);
         }
 
         SDValue IntMax =
@@ -22493,7 +22493,7 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
         EVT SelCCVT =
             getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), DstVT);
         if (CCVT != SelCCVT)
-          IsOvf = DAG.getNode(ISD::TRUNCATE, dl, SelCCVT, IsOvf);
+          IsOvf = DAG.getSExtOrTrunc(IsOvf, dl, SelCCVT);
         // v16i32 (512-bit, AVX512): use X86ISD::CVTTP2UI (VCVTTPS2UDQZ).
         // v4i32 (128-bit, SSE) and v8i32 (256-bit, AVX) are already covered
         // by CVTTPS2DQ/VCVTTPS2DQ via expandFP_TO_UINT_SSE
diff --git a/llvm/test/CodeGen/X86/fptosi-sat-vector-128.ll b/llvm/test/CodeGen/X86/fptosi-sat-vector-128.ll
index a92edf11edd22..b3d70d43ec3d9 100644
--- a/llvm/test/CodeGen/X86/fptosi-sat-vector-128.ll
+++ b/llvm/test/CodeGen/X86/fptosi-sat-vector-128.ll
@@ -9,116 +9,26 @@
 ;
 
 define <4 x i1> @test_signed_v4i1_v4f32(<4 x float> %f) nounwind {
-; SSE2-LABEL: test_signed_v4i1_v4f32:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movaps %xmm0, %xmm1
-; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[3,3],xmm0[3,3]
-; SSE2-NEXT:    movss {{.*#+}} xmm2 = [-1.0E+0,0.0E+0,0.0E+0,0.0E+0]
-; SSE2-NEXT:    xorl %eax, %eax
-; SSE2-NEXT:    ucomiss %xmm1, %xmm1
-; SSE2-NEXT:    maxss %xmm2, %xmm1
-; SSE2-NEXT:    xorps %xmm3, %xmm3
-; SSE2-NEXT:    minss %xmm3, %xmm1
-; SSE2-NEXT:    cvttss2si %xmm1, %ecx
-; SSE2-NEXT:    cmovpl %eax, %ecx
-; SSE2-NEXT:    movaps %xmm0, %xmm1
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
-; SSE2-NEXT:    ucomiss %xmm1, %xmm1
-; SSE2-NEXT:    maxss %xmm2, %xmm1
-; SSE2-NEXT:    minss %xmm3, %xmm1
-; SSE2-NEXT:    cvttss2si %xmm1, %edx
-; SSE2-NEXT:    movd %ecx, %xmm1
-; SSE2-NEXT:    cmovpl %eax, %edx
-; SSE2-NEXT:    movd %edx, %xmm4
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
-; SSE2-NEXT:    movaps %xmm0, %xmm1
-; SSE2-NEXT:    maxss %xmm2, %xmm1
-; SSE2-NEXT:    minss %xmm3, %xmm1
-; SSE2-NEXT:    cvttss2si %xmm1, %ecx
-; SSE2-NEXT:    ucomiss %xmm0, %xmm0
-; SSE2-NEXT:    cmovpl %eax, %ecx
-; SSE2-NEXT:    movd %ecx, %xmm1
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE2-NEXT:    ucomiss %xmm0, %xmm0
-; SSE2-NEXT:    maxss %xmm2, %xmm0
-; SSE2-NEXT:    minss %xmm3, %xmm0
-; SSE2-NEXT:    cvttss2si %xmm0, %ecx
-; SSE2-NEXT:    cmovpl %eax, %ecx
-; SSE2-NEXT:    movd %ecx, %xmm0
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
-; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm4[0]
-; SSE2-NEXT:    movdqa %xmm1, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE42-LABEL: test_signed_v4i1_v4f32:
-; SSE42:       # %bb.0:
-; SSE42-NEXT:    movshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; SSE42-NEXT:    movss {{.*#+}} xmm2 = [-1.0E+0,0.0E+0,0.0E+0,0.0E+0]
-; SSE42-NEXT:    xorl %eax, %eax
-; SSE42-NEXT:    ucomiss %xmm1, %xmm1
-; SSE42-NEXT:    maxss %xmm2, %xmm1
-; SSE42-NEXT:    xorps %xmm3, %xmm3
-; SSE42-NEXT:    minss %xmm3, %xmm1
-; SSE42-NEXT:    cvttss2si %xmm1, %ecx
-; SSE42-NEXT:    cmovpl %eax, %ecx
-; SSE42-NEXT:    movaps %xmm0, %xmm1
-; SSE42-NEXT:    maxss %xmm2, %xmm1
-; SSE42-NEXT:    minss %xmm3, %xmm1
-; SSE42-NEXT:    cvttss2si %xmm1, %edx
-; SSE42-NEXT:    ucomiss %xmm0, %xmm0
-; SSE42-NEXT:    cmovpl %eax, %edx
-; SSE42-NEXT:    movd %edx, %xmm1
-; SSE42-NEXT:    pinsrd $1, %ecx, %xmm1
-; SSE42-NEXT:    movaps %xmm0, %xmm4
-; SSE42-NEXT:    unpckhpd {{.*#+}} xmm4 = xmm4[1],xmm0[1]
-; SSE42-NEXT:    ucomiss %xmm4, %xmm4
-; SSE42-NEXT:    maxss %xmm2, %xmm4
-; SSE42-NEXT:    minss %xmm3, %xmm4
-; SSE42-NEXT:    cvttss2si %xmm4, %ecx
-; SSE42-NEXT:    cmovpl %eax, %ecx
-; SSE42-NEXT:    pinsrd $2, %ecx, %xmm1
-; SSE42-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE42-NEXT:    ucomiss %xmm0, %xmm0
-; SSE42-NEXT:    maxss %xmm2, %xmm0
-; SSE42-NEXT:    minss %xmm3, %xmm0
-; SSE42-NEXT:    cvttss2si %xmm0, %ecx
-; SSE42-NEXT:    cmovpl %eax, %ecx
-; SSE42-NEXT:    pinsrd $3, %ecx, %xmm1
-; SSE42-NEXT:    movdqa %xmm1, %xmm0
-; SSE42-NEXT:    retq
+; SSE-LABEL: test_signed_v4i1_v4f32:
+; SSE:       # %bb.0:
+; SSE-NEXT:    movaps %xmm0, %xmm1
+; SSE-NEXT:    maxps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE-NEXT:    xorps %xmm2, %xmm2
+; SSE-NEXT:    minps %xmm2, %xmm1
+; SSE-NEXT:    cvttps2dq %xmm1, %xmm1
+; SSE-NEXT:    cmpunordps %xmm0, %xmm0
+; SSE-NEXT:    andnps %xmm1, %xmm0
+; SSE-NEXT:    retq
 ;
 ; AVX2-LABEL: test_signed_v4i1_v4f32:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vmovshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; AVX2-NEXT:    vmovss {{.*#+}} xmm2 = [-1.0E+0,0.0E+0,0.0E+0,0.0E+0]
-; AVX2-NEXT:    vmaxss %xmm2, %xmm1, %xmm3
-; AVX2-NEXT:    vxorps %xmm4, %xmm4, %xmm4
-; AVX2-NEXT:    vminss %xmm4, %xmm3, %xmm3
-; AVX2-NEXT:    vcvttss2si %xmm3, %eax
-; AVX2-NEXT:    xorl %ecx, %ecx
-; AVX2-NEXT:    vucomiss %xmm1, %xmm1
-; AVX2-NEXT:    cmovpl %ecx, %eax
-; AVX2-NEXT:    vmaxss %xmm2, %xmm0, %xmm1
-; AVX2-NEXT:    vminss %xmm4, %xmm1, %xmm1
-; AVX2-NEXT:    vcvttss2si %xmm1, %edx
-; AVX2-NEXT:    vucomiss %xmm0, %xmm0
-; AVX2-NEXT:    cmovpl %ecx, %edx
-; AVX2-NEXT:    vmovd %edx, %xmm1
-; AVX2-NEXT:    vpinsrd $1, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm3 = xmm0[1,0]
-; AVX2-NEXT:    vmaxss %xmm2, %xmm3, %xmm5
-; AVX2-NEXT:    vminss %xmm4, %xmm5, %xmm5
-; AVX2-NEXT:    vcvttss2si %xmm5, %eax
-; AVX2-NEXT:    vucomiss %xmm3, %xmm3
-; AVX2-NEXT:    cmovpl %ecx, %eax
-; AVX2-NEXT:    vpinsrd $2, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX2-NEXT:    vmaxss %xmm2, %xmm0, %xmm2
-; AVX2-NEXT:    vminss %xmm4, %xmm2, %xmm2
-; AVX2-NEXT:    vcvttss2si %xmm2, %eax
-; AVX2-NEXT:    vucomiss %xmm0, %xmm0
-; AVX2-NEXT:    cmovpl %ecx, %eax
-; AVX2-NEXT:    vpinsrd $3, %eax, %xmm1, %xmm0
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm1 = [-1.0E+0,-1.0E+0,-1.0E+0,-1.0E+0]
+; AVX2-NEXT:    vmaxps %xmm1, %xmm0, %xmm1
+; AVX2-NEXT:    vxorps %xmm2, %xmm2, %xmm2
+; AVX2-NEXT:    vminps %xmm2, %xmm1, %xmm1
+; AVX2-NEXT:    vcvttps2dq %xmm1, %xmm1
+; AVX2-NEXT:    vcmpunordps %xmm0, %xmm0, %xmm0
+; AVX2-NEXT:    vandnps %xmm1, %xmm0, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_signed_v4i1_v4f32:
@@ -153,116 +63,26 @@ define <4 x i1> @test_signed_v4i1_v4f32(<4 x float> %f) nounwind {
 }
 
 define <4 x i1> @test_freeze_signed_v4i1_v4f32(<4 x float> %f) nounwind {
-; SSE2-LABEL: test_freeze_signed_v4i1_v4f32:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movaps %xmm0, %xmm1
-; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[3,3],xmm0[3,3]
-; SSE2-NEXT:    movss {{.*#+}} xmm2 = [-1.0E+0,0.0E+0,0.0E+0,0.0E+0]
-; SSE2-NEXT:    xorl %eax, %eax
-; SSE2-NEXT:    ucomiss %xmm1, %xmm1
-; SSE2-NEXT:    maxss %xmm2, %xmm1
-; SSE2-NEXT:    xorps %xmm3, %xmm3
-; SSE2-NEXT:    minss %xmm3, %xmm1
-; SSE2-NEXT:    cvttss2si %xmm1, %ecx
-; SSE2-NEXT:    cmovpl %eax, %ecx
-; SSE2-NEXT:    movaps %xmm0, %xmm1
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1],xmm0[1]
-; SSE2-NEXT:    ucomiss %xmm1, %xmm1
-; SSE2-NEXT:    maxss %xmm2, %xmm1
-; SSE2-NEXT:    minss %xmm3, %xmm1
-; SSE2-NEXT:    cvttss2si %xmm1, %edx
-; SSE2-NEXT:    movd %ecx, %xmm1
-; SSE2-NEXT:    cmovpl %eax, %edx
-; SSE2-NEXT:    movd %edx, %xmm4
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
-; SSE2-NEXT:    movaps %xmm0, %xmm1
-; SSE2-NEXT:    maxss %xmm2, %xmm1
-; SSE2-NEXT:    minss %xmm3, %xmm1
-; SSE2-NEXT:    cvttss2si %xmm1, %ecx
-; SSE2-NEXT:    ucomiss %xmm0, %xmm0
-; SSE2-NEXT:    cmovpl %eax, %ecx
-; SSE2-NEXT:    movd %ecx, %xmm1
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE2-NEXT:    ucomiss %xmm0, %xmm0
-; SSE2-NEXT:    maxss %xmm2, %xmm0
-; SSE2-NEXT:    minss %xmm3, %xmm0
-; SSE2-NEXT:    cvttss2si %xmm0, %ecx
-; SSE2-NEXT:    cmovpl %eax, %ecx
-; SSE2-NEXT:    movd %ecx, %xmm0
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
-; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm4[0]
-; SSE2-NEXT:    movdqa %xmm1, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE42-LABEL: test_freeze_signed_v4i1_v4f32:
-; SSE42:       # %bb.0:
-; SSE42-NEXT:    movshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; SSE42-NEXT:    movss {{.*#+}} xmm2 = [-1.0E+0,0.0E+0,0.0E+0,0.0E+0]
-; SSE42-NEXT:    xorl %eax, %eax
-; SSE42-NEXT:    ucomiss %xmm1, %xmm1
-; SSE42-NEXT:    maxss %xmm2, %xmm1
-; SSE42-NEXT:    xorps %xmm3, %xmm3
-; SSE42-NEXT:    minss %xmm3, %xmm1
-; SSE42-NEXT:    cvttss2si %xmm1, %ecx
-; SSE42-NEXT:    cmovpl %eax, %ecx
-; SSE42-NEXT:    movaps %xmm0, %xmm1
-; SSE42-NEXT:    maxss %xmm2, %xmm1
-; SSE42-NEXT:    minss %xmm3, %xmm1
-; SSE42-NEXT:    cvttss2si %xmm1, %edx
-; SSE42-NEXT:    ucomiss %xmm0, %xmm0
-; SSE42-NEXT:    cmovpl %eax, %edx
-; SSE42-NEXT:    movd %edx, %xmm1
-; SSE42-NEXT:    pinsrd $1, %ecx, %xmm1
-; SSE42-NEXT:    movaps %xmm0, %xmm4
-; SSE42-NEXT:    unpckhpd {{.*#+}} xmm4 = xmm4[1],xmm0[1]
-; SSE42-NEXT:    ucomiss %xmm4, %xmm4
-; SSE42-NEXT:    maxss %xmm2, %xmm4
-; SSE42-NEXT:    minss %xmm3, %xmm4
-; SSE42-NEXT:    cvttss2si %xmm4, %ecx
-; SSE42-NEXT:    cmovpl %eax, %ecx
-; SSE42-NEXT:    pinsrd $2, %ecx, %xmm1
-; SSE42-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE42-NEXT:    ucomiss %xmm0, %xmm0
-; SSE42-NEXT:    maxss %xmm2, %xmm0
-; SSE42-NEXT:    minss %xmm3, %xmm0
-; SSE42-NEXT:    cvttss2si %xmm0, %ecx
-; SSE42-NEXT:    cmovpl %eax, %ecx
-; SSE42-NEXT:    pinsrd $3, %ecx, %xmm1
-; SSE42-NEXT:    movdqa %xmm1, %xmm0
-; SSE42-NEXT:    retq
+; SSE-LABEL: test_freeze_signed_v4i1_v4f32:
+; SSE:       # %bb.0:
+; SSE-NEXT:    movaps %xmm0, %xmm1
+; SSE-NEXT:    maxps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE-NEXT:    xorps %xmm2, %xmm2
+; SSE-NEXT:    minps %xmm2, %xmm1
+; SSE-NEXT:    cvttps2dq %xmm1, %xmm1
+; SSE-NEXT:    cmpunordps %xmm0, %xmm0
+; SSE-NEXT:    andnps %xmm1, %xmm0
+; SSE-NEXT:    retq
 ;
 ; AVX2-LABEL: test_freeze_signed_v4i1_v4f32:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vmovshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; AVX2-NEXT:    vmovss {{.*#+}} xmm2 = [-1.0E+0,0.0E+0,0.0E+0,0.0E+0]
-; AVX2-NEXT:    vmaxss %xmm2, %xmm1, %xmm3
-; AVX2-NEXT:    vxorps %xmm4, %xmm4, %xmm4
-; AVX2-NEXT:    vminss %xmm4, %xmm3, %xmm3
-; AVX2-NEXT:    vcvttss2si %xmm3, %eax
-; AVX2-NEXT:    xorl %ecx, %ecx
-; AVX2-NEXT:    vucomiss %xmm1, %xmm1
-; AVX2-NEXT:    cmovpl %ecx, %eax
-; AVX2-NEXT:    vmaxss %xmm2, %xmm0, %xmm1
-; AVX2-NEXT:    vminss %xmm4, %xmm1, %xmm1
-; AVX2-NEXT:    vcvttss2si %xmm1, %edx
-; AVX2-NEXT:    vucomiss %xmm0, %xmm0
-; AVX2-NEXT:    cmovpl %ecx, %edx
-; AVX2-NEXT:    vmovd %edx, %xmm1
-; AVX2-NEXT:    vpinsrd $1, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm3 = xmm0[1,0]
-; AVX2-NEXT:    vmaxss %xmm2, %xmm3, %xmm5
-; AVX2-NEXT:    vminss %xmm4, %xmm5, %xmm5
-; AVX2-NEXT:    vcvttss2si %xmm5, %eax
-; AVX2-NEXT:    vucomiss %xmm3, %xmm3
-; AVX2-NEXT:    cmovpl %ecx, %eax
-; AVX2-NEXT:    vpinsrd $2, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX2-NEXT:    vmaxss %xmm2, %xmm0, %xmm2
-; AVX2-NEXT:    vminss %xmm4, %xmm2, %xmm2
-; AVX2-NEXT:    vcvttss2si %xmm2, %eax
-; AVX2-NEXT:    vucomiss %xmm0, %xmm0
-; AVX2-NEXT:    cmovpl %ecx, %eax
-; AVX2-NEXT:    vpinsrd $3, %eax, %xmm1, %xmm0
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm1 = [-1.0E+0,-1.0E+0,-1.0E+0,-1.0E+0]
+; AVX2-NEXT:    vmaxps %xmm1, %xmm0, %xmm1
+; AVX2-NEXT:    vxorps %xmm2, %xmm2, %xmm2
+; AVX2-NEXT:    vminps %xmm2, %xmm1, %xmm1
+; AVX2-NEXT:    vcvttps2dq %xmm1, %xmm1
+; AVX2-NEXT:    vcmpunordps %xmm0, %xmm0, %xmm0
+; AVX2-NEXT:    vandnps %xmm1, %xmm0, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_freeze_signed_v4i1_v4f32:
@@ -497,146 +317,48 @@ define <4 x i16> @test_signed_v4i16_v4f32(<4 x float> %f) nounwind {
 define <4 x i32> @test_signed_v4i32_v4f32(<4 x float> %f) nounwind {
 ; SSE2-LABEL: test_signed_v4i32_v4f32:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movaps %xmm0, %xmm2
-; SSE2-NEXT:    shufps {{.*#+}} xmm2 = xmm2[3,3],xmm0[3,3]
-; SSE2-NEXT:    cvttss2si %xmm2, %edx
-; SSE2-NEXT:    movss {{.*#+}} xmm1 = [2.14748352E+9,0.0E+0,0.0E+0,0.0E+0]
-; SSE2-NEXT:    ucomiss %xmm1, %xmm2
-; SSE2-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
-; SSE2-NEXT:    cmoval %eax, %edx
-; SSE2-NEXT:    xorl %ecx, %ecx
-; SSE2-NEXT:    ucomiss %xmm2, %xmm2
-; SSE2-NEXT:    cmovpl %ecx, %edx
-; SSE2-NEXT:    movaps %xmm0, %xmm2
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1],xmm0[1]
-; SSE2-NEXT:    cvttss2si %xmm2, %esi
-; SSE2-NEXT:    ucomiss %xmm1, %xmm2
-; SSE2-NEXT:    cmoval %eax, %esi
-; SSE2-NEXT:    ucomiss %xmm2, %xmm2
-; SSE2-NEXT:    cmovpl %ecx, %esi
-; SSE2-NEXT:    cvttss2si %xmm0, %edi
-; SSE2-NEXT:    ucomiss %xmm1, %xmm0
-; SSE2-NEXT:    cmoval %eax, %edi
-; SSE2-NEXT:    ucomiss %xmm0, %xmm0
-; SSE2-NEXT:    cmovpl %ecx, %edi
-; SSE2-NEXT:    movd %edx, %xmm2
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE2-NEXT:    ucomiss %xmm1, %xmm0
-; SSE2-NEXT:    movd %esi, %xmm3
-; SSE2-NEXT:    movd %edi, %xmm1
-; SSE2-NEXT:    cvttss2si %xmm0, %edx
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
-; SSE2-NEXT:    cmoval %eax, %edx
-; SSE2-NEXT:    ucomiss %xmm0, %xmm0
-; SSE2-NEXT:    cmovpl %ecx, %edx
-; SSE2-NEXT:    movd %edx, %xmm0
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
-; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm3[0]
-; SSE2-NEXT:    movdqa %xmm1, %xmm0
+; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
+; SSE2-NEXT:    cmpleps %xmm0, %xmm1
+; SSE2-NEXT:    cvttps2dq %xmm0, %xmm2
+; SSE2-NEXT:    movaps %xmm1, %xmm3
+; SSE2-NEXT:    andnps %xmm2, %xmm3
+; SSE2-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE2-NEXT:    orps %xmm3, %xmm1
+; SSE2-NEXT:    cmpunordps %xmm0, %xmm0
+; SSE2-NEXT:    andnps %xmm1, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE42-LABEL: test_signed_v4i32_v4f32:
 ; SSE42:       # %bb.0:
-; SSE42-NEXT:    movshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; SSE42-NEXT:    cvttss2si %xmm1, %edx
-; SSE42-NEXT:    movss {{.*#+}} xmm2 = [2.14748352E+9,0.0E+0,0.0E+0,0.0E+0]
-; SSE42-NEXT:    ucomiss %xmm2, %xmm1
-; SSE42-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
-; SSE42-NEXT:    cmoval %eax, %edx
-; SSE42-NEXT:    xorl %ecx, %ecx
-; SSE42-NEXT:    ucomiss %xmm1, %xmm1
-; SSE42-NEXT:    cmovpl %ecx, %edx
-; SSE42-NEXT:    cvttss2si %xmm0, %esi
-; SSE42-NEXT:    ucomiss %xmm2, %xmm0
-; SSE42-NEXT:    cmoval %eax, %esi
-; SSE42-NEXT:    ucomiss %xmm0, %xmm0
-; SSE42-NEXT:    cmovpl %ecx, %esi
-; SSE42-NEXT:    movd %esi, %xmm1
-; SSE42-NEXT:    pinsrd $1, %edx, %xmm1
-; SSE42-NEXT:    movaps %xmm0, %xmm3
-; SSE42-NEXT:    unpckhpd {{.*#+}} xmm3 = xmm3[1],xmm0[1]
-; SSE42-NEXT:    cvttss2si %xmm3, %edx
-; SSE42-NEXT:    ucomiss %xmm2, %xmm3
-; SSE42-NEXT:    cmoval %eax, %edx
-; SSE42-NEXT:    ucomiss %xmm3, %xmm3
-; SSE42-NEXT:    cmovpl %ecx, %edx
-; SSE42-NEXT:    pinsrd $2, %edx, %xmm1
-; SSE42-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE42-NEXT:    cvttss2si %xmm0, %edx
-; SSE42-NEXT:    ucomiss %xmm2, %xmm0
-; SSE42-NEXT:    cmoval %eax, %edx
-; SSE42-NEXT:    ucomiss %xmm0, %xmm0
-; SSE42-NEXT:    cmovpl %ecx, %edx
-; SSE42-NEXT:    pinsrd $3, %edx, %xmm1
-; SSE42-NEXT:    movdqa %xmm1, %xmm0
+; SSE42-NEXT:    movaps %xmm0, %xmm1
+; SSE42-NEXT:    movaps {{.*#+}} xmm0 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
+; SSE42-NEXT:    cmpleps %xmm1, %xmm0
+; SSE42-NEXT:    cvttps2dq %xmm1, %xmm2
+; SSE42-NEXT:    blendvps %xmm0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE42-NEXT:    cmpunordps %xmm1, %xmm1
+; SSE42-NEXT:    andnps %xmm2, %xmm1
+; SSE42-NEXT:    movaps %xmm1, %xmm0
 ; SSE42-NEXT:    retq
 ;
 ; AVX2-LABEL: test_signed_v4i32_v4f32:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vmovshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; AVX2-NEXT:    vcvttss2si %xmm1, %eax
-; AVX2-NEXT:    vmovss {{.*#+}} xmm2 = [2.14748352E+9,0.0E+0,0.0E+0,0.0E+0]
-; AVX2-NEXT:    vucomiss %xmm2, %xmm1
-; AVX2-NEXT:    movl $2147483647, %ecx # imm = 0x7FFFFFFF
-; AVX2-NEXT:    cmoval %ecx, %eax
-; AVX2-NEXT:    xorl %edx, %edx
-; AVX2-NEXT:    vucomiss %xmm1, %xmm1
-; AVX2-NEXT:    cmovpl %edx, %eax
-; AVX2-NEXT:    vcvttss2si %xmm0, %esi
-; AVX2-NEXT:    vucomiss %xmm2, %xmm0
-; AVX2-NEXT:    cmoval %ecx, %esi
-; AVX2-NEXT:    vucomiss %xmm0, %xmm0
-; AVX2-NEXT:    cmovpl %edx, %esi
-; AVX2-NEXT:    vmovd %esi, %xmm1
-; AVX2-NEXT:    vpinsrd $1, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm3 = xmm0[1,0]
-; AVX2-NEXT:    vcvttss2si %xmm3, %eax
-; AVX2-NEXT:    vucomiss %xmm2, %xmm3
-; AVX2-NEXT:    cmoval %ecx, %eax
-; AVX2-NEXT:    vucomiss %xmm3, %xmm3
-; AVX2-NEXT:    cmovpl %edx, %eax
-; AVX2-NEXT:    vpinsrd $2, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX2-NEXT:    vcvttss2si %xmm0, %eax
-; AVX2-NEXT:    vucomiss %xmm2, %xmm0
-; AVX2-NEXT:    cmoval %ecx, %eax
-; AVX2-NEXT:    vucomiss %xmm0, %xmm0
-; AVX2-NEXT:    cmovpl %edx, %eax
-; AVX2-NEXT:    vpinsrd $3, %eax, %xmm1, %xmm0
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm1 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
+; AVX2-NEXT:    vcmpleps %xmm0, %xmm1, %xmm1
+; AVX2-NEXT:    vcvttps2dq %xmm0, %xmm2
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm3 = [2147483647,2147483647,2147483647,2147483647]
+; AVX2-NEXT:    vblendvps %xmm1, %xmm3, %xmm2, %xmm1
+; AVX2-NEXT:    vcmpunordps %xmm0, %xmm0, %xmm0
+; AVX2-NEXT:    vandnps %xmm1, %xmm0, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_signed_v4i32_v4f32:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm1, %eax
-; AVX512-NEXT:    vmovss {{.*#+}} xmm2 = [2.14748352E+9,0.0E+0,0.0E+0,0.0E+0]
-; AVX512-NEXT:    vucomiss %xmm2, %xmm1
-; AVX512-NEXT:    movl $2147483647, %ecx # imm = 0x7FFFFFFF
-; AVX512-NEXT:    cmoval %ecx, %eax
-; AVX512-NEXT:    xorl %edx, %edx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm1
-; AVX512-NEXT:    vcvttss2si %xmm0, %esi
-; AVX512-NEXT:    cmovpl %edx, %eax
-; AVX512-NEXT:    vucomiss %xmm2, %xmm0
-; AVX512-NEXT:    cmoval %ecx, %esi
-; AVX512-NEXT:    vucomiss %xmm0, %xmm0
-; AVX512-NEXT:    cmovpl %edx, %esi
-; AVX512-NEXT:    vmovd %esi, %xmm1
-; AVX512-NEXT:    vpinsrd $1, %eax, %xmm1, %xmm1
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm3 = xmm0[1,0]
-; AVX512-NEXT:    vcvttss2si %xmm3, %eax
-; AVX512-NEXT:    vucomiss %xmm2, %xmm3
-; AVX512-NEXT:    cmoval %ecx, %eax
-; AVX512-NEXT:    vucomiss %xmm3, %xmm3
-; AVX512-NEXT:    cmovpl %edx, %eax
-; AVX512-NEXT:    vpinsrd $2, %eax, %xmm1, %xmm1
-; AVX512-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm0, %eax
-; AVX512-NEXT:    vucomiss %xmm2, %xmm0
-; AVX512-NEXT:    cmoval %ecx, %eax
-; AVX512-NEXT:    vucomiss %xmm0, %xmm0
-; AVX512-NEXT:    cmovpl %edx, %eax
-; AVX512-NEXT:    vpinsrd $3, %eax, %xmm1, %xmm0
+; AVX512-NEXT:    vcmpgeps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm0, %k1
+; AVX512-NEXT:    vcvttps2dq %xmm0, %xmm1
+; AVX512-NEXT:    vpbroadcastd {{.*#+}} xmm1 {%k1} = [2147483647,2147483647,2147483647,2147483647]
+; AVX512-NEXT:    vcmpunordps %xmm0, %xmm0, %k0
+; AVX512-NEXT:    knotw %k0, %k1
+; AVX512-NEXT:    vmovdqa32 %xmm1, %xmm0 {%k1} {z}
 ; AVX512-NEXT:    retq
   %x = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> %f)
   ret <4 x i32> %x
diff --git a/llvm/test/CodeGen/X86/fptosi-sat-vector-256.ll b/llvm/test/CodeGen/X86/fptosi-sat-vector-256.ll
index f50ebad3aab7c..a58bc1f938f3d 100644
--- a/llvm/test/CodeGen/X86/fptosi-sat-vector-256.ll
+++ b/llvm/test/CodeGen/X86/fptosi-sat-vector-256.ll
@@ -398,68 +398,26 @@ define <8 x i16> @test_signed_v8i16_v8f32(<8 x float> %f) nounwind {
 }
 
 define <8 x i32> @test_signed_v8i32_v8f32(<8 x float> %f) nounwind {
-; CHECK-LABEL: test_signed_v8i32_v8f32:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    vextractf128 $1, %ymm0, %xmm2
-; CHECK-NEXT:    vmovshdup {{.*#+}} xmm3 = xmm2[1,1,3,3]
-; CHECK-NEXT:    vcvttss2si %xmm3, %edx
-; CHECK-NEXT:    vmovss {{.*#+}} xmm1 = [2.14748352E+9,0.0E+0,0.0E+0,0.0E+0]
-; CHECK-NEXT:    vucomiss %xmm1, %xmm3
-; CHECK-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
-; CHECK-NEXT:    cmoval %eax, %edx
-; CHECK-NEXT:    xorl %ecx, %ecx
-; CHECK-NEXT:    vucomiss %xmm3, %xmm3
-; CHECK-NEXT:    cmovpl %ecx, %edx
-; CHECK-NEXT:    vcvttss2si %xmm2, %esi
-; CHECK-NEXT:    vucomiss %xmm1, %xmm2
-; CHECK-NEXT:    cmoval %eax, %esi
-; CHECK-NEXT:    vucomiss %xmm2, %xmm2
-; CHECK-NEXT:    cmovpl %ecx, %esi
-; CHECK-NEXT:    vmovd %esi, %xmm3
-; CHECK-NEXT:    vpinsrd $1, %edx, %xmm3, %xmm3
-; CHECK-NEXT:    vshufpd {{.*#+}} xmm4 = xmm2[1,0]
-; CHECK-NEXT:    vcvttss2si %xmm4, %edx
-; CHECK-NEXT:    vucomiss %xmm1, %xmm4
-; CHECK-NEXT:    cmoval %eax, %edx
-; CHECK-NEXT:    vucomiss %xmm4, %xmm4
-; CHECK-NEXT:    cmovpl %ecx, %edx
-; CHECK-NEXT:    vpinsrd $2, %edx, %xmm3, %xmm3
-; CHECK-NEXT:    vshufps {{.*#+}} xmm2 = xmm2[3,3,3,3]
-; CHECK-NEXT:    vcvttss2si %xmm2, %edx
-; CHECK-NEXT:    vucomiss %xmm1, %xmm2
-; CHECK-NEXT:    cmoval %eax, %edx
-; CHECK-NEXT:    vucomiss %xmm2, %xmm2
-; CHECK-NEXT:    cmovpl %ecx, %edx
-; CHECK-NEXT:    vpinsrd $3, %edx, %xmm3, %xmm2
-; CHECK-NEXT:    vmovshdup {{.*#+}} xmm3 = xmm0[1,1,3,3]
-; CHECK-NEXT:    vcvttss2si %xmm3, %edx
-; CHECK-NEXT:    vucomiss %xmm1, %xmm3
-; CHECK-NEXT:    cmoval %eax, %edx
-; CHECK-NEXT:    vucomiss %xmm3, %xmm3
-; CHECK-NEXT:    cmovpl %ecx, %edx
-; CHECK-NEXT:    vcvttss2si %xmm0, %esi
-; CHECK-NEXT:    vucomiss %xmm1, %xmm0
-; CHECK-NEXT:    cmoval %eax, %esi
-; CHECK-NEXT:    vucomiss %xmm0, %xmm0
-; CHECK-NEXT:    cmovpl %ecx, %esi
-; CHECK-NEXT:    vmovd %esi, %xmm3
-; CHECK-NEXT:    vpinsrd $1, %edx, %xmm3, %xmm3
-; CHECK-NEXT:    vshufpd {{.*#+}} xmm4 = xmm0[1,0]
-; CHECK-NEXT:    vcvttss2si %xmm4, %edx
-; CHECK-NEXT:    vucomiss %xmm1, %xmm4
-; CHECK-NEXT:    cmoval %eax, %edx
-; CHECK-NEXT:    vucomiss %xmm4, %xmm4
-; CHECK-NEXT:    cmovpl %ecx, %edx
-; CHECK-NEXT:    vpinsrd $2, %edx, %xmm3, %xmm3
-; CHECK-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; CHECK-NEXT:    vcvttss2si %xmm0, %edx
-; CHECK-NEXT:    vucomiss %xmm1, %xmm0
-; CHECK-NEXT:    cmoval %eax, %edx
-; CHECK-NEXT:    vucomiss %xmm0, %xmm0
-; CHECK-NEXT:    cmovpl %ecx, %edx
-; CHECK-NEXT:    vpinsrd $3, %edx, %xmm3, %xmm0
-; CHECK-NEXT:    vinserti128 $1, %xmm2, %ymm0, %ymm0
-; CHECK-NEXT:    retq
+; AVX2-LABEL: test_signed_v8i32_v8f32:
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    vbroadcastss {{.*#+}} ymm1 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
+; AVX2-NEXT:    vcmpleps %ymm0, %ymm1, %ymm1
+; AVX2-NEXT:    vcvttps2dq %ymm0, %ymm2
+; AVX2-NEXT:    vbroadcastss {{.*#+}} ymm3 = [2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647]
+; AVX2-NEXT:    vblendvps %ymm1, %ymm3, %ymm2, %ymm1
+; AVX2-NEXT:    vcmpunordps %ymm0, %ymm0, %ymm0
+; AVX2-NEXT:    vandnps %ymm1, %ymm0, %ymm0
+; AVX2-NEXT:    retq
+;
+; AVX512-LABEL: test_signed_v8i32_v8f32:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vcmpgeps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm0, %k1
+; AVX512-NEXT:    vcvttps2dq %ymm0, %ymm1
+; AVX512-NEXT:    vpbroadcastd {{.*#+}} ymm1 {%k1} = [2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647]
+; AVX512-NEXT:    vcmpunordps %ymm0, %ymm0, %k0
+; AVX512-NEXT:    knotb %k0, %k1
+; AVX512-NEXT:    vmovdqa32 %ymm1, %ymm0 {%k1} {z}
+; AVX512-NEXT:    retq
   %x = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f32(<8 x float> %f)
   ret <8 x i32> %x
 }
@@ -811,36 +769,16 @@ define <8 x i128> @test_signed_v8i128_v8f32(<8 x float> %f) nounwind {
 define <4 x i1> @test_signed_v4i1_v4f64(<4 x double> %f) nounwind {
 ; AVX2-LABEL: test_signed_v4i1_v4f64:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm1 = xmm0[1,0]
-; AVX2-NEXT:    vmovsd {{.*#+}} xmm2 = [-1.0E+0,0.0E+0]
-; AVX2-NEXT:    vmaxsd %xmm2, %xmm1, %xmm3
-; AVX2-NEXT:    vxorpd %xmm4, %xmm4, %xmm4
-; AVX2-NEXT:    vminsd %xmm4, %xmm3, %xmm3
-; AVX2-NEXT:    vcvttsd2si %xmm3, %eax
-; AVX2-NEXT:    xorl %ecx, %ecx
-; AVX2-NEXT:    vucomisd %xmm1, %xmm1
-; AVX2-NEXT:    cmovpl %ecx, %eax
-; AVX2-NEXT:    vmaxsd %xmm2, %xmm0, %xmm1
-; AVX2-NEXT:    vminsd %xmm4, %xmm1, %xmm1
-; AVX2-NEXT:    vcvttsd2si %xmm1, %edx
-; AVX2-NEXT:    vucomisd %xmm0, %xmm0
-; AVX2-NEXT:    cmovpl %ecx, %edx
-; AVX2-NEXT:    vmovd %edx, %xmm1
-; AVX2-NEXT:    vpinsrd $1, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm0
-; AVX2-NEXT:    vmaxsd %xmm2, %xmm0, %xmm3
-; AVX2-NEXT:    vminsd %xmm4, %xmm3, %xmm3
-; AVX2-NEXT:    vcvttsd2si %xmm3, %eax
-; AVX2-NEXT:    vucomisd %xmm0, %xmm0
-; AVX2-NEXT:    cmovpl %ecx, %eax
-; AVX2-NEXT:    vpinsrd $2, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm0 = xmm0[1,0]
-; AVX2-NEXT:    vmaxsd %xmm2, %xmm0, %xmm2
-; AVX2-NEXT:    vminsd %xmm4, %xmm2, %xmm2
-; AVX2-NEXT:    vcvttsd2si %xmm2, %eax
-; AVX2-NEXT:    vucomisd %xmm0, %xmm0
-; AVX2-NEXT:    cmovpl %ecx, %eax
-; AVX2-NEXT:    vpinsrd $3, %eax, %xmm1, %xmm0
+; AVX2-NEXT:    vcmpunordpd %ymm0, %ymm0, %ymm1
+; AVX2-NEXT:    vbroadcastsd {{.*#+}} ymm2 = [-1.0E+0,-1.0E+0,-1.0E+0,-1.0E+0]
+; AVX2-NEXT:    vmaxpd %ymm2, %ymm0, %ymm0
+; AVX2-NEXT:    vxorpd %xmm2, %xmm2, %xmm2
+; AVX2-NEXT:    vminpd %ymm2, %ymm0, %ymm0
+; AVX2-NEXT:    vextractf128 $1, %ymm1, %xmm2
+; AVX2-NEXT:    vcvttpd2dq %ymm0, %xmm0
+; AVX2-NEXT:    vpackssdw %xmm2, %xmm1, %xmm1
+; AVX2-NEXT:    vxorpd %xmm2, %xmm2, %xmm2
+; AVX2-NEXT:    vblendvps %xmm1, %xmm2, %xmm0, %xmm0
 ; AVX2-NEXT:    vzeroupper
 ; AVX2-NEXT:    retq
 ;
@@ -939,71 +877,29 @@ define <4 x i16> @test_signed_v4i16_v4f64(<4 x double> %f) nounwind {
 define <4 x i32> @test_signed_v4i32_v4f64(<4 x double> %f) nounwind {
 ; AVX2-LABEL: test_signed_v4i32_v4f64:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm1 = xmm0[1,0]
-; AVX2-NEXT:    vmovsd {{.*#+}} xmm2 = [-2.147483648E+9,0.0E+0]
-; AVX2-NEXT:    vmaxsd %xmm2, %xmm1, %xmm3
-; AVX2-NEXT:    vmovsd {{.*#+}} xmm4 = [2.147483647E+9,0.0E+0]
-; AVX2-NEXT:    vminsd %xmm4, %xmm3, %xmm3
-; AVX2-NEXT:    vcvttsd2si %xmm3, %eax
-; AVX2-NEXT:    xorl %ecx, %ecx
-; AVX2-NEXT:    vucomisd %xmm1, %xmm1
-; AVX2-NEXT:    cmovpl %ecx, %eax
-; AVX2-NEXT:    vmaxsd %xmm2, %xmm0, %xmm1
-; AVX2-NEXT:    vminsd %xmm4, %xmm1, %xmm1
-; AVX2-NEXT:    vcvttsd2si %xmm1, %edx
-; AVX2-NEXT:    vucomisd %xmm0, %xmm0
-; AVX2-NEXT:    cmovpl %ecx, %edx
-; AVX2-NEXT:    vmovd %edx, %xmm1
-; AVX2-NEXT:    vpinsrd $1, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm0
-; AVX2-NEXT:    vmaxsd %xmm2, %xmm0, %xmm3
-; AVX2-NEXT:    vminsd %xmm4, %xmm3, %xmm3
-; AVX2-NEXT:    vcvttsd2si %xmm3, %eax
-; AVX2-NEXT:    vucomisd %xmm0, %xmm0
-; AVX2-NEXT:    cmovpl %ecx, %eax
-; AVX2-NEXT:    vpinsrd $2, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm0 = xmm0[1,0]
-; AVX2-NEXT:    vmaxsd %xmm2, %xmm0, %xmm2
-; AVX2-NEXT:    vminsd %xmm4, %xmm2, %xmm2
-; AVX2-NEXT:    vcvttsd2si %xmm2, %eax
-; AVX2-NEXT:    vucomisd %xmm0, %xmm0
-; AVX2-NEXT:    cmovpl %ecx, %eax
-; AVX2-NEXT:    vpinsrd $3, %eax, %xmm1, %xmm0
+; AVX2-NEXT:    vbroadcastsd {{.*#+}} ymm1 = [2.147483648E+9,2.147483648E+9,2.147483648E+9,2.147483648E+9]
+; AVX2-NEXT:    vcmplepd %ymm0, %ymm1, %ymm1
+; AVX2-NEXT:    vextractf128 $1, %ymm1, %xmm2
+; AVX2-NEXT:    vpackssdw %xmm2, %xmm1, %xmm1
+; AVX2-NEXT:    vcvttpd2dq %ymm0, %xmm2
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm3 = [2147483647,2147483647,2147483647,2147483647]
+; AVX2-NEXT:    vblendvps %xmm1, %xmm3, %xmm2, %xmm1
+; AVX2-NEXT:    vcmpunordpd %ymm0, %ymm0, %ymm0
+; AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm2
+; AVX2-NEXT:    vpackssdw %xmm2, %xmm0, %xmm0
+; AVX2-NEXT:    vxorpd %xmm2, %xmm2, %xmm2
+; AVX2-NEXT:    vblendvps %xmm0, %xmm2, %xmm1, %xmm0
 ; AVX2-NEXT:    vzeroupper
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_signed_v4i32_v4f64:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm1 = xmm0[1,0]
-; AVX512-NEXT:    vmovsd {{.*#+}} xmm2 = [-2.147483648E+9,0.0E+0]
-; AVX512-NEXT:    vmaxsd %xmm2, %xmm1, %xmm3
-; AVX512-NEXT:    vmovsd {{.*#+}} xmm4 = [2.147483647E+9,0.0E+0]
-; AVX512-NEXT:    vminsd %xmm4, %xmm3, %xmm3
-; AVX512-NEXT:    vcvttsd2si %xmm3, %eax
-; AVX512-NEXT:    xorl %ecx, %ecx
-; AVX512-NEXT:    vucomisd %xmm1, %xmm1
-; AVX512-NEXT:    vmaxsd %xmm2, %xmm0, %xmm1
-; AVX512-NEXT:    vminsd %xmm4, %xmm1, %xmm1
-; AVX512-NEXT:    vcvttsd2si %xmm1, %edx
-; AVX512-NEXT:    cmovpl %ecx, %eax
-; AVX512-NEXT:    vucomisd %xmm0, %xmm0
-; AVX512-NEXT:    cmovpl %ecx, %edx
-; AVX512-NEXT:    vmovd %edx, %xmm1
-; AVX512-NEXT:    vpinsrd $1, %eax, %xmm1, %xmm1
-; AVX512-NEXT:    vextractf128 $1, %ymm0, %xmm0
-; AVX512-NEXT:    vmaxsd %xmm2, %xmm0, %xmm3
-; AVX512-NEXT:    vminsd %xmm4, %xmm3, %xmm3
-; AVX512-NEXT:    vcvttsd2si %xmm3, %eax
-; AVX512-NEXT:    vucomisd %xmm0, %xmm0
-; AVX512-NEXT:    cmovpl %ecx, %eax
-; AVX512-NEXT:    vpinsrd $2, %eax, %xmm1, %xmm1
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm0 = xmm0[1,0]
-; AVX512-NEXT:    vmaxsd %xmm2, %xmm0, %xmm2
-; AVX512-NEXT:    vminsd %xmm4, %xmm2, %xmm2
-; AVX512-NEXT:    vcvttsd2si %xmm2, %eax
-; AVX512-NEXT:    vucomisd %xmm0, %xmm0
-; AVX512-NEXT:    cmovpl %ecx, %eax
-; AVX512-NEXT:    vpinsrd $3, %eax, %xmm1, %xmm0
+; AVX512-NEXT:    vcmpgepd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm0, %k1
+; AVX512-NEXT:    vcvttpd2dq %ymm0, %xmm1
+; AVX512-NEXT:    vpbroadcastd {{.*#+}} xmm1 {%k1} = [2147483647,2147483647,2147483647,2147483647]
+; AVX512-NEXT:    vcmpunordpd %ymm0, %ymm0, %k0
+; AVX512-NEXT:    knotw %k0, %k1
+; AVX512-NEXT:    vmovdqa32 %xmm1, %xmm0 {%k1} {z}
 ; AVX512-NEXT:    vzeroupper
 ; AVX512-NEXT:    retq
   %x = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f64(<4 x double> %f)
diff --git a/llvm/test/CodeGen/X86/fptosi-sat-vector-512.ll b/llvm/test/CodeGen/X86/fptosi-sat-vector-512.ll
index 92103b56925c0..1a78d45a14a0d 100644
--- a/llvm/test/CodeGen/X86/fptosi-sat-vector-512.ll
+++ b/llvm/test/CodeGen/X86/fptosi-sat-vector-512.ll
@@ -721,247 +721,15 @@ define <16 x i16> @test_signed_v16i16_v16f32(<16 x float> %f) nounwind {
 }
 
 define <16 x i32> @test_signed_v16i32_v16f32(<16 x float> %f) nounwind {
-; AVX512F-LABEL: test_signed_v16i32_v16f32:
-; AVX512F:       # %bb.0:
-; AVX512F-NEXT:    vextractf32x4 $3, %zmm0, %xmm2
-; AVX512F-NEXT:    vmovshdup {{.*#+}} xmm3 = xmm2[1,1,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm3, %edx
-; AVX512F-NEXT:    vmovss {{.*#+}} xmm1 = [2.14748352E+9,0.0E+0,0.0E+0,0.0E+0]
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm3
-; AVX512F-NEXT:    movl $2147483647, %ecx # imm = 0x7FFFFFFF
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    xorl %eax, %eax
-; AVX512F-NEXT:    vucomiss %xmm3, %xmm3
-; AVX512F-NEXT:    cmovpl %eax, %edx
-; AVX512F-NEXT:    vcvttss2si %xmm2, %esi
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm2
-; AVX512F-NEXT:    cmoval %ecx, %esi
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm2
-; AVX512F-NEXT:    cmovpl %eax, %esi
-; AVX512F-NEXT:    vmovd %esi, %xmm3
-; AVX512F-NEXT:    vpinsrd $1, %edx, %xmm3, %xmm3
-; AVX512F-NEXT:    vshufpd {{.*#+}} xmm4 = xmm2[1,0]
-; AVX512F-NEXT:    vcvttss2si %xmm4, %edx
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vucomiss %xmm4, %xmm4
-; AVX512F-NEXT:    cmovpl %eax, %edx
-; AVX512F-NEXT:    vpinsrd $2, %edx, %xmm3, %xmm3
-; AVX512F-NEXT:    vshufps {{.*#+}} xmm2 = xmm2[3,3,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm2, %edx
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm2
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm2
-; AVX512F-NEXT:    cmovpl %eax, %edx
-; AVX512F-NEXT:    vpinsrd $3, %edx, %xmm3, %xmm2
-; AVX512F-NEXT:    vextractf32x4 $2, %zmm0, %xmm3
-; AVX512F-NEXT:    vmovshdup {{.*#+}} xmm4 = xmm3[1,1,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm4, %edx
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vucomiss %xmm4, %xmm4
-; AVX512F-NEXT:    cmovpl %eax, %edx
-; AVX512F-NEXT:    vcvttss2si %xmm3, %esi
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm3
-; AVX512F-NEXT:    cmoval %ecx, %esi
-; AVX512F-NEXT:    vucomiss %xmm3, %xmm3
-; AVX512F-NEXT:    cmovpl %eax, %esi
-; AVX512F-NEXT:    vmovd %esi, %xmm4
-; AVX512F-NEXT:    vpinsrd $1, %edx, %xmm4, %xmm4
-; AVX512F-NEXT:    vshufpd {{.*#+}} xmm5 = xmm3[1,0]
-; AVX512F-NEXT:    vcvttss2si %xmm5, %edx
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vucomiss %xmm5, %xmm5
-; AVX512F-NEXT:    cmovpl %eax, %edx
-; AVX512F-NEXT:    vpinsrd $2, %edx, %xmm4, %xmm4
-; AVX512F-NEXT:    vshufps {{.*#+}} xmm3 = xmm3[3,3,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm3, %edx
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm3
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vucomiss %xmm3, %xmm3
-; AVX512F-NEXT:    cmovpl %eax, %edx
-; AVX512F-NEXT:    vpinsrd $3, %edx, %xmm4, %xmm3
-; AVX512F-NEXT:    vextractf128 $1, %ymm0, %xmm4
-; AVX512F-NEXT:    vmovshdup {{.*#+}} xmm5 = xmm4[1,1,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm5, %edx
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vucomiss %xmm5, %xmm5
-; AVX512F-NEXT:    cmovpl %eax, %edx
-; AVX512F-NEXT:    vcvttss2si %xmm4, %esi
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512F-NEXT:    cmoval %ecx, %esi
-; AVX512F-NEXT:    vucomiss %xmm4, %xmm4
-; AVX512F-NEXT:    cmovpl %eax, %esi
-; AVX512F-NEXT:    vshufpd {{.*#+}} xmm5 = xmm4[1,0]
-; AVX512F-NEXT:    vcvttss2si %xmm5, %edi
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512F-NEXT:    cmoval %ecx, %edi
-; AVX512F-NEXT:    vucomiss %xmm5, %xmm5
-; AVX512F-NEXT:    vmovd %esi, %xmm5
-; AVX512F-NEXT:    vpinsrd $1, %edx, %xmm5, %xmm5
-; AVX512F-NEXT:    cmovpl %eax, %edi
-; AVX512F-NEXT:    vpinsrd $2, %edi, %xmm5, %xmm5
-; AVX512F-NEXT:    vshufps {{.*#+}} xmm4 = xmm4[3,3,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm4, %edx
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vucomiss %xmm4, %xmm4
-; AVX512F-NEXT:    cmovpl %eax, %edx
-; AVX512F-NEXT:    vpinsrd $3, %edx, %xmm5, %xmm4
-; AVX512F-NEXT:    vmovshdup {{.*#+}} xmm5 = xmm0[1,1,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm5, %edx
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vucomiss %xmm5, %xmm5
-; AVX512F-NEXT:    cmovpl %eax, %edx
-; AVX512F-NEXT:    vcvttss2si %xmm0, %esi
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm0
-; AVX512F-NEXT:    cmoval %ecx, %esi
-; AVX512F-NEXT:    vucomiss %xmm0, %xmm0
-; AVX512F-NEXT:    cmovpl %eax, %esi
-; AVX512F-NEXT:    vshufpd {{.*#+}} xmm5 = xmm0[1,0]
-; AVX512F-NEXT:    vcvttss2si %xmm5, %edi
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512F-NEXT:    cmoval %ecx, %edi
-; AVX512F-NEXT:    vucomiss %xmm5, %xmm5
-; AVX512F-NEXT:    vmovd %esi, %xmm5
-; AVX512F-NEXT:    vpinsrd $1, %edx, %xmm5, %xmm5
-; AVX512F-NEXT:    cmovpl %eax, %edi
-; AVX512F-NEXT:    vpinsrd $2, %edi, %xmm5, %xmm5
-; AVX512F-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm0, %edx
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm0
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vinserti128 $1, %xmm2, %ymm3, %ymm1
-; AVX512F-NEXT:    vucomiss %xmm0, %xmm0
-; AVX512F-NEXT:    cmovpl %eax, %edx
-; AVX512F-NEXT:    vpinsrd $3, %edx, %xmm5, %xmm0
-; AVX512F-NEXT:    vinserti128 $1, %xmm4, %ymm0, %ymm0
-; AVX512F-NEXT:    vinserti64x4 $1, %ymm1, %zmm0, %zmm0
-; AVX512F-NEXT:    retq
-;
-; AVX512-LABEL: test_signed_v16i32_v16f32:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vextractf32x4 $3, %zmm0, %xmm2
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm3 = xmm2[1,1,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm3, %edx
-; AVX512-NEXT:    vmovss {{.*#+}} xmm1 = [2.14748352E+9,0.0E+0,0.0E+0,0.0E+0]
-; AVX512-NEXT:    vucomiss %xmm1, %xmm3
-; AVX512-NEXT:    movl $2147483647, %eax # imm = 0x7FFFFFFF
-; AVX512-NEXT:    cmoval %eax, %edx
-; AVX512-NEXT:    xorl %ecx, %ecx
-; AVX512-NEXT:    vucomiss %xmm3, %xmm3
-; AVX512-NEXT:    vcvttss2si %xmm2, %esi
-; AVX512-NEXT:    cmovpl %ecx, %edx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm2
-; AVX512-NEXT:    cmoval %eax, %esi
-; AVX512-NEXT:    vucomiss %xmm2, %xmm2
-; AVX512-NEXT:    cmovpl %ecx, %esi
-; AVX512-NEXT:    vmovd %esi, %xmm3
-; AVX512-NEXT:    vpinsrd $1, %edx, %xmm3, %xmm3
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm4 = xmm2[1,0]
-; AVX512-NEXT:    vcvttss2si %xmm4, %edx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512-NEXT:    cmoval %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm4, %xmm4
-; AVX512-NEXT:    cmovpl %ecx, %edx
-; AVX512-NEXT:    vpinsrd $2, %edx, %xmm3, %xmm3
-; AVX512-NEXT:    vshufps {{.*#+}} xmm2 = xmm2[3,3,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm2, %edx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm2
-; AVX512-NEXT:    cmoval %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm2
-; AVX512-NEXT:    cmovpl %ecx, %edx
-; AVX512-NEXT:    vpinsrd $3, %edx, %xmm3, %xmm2
-; AVX512-NEXT:    vextractf32x4 $2, %zmm0, %xmm3
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm4 = xmm3[1,1,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm4, %edx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512-NEXT:    cmoval %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm4, %xmm4
-; AVX512-NEXT:    cmovpl %ecx, %edx
-; AVX512-NEXT:    vcvttss2si %xmm3, %esi
-; AVX512-NEXT:    vucomiss %xmm1, %xmm3
-; AVX512-NEXT:    cmoval %eax, %esi
-; AVX512-NEXT:    vucomiss %xmm3, %xmm3
-; AVX512-NEXT:    cmovpl %ecx, %esi
-; AVX512-NEXT:    vmovd %esi, %xmm4
-; AVX512-NEXT:    vpinsrd $1, %edx, %xmm4, %xmm4
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm5 = xmm3[1,0]
-; AVX512-NEXT:    vcvttss2si %xmm5, %edx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512-NEXT:    cmoval %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm5, %xmm5
-; AVX512-NEXT:    cmovpl %ecx, %edx
-; AVX512-NEXT:    vpinsrd $2, %edx, %xmm4, %xmm4
-; AVX512-NEXT:    vshufps {{.*#+}} xmm3 = xmm3[3,3,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm3, %edx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm3
-; AVX512-NEXT:    cmoval %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm3, %xmm3
-; AVX512-NEXT:    cmovpl %ecx, %edx
-; AVX512-NEXT:    vpinsrd $3, %edx, %xmm4, %xmm3
-; AVX512-NEXT:    vextractf128 $1, %ymm0, %xmm4
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm5 = xmm4[1,1,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm5, %edx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512-NEXT:    cmoval %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm5, %xmm5
-; AVX512-NEXT:    cmovpl %ecx, %edx
-; AVX512-NEXT:    vcvttss2si %xmm4, %esi
-; AVX512-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512-NEXT:    cmoval %eax, %esi
-; AVX512-NEXT:    vucomiss %xmm4, %xmm4
-; AVX512-NEXT:    cmovpl %ecx, %esi
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm5 = xmm4[1,0]
-; AVX512-NEXT:    vcvttss2si %xmm5, %edi
-; AVX512-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512-NEXT:    cmoval %eax, %edi
-; AVX512-NEXT:    vucomiss %xmm5, %xmm5
-; AVX512-NEXT:    vmovd %esi, %xmm5
-; AVX512-NEXT:    vpinsrd $1, %edx, %xmm5, %xmm5
-; AVX512-NEXT:    cmovpl %ecx, %edi
-; AVX512-NEXT:    vpinsrd $2, %edi, %xmm5, %xmm5
-; AVX512-NEXT:    vshufps {{.*#+}} xmm4 = xmm4[3,3,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm4, %edx
-; AVX512-NEXT:    vinserti128 $1, %xmm2, %ymm3, %ymm2
-; AVX512-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512-NEXT:    cmoval %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm4, %xmm4
-; AVX512-NEXT:    cmovpl %ecx, %edx
-; AVX512-NEXT:    vpinsrd $3, %edx, %xmm5, %xmm3
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm4 = xmm0[1,1,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm4, %edx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512-NEXT:    cmoval %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm4, %xmm4
-; AVX512-NEXT:    cmovpl %ecx, %edx
-; AVX512-NEXT:    vcvttss2si %xmm0, %esi
-; AVX512-NEXT:    vucomiss %xmm1, %xmm0
-; AVX512-NEXT:    cmoval %eax, %esi
-; AVX512-NEXT:    vucomiss %xmm0, %xmm0
-; AVX512-NEXT:    cmovpl %ecx, %esi
-; AVX512-NEXT:    vmovd %esi, %xmm4
-; AVX512-NEXT:    vpinsrd $1, %edx, %xmm4, %xmm4
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm5 = xmm0[1,0]
-; AVX512-NEXT:    vcvttss2si %xmm5, %edx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512-NEXT:    cmoval %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm5, %xmm5
-; AVX512-NEXT:    cmovpl %ecx, %edx
-; AVX512-NEXT:    vpinsrd $2, %edx, %xmm4, %xmm4
-; AVX512-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm0, %edx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm0
-; AVX512-NEXT:    cmoval %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm0, %xmm0
-; AVX512-NEXT:    cmovpl %ecx, %edx
-; AVX512-NEXT:    vpinsrd $3, %edx, %xmm4, %xmm0
-; AVX512-NEXT:    vinserti128 $1, %xmm3, %ymm0, %ymm0
-; AVX512-NEXT:    vinserti64x4 $1, %ymm2, %zmm0, %zmm0
-; AVX512-NEXT:    retq
+; CHECK-LABEL: test_signed_v16i32_v16f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vcmpgeps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to16}, %zmm0, %k1
+; CHECK-NEXT:    vcvttps2dq %zmm0, %zmm1
+; CHECK-NEXT:    vpbroadcastd {{.*#+}} zmm1 {%k1} = [2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647]
+; CHECK-NEXT:    vcmpunordps %zmm0, %zmm0, %k0
+; CHECK-NEXT:    knotw %k0, %k1
+; CHECK-NEXT:    vmovdqa32 %zmm1, %zmm0 {%k1} {z}
+; CHECK-NEXT:    retq
   %x = call <16 x i32> @llvm.fptosi.sat.v16i32.v16f32(<16 x float> %f)
   ret <16 x i32> %x
 }
@@ -2263,68 +2031,27 @@ define <8 x i16> @test_signed_v8i16_v8f64(<8 x double> %f) nounwind {
 }
 
 define <8 x i32> @test_signed_v8i32_v8f64(<8 x double> %f) nounwind {
-; CHECK-LABEL: test_signed_v8i32_v8f64:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    vextractf32x4 $2, %zmm0, %xmm1
-; CHECK-NEXT:    vshufpd {{.*#+}} xmm2 = xmm1[1,0]
-; CHECK-NEXT:    vmovsd {{.*#+}} xmm3 = [-2.147483648E+9,0.0E+0]
-; CHECK-NEXT:    vmaxsd %xmm3, %xmm2, %xmm4
-; CHECK-NEXT:    vmovsd {{.*#+}} xmm5 = [2.147483647E+9,0.0E+0]
-; CHECK-NEXT:    vminsd %xmm5, %xmm4, %xmm4
-; CHECK-NEXT:    vcvttsd2si %xmm4, %ecx
-; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    vucomisd %xmm2, %xmm2
-; CHECK-NEXT:    cmovpl %eax, %ecx
-; CHECK-NEXT:    vmaxsd %xmm3, %xmm1, %xmm2
-; CHECK-NEXT:    vminsd %xmm5, %xmm2, %xmm2
-; CHECK-NEXT:    vcvttsd2si %xmm2, %edx
-; CHECK-NEXT:    vucomisd %xmm1, %xmm1
-; CHECK-NEXT:    cmovpl %eax, %edx
-; CHECK-NEXT:    vmovd %edx, %xmm1
-; CHECK-NEXT:    vpinsrd $1, %ecx, %xmm1, %xmm1
-; CHECK-NEXT:    vextractf32x4 $3, %zmm0, %xmm2
-; CHECK-NEXT:    vmaxsd %xmm3, %xmm2, %xmm4
-; CHECK-NEXT:    vminsd %xmm5, %xmm4, %xmm4
-; CHECK-NEXT:    vcvttsd2si %xmm4, %ecx
-; CHECK-NEXT:    vucomisd %xmm2, %xmm2
-; CHECK-NEXT:    cmovpl %eax, %ecx
-; CHECK-NEXT:    vpinsrd $2, %ecx, %xmm1, %xmm1
-; CHECK-NEXT:    vshufpd {{.*#+}} xmm2 = xmm2[1,0]
-; CHECK-NEXT:    vmaxsd %xmm3, %xmm2, %xmm4
-; CHECK-NEXT:    vminsd %xmm5, %xmm4, %xmm4
-; CHECK-NEXT:    vcvttsd2si %xmm4, %ecx
-; CHECK-NEXT:    vucomisd %xmm2, %xmm2
-; CHECK-NEXT:    cmovpl %eax, %ecx
-; CHECK-NEXT:    vpinsrd $3, %ecx, %xmm1, %xmm1
-; CHECK-NEXT:    vshufpd {{.*#+}} xmm2 = xmm0[1,0]
-; CHECK-NEXT:    vmaxsd %xmm3, %xmm2, %xmm4
-; CHECK-NEXT:    vminsd %xmm5, %xmm4, %xmm4
-; CHECK-NEXT:    vcvttsd2si %xmm4, %ecx
-; CHECK-NEXT:    vucomisd %xmm2, %xmm2
-; CHECK-NEXT:    cmovpl %eax, %ecx
-; CHECK-NEXT:    vmaxsd %xmm3, %xmm0, %xmm2
-; CHECK-NEXT:    vminsd %xmm5, %xmm2, %xmm2
-; CHECK-NEXT:    vcvttsd2si %xmm2, %edx
-; CHECK-NEXT:    vucomisd %xmm0, %xmm0
-; CHECK-NEXT:    cmovpl %eax, %edx
-; CHECK-NEXT:    vmovd %edx, %xmm2
-; CHECK-NEXT:    vpinsrd $1, %ecx, %xmm2, %xmm2
-; CHECK-NEXT:    vextractf128 $1, %ymm0, %xmm0
-; CHECK-NEXT:    vmaxsd %xmm3, %xmm0, %xmm4
-; CHECK-NEXT:    vminsd %xmm5, %xmm4, %xmm4
-; CHECK-NEXT:    vcvttsd2si %xmm4, %ecx
-; CHECK-NEXT:    vucomisd %xmm0, %xmm0
-; CHECK-NEXT:    cmovpl %eax, %ecx
-; CHECK-NEXT:    vpinsrd $2, %ecx, %xmm2, %xmm2
-; CHECK-NEXT:    vshufpd {{.*#+}} xmm0 = xmm0[1,0]
-; CHECK-NEXT:    vmaxsd %xmm3, %xmm0, %xmm3
-; CHECK-NEXT:    vminsd %xmm5, %xmm3, %xmm3
-; CHECK-NEXT:    vcvttsd2si %xmm3, %ecx
-; CHECK-NEXT:    vucomisd %xmm0, %xmm0
-; CHECK-NEXT:    cmovpl %eax, %ecx
-; CHECK-NEXT:    vpinsrd $3, %ecx, %xmm2, %xmm0
-; CHECK-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
-; CHECK-NEXT:    retq
+; AVX512F-LABEL: test_signed_v8i32_v8f64:
+; AVX512F:       # %bb.0:
+; AVX512F-NEXT:    vcvttpd2dq %zmm0, %ymm1
+; AVX512F-NEXT:    vcmpgepd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %k1
+; AVX512F-NEXT:    vpternlogd {{.*#+}} zmm2 {%k1} {z} = -1
+; AVX512F-NEXT:    vbroadcastss {{.*#+}} ymm3 = [2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647]
+; AVX512F-NEXT:    vblendvps %ymm2, %ymm3, %ymm1, %ymm1
+; AVX512F-NEXT:    vcmpunordpd %zmm0, %zmm0, %k1
+; AVX512F-NEXT:    vpternlogd {{.*#+}} zmm0 {%k1} {z} = -1
+; AVX512F-NEXT:    vpandn %ymm1, %ymm0, %ymm0
+; AVX512F-NEXT:    retq
+;
+; AVX512-LABEL: test_signed_v8i32_v8f64:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vcmpgepd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %k1
+; AVX512-NEXT:    vcvttpd2dq %zmm0, %ymm1
+; AVX512-NEXT:    vpbroadcastd {{.*#+}} ymm1 {%k1} = [2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647]
+; AVX512-NEXT:    vcmpunordpd %zmm0, %zmm0, %k0
+; AVX512-NEXT:    knotb %k0, %k1
+; AVX512-NEXT:    vmovdqa32 %ymm1, %ymm0 {%k1} {z}
+; AVX512-NEXT:    retq
   %x = call <8 x i32> @llvm.fptosi.sat.v8i32.v8f64(<8 x double> %f)
   ret <8 x i32> %x
 }
diff --git a/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll b/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll
index 15306764a1936..f7b127c97edde 100644
--- a/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll
+++ b/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll
@@ -9,89 +9,21 @@
 ;
 
 define <4 x i1> @test_unsigned_v4i1_v4f32(<4 x float> %f) nounwind {
-; SSE2-LABEL: test_unsigned_v4i1_v4f32:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movaps %xmm0, %xmm1
-; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[3,3],xmm0[3,3]
-; SSE2-NEXT:    xorps %xmm2, %xmm2
-; SSE2-NEXT:    maxss %xmm2, %xmm1
-; SSE2-NEXT:    movss {{.*#+}} xmm3 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
-; SSE2-NEXT:    minss %xmm3, %xmm1
-; SSE2-NEXT:    cvttss2si %xmm1, %eax
-; SSE2-NEXT:    movd %eax, %xmm1
-; SSE2-NEXT:    movaps %xmm0, %xmm4
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm4 = xmm4[1],xmm0[1]
-; SSE2-NEXT:    maxss %xmm2, %xmm4
-; SSE2-NEXT:    minss %xmm3, %xmm4
-; SSE2-NEXT:    cvttss2si %xmm4, %eax
-; SSE2-NEXT:    movd %eax, %xmm4
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
-; SSE2-NEXT:    movaps %xmm0, %xmm1
-; SSE2-NEXT:    maxss %xmm2, %xmm1
-; SSE2-NEXT:    minss %xmm3, %xmm1
-; SSE2-NEXT:    cvttss2si %xmm1, %eax
-; SSE2-NEXT:    movd %eax, %xmm1
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE2-NEXT:    maxss %xmm2, %xmm0
-; SSE2-NEXT:    minss %xmm3, %xmm0
-; SSE2-NEXT:    cvttss2si %xmm0, %eax
-; SSE2-NEXT:    movd %eax, %xmm0
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
-; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm4[0]
-; SSE2-NEXT:    movdqa %xmm1, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE42-LABEL: test_unsigned_v4i1_v4f32:
-; SSE42:       # %bb.0:
-; SSE42-NEXT:    movshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; SSE42-NEXT:    xorps %xmm2, %xmm2
-; SSE42-NEXT:    maxss %xmm2, %xmm1
-; SSE42-NEXT:    movss {{.*#+}} xmm3 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
-; SSE42-NEXT:    minss %xmm3, %xmm1
-; SSE42-NEXT:    cvttss2si %xmm1, %eax
-; SSE42-NEXT:    movaps %xmm0, %xmm1
-; SSE42-NEXT:    maxss %xmm2, %xmm1
-; SSE42-NEXT:    minss %xmm3, %xmm1
-; SSE42-NEXT:    cvttss2si %xmm1, %ecx
-; SSE42-NEXT:    movd %ecx, %xmm1
-; SSE42-NEXT:    pinsrd $1, %eax, %xmm1
-; SSE42-NEXT:    movaps %xmm0, %xmm4
-; SSE42-NEXT:    unpckhpd {{.*#+}} xmm4 = xmm4[1],xmm0[1]
-; SSE42-NEXT:    maxss %xmm2, %xmm4
-; SSE42-NEXT:    minss %xmm3, %xmm4
-; SSE42-NEXT:    cvttss2si %xmm4, %eax
-; SSE42-NEXT:    pinsrd $2, %eax, %xmm1
-; SSE42-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE42-NEXT:    maxss %xmm2, %xmm0
-; SSE42-NEXT:    minss %xmm3, %xmm0
-; SSE42-NEXT:    cvttss2si %xmm0, %eax
-; SSE42-NEXT:    pinsrd $3, %eax, %xmm1
-; SSE42-NEXT:    movdqa %xmm1, %xmm0
-; SSE42-NEXT:    retq
+; SSE-LABEL: test_unsigned_v4i1_v4f32:
+; SSE:       # %bb.0:
+; SSE-NEXT:    xorps %xmm1, %xmm1
+; SSE-NEXT:    maxps %xmm1, %xmm0
+; SSE-NEXT:    minps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    cvttps2dq %xmm0, %xmm0
+; SSE-NEXT:    retq
 ;
 ; AVX2-LABEL: test_unsigned_v4i1_v4f32:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vmovshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; AVX2-NEXT:    vxorps %xmm2, %xmm2, %xmm2
-; AVX2-NEXT:    vmaxss %xmm2, %xmm1, %xmm1
-; AVX2-NEXT:    vmovss {{.*#+}} xmm3 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
-; AVX2-NEXT:    vminss %xmm3, %xmm1, %xmm1
-; AVX2-NEXT:    vcvttss2si %xmm1, %eax
-; AVX2-NEXT:    vmaxss %xmm2, %xmm0, %xmm1
-; AVX2-NEXT:    vminss %xmm3, %xmm1, %xmm1
-; AVX2-NEXT:    vcvttss2si %xmm1, %ecx
-; AVX2-NEXT:    vmovd %ecx, %xmm1
-; AVX2-NEXT:    vpinsrd $1, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm4 = xmm0[1,0]
-; AVX2-NEXT:    vmaxss %xmm2, %xmm4, %xmm4
-; AVX2-NEXT:    vminss %xmm3, %xmm4, %xmm4
-; AVX2-NEXT:    vcvttss2si %xmm4, %eax
-; AVX2-NEXT:    vpinsrd $2, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX2-NEXT:    vmaxss %xmm2, %xmm0, %xmm0
-; AVX2-NEXT:    vminss %xmm3, %xmm0, %xmm0
-; AVX2-NEXT:    vcvttss2si %xmm0, %eax
-; AVX2-NEXT:    vpinsrd $3, %eax, %xmm1, %xmm0
+; AVX2-NEXT:    vxorps %xmm1, %xmm1, %xmm1
+; AVX2-NEXT:    vmaxps %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]
+; AVX2-NEXT:    vminps %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vcvttps2dq %xmm0, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_unsigned_v4i1_v4f32:
@@ -126,89 +58,21 @@ define <4 x i1> @test_unsigned_v4i1_v4f32(<4 x float> %f) nounwind {
 }
 
 define <4 x i1> @test_freeze_unsigned_v4i1_v4f32(<4 x float> %f) nounwind {
-; SSE2-LABEL: test_freeze_unsigned_v4i1_v4f32:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movaps %xmm0, %xmm1
-; SSE2-NEXT:    shufps {{.*#+}} xmm1 = xmm1[3,3],xmm0[3,3]
-; SSE2-NEXT:    xorps %xmm2, %xmm2
-; SSE2-NEXT:    maxss %xmm2, %xmm1
-; SSE2-NEXT:    movss {{.*#+}} xmm3 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
-; SSE2-NEXT:    minss %xmm3, %xmm1
-; SSE2-NEXT:    cvttss2si %xmm1, %eax
-; SSE2-NEXT:    movd %eax, %xmm1
-; SSE2-NEXT:    movaps %xmm0, %xmm4
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm4 = xmm4[1],xmm0[1]
-; SSE2-NEXT:    maxss %xmm2, %xmm4
-; SSE2-NEXT:    minss %xmm3, %xmm4
-; SSE2-NEXT:    cvttss2si %xmm4, %eax
-; SSE2-NEXT:    movd %eax, %xmm4
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
-; SSE2-NEXT:    movaps %xmm0, %xmm1
-; SSE2-NEXT:    maxss %xmm2, %xmm1
-; SSE2-NEXT:    minss %xmm3, %xmm1
-; SSE2-NEXT:    cvttss2si %xmm1, %eax
-; SSE2-NEXT:    movd %eax, %xmm1
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE2-NEXT:    maxss %xmm2, %xmm0
-; SSE2-NEXT:    minss %xmm3, %xmm0
-; SSE2-NEXT:    cvttss2si %xmm0, %eax
-; SSE2-NEXT:    movd %eax, %xmm0
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
-; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm4[0]
-; SSE2-NEXT:    movdqa %xmm1, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE42-LABEL: test_freeze_unsigned_v4i1_v4f32:
-; SSE42:       # %bb.0:
-; SSE42-NEXT:    movshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; SSE42-NEXT:    xorps %xmm2, %xmm2
-; SSE42-NEXT:    maxss %xmm2, %xmm1
-; SSE42-NEXT:    movss {{.*#+}} xmm3 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
-; SSE42-NEXT:    minss %xmm3, %xmm1
-; SSE42-NEXT:    cvttss2si %xmm1, %eax
-; SSE42-NEXT:    movaps %xmm0, %xmm1
-; SSE42-NEXT:    maxss %xmm2, %xmm1
-; SSE42-NEXT:    minss %xmm3, %xmm1
-; SSE42-NEXT:    cvttss2si %xmm1, %ecx
-; SSE42-NEXT:    movd %ecx, %xmm1
-; SSE42-NEXT:    pinsrd $1, %eax, %xmm1
-; SSE42-NEXT:    movaps %xmm0, %xmm4
-; SSE42-NEXT:    unpckhpd {{.*#+}} xmm4 = xmm4[1],xmm0[1]
-; SSE42-NEXT:    maxss %xmm2, %xmm4
-; SSE42-NEXT:    minss %xmm3, %xmm4
-; SSE42-NEXT:    cvttss2si %xmm4, %eax
-; SSE42-NEXT:    pinsrd $2, %eax, %xmm1
-; SSE42-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE42-NEXT:    maxss %xmm2, %xmm0
-; SSE42-NEXT:    minss %xmm3, %xmm0
-; SSE42-NEXT:    cvttss2si %xmm0, %eax
-; SSE42-NEXT:    pinsrd $3, %eax, %xmm1
-; SSE42-NEXT:    movdqa %xmm1, %xmm0
-; SSE42-NEXT:    retq
+; SSE-LABEL: test_freeze_unsigned_v4i1_v4f32:
+; SSE:       # %bb.0:
+; SSE-NEXT:    xorps %xmm1, %xmm1
+; SSE-NEXT:    maxps %xmm1, %xmm0
+; SSE-NEXT:    minps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE-NEXT:    cvttps2dq %xmm0, %xmm0
+; SSE-NEXT:    retq
 ;
 ; AVX2-LABEL: test_freeze_unsigned_v4i1_v4f32:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vmovshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; AVX2-NEXT:    vxorps %xmm2, %xmm2, %xmm2
-; AVX2-NEXT:    vmaxss %xmm2, %xmm1, %xmm1
-; AVX2-NEXT:    vmovss {{.*#+}} xmm3 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
-; AVX2-NEXT:    vminss %xmm3, %xmm1, %xmm1
-; AVX2-NEXT:    vcvttss2si %xmm1, %eax
-; AVX2-NEXT:    vmaxss %xmm2, %xmm0, %xmm1
-; AVX2-NEXT:    vminss %xmm3, %xmm1, %xmm1
-; AVX2-NEXT:    vcvttss2si %xmm1, %ecx
-; AVX2-NEXT:    vmovd %ecx, %xmm1
-; AVX2-NEXT:    vpinsrd $1, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm4 = xmm0[1,0]
-; AVX2-NEXT:    vmaxss %xmm2, %xmm4, %xmm4
-; AVX2-NEXT:    vminss %xmm3, %xmm4, %xmm4
-; AVX2-NEXT:    vcvttss2si %xmm4, %eax
-; AVX2-NEXT:    vpinsrd $2, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX2-NEXT:    vmaxss %xmm2, %xmm0, %xmm0
-; AVX2-NEXT:    vminss %xmm3, %xmm0, %xmm0
-; AVX2-NEXT:    vcvttss2si %xmm0, %eax
-; AVX2-NEXT:    vpinsrd $3, %eax, %xmm1, %xmm0
+; AVX2-NEXT:    vxorps %xmm1, %xmm1, %xmm1
+; AVX2-NEXT:    vmaxps %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]
+; AVX2-NEXT:    vminps %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vcvttps2dq %xmm0, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_freeze_unsigned_v4i1_v4f32:
@@ -443,149 +307,65 @@ define <4 x i16> @test_unsigned_v4i16_v4f32(<4 x float> %f) nounwind {
 define <4 x i32> @test_unsigned_v4i32_v4f32(<4 x float> %f) nounwind {
 ; SSE2-LABEL: test_unsigned_v4i32_v4f32:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movaps %xmm0, %xmm3
-; SSE2-NEXT:    shufps {{.*#+}} xmm3 = xmm3[3,3],xmm0[3,3]
-; SSE2-NEXT:    cvttss2si %xmm3, %rdx
-; SSE2-NEXT:    xorl %eax, %eax
-; SSE2-NEXT:    xorps %xmm2, %xmm2
-; SSE2-NEXT:    ucomiss %xmm2, %xmm3
-; SSE2-NEXT:    cmovbl %eax, %edx
-; SSE2-NEXT:    movss {{.*#+}} xmm1 = [4.29496704E+9,0.0E+0,0.0E+0,0.0E+0]
-; SSE2-NEXT:    ucomiss %xmm1, %xmm3
-; SSE2-NEXT:    movl $-1, %ecx
-; SSE2-NEXT:    cmoval %ecx, %edx
-; SSE2-NEXT:    movaps %xmm0, %xmm3
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm3 = xmm3[1],xmm0[1]
-; SSE2-NEXT:    cvttss2si %xmm3, %rsi
-; SSE2-NEXT:    ucomiss %xmm2, %xmm3
-; SSE2-NEXT:    cmovbl %eax, %esi
-; SSE2-NEXT:    ucomiss %xmm1, %xmm3
-; SSE2-NEXT:    cmoval %ecx, %esi
-; SSE2-NEXT:    cvttss2si %xmm0, %rdi
-; SSE2-NEXT:    ucomiss %xmm2, %xmm0
-; SSE2-NEXT:    cmovbl %eax, %edi
-; SSE2-NEXT:    ucomiss %xmm1, %xmm0
-; SSE2-NEXT:    cmoval %ecx, %edi
-; SSE2-NEXT:    movd %edx, %xmm3
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE2-NEXT:    cvttss2si %xmm0, %rdx
-; SSE2-NEXT:    ucomiss %xmm2, %xmm0
-; SSE2-NEXT:    cmovbl %eax, %edx
-; SSE2-NEXT:    movd %esi, %xmm2
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
-; SSE2-NEXT:    ucomiss %xmm1, %xmm0
-; SSE2-NEXT:    movd %edi, %xmm0
-; SSE2-NEXT:    cmoval %ecx, %edx
-; SSE2-NEXT:    movd %edx, %xmm1
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
-; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0]
+; SSE2-NEXT:    xorps %xmm1, %xmm1
+; SSE2-NEXT:    maxps %xmm1, %xmm0
+; SSE2-NEXT:    cvttps2dq %xmm0, %xmm2
+; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
+; SSE2-NEXT:    cmpleps %xmm0, %xmm1
+; SSE2-NEXT:    orps %xmm2, %xmm1
+; SSE2-NEXT:    psrad $31, %xmm2
+; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE2-NEXT:    cvttps2dq %xmm0, %xmm0
+; SSE2-NEXT:    pand %xmm2, %xmm0
+; SSE2-NEXT:    orps %xmm0, %xmm1
+; SSE2-NEXT:    movaps %xmm1, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE42-LABEL: test_unsigned_v4i32_v4f32:
 ; SSE42:       # %bb.0:
-; SSE42-NEXT:    movshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; SSE42-NEXT:    cvttss2si %xmm1, %rdx
-; SSE42-NEXT:    xorl %eax, %eax
-; SSE42-NEXT:    xorps %xmm2, %xmm2
-; SSE42-NEXT:    ucomiss %xmm2, %xmm1
-; SSE42-NEXT:    cmovbl %eax, %edx
-; SSE42-NEXT:    movss {{.*#+}} xmm3 = [4.29496704E+9,0.0E+0,0.0E+0,0.0E+0]
-; SSE42-NEXT:    ucomiss %xmm3, %xmm1
-; SSE42-NEXT:    movl $-1, %ecx
-; SSE42-NEXT:    cmoval %ecx, %edx
-; SSE42-NEXT:    cvttss2si %xmm0, %rsi
-; SSE42-NEXT:    ucomiss %xmm2, %xmm0
-; SSE42-NEXT:    cmovbl %eax, %esi
-; SSE42-NEXT:    ucomiss %xmm3, %xmm0
-; SSE42-NEXT:    cmoval %ecx, %esi
-; SSE42-NEXT:    movd %esi, %xmm1
-; SSE42-NEXT:    pinsrd $1, %edx, %xmm1
-; SSE42-NEXT:    movaps %xmm0, %xmm4
-; SSE42-NEXT:    unpckhpd {{.*#+}} xmm4 = xmm4[1],xmm0[1]
-; SSE42-NEXT:    cvttss2si %xmm4, %rdx
-; SSE42-NEXT:    ucomiss %xmm2, %xmm4
-; SSE42-NEXT:    cmovbl %eax, %edx
-; SSE42-NEXT:    ucomiss %xmm3, %xmm4
-; SSE42-NEXT:    cmoval %ecx, %edx
-; SSE42-NEXT:    pinsrd $2, %edx, %xmm1
-; SSE42-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE42-NEXT:    cvttss2si %xmm0, %rdx
-; SSE42-NEXT:    ucomiss %xmm2, %xmm0
-; SSE42-NEXT:    cmovbl %eax, %edx
-; SSE42-NEXT:    ucomiss %xmm3, %xmm0
-; SSE42-NEXT:    cmoval %ecx, %edx
-; SSE42-NEXT:    pinsrd $3, %edx, %xmm1
-; SSE42-NEXT:    movdqa %xmm1, %xmm0
+; SSE42-NEXT:    xorps %xmm1, %xmm1
+; SSE42-NEXT:    maxps %xmm1, %xmm0
+; SSE42-NEXT:    cvttps2dq %xmm0, %xmm2
+; SSE42-NEXT:    movdqa %xmm2, %xmm3
+; SSE42-NEXT:    psrad $31, %xmm3
+; SSE42-NEXT:    movaps {{.*#+}} xmm1 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
+; SSE42-NEXT:    cmpleps %xmm0, %xmm1
+; SSE42-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE42-NEXT:    cvttps2dq %xmm0, %xmm0
+; SSE42-NEXT:    pand %xmm3, %xmm0
+; SSE42-NEXT:    por %xmm2, %xmm0
+; SSE42-NEXT:    orps %xmm0, %xmm1
+; SSE42-NEXT:    movaps %xmm1, %xmm0
 ; SSE42-NEXT:    retq
 ;
 ; AVX2-LABEL: test_unsigned_v4i32_v4f32:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vmovshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; AVX2-NEXT:    vcvttss2si %xmm1, %rdx
-; AVX2-NEXT:    xorl %eax, %eax
-; AVX2-NEXT:    vxorps %xmm2, %xmm2, %xmm2
-; AVX2-NEXT:    vucomiss %xmm2, %xmm1
-; AVX2-NEXT:    cmovbl %eax, %edx
-; AVX2-NEXT:    vmovss {{.*#+}} xmm3 = [4.29496704E+9,0.0E+0,0.0E+0,0.0E+0]
-; AVX2-NEXT:    vucomiss %xmm3, %xmm1
-; AVX2-NEXT:    movl $-1, %ecx
-; AVX2-NEXT:    cmoval %ecx, %edx
-; AVX2-NEXT:    vcvttss2si %xmm0, %rsi
-; AVX2-NEXT:    vucomiss %xmm2, %xmm0
-; AVX2-NEXT:    cmovbl %eax, %esi
-; AVX2-NEXT:    vucomiss %xmm3, %xmm0
-; AVX2-NEXT:    cmoval %ecx, %esi
-; AVX2-NEXT:    vmovd %esi, %xmm1
-; AVX2-NEXT:    vpinsrd $1, %edx, %xmm1, %xmm1
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm4 = xmm0[1,0]
-; AVX2-NEXT:    vcvttss2si %xmm4, %rdx
-; AVX2-NEXT:    vucomiss %xmm2, %xmm4
-; AVX2-NEXT:    cmovbl %eax, %edx
-; AVX2-NEXT:    vucomiss %xmm3, %xmm4
-; AVX2-NEXT:    cmoval %ecx, %edx
-; AVX2-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX2-NEXT:    vcvttss2si %xmm0, %rsi
-; AVX2-NEXT:    vucomiss %xmm2, %xmm0
-; AVX2-NEXT:    cmovbl %eax, %esi
-; AVX2-NEXT:    vucomiss %xmm3, %xmm0
-; AVX2-NEXT:    cmoval %ecx, %esi
-; AVX2-NEXT:    vpinsrd $2, %edx, %xmm1, %xmm0
-; AVX2-NEXT:    vpinsrd $3, %esi, %xmm0, %xmm0
+; AVX2-NEXT:    vxorps %xmm1, %xmm1, %xmm1
+; AVX2-NEXT:    vmaxps %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vcvttps2dq %xmm0, %xmm1
+; AVX2-NEXT:    vpsrad $31, %xmm1, %xmm2
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm3 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
+; AVX2-NEXT:    vsubps %xmm3, %xmm0, %xmm3
+; AVX2-NEXT:    vcvttps2dq %xmm3, %xmm3
+; AVX2-NEXT:    vpand %xmm2, %xmm3, %xmm2
+; AVX2-NEXT:    vpor %xmm2, %xmm1, %xmm1
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm2 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
+; AVX2-NEXT:    vcmpleps %xmm0, %xmm2, %xmm0
+; AVX2-NEXT:    vorps %xmm1, %xmm0, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_unsigned_v4i32_v4f32:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm1 = xmm0[1,1,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm1, %rdx
-; AVX512-NEXT:    xorl %eax, %eax
-; AVX512-NEXT:    vxorps %xmm2, %xmm2, %xmm2
-; AVX512-NEXT:    vucomiss %xmm2, %xmm1
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vmovss {{.*#+}} xmm3 = [4.29496704E+9,0.0E+0,0.0E+0,0.0E+0]
-; AVX512-NEXT:    vucomiss %xmm3, %xmm1
-; AVX512-NEXT:    movl $-1, %ecx
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vcvttss2si %xmm0, %rsi
-; AVX512-NEXT:    vucomiss %xmm2, %xmm0
-; AVX512-NEXT:    cmovbl %eax, %esi
-; AVX512-NEXT:    vucomiss %xmm3, %xmm0
-; AVX512-NEXT:    cmoval %ecx, %esi
-; AVX512-NEXT:    vmovd %esi, %xmm1
-; AVX512-NEXT:    vpinsrd $1, %edx, %xmm1, %xmm1
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm4 = xmm0[1,0]
-; AVX512-NEXT:    vcvttss2si %xmm4, %rdx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm4
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm3, %xmm4
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vpinsrd $2, %edx, %xmm1, %xmm1
-; AVX512-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm0, %rdx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm0
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm3, %xmm0
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vpinsrd $3, %edx, %xmm1, %xmm0
+; AVX512-NEXT:    vxorps %xmm1, %xmm1, %xmm1
+; AVX512-NEXT:    vmaxps %xmm1, %xmm0, %xmm1
+; AVX512-NEXT:    vcvttps2dq %xmm1, %xmm2
+; AVX512-NEXT:    vpsrad $31, %xmm2, %xmm3
+; AVX512-NEXT:    vsubps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm1, %xmm0
+; AVX512-NEXT:    vcvttps2dq %xmm0, %xmm0
+; AVX512-NEXT:    vpternlogd {{.*#+}} xmm0 = (xmm0 & xmm3) | xmm2
+; AVX512-NEXT:    vcmpgeps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm1, %k1
+; AVX512-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
+; AVX512-NEXT:    vmovdqa32 %xmm1, %xmm0 {%k1}
 ; AVX512-NEXT:    retq
   %x = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> %f)
   ret <4 x i32> %x
diff --git a/llvm/test/CodeGen/X86/fptoui-sat-vector-256.ll b/llvm/test/CodeGen/X86/fptoui-sat-vector-256.ll
index 98eef96f1ab19..10f09ce44bbf2 100644
--- a/llvm/test/CodeGen/X86/fptoui-sat-vector-256.ll
+++ b/llvm/test/CodeGen/X86/fptoui-sat-vector-256.ll
@@ -400,130 +400,32 @@ define <8 x i16> @test_unsigned_v8i16_v8f32(<8 x float> %f) nounwind {
 define <8 x i32> @test_unsigned_v8i32_v8f32(<8 x float> %f) nounwind {
 ; AVX2-LABEL: test_unsigned_v8i32_v8f32:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm3
-; AVX2-NEXT:    vmovshdup {{.*#+}} xmm4 = xmm3[1,1,3,3]
-; AVX2-NEXT:    vcvttss2si %xmm4, %rdx
-; AVX2-NEXT:    xorl %eax, %eax
 ; AVX2-NEXT:    vxorps %xmm1, %xmm1, %xmm1
-; AVX2-NEXT:    vucomiss %xmm1, %xmm4
-; AVX2-NEXT:    cmovbl %eax, %edx
-; AVX2-NEXT:    vmovss {{.*#+}} xmm2 = [4.29496704E+9,0.0E+0,0.0E+0,0.0E+0]
-; AVX2-NEXT:    vucomiss %xmm2, %xmm4
-; AVX2-NEXT:    movl $-1, %ecx
-; AVX2-NEXT:    cmoval %ecx, %edx
-; AVX2-NEXT:    vcvttss2si %xmm3, %rsi
-; AVX2-NEXT:    vucomiss %xmm1, %xmm3
-; AVX2-NEXT:    cmovbl %eax, %esi
-; AVX2-NEXT:    vucomiss %xmm2, %xmm3
-; AVX2-NEXT:    cmoval %ecx, %esi
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm4 = xmm3[1,0]
-; AVX2-NEXT:    vcvttss2si %xmm4, %rdi
-; AVX2-NEXT:    vmovd %esi, %xmm5
-; AVX2-NEXT:    vucomiss %xmm1, %xmm4
-; AVX2-NEXT:    cmovbl %eax, %edi
-; AVX2-NEXT:    vucomiss %xmm2, %xmm4
-; AVX2-NEXT:    cmoval %ecx, %edi
-; AVX2-NEXT:    vpinsrd $1, %edx, %xmm5, %xmm4
-; AVX2-NEXT:    vpinsrd $2, %edi, %xmm4, %xmm4
-; AVX2-NEXT:    vshufps {{.*#+}} xmm3 = xmm3[3,3,3,3]
-; AVX2-NEXT:    vcvttss2si %xmm3, %rdx
-; AVX2-NEXT:    vucomiss %xmm1, %xmm3
-; AVX2-NEXT:    cmovbl %eax, %edx
-; AVX2-NEXT:    vucomiss %xmm2, %xmm3
-; AVX2-NEXT:    cmoval %ecx, %edx
-; AVX2-NEXT:    vmovshdup {{.*#+}} xmm3 = xmm0[1,1,3,3]
-; AVX2-NEXT:    vcvttss2si %xmm3, %rsi
-; AVX2-NEXT:    vucomiss %xmm1, %xmm3
-; AVX2-NEXT:    cmovbl %eax, %esi
-; AVX2-NEXT:    vucomiss %xmm2, %xmm3
-; AVX2-NEXT:    cmoval %ecx, %esi
-; AVX2-NEXT:    vpinsrd $3, %edx, %xmm4, %xmm3
-; AVX2-NEXT:    vcvttss2si %xmm0, %rdx
-; AVX2-NEXT:    vucomiss %xmm1, %xmm0
-; AVX2-NEXT:    cmovbl %eax, %edx
-; AVX2-NEXT:    vucomiss %xmm2, %xmm0
-; AVX2-NEXT:    cmoval %ecx, %edx
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm4 = xmm0[1,0]
-; AVX2-NEXT:    vcvttss2si %xmm4, %rdi
-; AVX2-NEXT:    vmovd %edx, %xmm5
-; AVX2-NEXT:    vucomiss %xmm1, %xmm4
-; AVX2-NEXT:    cmovbl %eax, %edi
-; AVX2-NEXT:    vucomiss %xmm2, %xmm4
-; AVX2-NEXT:    cmoval %ecx, %edi
-; AVX2-NEXT:    vpinsrd $1, %esi, %xmm5, %xmm4
-; AVX2-NEXT:    vpinsrd $2, %edi, %xmm4, %xmm4
-; AVX2-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX2-NEXT:    vcvttss2si %xmm0, %rdx
-; AVX2-NEXT:    vucomiss %xmm1, %xmm0
-; AVX2-NEXT:    cmovbl %eax, %edx
-; AVX2-NEXT:    vucomiss %xmm2, %xmm0
-; AVX2-NEXT:    cmoval %ecx, %edx
-; AVX2-NEXT:    vpinsrd $3, %edx, %xmm4, %xmm0
-; AVX2-NEXT:    vinserti128 $1, %xmm3, %ymm0, %ymm0
+; AVX2-NEXT:    vmaxps %ymm1, %ymm0, %ymm0
+; AVX2-NEXT:    vcvttps2dq %ymm0, %ymm1
+; AVX2-NEXT:    vpsrad $31, %ymm1, %ymm2
+; AVX2-NEXT:    vbroadcastss {{.*#+}} ymm3 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
+; AVX2-NEXT:    vsubps %ymm3, %ymm0, %ymm3
+; AVX2-NEXT:    vcvttps2dq %ymm3, %ymm3
+; AVX2-NEXT:    vpand %ymm2, %ymm3, %ymm2
+; AVX2-NEXT:    vpor %ymm2, %ymm1, %ymm1
+; AVX2-NEXT:    vbroadcastss {{.*#+}} ymm2 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
+; AVX2-NEXT:    vcmpleps %ymm0, %ymm2, %ymm0
+; AVX2-NEXT:    vorps %ymm1, %ymm0, %ymm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_unsigned_v8i32_v8f32:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vextractf128 $1, %ymm0, %xmm3
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm4 = xmm3[1,1,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm4, %rdx
-; AVX512-NEXT:    xorl %eax, %eax
 ; AVX512-NEXT:    vxorps %xmm1, %xmm1, %xmm1
-; AVX512-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vmovss {{.*#+}} xmm2 = [4.29496704E+9,0.0E+0,0.0E+0,0.0E+0]
-; AVX512-NEXT:    vucomiss %xmm2, %xmm4
-; AVX512-NEXT:    movl $-1, %ecx
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vcvttss2si %xmm3, %rsi
-; AVX512-NEXT:    vucomiss %xmm1, %xmm3
-; AVX512-NEXT:    cmovbl %eax, %esi
-; AVX512-NEXT:    vucomiss %xmm2, %xmm3
-; AVX512-NEXT:    cmoval %ecx, %esi
-; AVX512-NEXT:    vmovd %esi, %xmm4
-; AVX512-NEXT:    vpinsrd $1, %edx, %xmm4, %xmm4
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm5 = xmm3[1,0]
-; AVX512-NEXT:    vcvttss2si %xmm5, %rdx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm5
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vpinsrd $2, %edx, %xmm4, %xmm4
-; AVX512-NEXT:    vshufps {{.*#+}} xmm3 = xmm3[3,3,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm3, %rdx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm3
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm3
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vpinsrd $3, %edx, %xmm4, %xmm3
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm4 = xmm0[1,1,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm4, %rdx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm4
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vcvttss2si %xmm0, %rsi
-; AVX512-NEXT:    vucomiss %xmm1, %xmm0
-; AVX512-NEXT:    cmovbl %eax, %esi
-; AVX512-NEXT:    vucomiss %xmm2, %xmm0
-; AVX512-NEXT:    cmoval %ecx, %esi
-; AVX512-NEXT:    vmovd %esi, %xmm4
-; AVX512-NEXT:    vpinsrd $1, %edx, %xmm4, %xmm4
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm5 = xmm0[1,0]
-; AVX512-NEXT:    vcvttss2si %xmm5, %rdx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm5
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vpinsrd $2, %edx, %xmm4, %xmm4
-; AVX512-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm0, %rdx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm0
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm0
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vpinsrd $3, %edx, %xmm4, %xmm0
-; AVX512-NEXT:    vinserti128 $1, %xmm3, %ymm0, %ymm0
+; AVX512-NEXT:    vmaxps %ymm1, %ymm0, %ymm1
+; AVX512-NEXT:    vcvttps2dq %ymm1, %ymm2
+; AVX512-NEXT:    vpsrad $31, %ymm2, %ymm3
+; AVX512-NEXT:    vsubps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm1, %ymm0
+; AVX512-NEXT:    vcvttps2dq %ymm0, %ymm0
+; AVX512-NEXT:    vpternlogd {{.*#+}} ymm0 = (ymm0 & ymm3) | ymm2
+; AVX512-NEXT:    vcmpgeps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm1, %k1
+; AVX512-NEXT:    vpcmpeqd %ymm1, %ymm1, %ymm1
+; AVX512-NEXT:    vmovdqa32 %ymm1, %ymm0 {%k1}
 ; AVX512-NEXT:    retq
   %x = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> %f)
   ret <8 x i32> %x
@@ -896,27 +798,11 @@ define <8 x i128> @test_unsigned_v8i128_v8f32(<8 x float> %f) nounwind {
 define <4 x i1> @test_unsigned_v4i1_v4f64(<4 x double> %f) nounwind {
 ; AVX2-LABEL: test_unsigned_v4i1_v4f64:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm1 = xmm0[1,0]
-; AVX2-NEXT:    vxorpd %xmm2, %xmm2, %xmm2
-; AVX2-NEXT:    vmaxsd %xmm2, %xmm1, %xmm1
-; AVX2-NEXT:    vmovsd {{.*#+}} xmm3 = [1.0E+0,0.0E+0]
-; AVX2-NEXT:    vminsd %xmm3, %xmm1, %xmm1
-; AVX2-NEXT:    vcvttsd2si %xmm1, %eax
-; AVX2-NEXT:    vmaxsd %xmm2, %xmm0, %xmm1
-; AVX2-NEXT:    vminsd %xmm3, %xmm1, %xmm1
-; AVX2-NEXT:    vcvttsd2si %xmm1, %ecx
-; AVX2-NEXT:    vmovd %ecx, %xmm1
-; AVX2-NEXT:    vpinsrd $1, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm0
-; AVX2-NEXT:    vmaxsd %xmm2, %xmm0, %xmm4
-; AVX2-NEXT:    vminsd %xmm3, %xmm4, %xmm4
-; AVX2-NEXT:    vcvttsd2si %xmm4, %eax
-; AVX2-NEXT:    vpinsrd $2, %eax, %xmm1, %xmm1
-; AVX2-NEXT:    vshufpd {{.*#+}} xmm0 = xmm0[1,0]
-; AVX2-NEXT:    vmaxsd %xmm2, %xmm0, %xmm0
-; AVX2-NEXT:    vminsd %xmm3, %xmm0, %xmm0
-; AVX2-NEXT:    vcvttsd2si %xmm0, %eax
-; AVX2-NEXT:    vpinsrd $3, %eax, %xmm1, %xmm0
+; AVX2-NEXT:    vxorpd %xmm1, %xmm1, %xmm1
+; AVX2-NEXT:    vmaxpd %ymm1, %ymm0, %ymm0
+; AVX2-NEXT:    vbroadcastsd {{.*#+}} ymm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]
+; AVX2-NEXT:    vminpd %ymm1, %ymm0, %ymm0
+; AVX2-NEXT:    vcvttpd2dq %ymm0, %xmm0
 ; AVX2-NEXT:    vzeroupper
 ; AVX2-NEXT:    retq
 ;
@@ -1013,31 +899,40 @@ define <4 x i16> @test_unsigned_v4i16_v4f64(<4 x double> %f) nounwind {
 }
 
 define <4 x i32> @test_unsigned_v4i32_v4f64(<4 x double> %f) nounwind {
-; CHECK-LABEL: test_unsigned_v4i32_v4f64:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    vshufpd {{.*#+}} xmm1 = xmm0[1,0]
-; CHECK-NEXT:    vxorpd %xmm2, %xmm2, %xmm2
-; CHECK-NEXT:    vmaxsd %xmm1, %xmm2, %xmm1
-; CHECK-NEXT:    vmovsd {{.*#+}} xmm3 = [4.294967295E+9,0.0E+0]
-; CHECK-NEXT:    vminsd %xmm1, %xmm3, %xmm1
-; CHECK-NEXT:    vcvttsd2si %xmm1, %rax
-; CHECK-NEXT:    vmaxsd %xmm0, %xmm2, %xmm1
-; CHECK-NEXT:    vminsd %xmm1, %xmm3, %xmm1
-; CHECK-NEXT:    vcvttsd2si %xmm1, %rcx
-; CHECK-NEXT:    vmovd %ecx, %xmm1
-; CHECK-NEXT:    vpinsrd $1, %eax, %xmm1, %xmm1
-; CHECK-NEXT:    vextractf128 $1, %ymm0, %xmm0
-; CHECK-NEXT:    vmaxsd %xmm0, %xmm2, %xmm4
-; CHECK-NEXT:    vminsd %xmm4, %xmm3, %xmm4
-; CHECK-NEXT:    vcvttsd2si %xmm4, %rax
-; CHECK-NEXT:    vpinsrd $2, %eax, %xmm1, %xmm1
-; CHECK-NEXT:    vshufpd {{.*#+}} xmm0 = xmm0[1,0]
-; CHECK-NEXT:    vmaxsd %xmm0, %xmm2, %xmm0
-; CHECK-NEXT:    vminsd %xmm0, %xmm3, %xmm0
-; CHECK-NEXT:    vcvttsd2si %xmm0, %rax
-; CHECK-NEXT:    vpinsrd $3, %eax, %xmm1, %xmm0
-; CHECK-NEXT:    vzeroupper
-; CHECK-NEXT:    retq
+; AVX2-LABEL: test_unsigned_v4i32_v4f64:
+; AVX2:       # %bb.0:
+; AVX2-NEXT:    vxorpd %xmm1, %xmm1, %xmm1
+; AVX2-NEXT:    vmaxpd %ymm1, %ymm0, %ymm0
+; AVX2-NEXT:    vbroadcastsd {{.*#+}} ymm1 = [4.294967296E+9,4.294967296E+9,4.294967296E+9,4.294967296E+9]
+; AVX2-NEXT:    vcmplepd %ymm0, %ymm1, %ymm1
+; AVX2-NEXT:    vextractf128 $1, %ymm1, %xmm2
+; AVX2-NEXT:    vpackssdw %xmm2, %xmm1, %xmm1
+; AVX2-NEXT:    vcvttpd2dq %ymm0, %xmm2
+; AVX2-NEXT:    vpsrad $31, %xmm2, %xmm3
+; AVX2-NEXT:    vbroadcastsd {{.*#+}} ymm4 = [2.147483648E+9,2.147483648E+9,2.147483648E+9,2.147483648E+9]
+; AVX2-NEXT:    vsubpd %ymm4, %ymm0, %ymm0
+; AVX2-NEXT:    vcvttpd2dq %ymm0, %xmm0
+; AVX2-NEXT:    vandpd %xmm3, %xmm0, %xmm0
+; AVX2-NEXT:    vorpd %xmm0, %xmm2, %xmm0
+; AVX2-NEXT:    vpcmpeqd %xmm2, %xmm2, %xmm2
+; AVX2-NEXT:    vblendvps %xmm1, %xmm2, %xmm0, %xmm0
+; AVX2-NEXT:    vzeroupper
+; AVX2-NEXT:    retq
+;
+; AVX512-LABEL: test_unsigned_v4i32_v4f64:
+; AVX512:       # %bb.0:
+; AVX512-NEXT:    vxorpd %xmm1, %xmm1, %xmm1
+; AVX512-NEXT:    vmaxpd %ymm1, %ymm0, %ymm1
+; AVX512-NEXT:    vcvttpd2dq %ymm1, %xmm2
+; AVX512-NEXT:    vsubpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm1, %ymm0
+; AVX512-NEXT:    vcvttpd2dq %ymm0, %xmm0
+; AVX512-NEXT:    vpsrad $31, %xmm2, %xmm3
+; AVX512-NEXT:    vpternlogd {{.*#+}} xmm0 = (xmm0 & xmm3) | xmm2
+; AVX512-NEXT:    vcmpgepd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm1, %k1
+; AVX512-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
+; AVX512-NEXT:    vmovdqa32 %xmm1, %xmm0 {%k1}
+; AVX512-NEXT:    vzeroupper
+; AVX512-NEXT:    retq
   %x = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> %f)
   ret <4 x i32> %x
 }
diff --git a/llvm/test/CodeGen/X86/fptoui-sat-vector-512.ll b/llvm/test/CodeGen/X86/fptoui-sat-vector-512.ll
index 905ddef1db787..17f4499fb0bb7 100644
--- a/llvm/test/CodeGen/X86/fptoui-sat-vector-512.ll
+++ b/llvm/test/CodeGen/X86/fptoui-sat-vector-512.ll
@@ -721,249 +721,15 @@ define <16 x i16> @test_unsigned_v16i16_v16f32(<16 x float> %f) nounwind {
 }
 
 define <16 x i32> @test_unsigned_v16i32_v16f32(<16 x float> %f) nounwind {
-; AVX512F-LABEL: test_unsigned_v16i32_v16f32:
-; AVX512F:       # %bb.0:
-; AVX512F-NEXT:    vextractf32x4 $3, %zmm0, %xmm3
-; AVX512F-NEXT:    vmovshdup {{.*#+}} xmm4 = xmm3[1,1,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm4, %rdx
-; AVX512F-NEXT:    xorl %eax, %eax
-; AVX512F-NEXT:    vxorps %xmm1, %xmm1, %xmm1
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512F-NEXT:    cmovbl %eax, %edx
-; AVX512F-NEXT:    vmovss {{.*#+}} xmm2 = [4.29496704E+9,0.0E+0,0.0E+0,0.0E+0]
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm4
-; AVX512F-NEXT:    movl $-1, %ecx
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vcvttss2si %xmm3, %rsi
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm3
-; AVX512F-NEXT:    cmovbl %eax, %esi
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm3
-; AVX512F-NEXT:    cmoval %ecx, %esi
-; AVX512F-NEXT:    vshufpd {{.*#+}} xmm4 = xmm3[1,0]
-; AVX512F-NEXT:    vcvttss2si %xmm4, %rdi
-; AVX512F-NEXT:    vmovd %esi, %xmm5
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512F-NEXT:    cmovbl %eax, %edi
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm4
-; AVX512F-NEXT:    cmoval %ecx, %edi
-; AVX512F-NEXT:    vpinsrd $1, %edx, %xmm5, %xmm4
-; AVX512F-NEXT:    vpinsrd $2, %edi, %xmm4, %xmm5
-; AVX512F-NEXT:    vshufps {{.*#+}} xmm3 = xmm3[3,3,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm3, %rdx
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm3
-; AVX512F-NEXT:    cmovbl %eax, %edx
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm3
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vextractf32x4 $2, %zmm0, %xmm4
-; AVX512F-NEXT:    vmovshdup {{.*#+}} xmm3 = xmm4[1,1,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm3, %rsi
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm3
-; AVX512F-NEXT:    cmovbl %eax, %esi
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm3
-; AVX512F-NEXT:    cmoval %ecx, %esi
-; AVX512F-NEXT:    vpinsrd $3, %edx, %xmm5, %xmm3
-; AVX512F-NEXT:    vcvttss2si %xmm4, %rdx
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512F-NEXT:    cmovbl %eax, %edx
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm4
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vshufpd {{.*#+}} xmm5 = xmm4[1,0]
-; AVX512F-NEXT:    vcvttss2si %xmm5, %rdi
-; AVX512F-NEXT:    vmovd %edx, %xmm6
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512F-NEXT:    cmovbl %eax, %edi
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm5
-; AVX512F-NEXT:    cmoval %ecx, %edi
-; AVX512F-NEXT:    vpinsrd $1, %esi, %xmm6, %xmm5
-; AVX512F-NEXT:    vpinsrd $2, %edi, %xmm5, %xmm6
-; AVX512F-NEXT:    vshufps {{.*#+}} xmm4 = xmm4[3,3,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm4, %rdx
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512F-NEXT:    cmovbl %eax, %edx
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm4
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vextractf128 $1, %ymm0, %xmm5
-; AVX512F-NEXT:    vmovshdup {{.*#+}} xmm4 = xmm5[1,1,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm4, %rsi
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512F-NEXT:    cmovbl %eax, %esi
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm4
-; AVX512F-NEXT:    cmoval %ecx, %esi
-; AVX512F-NEXT:    vpinsrd $3, %edx, %xmm6, %xmm4
-; AVX512F-NEXT:    vcvttss2si %xmm5, %rdx
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512F-NEXT:    cmovbl %eax, %edx
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm5
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vshufpd {{.*#+}} xmm6 = xmm5[1,0]
-; AVX512F-NEXT:    vcvttss2si %xmm6, %rdi
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm6
-; AVX512F-NEXT:    cmovbl %eax, %edi
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm6
-; AVX512F-NEXT:    vmovd %edx, %xmm6
-; AVX512F-NEXT:    cmoval %ecx, %edi
-; AVX512F-NEXT:    vpinsrd $1, %esi, %xmm6, %xmm6
-; AVX512F-NEXT:    vpinsrd $2, %edi, %xmm6, %xmm6
-; AVX512F-NEXT:    vshufps {{.*#+}} xmm5 = xmm5[3,3,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm5, %rdx
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512F-NEXT:    cmovbl %eax, %edx
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm5
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vmovshdup {{.*#+}} xmm5 = xmm0[1,1,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm5, %rsi
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512F-NEXT:    cmovbl %eax, %esi
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm5
-; AVX512F-NEXT:    cmoval %ecx, %esi
-; AVX512F-NEXT:    vpinsrd $3, %edx, %xmm6, %xmm5
-; AVX512F-NEXT:    vcvttss2si %xmm0, %rdx
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm0
-; AVX512F-NEXT:    cmovbl %eax, %edx
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm0
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vshufpd {{.*#+}} xmm6 = xmm0[1,0]
-; AVX512F-NEXT:    vcvttss2si %xmm6, %rdi
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm6
-; AVX512F-NEXT:    cmovbl %eax, %edi
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm6
-; AVX512F-NEXT:    vmovd %edx, %xmm6
-; AVX512F-NEXT:    cmoval %ecx, %edi
-; AVX512F-NEXT:    vpinsrd $1, %esi, %xmm6, %xmm6
-; AVX512F-NEXT:    vpinsrd $2, %edi, %xmm6, %xmm6
-; AVX512F-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX512F-NEXT:    vcvttss2si %xmm0, %rdx
-; AVX512F-NEXT:    vinserti128 $1, %xmm3, %ymm4, %ymm3
-; AVX512F-NEXT:    vucomiss %xmm1, %xmm0
-; AVX512F-NEXT:    cmovbl %eax, %edx
-; AVX512F-NEXT:    vucomiss %xmm2, %xmm0
-; AVX512F-NEXT:    cmoval %ecx, %edx
-; AVX512F-NEXT:    vpinsrd $3, %edx, %xmm6, %xmm0
-; AVX512F-NEXT:    vinserti128 $1, %xmm5, %ymm0, %ymm0
-; AVX512F-NEXT:    vinserti64x4 $1, %ymm3, %zmm0, %zmm0
-; AVX512F-NEXT:    retq
-;
-; AVX512-LABEL: test_unsigned_v16i32_v16f32:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vextractf32x4 $3, %zmm0, %xmm3
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm4 = xmm3[1,1,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm4, %rdx
-; AVX512-NEXT:    xorl %eax, %eax
-; AVX512-NEXT:    vxorps %xmm1, %xmm1, %xmm1
-; AVX512-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vmovss {{.*#+}} xmm2 = [4.29496704E+9,0.0E+0,0.0E+0,0.0E+0]
-; AVX512-NEXT:    vucomiss %xmm2, %xmm4
-; AVX512-NEXT:    movl $-1, %ecx
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vcvttss2si %xmm3, %rsi
-; AVX512-NEXT:    vucomiss %xmm1, %xmm3
-; AVX512-NEXT:    cmovbl %eax, %esi
-; AVX512-NEXT:    vucomiss %xmm2, %xmm3
-; AVX512-NEXT:    cmoval %ecx, %esi
-; AVX512-NEXT:    vmovd %esi, %xmm4
-; AVX512-NEXT:    vpinsrd $1, %edx, %xmm4, %xmm4
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm5 = xmm3[1,0]
-; AVX512-NEXT:    vcvttss2si %xmm5, %rdx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm5
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vpinsrd $2, %edx, %xmm4, %xmm4
-; AVX512-NEXT:    vshufps {{.*#+}} xmm3 = xmm3[3,3,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm3, %rdx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm3
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm3
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vpinsrd $3, %edx, %xmm4, %xmm3
-; AVX512-NEXT:    vextractf32x4 $2, %zmm0, %xmm4
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm5 = xmm4[1,1,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm5, %rdx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm5
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vcvttss2si %xmm4, %rsi
-; AVX512-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512-NEXT:    cmovbl %eax, %esi
-; AVX512-NEXT:    vucomiss %xmm2, %xmm4
-; AVX512-NEXT:    cmoval %ecx, %esi
-; AVX512-NEXT:    vmovd %esi, %xmm5
-; AVX512-NEXT:    vpinsrd $1, %edx, %xmm5, %xmm5
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm6 = xmm4[1,0]
-; AVX512-NEXT:    vcvttss2si %xmm6, %rdx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm6
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm6
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vpinsrd $2, %edx, %xmm5, %xmm5
-; AVX512-NEXT:    vshufps {{.*#+}} xmm4 = xmm4[3,3,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm4, %rdx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm4
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm4
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vpinsrd $3, %edx, %xmm5, %xmm4
-; AVX512-NEXT:    vextractf128 $1, %ymm0, %xmm5
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm6 = xmm5[1,1,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm6, %rdx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm6
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm6
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vcvttss2si %xmm5, %rsi
-; AVX512-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512-NEXT:    cmovbl %eax, %esi
-; AVX512-NEXT:    vucomiss %xmm2, %xmm5
-; AVX512-NEXT:    cmoval %ecx, %esi
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm6 = xmm5[1,0]
-; AVX512-NEXT:    vcvttss2si %xmm6, %rdi
-; AVX512-NEXT:    vucomiss %xmm1, %xmm6
-; AVX512-NEXT:    cmovbl %eax, %edi
-; AVX512-NEXT:    vucomiss %xmm2, %xmm6
-; AVX512-NEXT:    vmovd %esi, %xmm6
-; AVX512-NEXT:    vpinsrd $1, %edx, %xmm6, %xmm6
-; AVX512-NEXT:    cmoval %ecx, %edi
-; AVX512-NEXT:    vpinsrd $2, %edi, %xmm6, %xmm6
-; AVX512-NEXT:    vshufps {{.*#+}} xmm5 = xmm5[3,3,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm5, %rdx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm5
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm5
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vpinsrd $3, %edx, %xmm6, %xmm5
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm6 = xmm0[1,1,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm6, %rdx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm6
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm6
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vinserti128 $1, %xmm3, %ymm4, %ymm3
-; AVX512-NEXT:    vcvttss2si %xmm0, %rsi
-; AVX512-NEXT:    vucomiss %xmm1, %xmm0
-; AVX512-NEXT:    cmovbl %eax, %esi
-; AVX512-NEXT:    vucomiss %xmm2, %xmm0
-; AVX512-NEXT:    cmoval %ecx, %esi
-; AVX512-NEXT:    vmovd %esi, %xmm4
-; AVX512-NEXT:    vpinsrd $1, %edx, %xmm4, %xmm4
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm6 = xmm0[1,0]
-; AVX512-NEXT:    vcvttss2si %xmm6, %rdx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm6
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm6
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vpinsrd $2, %edx, %xmm4, %xmm4
-; AVX512-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX512-NEXT:    vcvttss2si %xmm0, %rdx
-; AVX512-NEXT:    vucomiss %xmm1, %xmm0
-; AVX512-NEXT:    cmovbl %eax, %edx
-; AVX512-NEXT:    vucomiss %xmm2, %xmm0
-; AVX512-NEXT:    cmoval %ecx, %edx
-; AVX512-NEXT:    vpinsrd $3, %edx, %xmm4, %xmm0
-; AVX512-NEXT:    vinserti128 $1, %xmm5, %ymm0, %ymm0
-; AVX512-NEXT:    vinserti64x4 $1, %ymm3, %zmm0, %zmm0
-; AVX512-NEXT:    retq
+; CHECK-LABEL: test_unsigned_v16i32_v16f32:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vxorps %xmm1, %xmm1, %xmm1
+; CHECK-NEXT:    vmaxps %zmm1, %zmm0, %zmm0
+; CHECK-NEXT:    vcmpgeps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to16}, %zmm0, %k1
+; CHECK-NEXT:    vcvttps2udq %zmm0, %zmm0
+; CHECK-NEXT:    vpternlogd {{.*#+}} zmm1 = -1
+; CHECK-NEXT:    vmovdqa32 %zmm1, %zmm0 {%k1}
+; CHECK-NEXT:    retq
   %x = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> %f)
   ret <16 x i32> %x
 }
@@ -2161,94 +1927,31 @@ define <8 x i16> @test_unsigned_v8i16_v8f64(<8 x double> %f) nounwind {
 define <8 x i32> @test_unsigned_v8i32_v8f64(<8 x double> %f) nounwind {
 ; AVX512F-LABEL: test_unsigned_v8i32_v8f64:
 ; AVX512F:       # %bb.0:
-; AVX512F-NEXT:    vextractf32x4 $2, %zmm0, %xmm1
-; AVX512F-NEXT:    vshufpd {{.*#+}} xmm2 = xmm1[1,0]
-; AVX512F-NEXT:    vxorpd %xmm3, %xmm3, %xmm3
-; AVX512F-NEXT:    vmaxsd %xmm2, %xmm3, %xmm2
-; AVX512F-NEXT:    vmovsd {{.*#+}} xmm4 = [4.294967295E+9,0.0E+0]
-; AVX512F-NEXT:    vminsd %xmm2, %xmm4, %xmm2
-; AVX512F-NEXT:    vcvttsd2si %xmm2, %rax
-; AVX512F-NEXT:    vmaxsd %xmm1, %xmm3, %xmm1
-; AVX512F-NEXT:    vminsd %xmm1, %xmm4, %xmm1
-; AVX512F-NEXT:    vcvttsd2si %xmm1, %rcx
-; AVX512F-NEXT:    vmovd %ecx, %xmm1
-; AVX512F-NEXT:    vpinsrd $1, %eax, %xmm1, %xmm1
-; AVX512F-NEXT:    vextractf32x4 $3, %zmm0, %xmm2
-; AVX512F-NEXT:    vmaxsd %xmm2, %xmm3, %xmm5
-; AVX512F-NEXT:    vminsd %xmm5, %xmm4, %xmm5
-; AVX512F-NEXT:    vcvttsd2si %xmm5, %rax
-; AVX512F-NEXT:    vpinsrd $2, %eax, %xmm1, %xmm1
-; AVX512F-NEXT:    vshufpd {{.*#+}} xmm2 = xmm2[1,0]
-; AVX512F-NEXT:    vmaxsd %xmm2, %xmm3, %xmm2
-; AVX512F-NEXT:    vminsd %xmm2, %xmm4, %xmm2
-; AVX512F-NEXT:    vcvttsd2si %xmm2, %rax
-; AVX512F-NEXT:    vpinsrd $3, %eax, %xmm1, %xmm1
-; AVX512F-NEXT:    vshufpd {{.*#+}} xmm2 = xmm0[1,0]
-; AVX512F-NEXT:    vmaxsd %xmm2, %xmm3, %xmm2
-; AVX512F-NEXT:    vminsd %xmm2, %xmm4, %xmm2
-; AVX512F-NEXT:    vcvttsd2si %xmm2, %rax
-; AVX512F-NEXT:    vmaxsd %xmm0, %xmm3, %xmm2
-; AVX512F-NEXT:    vminsd %xmm2, %xmm4, %xmm2
-; AVX512F-NEXT:    vcvttsd2si %xmm2, %rcx
-; AVX512F-NEXT:    vmovd %ecx, %xmm2
-; AVX512F-NEXT:    vpinsrd $1, %eax, %xmm2, %xmm2
-; AVX512F-NEXT:    vextractf128 $1, %ymm0, %xmm0
-; AVX512F-NEXT:    vmaxsd %xmm0, %xmm3, %xmm5
-; AVX512F-NEXT:    vminsd %xmm5, %xmm4, %xmm5
-; AVX512F-NEXT:    vcvttsd2si %xmm5, %rax
-; AVX512F-NEXT:    vpinsrd $2, %eax, %xmm2, %xmm2
-; AVX512F-NEXT:    vshufpd {{.*#+}} xmm0 = xmm0[1,0]
-; AVX512F-NEXT:    vmaxsd %xmm0, %xmm3, %xmm0
-; AVX512F-NEXT:    vminsd %xmm0, %xmm4, %xmm0
-; AVX512F-NEXT:    vcvttsd2si %xmm0, %rax
-; AVX512F-NEXT:    vpinsrd $3, %eax, %xmm2, %xmm0
-; AVX512F-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
+; AVX512F-NEXT:    vxorpd %xmm1, %xmm1, %xmm1
+; AVX512F-NEXT:    vmaxpd %zmm1, %zmm0, %zmm0
+; AVX512F-NEXT:    vcvttpd2dq %zmm0, %ymm1
+; AVX512F-NEXT:    vpsrad $31, %ymm1, %ymm2
+; AVX512F-NEXT:    vsubpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %zmm3
+; AVX512F-NEXT:    vcvttpd2dq %zmm3, %ymm3
+; AVX512F-NEXT:    vpand %ymm2, %ymm3, %ymm2
+; AVX512F-NEXT:    vpor %ymm2, %ymm1, %ymm1
+; AVX512F-NEXT:    vcmpgepd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %k1
+; AVX512F-NEXT:    vpternlogd {{.*#+}} zmm0 {%k1} {z} = -1
+; AVX512F-NEXT:    vpor %ymm1, %ymm0, %ymm0
 ; AVX512F-NEXT:    retq
 ;
 ; AVX512-LABEL: test_unsigned_v8i32_v8f64:
 ; AVX512:       # %bb.0:
-; AVX512-NEXT:    vextractf32x4 $2, %zmm0, %xmm1
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm2 = xmm1[1,0]
-; AVX512-NEXT:    vxorpd %xmm3, %xmm3, %xmm3
-; AVX512-NEXT:    vmovsd {{.*#+}} xmm4 = [4.294967295E+9,0.0E+0]
-; AVX512-NEXT:    vmaxsd %xmm2, %xmm3, %xmm2
-; AVX512-NEXT:    vminsd %xmm2, %xmm4, %xmm2
-; AVX512-NEXT:    vcvttsd2si %xmm2, %rax
-; AVX512-NEXT:    vmaxsd %xmm1, %xmm3, %xmm1
-; AVX512-NEXT:    vminsd %xmm1, %xmm4, %xmm1
-; AVX512-NEXT:    vcvttsd2si %xmm1, %rcx
-; AVX512-NEXT:    vmovd %ecx, %xmm1
-; AVX512-NEXT:    vpinsrd $1, %eax, %xmm1, %xmm1
-; AVX512-NEXT:    vextractf32x4 $3, %zmm0, %xmm2
-; AVX512-NEXT:    vmaxsd %xmm2, %xmm3, %xmm5
-; AVX512-NEXT:    vminsd %xmm5, %xmm4, %xmm5
-; AVX512-NEXT:    vcvttsd2si %xmm5, %rax
-; AVX512-NEXT:    vpinsrd $2, %eax, %xmm1, %xmm1
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm2 = xmm2[1,0]
-; AVX512-NEXT:    vmaxsd %xmm2, %xmm3, %xmm2
-; AVX512-NEXT:    vminsd %xmm2, %xmm4, %xmm2
-; AVX512-NEXT:    vcvttsd2si %xmm2, %rax
-; AVX512-NEXT:    vpinsrd $3, %eax, %xmm1, %xmm1
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm2 = xmm0[1,0]
-; AVX512-NEXT:    vmaxsd %xmm2, %xmm3, %xmm2
-; AVX512-NEXT:    vminsd %xmm2, %xmm4, %xmm2
-; AVX512-NEXT:    vcvttsd2si %xmm2, %rax
-; AVX512-NEXT:    vmaxsd %xmm0, %xmm3, %xmm2
-; AVX512-NEXT:    vminsd %xmm2, %xmm4, %xmm2
-; AVX512-NEXT:    vcvttsd2si %xmm2, %rcx
-; AVX512-NEXT:    vmovd %ecx, %xmm2
-; AVX512-NEXT:    vpinsrd $1, %eax, %xmm2, %xmm2
-; AVX512-NEXT:    vextractf128 $1, %ymm0, %xmm0
-; AVX512-NEXT:    vmaxsd %xmm0, %xmm3, %xmm5
-; AVX512-NEXT:    vminsd %xmm5, %xmm4, %xmm5
-; AVX512-NEXT:    vcvttsd2si %xmm5, %rax
-; AVX512-NEXT:    vpinsrd $2, %eax, %xmm2, %xmm2
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm0 = xmm0[1,0]
-; AVX512-NEXT:    vmaxsd %xmm0, %xmm3, %xmm0
-; AVX512-NEXT:    vminsd %xmm0, %xmm4, %xmm0
-; AVX512-NEXT:    vcvttsd2si %xmm0, %rax
-; AVX512-NEXT:    vpinsrd $3, %eax, %xmm2, %xmm0
-; AVX512-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
+; AVX512-NEXT:    vxorpd %xmm1, %xmm1, %xmm1
+; AVX512-NEXT:    vmaxpd %zmm1, %zmm0, %zmm1
+; AVX512-NEXT:    vcvttpd2dq %zmm1, %ymm2
+; AVX512-NEXT:    vsubpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm1, %zmm0
+; AVX512-NEXT:    vcvttpd2dq %zmm0, %ymm0
+; AVX512-NEXT:    vpsrad $31, %ymm2, %ymm3
+; AVX512-NEXT:    vpternlogd {{.*#+}} ymm0 = (ymm0 & ymm3) | ymm2
+; AVX512-NEXT:    vcmpgepd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm1, %k1
+; AVX512-NEXT:    vpcmpeqd %ymm1, %ymm1, %ymm1
+; AVX512-NEXT:    vmovdqa32 %ymm1, %ymm0 {%k1}
 ; AVX512-NEXT:    retq
   %x = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> %f)
   ret <8 x i32> %x

>From 2abcbe697026345a500ca4a02b119a75ffbeb430 Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Tue, 16 Jun 2026 15:58:29 +0200
Subject: [PATCH 14/18] Remove redundant test file fp-to-int-sat-vector-sse2.ll

---
 .../CodeGen/X86/fp-to-int-sat-vector-sse2.ll  | 113 ------------------
 1 file changed, 113 deletions(-)
 delete mode 100644 llvm/test/CodeGen/X86/fp-to-int-sat-vector-sse2.ll

diff --git a/llvm/test/CodeGen/X86/fp-to-int-sat-vector-sse2.ll b/llvm/test/CodeGen/X86/fp-to-int-sat-vector-sse2.ll
deleted file mode 100644
index b9ae1157f991f..0000000000000
--- a/llvm/test/CodeGen/X86/fp-to-int-sat-vector-sse2.ll
+++ /dev/null
@@ -1,113 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=x86_64 -mattr=+sse2,-avx | FileCheck %s --check-prefix=SSE2
-
-declare <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float>)
-declare <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float>)
-
-; 1. Base case variables
-define <4 x i32> @test_signed_var(<4 x float> %f) {
-; SSE2-LABEL: test_signed_var:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
-; SSE2-NEXT:    cmpleps %xmm0, %xmm1
-; SSE2-NEXT:    cvttps2dq %xmm0, %xmm2
-; SSE2-NEXT:    movaps %xmm1, %xmm3
-; SSE2-NEXT:    andnps %xmm2, %xmm3
-; SSE2-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE2-NEXT:    orps %xmm3, %xmm1
-; SSE2-NEXT:    cmpunordps %xmm0, %xmm0
-; SSE2-NEXT:    andnps %xmm1, %xmm0
-; SSE2-NEXT:    retq
-  %x = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> %f)
-  ret <4 x i32> %x
-}
-
-define <4 x i32> @test_unsigned_var(<4 x float> %f) {
-; SSE2-LABEL: test_unsigned_var:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    xorps %xmm1, %xmm1
-; SSE2-NEXT:    maxps %xmm1, %xmm0
-; SSE2-NEXT:    cvttps2dq %xmm0, %xmm2
-; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
-; SSE2-NEXT:    cmpleps %xmm0, %xmm1
-; SSE2-NEXT:    orps %xmm2, %xmm1
-; SSE2-NEXT:    psrad $31, %xmm2
-; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    cvttps2dq %xmm0, %xmm0
-; SSE2-NEXT:    pand %xmm2, %xmm0
-; SSE2-NEXT:    orps %xmm0, %xmm1
-; SSE2-NEXT:    movaps %xmm1, %xmm0
-; SSE2-NEXT:    retq
-  %x = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> %f)
-  ret <4 x i32> %x
-}
-
-; 2. Signed edge cases
-define <4 x i32> @test_signed_edge1() {
-  ; NaN, +Inf, -Inf, 0.0
-; SSE2-LABEL: test_signed_edge1:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    cvttps2dq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE2-NEXT:    movaps {{.*#+}} xmm0 = [u,u,NaN,u]
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[2,3]
-; SSE2-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    retq
-  %x = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> <float 0x7FF8000000000000, float 0x7FF0000000000000, float 0xFFF0000000000000, float 0.0>)
-  ret <4 x i32> %x
-}
-
-define <4 x i32> @test_signed_edge2() {
-  ; exact limits and slight overflow
-  ; 2^31, < -2^31, max f32 < 2^31, -2^31
-; SSE2-LABEL: test_signed_edge2:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [2147483647,2147483647,2147483647,2147483647]
-; SSE2-NEXT:    cvttps2dq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    movss {{.*#+}} xmm0 = xmm1[0],xmm0[1,2,3]
-; SSE2-NEXT:    retq
-  %x = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> <float 2147483648.0, float -2147483904.0, float 2147483520.0, float -2147483648.0>)
-  ret <4 x i32> %x
-}
-
-; 3. Unsigned edge cases
-define <4 x i32> @test_unsigned_edge1() {
-  ; NaN, -1.0, +Inf, 0.0
-; SSE2-LABEL: test_unsigned_edge1:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    xorps %xmm0, %xmm0
-; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [NaN,-1.0E+0,+Inf,0.0E+0]
-; SSE2-NEXT:    maxps %xmm0, %xmm1
-; SSE2-NEXT:    cvttps2dq %xmm1, %xmm2
-; SSE2-NEXT:    movaps {{.*#+}} xmm0 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
-; SSE2-NEXT:    cmpleps %xmm1, %xmm0
-; SSE2-NEXT:    orps %xmm2, %xmm0
-; SSE2-NEXT:    psrad $31, %xmm2
-; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE2-NEXT:    cvttps2dq %xmm1, %xmm1
-; SSE2-NEXT:    pand %xmm2, %xmm1
-; SSE2-NEXT:    orps %xmm1, %xmm0
-; SSE2-NEXT:    retq
-  %x = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> <float 0x7FF8000000000000, float -1.0, float 0x7FF0000000000000, float 0.0>)
-  ret <4 x i32> %x
-}
-
-define <4 x i32> @test_unsigned_edge2() {
-  ; slight below zero, > 2^32, max f32 < 2^32, 2^32 exact
-; SSE2-LABEL: test_unsigned_edge2:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    xorps %xmm0, %xmm0
-; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [-5.0E-1,4.2949673E+9,4.29496704E+9,4.2949673E+9]
-; SSE2-NEXT:    maxps %xmm0, %xmm1
-; SSE2-NEXT:    cvttps2dq %xmm1, %xmm2
-; SSE2-NEXT:    movaps {{.*#+}} xmm0 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
-; SSE2-NEXT:    cmpleps %xmm1, %xmm0
-; SSE2-NEXT:    orps %xmm2, %xmm0
-; SSE2-NEXT:    psrad $31, %xmm2
-; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE2-NEXT:    cvttps2dq %xmm1, %xmm1
-; SSE2-NEXT:    pand %xmm2, %xmm1
-; SSE2-NEXT:    orps %xmm1, %xmm0
-; SSE2-NEXT:    retq
-  %x = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> <float -0.5, float 4294967296.0, float 4294967040.0, float 4294967296.0>)
-  ret <4 x i32> %x
-}

>From 29f5472a7761a9ca27193bd4c9adec5cd51b4097 Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Wed, 15 Jul 2026 00:59:02 +0200
Subject: [PATCH 15/18] refactore code and cover NaN bug. Fixed unsigned vector
 saturation by explicitly masking out NaN inputs, as x86 maxps / minps
 propagate NaN which incorrectly saturated to INT_MIN instead of 0

---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  50 ++++----
 .../test/CodeGen/X86/fptoui-sat-vector-128.ll | 121 ++++++++++--------
 .../test/CodeGen/X86/fptoui-sat-vector-256.ll |  90 +++++++------
 .../test/CodeGen/X86/fptoui-sat-vector-512.ll |  41 +++---
 4 files changed, 174 insertions(+), 128 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 0d1d861c06820..d546e05dd17a8 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -322,14 +322,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
     setOperationAction(ISD::FP_TO_UINT_SAT, MVT::v4i32, Custom);
     setOperationAction(ISD::FP_TO_SINT_SAT, MVT::v4i32, Custom);
   }
-  if (Subtarget.hasAVX()) {
-    setOperationAction(ISD::FP_TO_UINT_SAT, MVT::v8i32, Custom);
-    setOperationAction(ISD::FP_TO_SINT_SAT, MVT::v8i32, Custom);
-  }
-  if (Subtarget.hasAVX512()) {
-    setOperationAction(ISD::FP_TO_UINT_SAT, MVT::v16i32, Custom);
-    setOperationAction(ISD::FP_TO_SINT_SAT, MVT::v16i32, Custom);
-  }
+
   if (Subtarget.hasAVX10_2()) {
     for (MVT VT : {MVT::v8i8, MVT::v16i8, MVT::v32i8}) {
       setOperationAction(ISD::FP_TO_UINT_SAT, VT, Custom);
@@ -1555,6 +1548,8 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
     setOperationPromotedToType(ISD::STRICT_FP_TO_UINT, MVT::v8i16, MVT::v8i32);
     setOperationAction(ISD::FP_TO_SINT,                MVT::v8i32, Custom);
     setOperationAction(ISD::FP_TO_UINT,                MVT::v8i32, Custom);
+    setOperationAction(ISD::FP_TO_SINT_SAT,            MVT::v8i32, Custom);
+    setOperationAction(ISD::FP_TO_UINT_SAT,            MVT::v8i32, Custom);
     setOperationAction(ISD::STRICT_FP_TO_SINT,         MVT::v8i32, Custom);
 
     setOperationAction(ISD::SINT_TO_FP,         MVT::v8i32, Custom);
@@ -1955,6 +1950,9 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
       setOperationAction(ISD::STRICT_FP_TO_UINT, VT, Custom);
     }
 
+    setOperationAction(ISD::FP_TO_SINT_SAT, MVT::v16i32, Custom);
+    setOperationAction(ISD::FP_TO_UINT_SAT, MVT::v16i32, Custom);
+
     setOperationAction(ISD::SINT_TO_FP,        MVT::v16i32, Custom);
     setOperationAction(ISD::UINT_TO_FP,        MVT::v16i32, Custom);
     setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::v16i32, Custom);
@@ -22504,7 +22502,13 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
           Cvt = expandFP_TO_UINT_SSE(DstVT.getSimpleVT(), Clamped, dl, DAG,
                                      Subtarget);
         SDValue UintMax = DAG.getConstant(APInt::getMaxValue(32), dl, DstVT);
-        return DAG.getSelect(dl, DstVT, IsOvf, UintMax, Cvt);
+        SDValue Result = DAG.getSelect(dl, DstVT, IsOvf, UintMax, Cvt);
+        
+        SDValue Zero = DAG.getConstant(0, dl, DstVT);
+        SDValue IsNaN = DAG.getSetCC(dl, CCVT, Src, Src, ISD::SETUO);
+        if (CCVT != SelCCVT)
+          IsNaN = DAG.getSExtOrTrunc(IsNaN, dl, SelCCVT);
+        return DAG.getSelect(dl, DstVT, IsNaN, Zero, Result);
       }
     }
 
@@ -22542,22 +22546,18 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
     // legalization and guarantee the out-of-range behavior.
     SDValue Result = DAG.getNode(X86ISD::CVTTP2SI, dl, DstVT, ClampedTop);
 
-    // For signed saturation, NaN was mapped to MinC, so FP_TO_SINT produces
-    // INT_MIN. ISD::FP_TO_SINT_SAT requires NaN -> 0; fix with a zero-select.
-    // For unsigned saturation, MinC == 0.0, so NaN -> 0.0 -> 0: already
-    // correct.
-    if (IsSigned) {
-      SDValue Zero = DAG.getConstant(0, dl, DstVT);
-      EVT CCVT =
-          getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), SrcVT);
-      SDValue IsNaN = DAG.getSetCC(dl, CCVT, Src, Src, ISD::SETUO);
-      EVT SelCCVT =
-          getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), DstVT);
-      if (CCVT != SelCCVT)
-        IsNaN = DAG.getNode(ISD::TRUNCATE, dl, SelCCVT, IsNaN);
-      return DAG.getSelect(dl, DstVT, IsNaN, Zero, Result);
-    }
-    return Result;
+    // For saturation, FMAX and FMIN might pass NaN through (since they return
+    // the second operand if either is NaN).
+    // Fix up NaN by selecting 0 explicitly.
+    SDValue Zero = DAG.getConstant(0, dl, DstVT);
+    EVT CCVT =
+        getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), SrcVT);
+    SDValue IsNaN = DAG.getSetCC(dl, CCVT, Src, Src, ISD::SETUO);
+    EVT SelCCVT =
+        getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), DstVT);
+    if (CCVT != SelCCVT)
+      IsNaN = DAG.getNode(ISD::TRUNCATE, dl, SelCCVT, IsNaN);
+    return DAG.getSelect(dl, DstVT, IsNaN, Zero, Result);
   }
   // This code is only for floats and doubles. Fall back to generic code for
   // anything else.
diff --git a/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll b/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll
index f7b127c97edde..f5986d4050442 100644
--- a/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll
+++ b/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll
@@ -12,18 +12,23 @@ define <4 x i1> @test_unsigned_v4i1_v4f32(<4 x float> %f) nounwind {
 ; SSE-LABEL: test_unsigned_v4i1_v4f32:
 ; SSE:       # %bb.0:
 ; SSE-NEXT:    xorps %xmm1, %xmm1
-; SSE-NEXT:    maxps %xmm1, %xmm0
-; SSE-NEXT:    minps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE-NEXT:    cvttps2dq %xmm0, %xmm0
+; SSE-NEXT:    movaps %xmm0, %xmm2
+; SSE-NEXT:    maxps %xmm1, %xmm2
+; SSE-NEXT:    minps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE-NEXT:    cvttps2dq %xmm2, %xmm1
+; SSE-NEXT:    cmpunordps %xmm0, %xmm0
+; SSE-NEXT:    andnps %xmm1, %xmm0
 ; SSE-NEXT:    retq
 ;
 ; AVX2-LABEL: test_unsigned_v4i1_v4f32:
 ; AVX2:       # %bb.0:
 ; AVX2-NEXT:    vxorps %xmm1, %xmm1, %xmm1
-; AVX2-NEXT:    vmaxps %xmm1, %xmm0, %xmm0
-; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]
-; AVX2-NEXT:    vminps %xmm1, %xmm0, %xmm0
-; AVX2-NEXT:    vcvttps2dq %xmm0, %xmm0
+; AVX2-NEXT:    vmaxps %xmm1, %xmm0, %xmm1
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm2 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]
+; AVX2-NEXT:    vminps %xmm2, %xmm1, %xmm1
+; AVX2-NEXT:    vcvttps2dq %xmm1, %xmm1
+; AVX2-NEXT:    vcmpunordps %xmm0, %xmm0, %xmm0
+; AVX2-NEXT:    vandnps %xmm1, %xmm0, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_unsigned_v4i1_v4f32:
@@ -61,18 +66,23 @@ define <4 x i1> @test_freeze_unsigned_v4i1_v4f32(<4 x float> %f) nounwind {
 ; SSE-LABEL: test_freeze_unsigned_v4i1_v4f32:
 ; SSE:       # %bb.0:
 ; SSE-NEXT:    xorps %xmm1, %xmm1
-; SSE-NEXT:    maxps %xmm1, %xmm0
-; SSE-NEXT:    minps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE-NEXT:    cvttps2dq %xmm0, %xmm0
+; SSE-NEXT:    movaps %xmm0, %xmm2
+; SSE-NEXT:    maxps %xmm1, %xmm2
+; SSE-NEXT:    minps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE-NEXT:    cvttps2dq %xmm2, %xmm1
+; SSE-NEXT:    cmpunordps %xmm0, %xmm0
+; SSE-NEXT:    andnps %xmm1, %xmm0
 ; SSE-NEXT:    retq
 ;
 ; AVX2-LABEL: test_freeze_unsigned_v4i1_v4f32:
 ; AVX2:       # %bb.0:
 ; AVX2-NEXT:    vxorps %xmm1, %xmm1, %xmm1
-; AVX2-NEXT:    vmaxps %xmm1, %xmm0, %xmm0
-; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]
-; AVX2-NEXT:    vminps %xmm1, %xmm0, %xmm0
-; AVX2-NEXT:    vcvttps2dq %xmm0, %xmm0
+; AVX2-NEXT:    vmaxps %xmm1, %xmm0, %xmm1
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm2 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]
+; AVX2-NEXT:    vminps %xmm2, %xmm1, %xmm1
+; AVX2-NEXT:    vcvttps2dq %xmm1, %xmm1
+; AVX2-NEXT:    vcmpunordps %xmm0, %xmm0, %xmm0
+; AVX2-NEXT:    vandnps %xmm1, %xmm0, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_freeze_unsigned_v4i1_v4f32:
@@ -308,50 +318,56 @@ define <4 x i32> @test_unsigned_v4i32_v4f32(<4 x float> %f) nounwind {
 ; SSE2-LABEL: test_unsigned_v4i32_v4f32:
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    xorps %xmm1, %xmm1
-; SSE2-NEXT:    maxps %xmm1, %xmm0
-; SSE2-NEXT:    cvttps2dq %xmm0, %xmm2
-; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
-; SSE2-NEXT:    cmpleps %xmm0, %xmm1
-; SSE2-NEXT:    orps %xmm2, %xmm1
-; SSE2-NEXT:    psrad $31, %xmm2
-; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    cvttps2dq %xmm0, %xmm0
-; SSE2-NEXT:    pand %xmm2, %xmm0
-; SSE2-NEXT:    orps %xmm0, %xmm1
-; SSE2-NEXT:    movaps %xmm1, %xmm0
+; SSE2-NEXT:    movaps %xmm0, %xmm2
+; SSE2-NEXT:    maxps %xmm1, %xmm2
+; SSE2-NEXT:    cvttps2dq %xmm2, %xmm1
+; SSE2-NEXT:    movaps {{.*#+}} xmm3 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
+; SSE2-NEXT:    cmpleps %xmm2, %xmm3
+; SSE2-NEXT:    orps %xmm1, %xmm3
+; SSE2-NEXT:    psrad $31, %xmm1
+; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    cvttps2dq %xmm2, %xmm2
+; SSE2-NEXT:    pand %xmm1, %xmm2
+; SSE2-NEXT:    orps %xmm2, %xmm3
+; SSE2-NEXT:    cmpunordps %xmm0, %xmm0
+; SSE2-NEXT:    andnps %xmm3, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE42-LABEL: test_unsigned_v4i32_v4f32:
 ; SSE42:       # %bb.0:
 ; SSE42-NEXT:    xorps %xmm1, %xmm1
-; SSE42-NEXT:    maxps %xmm1, %xmm0
-; SSE42-NEXT:    cvttps2dq %xmm0, %xmm2
-; SSE42-NEXT:    movdqa %xmm2, %xmm3
+; SSE42-NEXT:    movaps %xmm0, %xmm2
+; SSE42-NEXT:    maxps %xmm1, %xmm2
+; SSE42-NEXT:    cvttps2dq %xmm2, %xmm1
+; SSE42-NEXT:    movdqa %xmm1, %xmm3
+; SSE42-NEXT:    movaps {{.*#+}} xmm4 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
+; SSE42-NEXT:    cmpleps %xmm2, %xmm4
+; SSE42-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
 ; SSE42-NEXT:    psrad $31, %xmm3
-; SSE42-NEXT:    movaps {{.*#+}} xmm1 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
-; SSE42-NEXT:    cmpleps %xmm0, %xmm1
-; SSE42-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE42-NEXT:    cvttps2dq %xmm0, %xmm0
-; SSE42-NEXT:    pand %xmm3, %xmm0
-; SSE42-NEXT:    por %xmm2, %xmm0
-; SSE42-NEXT:    orps %xmm0, %xmm1
-; SSE42-NEXT:    movaps %xmm1, %xmm0
+; SSE42-NEXT:    cvttps2dq %xmm2, %xmm2
+; SSE42-NEXT:    pand %xmm3, %xmm2
+; SSE42-NEXT:    por %xmm1, %xmm2
+; SSE42-NEXT:    orps %xmm2, %xmm4
+; SSE42-NEXT:    cmpunordps %xmm0, %xmm0
+; SSE42-NEXT:    andnps %xmm4, %xmm0
 ; SSE42-NEXT:    retq
 ;
 ; AVX2-LABEL: test_unsigned_v4i32_v4f32:
 ; AVX2:       # %bb.0:
 ; AVX2-NEXT:    vxorps %xmm1, %xmm1, %xmm1
-; AVX2-NEXT:    vmaxps %xmm1, %xmm0, %xmm0
-; AVX2-NEXT:    vcvttps2dq %xmm0, %xmm1
-; AVX2-NEXT:    vpsrad $31, %xmm1, %xmm2
-; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm3 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
-; AVX2-NEXT:    vsubps %xmm3, %xmm0, %xmm3
-; AVX2-NEXT:    vcvttps2dq %xmm3, %xmm3
-; AVX2-NEXT:    vpand %xmm2, %xmm3, %xmm2
-; AVX2-NEXT:    vpor %xmm2, %xmm1, %xmm1
-; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm2 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
-; AVX2-NEXT:    vcmpleps %xmm0, %xmm2, %xmm0
-; AVX2-NEXT:    vorps %xmm1, %xmm0, %xmm0
+; AVX2-NEXT:    vmaxps %xmm1, %xmm0, %xmm1
+; AVX2-NEXT:    vcvttps2dq %xmm1, %xmm2
+; AVX2-NEXT:    vpsrad $31, %xmm2, %xmm3
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm4 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
+; AVX2-NEXT:    vsubps %xmm4, %xmm1, %xmm4
+; AVX2-NEXT:    vcvttps2dq %xmm4, %xmm4
+; AVX2-NEXT:    vpand %xmm3, %xmm4, %xmm3
+; AVX2-NEXT:    vpor %xmm3, %xmm2, %xmm2
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm3 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
+; AVX2-NEXT:    vcmpleps %xmm1, %xmm3, %xmm1
+; AVX2-NEXT:    vorps %xmm2, %xmm1, %xmm1
+; AVX2-NEXT:    vcmpunordps %xmm0, %xmm0, %xmm0
+; AVX2-NEXT:    vandnps %xmm1, %xmm0, %xmm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_unsigned_v4i32_v4f32:
@@ -360,12 +376,15 @@ define <4 x i32> @test_unsigned_v4i32_v4f32(<4 x float> %f) nounwind {
 ; AVX512-NEXT:    vmaxps %xmm1, %xmm0, %xmm1
 ; AVX512-NEXT:    vcvttps2dq %xmm1, %xmm2
 ; AVX512-NEXT:    vpsrad $31, %xmm2, %xmm3
-; AVX512-NEXT:    vsubps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm1, %xmm0
-; AVX512-NEXT:    vcvttps2dq %xmm0, %xmm0
-; AVX512-NEXT:    vpternlogd {{.*#+}} xmm0 = (xmm0 & xmm3) | xmm2
+; AVX512-NEXT:    vsubps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm1, %xmm4
+; AVX512-NEXT:    vcvttps2dq %xmm4, %xmm4
 ; AVX512-NEXT:    vcmpgeps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm1, %k1
+; AVX512-NEXT:    vpternlogd {{.*#+}} xmm4 = (xmm4 & xmm3) | xmm2
 ; AVX512-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
-; AVX512-NEXT:    vmovdqa32 %xmm1, %xmm0 {%k1}
+; AVX512-NEXT:    vmovdqa32 %xmm1, %xmm4 {%k1}
+; AVX512-NEXT:    vcmpunordps %xmm0, %xmm0, %k0
+; AVX512-NEXT:    knotw %k0, %k1
+; AVX512-NEXT:    vmovdqa32 %xmm4, %xmm0 {%k1} {z}
 ; AVX512-NEXT:    retq
   %x = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> %f)
   ret <4 x i32> %x
diff --git a/llvm/test/CodeGen/X86/fptoui-sat-vector-256.ll b/llvm/test/CodeGen/X86/fptoui-sat-vector-256.ll
index 10f09ce44bbf2..542e1d1198b83 100644
--- a/llvm/test/CodeGen/X86/fptoui-sat-vector-256.ll
+++ b/llvm/test/CodeGen/X86/fptoui-sat-vector-256.ll
@@ -401,17 +401,19 @@ define <8 x i32> @test_unsigned_v8i32_v8f32(<8 x float> %f) nounwind {
 ; AVX2-LABEL: test_unsigned_v8i32_v8f32:
 ; AVX2:       # %bb.0:
 ; AVX2-NEXT:    vxorps %xmm1, %xmm1, %xmm1
-; AVX2-NEXT:    vmaxps %ymm1, %ymm0, %ymm0
-; AVX2-NEXT:    vcvttps2dq %ymm0, %ymm1
-; AVX2-NEXT:    vpsrad $31, %ymm1, %ymm2
-; AVX2-NEXT:    vbroadcastss {{.*#+}} ymm3 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
-; AVX2-NEXT:    vsubps %ymm3, %ymm0, %ymm3
-; AVX2-NEXT:    vcvttps2dq %ymm3, %ymm3
-; AVX2-NEXT:    vpand %ymm2, %ymm3, %ymm2
-; AVX2-NEXT:    vpor %ymm2, %ymm1, %ymm1
-; AVX2-NEXT:    vbroadcastss {{.*#+}} ymm2 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
-; AVX2-NEXT:    vcmpleps %ymm0, %ymm2, %ymm0
-; AVX2-NEXT:    vorps %ymm1, %ymm0, %ymm0
+; AVX2-NEXT:    vmaxps %ymm1, %ymm0, %ymm1
+; AVX2-NEXT:    vcvttps2dq %ymm1, %ymm2
+; AVX2-NEXT:    vpsrad $31, %ymm2, %ymm3
+; AVX2-NEXT:    vbroadcastss {{.*#+}} ymm4 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
+; AVX2-NEXT:    vsubps %ymm4, %ymm1, %ymm4
+; AVX2-NEXT:    vcvttps2dq %ymm4, %ymm4
+; AVX2-NEXT:    vpand %ymm3, %ymm4, %ymm3
+; AVX2-NEXT:    vpor %ymm3, %ymm2, %ymm2
+; AVX2-NEXT:    vbroadcastss {{.*#+}} ymm3 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
+; AVX2-NEXT:    vcmpleps %ymm1, %ymm3, %ymm1
+; AVX2-NEXT:    vorps %ymm2, %ymm1, %ymm1
+; AVX2-NEXT:    vcmpunordps %ymm0, %ymm0, %ymm0
+; AVX2-NEXT:    vandnps %ymm1, %ymm0, %ymm0
 ; AVX2-NEXT:    retq
 ;
 ; AVX512-LABEL: test_unsigned_v8i32_v8f32:
@@ -420,12 +422,15 @@ define <8 x i32> @test_unsigned_v8i32_v8f32(<8 x float> %f) nounwind {
 ; AVX512-NEXT:    vmaxps %ymm1, %ymm0, %ymm1
 ; AVX512-NEXT:    vcvttps2dq %ymm1, %ymm2
 ; AVX512-NEXT:    vpsrad $31, %ymm2, %ymm3
-; AVX512-NEXT:    vsubps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm1, %ymm0
-; AVX512-NEXT:    vcvttps2dq %ymm0, %ymm0
-; AVX512-NEXT:    vpternlogd {{.*#+}} ymm0 = (ymm0 & ymm3) | ymm2
+; AVX512-NEXT:    vsubps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm1, %ymm4
+; AVX512-NEXT:    vcvttps2dq %ymm4, %ymm4
 ; AVX512-NEXT:    vcmpgeps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %ymm1, %k1
+; AVX512-NEXT:    vpternlogd {{.*#+}} ymm4 = (ymm4 & ymm3) | ymm2
 ; AVX512-NEXT:    vpcmpeqd %ymm1, %ymm1, %ymm1
-; AVX512-NEXT:    vmovdqa32 %ymm1, %ymm0 {%k1}
+; AVX512-NEXT:    vmovdqa32 %ymm1, %ymm4 {%k1}
+; AVX512-NEXT:    vcmpunordps %ymm0, %ymm0, %k0
+; AVX512-NEXT:    knotb %k0, %k1
+; AVX512-NEXT:    vmovdqa32 %ymm4, %ymm0 {%k1} {z}
 ; AVX512-NEXT:    retq
   %x = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f32(<8 x float> %f)
   ret <8 x i32> %x
@@ -798,11 +803,16 @@ define <8 x i128> @test_unsigned_v8i128_v8f32(<8 x float> %f) nounwind {
 define <4 x i1> @test_unsigned_v4i1_v4f64(<4 x double> %f) nounwind {
 ; AVX2-LABEL: test_unsigned_v4i1_v4f64:
 ; AVX2:       # %bb.0:
-; AVX2-NEXT:    vxorpd %xmm1, %xmm1, %xmm1
-; AVX2-NEXT:    vmaxpd %ymm1, %ymm0, %ymm0
-; AVX2-NEXT:    vbroadcastsd {{.*#+}} ymm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]
-; AVX2-NEXT:    vminpd %ymm1, %ymm0, %ymm0
+; AVX2-NEXT:    vcmpunordpd %ymm0, %ymm0, %ymm1
+; AVX2-NEXT:    vxorpd %xmm2, %xmm2, %xmm2
+; AVX2-NEXT:    vmaxpd %ymm2, %ymm0, %ymm0
+; AVX2-NEXT:    vbroadcastsd {{.*#+}} ymm2 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]
+; AVX2-NEXT:    vminpd %ymm2, %ymm0, %ymm0
+; AVX2-NEXT:    vextractf128 $1, %ymm1, %xmm2
 ; AVX2-NEXT:    vcvttpd2dq %ymm0, %xmm0
+; AVX2-NEXT:    vpackssdw %xmm2, %xmm1, %xmm1
+; AVX2-NEXT:    vxorpd %xmm2, %xmm2, %xmm2
+; AVX2-NEXT:    vblendvps %xmm1, %xmm2, %xmm0, %xmm0
 ; AVX2-NEXT:    vzeroupper
 ; AVX2-NEXT:    retq
 ;
@@ -902,20 +912,25 @@ define <4 x i32> @test_unsigned_v4i32_v4f64(<4 x double> %f) nounwind {
 ; AVX2-LABEL: test_unsigned_v4i32_v4f64:
 ; AVX2:       # %bb.0:
 ; AVX2-NEXT:    vxorpd %xmm1, %xmm1, %xmm1
-; AVX2-NEXT:    vmaxpd %ymm1, %ymm0, %ymm0
-; AVX2-NEXT:    vbroadcastsd {{.*#+}} ymm1 = [4.294967296E+9,4.294967296E+9,4.294967296E+9,4.294967296E+9]
-; AVX2-NEXT:    vcmplepd %ymm0, %ymm1, %ymm1
-; AVX2-NEXT:    vextractf128 $1, %ymm1, %xmm2
-; AVX2-NEXT:    vpackssdw %xmm2, %xmm1, %xmm1
-; AVX2-NEXT:    vcvttpd2dq %ymm0, %xmm2
-; AVX2-NEXT:    vpsrad $31, %xmm2, %xmm3
+; AVX2-NEXT:    vmaxpd %ymm1, %ymm0, %ymm1
+; AVX2-NEXT:    vbroadcastsd {{.*#+}} ymm2 = [4.294967296E+9,4.294967296E+9,4.294967296E+9,4.294967296E+9]
+; AVX2-NEXT:    vcmplepd %ymm1, %ymm2, %ymm2
+; AVX2-NEXT:    vextractf128 $1, %ymm2, %xmm3
+; AVX2-NEXT:    vpackssdw %xmm3, %xmm2, %xmm2
+; AVX2-NEXT:    vcvttpd2dq %ymm1, %xmm3
 ; AVX2-NEXT:    vbroadcastsd {{.*#+}} ymm4 = [2.147483648E+9,2.147483648E+9,2.147483648E+9,2.147483648E+9]
-; AVX2-NEXT:    vsubpd %ymm4, %ymm0, %ymm0
-; AVX2-NEXT:    vcvttpd2dq %ymm0, %xmm0
-; AVX2-NEXT:    vandpd %xmm3, %xmm0, %xmm0
-; AVX2-NEXT:    vorpd %xmm0, %xmm2, %xmm0
-; AVX2-NEXT:    vpcmpeqd %xmm2, %xmm2, %xmm2
-; AVX2-NEXT:    vblendvps %xmm1, %xmm2, %xmm0, %xmm0
+; AVX2-NEXT:    vsubpd %ymm4, %ymm1, %ymm1
+; AVX2-NEXT:    vcvttpd2dq %ymm1, %xmm1
+; AVX2-NEXT:    vpsrad $31, %xmm3, %xmm4
+; AVX2-NEXT:    vandpd %xmm4, %xmm1, %xmm1
+; AVX2-NEXT:    vorpd %xmm1, %xmm3, %xmm1
+; AVX2-NEXT:    vpcmpeqd %xmm3, %xmm3, %xmm3
+; AVX2-NEXT:    vblendvps %xmm2, %xmm3, %xmm1, %xmm1
+; AVX2-NEXT:    vcmpunordpd %ymm0, %ymm0, %ymm0
+; AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm2
+; AVX2-NEXT:    vpackssdw %xmm2, %xmm0, %xmm0
+; AVX2-NEXT:    vxorpd %xmm2, %xmm2, %xmm2
+; AVX2-NEXT:    vblendvps %xmm0, %xmm2, %xmm1, %xmm0
 ; AVX2-NEXT:    vzeroupper
 ; AVX2-NEXT:    retq
 ;
@@ -924,13 +939,16 @@ define <4 x i32> @test_unsigned_v4i32_v4f64(<4 x double> %f) nounwind {
 ; AVX512-NEXT:    vxorpd %xmm1, %xmm1, %xmm1
 ; AVX512-NEXT:    vmaxpd %ymm1, %ymm0, %ymm1
 ; AVX512-NEXT:    vcvttpd2dq %ymm1, %xmm2
-; AVX512-NEXT:    vsubpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm1, %ymm0
-; AVX512-NEXT:    vcvttpd2dq %ymm0, %xmm0
 ; AVX512-NEXT:    vpsrad $31, %xmm2, %xmm3
-; AVX512-NEXT:    vpternlogd {{.*#+}} xmm0 = (xmm0 & xmm3) | xmm2
+; AVX512-NEXT:    vsubpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm1, %ymm4
+; AVX512-NEXT:    vcvttpd2dq %ymm4, %xmm4
 ; AVX512-NEXT:    vcmpgepd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %ymm1, %k1
+; AVX512-NEXT:    vpternlogd {{.*#+}} xmm4 = (xmm4 & xmm3) | xmm2
 ; AVX512-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
-; AVX512-NEXT:    vmovdqa32 %xmm1, %xmm0 {%k1}
+; AVX512-NEXT:    vmovdqa32 %xmm1, %xmm4 {%k1}
+; AVX512-NEXT:    vcmpunordpd %ymm0, %ymm0, %k0
+; AVX512-NEXT:    knotw %k0, %k1
+; AVX512-NEXT:    vmovdqa32 %xmm4, %xmm0 {%k1} {z}
 ; AVX512-NEXT:    vzeroupper
 ; AVX512-NEXT:    retq
   %x = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f64(<4 x double> %f)
diff --git a/llvm/test/CodeGen/X86/fptoui-sat-vector-512.ll b/llvm/test/CodeGen/X86/fptoui-sat-vector-512.ll
index 17f4499fb0bb7..f647c14cfc43d 100644
--- a/llvm/test/CodeGen/X86/fptoui-sat-vector-512.ll
+++ b/llvm/test/CodeGen/X86/fptoui-sat-vector-512.ll
@@ -724,11 +724,14 @@ define <16 x i32> @test_unsigned_v16i32_v16f32(<16 x float> %f) nounwind {
 ; CHECK-LABEL: test_unsigned_v16i32_v16f32:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    vxorps %xmm1, %xmm1, %xmm1
-; CHECK-NEXT:    vmaxps %zmm1, %zmm0, %zmm0
-; CHECK-NEXT:    vcmpgeps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to16}, %zmm0, %k1
-; CHECK-NEXT:    vcvttps2udq %zmm0, %zmm0
-; CHECK-NEXT:    vpternlogd {{.*#+}} zmm1 = -1
-; CHECK-NEXT:    vmovdqa32 %zmm1, %zmm0 {%k1}
+; CHECK-NEXT:    vmaxps %zmm1, %zmm0, %zmm1
+; CHECK-NEXT:    vcmpgeps {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to16}, %zmm1, %k1
+; CHECK-NEXT:    vcvttps2udq %zmm1, %zmm1
+; CHECK-NEXT:    vpternlogd {{.*#+}} zmm2 = -1
+; CHECK-NEXT:    vmovdqa32 %zmm2, %zmm1 {%k1}
+; CHECK-NEXT:    vcmpunordps %zmm0, %zmm0, %k0
+; CHECK-NEXT:    knotw %k0, %k1
+; CHECK-NEXT:    vmovdqa32 %zmm1, %zmm0 {%k1} {z}
 ; CHECK-NEXT:    retq
   %x = call <16 x i32> @llvm.fptoui.sat.v16i32.v16f32(<16 x float> %f)
   ret <16 x i32> %x
@@ -1928,16 +1931,19 @@ define <8 x i32> @test_unsigned_v8i32_v8f64(<8 x double> %f) nounwind {
 ; AVX512F-LABEL: test_unsigned_v8i32_v8f64:
 ; AVX512F:       # %bb.0:
 ; AVX512F-NEXT:    vxorpd %xmm1, %xmm1, %xmm1
-; AVX512F-NEXT:    vmaxpd %zmm1, %zmm0, %zmm0
-; AVX512F-NEXT:    vcvttpd2dq %zmm0, %ymm1
-; AVX512F-NEXT:    vpsrad $31, %ymm1, %ymm2
-; AVX512F-NEXT:    vsubpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %zmm3
+; AVX512F-NEXT:    vmaxpd %zmm1, %zmm0, %zmm1
+; AVX512F-NEXT:    vcvttpd2dq %zmm1, %ymm2
+; AVX512F-NEXT:    vsubpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm1, %zmm3
+; AVX512F-NEXT:    vpsrad $31, %ymm2, %ymm4
 ; AVX512F-NEXT:    vcvttpd2dq %zmm3, %ymm3
-; AVX512F-NEXT:    vpand %ymm2, %ymm3, %ymm2
+; AVX512F-NEXT:    vpand %ymm4, %ymm3, %ymm3
+; AVX512F-NEXT:    vpor %ymm3, %ymm2, %ymm2
+; AVX512F-NEXT:    vcmpgepd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm1, %k1
+; AVX512F-NEXT:    vpternlogd {{.*#+}} zmm1 {%k1} {z} = -1
 ; AVX512F-NEXT:    vpor %ymm2, %ymm1, %ymm1
-; AVX512F-NEXT:    vcmpgepd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %k1
+; AVX512F-NEXT:    vcmpunordpd %zmm0, %zmm0, %k1
 ; AVX512F-NEXT:    vpternlogd {{.*#+}} zmm0 {%k1} {z} = -1
-; AVX512F-NEXT:    vpor %ymm1, %ymm0, %ymm0
+; AVX512F-NEXT:    vpandn %ymm1, %ymm0, %ymm0
 ; AVX512F-NEXT:    retq
 ;
 ; AVX512-LABEL: test_unsigned_v8i32_v8f64:
@@ -1945,13 +1951,16 @@ define <8 x i32> @test_unsigned_v8i32_v8f64(<8 x double> %f) nounwind {
 ; AVX512-NEXT:    vxorpd %xmm1, %xmm1, %xmm1
 ; AVX512-NEXT:    vmaxpd %zmm1, %zmm0, %zmm1
 ; AVX512-NEXT:    vcvttpd2dq %zmm1, %ymm2
-; AVX512-NEXT:    vsubpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm1, %zmm0
-; AVX512-NEXT:    vcvttpd2dq %zmm0, %ymm0
 ; AVX512-NEXT:    vpsrad $31, %ymm2, %ymm3
-; AVX512-NEXT:    vpternlogd {{.*#+}} ymm0 = (ymm0 & ymm3) | ymm2
+; AVX512-NEXT:    vsubpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm1, %zmm4
+; AVX512-NEXT:    vcvttpd2dq %zmm4, %ymm4
 ; AVX512-NEXT:    vcmpgepd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm1, %k1
+; AVX512-NEXT:    vpternlogd {{.*#+}} ymm4 = (ymm4 & ymm3) | ymm2
 ; AVX512-NEXT:    vpcmpeqd %ymm1, %ymm1, %ymm1
-; AVX512-NEXT:    vmovdqa32 %ymm1, %ymm0 {%k1}
+; AVX512-NEXT:    vmovdqa32 %ymm1, %ymm4 {%k1}
+; AVX512-NEXT:    vcmpunordpd %zmm0, %zmm0, %k0
+; AVX512-NEXT:    knotb %k0, %k1
+; AVX512-NEXT:    vmovdqa32 %ymm4, %ymm0 {%k1} {z}
 ; AVX512-NEXT:    retq
   %x = call <8 x i32> @llvm.fptoui.sat.v8i32.v8f64(<8 x double> %f)
   ret <8 x i32> %x

>From d11afc7acf41cc6d0ea8e35d8cd359fd1330a806 Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Wed, 15 Jul 2026 01:28:49 +0200
Subject: [PATCH 16/18] Update FMAX/FMIN nodes to commutative variants
 (FMAXC/FMINC) following upstream refactoring, and update tests

---
 llvm/lib/Target/X86/X86ISelLowering.cpp       | 10 ++--
 .../test/CodeGen/X86/fptoui-sat-vector-128.ll | 50 +++++++++----------
 2 files changed, 28 insertions(+), 32 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index d546e05dd17a8..e34638b169f36 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22480,7 +22480,7 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
         return DAG.getSelect(dl, DstVT, IsNaN, Zero, Fixed);
       } else {
         SDValue ZeroFP = DAG.getConstantFP(0.0, dl, SrcVT);
-        SDValue Clamped = DAG.getNode(X86ISD::FMAX, dl, SrcVT, Src, ZeroFP);
+        SDValue Clamped = DAG.getNode(X86ISD::FMAXC, dl, SrcVT, Src, ZeroFP);
         APFloat OvfBoundFlt(SrcVT.getScalarType().getFltSemantics());
         OvfBoundFlt.convertFromAPInt(APInt::getOneBitSet(33, 32),
                                      /*IsSigned=*/false, APFloat::rmTowardZero);
@@ -22534,19 +22534,19 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
     SDValue MaxC = DAG.getConstantFP(MaxFloat, dl, SrcVT);
     SDValue MinC = DAG.getConstantFP(MinFloat, dl, SrcVT);
 
-    // Clamp from below. X86ISD::FMAX returns the second operand when either
+    // Clamp from below. X86ISD::FMAXC returns the second operand when either
     // input is NaN, so NaN maps to MinC here.
-    SDValue ClampedBottom = DAG.getNode(X86ISD::FMAX, dl, SrcVT, Src, MinC);
+    SDValue ClampedBottom = DAG.getNode(X86ISD::FMAXC, dl, SrcVT, Src, MinC);
     // Clamp from above. NaN (now MinC) is already in range and passes through.
     SDValue ClampedTop =
-        DAG.getNode(X86ISD::FMIN, dl, SrcVT, ClampedBottom, MaxC);
+        DAG.getNode(X86ISD::FMINC, dl, SrcVT, ClampedBottom, MaxC);
 
     // For smaller widths, the max unsigned value fits in a signed 32-bit int.
     // Use X86ISD::CVTTP2SI instead of FP_TO_UINT to avoid expensive
     // legalization and guarantee the out-of-range behavior.
     SDValue Result = DAG.getNode(X86ISD::CVTTP2SI, dl, DstVT, ClampedTop);
 
-    // For saturation, FMAX and FMIN might pass NaN through (since they return
+    // For saturation, FMAXC and FMINC might pass NaN through (since they return
     // the second operand if either is NaN).
     // Fix up NaN by selecting 0 explicitly.
     SDValue Zero = DAG.getConstant(0, dl, DstVT);
diff --git a/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll b/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll
index f5986d4050442..ab1886a758ca0 100644
--- a/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll
+++ b/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll
@@ -12,10 +12,9 @@ define <4 x i1> @test_unsigned_v4i1_v4f32(<4 x float> %f) nounwind {
 ; SSE-LABEL: test_unsigned_v4i1_v4f32:
 ; SSE:       # %bb.0:
 ; SSE-NEXT:    xorps %xmm1, %xmm1
-; SSE-NEXT:    movaps %xmm0, %xmm2
-; SSE-NEXT:    maxps %xmm1, %xmm2
-; SSE-NEXT:    minps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE-NEXT:    cvttps2dq %xmm2, %xmm1
+; SSE-NEXT:    maxps %xmm0, %xmm1
+; SSE-NEXT:    minps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE-NEXT:    cvttps2dq %xmm1, %xmm1
 ; SSE-NEXT:    cmpunordps %xmm0, %xmm0
 ; SSE-NEXT:    andnps %xmm1, %xmm0
 ; SSE-NEXT:    retq
@@ -66,10 +65,9 @@ define <4 x i1> @test_freeze_unsigned_v4i1_v4f32(<4 x float> %f) nounwind {
 ; SSE-LABEL: test_freeze_unsigned_v4i1_v4f32:
 ; SSE:       # %bb.0:
 ; SSE-NEXT:    xorps %xmm1, %xmm1
-; SSE-NEXT:    movaps %xmm0, %xmm2
-; SSE-NEXT:    maxps %xmm1, %xmm2
-; SSE-NEXT:    minps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE-NEXT:    cvttps2dq %xmm2, %xmm1
+; SSE-NEXT:    maxps %xmm0, %xmm1
+; SSE-NEXT:    minps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE-NEXT:    cvttps2dq %xmm1, %xmm1
 ; SSE-NEXT:    cmpunordps %xmm0, %xmm0
 ; SSE-NEXT:    andnps %xmm1, %xmm0
 ; SSE-NEXT:    retq
@@ -318,17 +316,16 @@ define <4 x i32> @test_unsigned_v4i32_v4f32(<4 x float> %f) nounwind {
 ; SSE2-LABEL: test_unsigned_v4i32_v4f32:
 ; SSE2:       # %bb.0:
 ; SSE2-NEXT:    xorps %xmm1, %xmm1
-; SSE2-NEXT:    movaps %xmm0, %xmm2
-; SSE2-NEXT:    maxps %xmm1, %xmm2
-; SSE2-NEXT:    cvttps2dq %xmm2, %xmm1
+; SSE2-NEXT:    maxps %xmm0, %xmm1
+; SSE2-NEXT:    cvttps2dq %xmm1, %xmm2
 ; SSE2-NEXT:    movaps {{.*#+}} xmm3 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
-; SSE2-NEXT:    cmpleps %xmm2, %xmm3
-; SSE2-NEXT:    orps %xmm1, %xmm3
-; SSE2-NEXT:    psrad $31, %xmm1
-; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    cvttps2dq %xmm2, %xmm2
-; SSE2-NEXT:    pand %xmm1, %xmm2
+; SSE2-NEXT:    cmpleps %xmm1, %xmm3
 ; SSE2-NEXT:    orps %xmm2, %xmm3
+; SSE2-NEXT:    psrad $31, %xmm2
+; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE2-NEXT:    cvttps2dq %xmm1, %xmm1
+; SSE2-NEXT:    pand %xmm2, %xmm1
+; SSE2-NEXT:    orps %xmm1, %xmm3
 ; SSE2-NEXT:    cmpunordps %xmm0, %xmm0
 ; SSE2-NEXT:    andnps %xmm3, %xmm0
 ; SSE2-NEXT:    retq
@@ -336,18 +333,17 @@ define <4 x i32> @test_unsigned_v4i32_v4f32(<4 x float> %f) nounwind {
 ; SSE42-LABEL: test_unsigned_v4i32_v4f32:
 ; SSE42:       # %bb.0:
 ; SSE42-NEXT:    xorps %xmm1, %xmm1
-; SSE42-NEXT:    movaps %xmm0, %xmm2
-; SSE42-NEXT:    maxps %xmm1, %xmm2
-; SSE42-NEXT:    cvttps2dq %xmm2, %xmm1
-; SSE42-NEXT:    movdqa %xmm1, %xmm3
+; SSE42-NEXT:    maxps %xmm0, %xmm1
+; SSE42-NEXT:    cvttps2dq %xmm1, %xmm2
+; SSE42-NEXT:    movdqa %xmm2, %xmm3
 ; SSE42-NEXT:    movaps {{.*#+}} xmm4 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
-; SSE42-NEXT:    cmpleps %xmm2, %xmm4
-; SSE42-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE42-NEXT:    cmpleps %xmm1, %xmm4
+; SSE42-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
 ; SSE42-NEXT:    psrad $31, %xmm3
-; SSE42-NEXT:    cvttps2dq %xmm2, %xmm2
-; SSE42-NEXT:    pand %xmm3, %xmm2
-; SSE42-NEXT:    por %xmm1, %xmm2
-; SSE42-NEXT:    orps %xmm2, %xmm4
+; SSE42-NEXT:    cvttps2dq %xmm1, %xmm1
+; SSE42-NEXT:    pand %xmm3, %xmm1
+; SSE42-NEXT:    por %xmm2, %xmm1
+; SSE42-NEXT:    orps %xmm1, %xmm4
 ; SSE42-NEXT:    cmpunordps %xmm0, %xmm0
 ; SSE42-NEXT:    andnps %xmm4, %xmm0
 ; SSE42-NEXT:    retq

>From 66d6681f0ea568de13c3b3353376c3eefe696d40 Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Tue, 4 Aug 2026 19:43:20 +0200
Subject: [PATCH 17/18] Refactore to logic implementation

---
 llvm/lib/Target/X86/X86ISelLowering.cpp       | 42 ++++++++++++--
 .../test/CodeGen/X86/fptosi-sat-vector-128.ll | 52 ++++++-----------
 .../test/CodeGen/X86/fptosi-sat-vector-256.ll | 16 ++---
 .../test/CodeGen/X86/fptosi-sat-vector-512.ll |  3 +-
 .../test/CodeGen/X86/fptoui-sat-vector-128.ll | 58 +++++++------------
 .../test/CodeGen/X86/fptoui-sat-vector-256.ll | 23 ++++----
 .../test/CodeGen/X86/fptoui-sat-vector-512.ll |  4 +-
 7 files changed, 94 insertions(+), 104 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index e34638b169f36..537b7d06e929b 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22473,6 +22473,16 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
           IsNaN = DAG.getSExtOrTrunc(IsNaN, dl, SelCCVT);
         }
 
+        // Optimize vector lowering on SSE2/AVX/AVX2 where mask is an all-ones
+        // bitmask vector (SelCCVT == DstVT). XOR(Cvt, PosOvf) maps INT_MIN
+        // (0x80000000) to INT_MAX (0x7FFFFFFF) on positive overflow without
+        // needing INT_MAX in the constant pool or select emulation.
+        if (SelCCVT == DstVT) {
+          SDValue Fixed = DAG.getNode(ISD::XOR, dl, DstVT, Cvt, PosOvf);
+          SDValue NotNaN = DAG.getNOT(dl, IsNaN, DstVT);
+          return DAG.getNode(ISD::AND, dl, DstVT, Fixed, NotNaN);
+        }
+
         SDValue IntMax =
             DAG.getConstant(APInt::getSignedMaxValue(32), dl, DstVT);
         SDValue Zero = DAG.getConstant(0, dl, DstVT);
@@ -22501,13 +22511,26 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
         else
           Cvt = expandFP_TO_UINT_SSE(DstVT.getSimpleVT(), Clamped, dl, DAG,
                                      Subtarget);
-        SDValue UintMax = DAG.getConstant(APInt::getMaxValue(32), dl, DstVT);
-        SDValue Result = DAG.getSelect(dl, DstVT, IsOvf, UintMax, Cvt);
-        
-        SDValue Zero = DAG.getConstant(0, dl, DstVT);
+        // Optimize vector lowering on SSE2/AVX/AVX2 where mask is an all-ones
+        // bitmask vector (SelCCVT == DstVT). OR(Cvt, IsOvf) produces UINT_MAX
+        // (0xFFFFFFFF) on overflow without a constant pool load or select.
+        SDValue Result;
+        if (SelCCVT == DstVT) {
+          Result = DAG.getNode(ISD::OR, dl, DstVT, Cvt, IsOvf);
+        } else {
+          SDValue UintMax = DAG.getConstant(APInt::getMaxValue(32), dl, DstVT);
+          Result = DAG.getSelect(dl, DstVT, IsOvf, UintMax, Cvt);
+        }
+
         SDValue IsNaN = DAG.getSetCC(dl, CCVT, Src, Src, ISD::SETUO);
         if (CCVT != SelCCVT)
           IsNaN = DAG.getSExtOrTrunc(IsNaN, dl, SelCCVT);
+
+        if (SelCCVT == DstVT) {
+          SDValue NotNaN = DAG.getNOT(dl, IsNaN, DstVT);
+          return DAG.getNode(ISD::AND, dl, DstVT, Result, NotNaN);
+        }
+        SDValue Zero = DAG.getConstant(0, dl, DstVT);
         return DAG.getSelect(dl, DstVT, IsNaN, Zero, Result);
       }
     }
@@ -22549,7 +22572,6 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
     // For saturation, FMAXC and FMINC might pass NaN through (since they return
     // the second operand if either is NaN).
     // Fix up NaN by selecting 0 explicitly.
-    SDValue Zero = DAG.getConstant(0, dl, DstVT);
     EVT CCVT =
         getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), SrcVT);
     SDValue IsNaN = DAG.getSetCC(dl, CCVT, Src, Src, ISD::SETUO);
@@ -22557,6 +22579,16 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
         getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), DstVT);
     if (CCVT != SelCCVT)
       IsNaN = DAG.getNode(ISD::TRUNCATE, dl, SelCCVT, IsNaN);
+
+    // On SSE2/AVX/AVX2 where mask is an all-ones bitmask vector, use ANDN
+    // (AND(Result, ~IsNaN)) to zero out NaN without needing a zero constant
+    // vector or select emulation.
+    if (SelCCVT == DstVT) {
+      SDValue NotNaN = DAG.getNOT(dl, IsNaN, DstVT);
+      return DAG.getNode(ISD::AND, dl, DstVT, Result, NotNaN);
+    }
+
+    SDValue Zero = DAG.getConstant(0, dl, DstVT);
     return DAG.getSelect(dl, DstVT, IsNaN, Zero, Result);
   }
   // This code is only for floats and doubles. Fall back to generic code for
diff --git a/llvm/test/CodeGen/X86/fptosi-sat-vector-128.ll b/llvm/test/CodeGen/X86/fptosi-sat-vector-128.ll
index b3d70d43ec3d9..30e849b65261c 100644
--- a/llvm/test/CodeGen/X86/fptosi-sat-vector-128.ll
+++ b/llvm/test/CodeGen/X86/fptosi-sat-vector-128.ll
@@ -11,11 +11,11 @@
 define <4 x i1> @test_signed_v4i1_v4f32(<4 x float> %f) nounwind {
 ; SSE-LABEL: test_signed_v4i1_v4f32:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    movaps %xmm0, %xmm1
-; SSE-NEXT:    maxps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE-NEXT:    movaps {{.*#+}} xmm1 = [-1.0E+0,-1.0E+0,-1.0E+0,-1.0E+0]
+; SSE-NEXT:    maxps %xmm0, %xmm1
 ; SSE-NEXT:    xorps %xmm2, %xmm2
-; SSE-NEXT:    minps %xmm2, %xmm1
-; SSE-NEXT:    cvttps2dq %xmm1, %xmm1
+; SSE-NEXT:    minps %xmm1, %xmm2
+; SSE-NEXT:    cvttps2dq %xmm2, %xmm1
 ; SSE-NEXT:    cmpunordps %xmm0, %xmm0
 ; SSE-NEXT:    andnps %xmm1, %xmm0
 ; SSE-NEXT:    retq
@@ -65,11 +65,11 @@ define <4 x i1> @test_signed_v4i1_v4f32(<4 x float> %f) nounwind {
 define <4 x i1> @test_freeze_signed_v4i1_v4f32(<4 x float> %f) nounwind {
 ; SSE-LABEL: test_freeze_signed_v4i1_v4f32:
 ; SSE:       # %bb.0:
-; SSE-NEXT:    movaps %xmm0, %xmm1
-; SSE-NEXT:    maxps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE-NEXT:    movaps {{.*#+}} xmm1 = [-1.0E+0,-1.0E+0,-1.0E+0,-1.0E+0]
+; SSE-NEXT:    maxps %xmm0, %xmm1
 ; SSE-NEXT:    xorps %xmm2, %xmm2
-; SSE-NEXT:    minps %xmm2, %xmm1
-; SSE-NEXT:    cvttps2dq %xmm1, %xmm1
+; SSE-NEXT:    minps %xmm1, %xmm2
+; SSE-NEXT:    cvttps2dq %xmm2, %xmm1
 ; SSE-NEXT:    cmpunordps %xmm0, %xmm0
 ; SSE-NEXT:    andnps %xmm1, %xmm0
 ; SSE-NEXT:    retq
@@ -315,38 +315,22 @@ define <4 x i16> @test_signed_v4i16_v4f32(<4 x float> %f) nounwind {
 }
 
 define <4 x i32> @test_signed_v4i32_v4f32(<4 x float> %f) nounwind {
-; SSE2-LABEL: test_signed_v4i32_v4f32:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
-; SSE2-NEXT:    cmpleps %xmm0, %xmm1
-; SSE2-NEXT:    cvttps2dq %xmm0, %xmm2
-; SSE2-NEXT:    movaps %xmm1, %xmm3
-; SSE2-NEXT:    andnps %xmm2, %xmm3
-; SSE2-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE2-NEXT:    orps %xmm3, %xmm1
-; SSE2-NEXT:    cmpunordps %xmm0, %xmm0
-; SSE2-NEXT:    andnps %xmm1, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE42-LABEL: test_signed_v4i32_v4f32:
-; SSE42:       # %bb.0:
-; SSE42-NEXT:    movaps %xmm0, %xmm1
-; SSE42-NEXT:    movaps {{.*#+}} xmm0 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
-; SSE42-NEXT:    cmpleps %xmm1, %xmm0
-; SSE42-NEXT:    cvttps2dq %xmm1, %xmm2
-; SSE42-NEXT:    blendvps %xmm0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE42-NEXT:    cmpunordps %xmm1, %xmm1
-; SSE42-NEXT:    andnps %xmm2, %xmm1
-; SSE42-NEXT:    movaps %xmm1, %xmm0
-; SSE42-NEXT:    retq
+; SSE-LABEL: test_signed_v4i32_v4f32:
+; SSE:       # %bb.0:
+; SSE-NEXT:    movaps {{.*#+}} xmm1 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
+; SSE-NEXT:    cmpleps %xmm0, %xmm1
+; SSE-NEXT:    cvttps2dq %xmm0, %xmm2
+; SSE-NEXT:    xorps %xmm1, %xmm2
+; SSE-NEXT:    cmpunordps %xmm0, %xmm0
+; SSE-NEXT:    andnps %xmm2, %xmm0
+; SSE-NEXT:    retq
 ;
 ; AVX2-LABEL: test_signed_v4i32_v4f32:
 ; AVX2:       # %bb.0:
 ; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm1 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
 ; AVX2-NEXT:    vcmpleps %xmm0, %xmm1, %xmm1
 ; AVX2-NEXT:    vcvttps2dq %xmm0, %xmm2
-; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm3 = [2147483647,2147483647,2147483647,2147483647]
-; AVX2-NEXT:    vblendvps %xmm1, %xmm3, %xmm2, %xmm1
+; AVX2-NEXT:    vxorps %xmm1, %xmm2, %xmm1
 ; AVX2-NEXT:    vcmpunordps %xmm0, %xmm0, %xmm0
 ; AVX2-NEXT:    vandnps %xmm1, %xmm0, %xmm0
 ; AVX2-NEXT:    retq
diff --git a/llvm/test/CodeGen/X86/fptosi-sat-vector-256.ll b/llvm/test/CodeGen/X86/fptosi-sat-vector-256.ll
index a58bc1f938f3d..4dd99201752bb 100644
--- a/llvm/test/CodeGen/X86/fptosi-sat-vector-256.ll
+++ b/llvm/test/CodeGen/X86/fptosi-sat-vector-256.ll
@@ -403,8 +403,7 @@ define <8 x i32> @test_signed_v8i32_v8f32(<8 x float> %f) nounwind {
 ; AVX2-NEXT:    vbroadcastss {{.*#+}} ymm1 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
 ; AVX2-NEXT:    vcmpleps %ymm0, %ymm1, %ymm1
 ; AVX2-NEXT:    vcvttps2dq %ymm0, %ymm2
-; AVX2-NEXT:    vbroadcastss {{.*#+}} ymm3 = [2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647]
-; AVX2-NEXT:    vblendvps %ymm1, %ymm3, %ymm2, %ymm1
+; AVX2-NEXT:    vxorps %ymm1, %ymm2, %ymm1
 ; AVX2-NEXT:    vcmpunordps %ymm0, %ymm0, %ymm0
 ; AVX2-NEXT:    vandnps %ymm1, %ymm0, %ymm0
 ; AVX2-NEXT:    retq
@@ -770,15 +769,14 @@ define <4 x i1> @test_signed_v4i1_v4f64(<4 x double> %f) nounwind {
 ; AVX2-LABEL: test_signed_v4i1_v4f64:
 ; AVX2:       # %bb.0:
 ; AVX2-NEXT:    vcmpunordpd %ymm0, %ymm0, %ymm1
+; AVX2-NEXT:    vextractf128 $1, %ymm1, %xmm2
+; AVX2-NEXT:    vpackssdw %xmm2, %xmm1, %xmm1
 ; AVX2-NEXT:    vbroadcastsd {{.*#+}} ymm2 = [-1.0E+0,-1.0E+0,-1.0E+0,-1.0E+0]
 ; AVX2-NEXT:    vmaxpd %ymm2, %ymm0, %ymm0
 ; AVX2-NEXT:    vxorpd %xmm2, %xmm2, %xmm2
 ; AVX2-NEXT:    vminpd %ymm2, %ymm0, %ymm0
-; AVX2-NEXT:    vextractf128 $1, %ymm1, %xmm2
 ; AVX2-NEXT:    vcvttpd2dq %ymm0, %xmm0
-; AVX2-NEXT:    vpackssdw %xmm2, %xmm1, %xmm1
-; AVX2-NEXT:    vxorpd %xmm2, %xmm2, %xmm2
-; AVX2-NEXT:    vblendvps %xmm1, %xmm2, %xmm0, %xmm0
+; AVX2-NEXT:    vpandn %xmm0, %xmm1, %xmm0
 ; AVX2-NEXT:    vzeroupper
 ; AVX2-NEXT:    retq
 ;
@@ -882,13 +880,11 @@ define <4 x i32> @test_signed_v4i32_v4f64(<4 x double> %f) nounwind {
 ; AVX2-NEXT:    vextractf128 $1, %ymm1, %xmm2
 ; AVX2-NEXT:    vpackssdw %xmm2, %xmm1, %xmm1
 ; AVX2-NEXT:    vcvttpd2dq %ymm0, %xmm2
-; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm3 = [2147483647,2147483647,2147483647,2147483647]
-; AVX2-NEXT:    vblendvps %xmm1, %xmm3, %xmm2, %xmm1
+; AVX2-NEXT:    vxorpd %xmm1, %xmm2, %xmm1
 ; AVX2-NEXT:    vcmpunordpd %ymm0, %ymm0, %ymm0
 ; AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm2
 ; AVX2-NEXT:    vpackssdw %xmm2, %xmm0, %xmm0
-; AVX2-NEXT:    vxorpd %xmm2, %xmm2, %xmm2
-; AVX2-NEXT:    vblendvps %xmm0, %xmm2, %xmm1, %xmm0
+; AVX2-NEXT:    vpandn %xmm1, %xmm0, %xmm0
 ; AVX2-NEXT:    vzeroupper
 ; AVX2-NEXT:    retq
 ;
diff --git a/llvm/test/CodeGen/X86/fptosi-sat-vector-512.ll b/llvm/test/CodeGen/X86/fptosi-sat-vector-512.ll
index 1a78d45a14a0d..9adca109d0bee 100644
--- a/llvm/test/CodeGen/X86/fptosi-sat-vector-512.ll
+++ b/llvm/test/CodeGen/X86/fptosi-sat-vector-512.ll
@@ -2036,8 +2036,7 @@ define <8 x i32> @test_signed_v8i32_v8f64(<8 x double> %f) nounwind {
 ; AVX512F-NEXT:    vcvttpd2dq %zmm0, %ymm1
 ; AVX512F-NEXT:    vcmpgepd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm0, %k1
 ; AVX512F-NEXT:    vpternlogd {{.*#+}} zmm2 {%k1} {z} = -1
-; AVX512F-NEXT:    vbroadcastss {{.*#+}} ymm3 = [2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647]
-; AVX512F-NEXT:    vblendvps %ymm2, %ymm3, %ymm1, %ymm1
+; AVX512F-NEXT:    vpxor %ymm2, %ymm1, %ymm1
 ; AVX512F-NEXT:    vcmpunordpd %zmm0, %zmm0, %k1
 ; AVX512F-NEXT:    vpternlogd {{.*#+}} zmm0 {%k1} {z} = -1
 ; AVX512F-NEXT:    vpandn %ymm1, %ymm0, %ymm0
diff --git a/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll b/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll
index ab1886a758ca0..288e6b2b4c15e 100644
--- a/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll
+++ b/llvm/test/CodeGen/X86/fptoui-sat-vector-128.ll
@@ -313,40 +313,22 @@ define <4 x i16> @test_unsigned_v4i16_v4f32(<4 x float> %f) nounwind {
 }
 
 define <4 x i32> @test_unsigned_v4i32_v4f32(<4 x float> %f) nounwind {
-; SSE2-LABEL: test_unsigned_v4i32_v4f32:
-; SSE2:       # %bb.0:
-; SSE2-NEXT:    xorps %xmm1, %xmm1
-; SSE2-NEXT:    maxps %xmm0, %xmm1
-; SSE2-NEXT:    cvttps2dq %xmm1, %xmm2
-; SSE2-NEXT:    movaps {{.*#+}} xmm3 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
-; SSE2-NEXT:    cmpleps %xmm1, %xmm3
-; SSE2-NEXT:    orps %xmm2, %xmm3
-; SSE2-NEXT:    psrad $31, %xmm2
-; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE2-NEXT:    cvttps2dq %xmm1, %xmm1
-; SSE2-NEXT:    pand %xmm2, %xmm1
-; SSE2-NEXT:    orps %xmm1, %xmm3
-; SSE2-NEXT:    cmpunordps %xmm0, %xmm0
-; SSE2-NEXT:    andnps %xmm3, %xmm0
-; SSE2-NEXT:    retq
-;
-; SSE42-LABEL: test_unsigned_v4i32_v4f32:
-; SSE42:       # %bb.0:
-; SSE42-NEXT:    xorps %xmm1, %xmm1
-; SSE42-NEXT:    maxps %xmm0, %xmm1
-; SSE42-NEXT:    cvttps2dq %xmm1, %xmm2
-; SSE42-NEXT:    movdqa %xmm2, %xmm3
-; SSE42-NEXT:    movaps {{.*#+}} xmm4 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
-; SSE42-NEXT:    cmpleps %xmm1, %xmm4
-; SSE42-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE42-NEXT:    psrad $31, %xmm3
-; SSE42-NEXT:    cvttps2dq %xmm1, %xmm1
-; SSE42-NEXT:    pand %xmm3, %xmm1
-; SSE42-NEXT:    por %xmm2, %xmm1
-; SSE42-NEXT:    orps %xmm1, %xmm4
-; SSE42-NEXT:    cmpunordps %xmm0, %xmm0
-; SSE42-NEXT:    andnps %xmm4, %xmm0
-; SSE42-NEXT:    retq
+; SSE-LABEL: test_unsigned_v4i32_v4f32:
+; SSE:       # %bb.0:
+; SSE-NEXT:    xorps %xmm1, %xmm1
+; SSE-NEXT:    maxps %xmm0, %xmm1
+; SSE-NEXT:    cvttps2dq %xmm1, %xmm2
+; SSE-NEXT:    movaps {{.*#+}} xmm3 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
+; SSE-NEXT:    cmpleps %xmm1, %xmm3
+; SSE-NEXT:    orps %xmm2, %xmm3
+; SSE-NEXT:    psrad $31, %xmm2
+; SSE-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE-NEXT:    cvttps2dq %xmm1, %xmm1
+; SSE-NEXT:    pand %xmm2, %xmm1
+; SSE-NEXT:    orps %xmm1, %xmm3
+; SSE-NEXT:    cmpunordps %xmm0, %xmm0
+; SSE-NEXT:    andnps %xmm3, %xmm0
+; SSE-NEXT:    retq
 ;
 ; AVX2-LABEL: test_unsigned_v4i32_v4f32:
 ; AVX2:       # %bb.0:
@@ -358,10 +340,10 @@ define <4 x i32> @test_unsigned_v4i32_v4f32(<4 x float> %f) nounwind {
 ; AVX2-NEXT:    vsubps %xmm4, %xmm1, %xmm4
 ; AVX2-NEXT:    vcvttps2dq %xmm4, %xmm4
 ; AVX2-NEXT:    vpand %xmm3, %xmm4, %xmm3
-; AVX2-NEXT:    vpor %xmm3, %xmm2, %xmm2
-; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm3 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
-; AVX2-NEXT:    vcmpleps %xmm1, %xmm3, %xmm1
-; AVX2-NEXT:    vorps %xmm2, %xmm1, %xmm1
+; AVX2-NEXT:    vbroadcastss {{.*#+}} xmm4 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
+; AVX2-NEXT:    vcmpleps %xmm1, %xmm4, %xmm1
+; AVX2-NEXT:    vpor %xmm1, %xmm2, %xmm1
+; AVX2-NEXT:    vpor %xmm3, %xmm1, %xmm1
 ; AVX2-NEXT:    vcmpunordps %xmm0, %xmm0, %xmm0
 ; AVX2-NEXT:    vandnps %xmm1, %xmm0, %xmm0
 ; AVX2-NEXT:    retq
diff --git a/llvm/test/CodeGen/X86/fptoui-sat-vector-256.ll b/llvm/test/CodeGen/X86/fptoui-sat-vector-256.ll
index 542e1d1198b83..4322501b3b6a4 100644
--- a/llvm/test/CodeGen/X86/fptoui-sat-vector-256.ll
+++ b/llvm/test/CodeGen/X86/fptoui-sat-vector-256.ll
@@ -408,10 +408,10 @@ define <8 x i32> @test_unsigned_v8i32_v8f32(<8 x float> %f) nounwind {
 ; AVX2-NEXT:    vsubps %ymm4, %ymm1, %ymm4
 ; AVX2-NEXT:    vcvttps2dq %ymm4, %ymm4
 ; AVX2-NEXT:    vpand %ymm3, %ymm4, %ymm3
-; AVX2-NEXT:    vpor %ymm3, %ymm2, %ymm2
-; AVX2-NEXT:    vbroadcastss {{.*#+}} ymm3 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
-; AVX2-NEXT:    vcmpleps %ymm1, %ymm3, %ymm1
-; AVX2-NEXT:    vorps %ymm2, %ymm1, %ymm1
+; AVX2-NEXT:    vbroadcastss {{.*#+}} ymm4 = [4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9,4.2949673E+9]
+; AVX2-NEXT:    vcmpleps %ymm1, %ymm4, %ymm1
+; AVX2-NEXT:    vpor %ymm1, %ymm2, %ymm1
+; AVX2-NEXT:    vpor %ymm3, %ymm1, %ymm1
 ; AVX2-NEXT:    vcmpunordps %ymm0, %ymm0, %ymm0
 ; AVX2-NEXT:    vandnps %ymm1, %ymm0, %ymm0
 ; AVX2-NEXT:    retq
@@ -804,15 +804,14 @@ define <4 x i1> @test_unsigned_v4i1_v4f64(<4 x double> %f) nounwind {
 ; AVX2-LABEL: test_unsigned_v4i1_v4f64:
 ; AVX2:       # %bb.0:
 ; AVX2-NEXT:    vcmpunordpd %ymm0, %ymm0, %ymm1
+; AVX2-NEXT:    vextractf128 $1, %ymm1, %xmm2
+; AVX2-NEXT:    vpackssdw %xmm2, %xmm1, %xmm1
 ; AVX2-NEXT:    vxorpd %xmm2, %xmm2, %xmm2
 ; AVX2-NEXT:    vmaxpd %ymm2, %ymm0, %ymm0
 ; AVX2-NEXT:    vbroadcastsd {{.*#+}} ymm2 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0]
 ; AVX2-NEXT:    vminpd %ymm2, %ymm0, %ymm0
-; AVX2-NEXT:    vextractf128 $1, %ymm1, %xmm2
 ; AVX2-NEXT:    vcvttpd2dq %ymm0, %xmm0
-; AVX2-NEXT:    vpackssdw %xmm2, %xmm1, %xmm1
-; AVX2-NEXT:    vxorpd %xmm2, %xmm2, %xmm2
-; AVX2-NEXT:    vblendvps %xmm1, %xmm2, %xmm0, %xmm0
+; AVX2-NEXT:    vpandn %xmm0, %xmm1, %xmm0
 ; AVX2-NEXT:    vzeroupper
 ; AVX2-NEXT:    retq
 ;
@@ -923,14 +922,12 @@ define <4 x i32> @test_unsigned_v4i32_v4f64(<4 x double> %f) nounwind {
 ; AVX2-NEXT:    vcvttpd2dq %ymm1, %xmm1
 ; AVX2-NEXT:    vpsrad $31, %xmm3, %xmm4
 ; AVX2-NEXT:    vandpd %xmm4, %xmm1, %xmm1
-; AVX2-NEXT:    vorpd %xmm1, %xmm3, %xmm1
-; AVX2-NEXT:    vpcmpeqd %xmm3, %xmm3, %xmm3
-; AVX2-NEXT:    vblendvps %xmm2, %xmm3, %xmm1, %xmm1
+; AVX2-NEXT:    vpor %xmm2, %xmm3, %xmm2
+; AVX2-NEXT:    vpor %xmm1, %xmm2, %xmm1
 ; AVX2-NEXT:    vcmpunordpd %ymm0, %ymm0, %ymm0
 ; AVX2-NEXT:    vextractf128 $1, %ymm0, %xmm2
 ; AVX2-NEXT:    vpackssdw %xmm2, %xmm0, %xmm0
-; AVX2-NEXT:    vxorpd %xmm2, %xmm2, %xmm2
-; AVX2-NEXT:    vblendvps %xmm0, %xmm2, %xmm1, %xmm0
+; AVX2-NEXT:    vpandn %xmm1, %xmm0, %xmm0
 ; AVX2-NEXT:    vzeroupper
 ; AVX2-NEXT:    retq
 ;
diff --git a/llvm/test/CodeGen/X86/fptoui-sat-vector-512.ll b/llvm/test/CodeGen/X86/fptoui-sat-vector-512.ll
index f647c14cfc43d..2574ac1220f40 100644
--- a/llvm/test/CodeGen/X86/fptoui-sat-vector-512.ll
+++ b/llvm/test/CodeGen/X86/fptoui-sat-vector-512.ll
@@ -1937,10 +1937,10 @@ define <8 x i32> @test_unsigned_v8i32_v8f64(<8 x double> %f) nounwind {
 ; AVX512F-NEXT:    vpsrad $31, %ymm2, %ymm4
 ; AVX512F-NEXT:    vcvttpd2dq %zmm3, %ymm3
 ; AVX512F-NEXT:    vpand %ymm4, %ymm3, %ymm3
-; AVX512F-NEXT:    vpor %ymm3, %ymm2, %ymm2
 ; AVX512F-NEXT:    vcmpgepd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to8}, %zmm1, %k1
 ; AVX512F-NEXT:    vpternlogd {{.*#+}} zmm1 {%k1} {z} = -1
-; AVX512F-NEXT:    vpor %ymm2, %ymm1, %ymm1
+; AVX512F-NEXT:    vpor %ymm1, %ymm2, %ymm1
+; AVX512F-NEXT:    vpor %ymm3, %ymm1, %ymm1
 ; AVX512F-NEXT:    vcmpunordpd %zmm0, %zmm0, %k1
 ; AVX512F-NEXT:    vpternlogd {{.*#+}} zmm0 {%k1} {z} = -1
 ; AVX512F-NEXT:    vpandn %ymm1, %ymm0, %ymm0

>From 00c3c0f0473fbb070509c288fb968e639aa5bfb7 Mon Sep 17 00:00:00 2001
From: Jordan Jazbor <jazborj at gmail.com>
Date: Tue, 4 Aug 2026 23:32:49 +0200
Subject: [PATCH 18/18] fix avx10.2

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 28 +++++++++++++++----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 537b7d06e929b..01db68b1e3382 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -319,8 +319,6 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
       setOperationAction(ISD::FP_TO_UINT_SAT, MVT::i64, Custom);
       setOperationAction(ISD::FP_TO_SINT_SAT, MVT::i64, Custom);
     }
-    setOperationAction(ISD::FP_TO_UINT_SAT, MVT::v4i32, Custom);
-    setOperationAction(ISD::FP_TO_SINT_SAT, MVT::v4i32, Custom);
   }
 
   if (Subtarget.hasAVX10_2()) {
@@ -1269,10 +1267,13 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
 
     setOperationAction(ISD::FP_TO_SINT,         MVT::v4i32, Custom);
     setOperationAction(ISD::FP_TO_UINT,         MVT::v4i32, Custom);
-    setOperationAction(ISD::FP_TO_SINT,         MVT::v2i32, Custom);
-    setOperationAction(ISD::FP_TO_UINT,         MVT::v2i32, Custom);
+    setOperationAction(ISD::FP_TO_SINT, MVT::v2i32, Custom);
     setOperationAction(ISD::STRICT_FP_TO_SINT,  MVT::v4i32, Custom);
     setOperationAction(ISD::STRICT_FP_TO_SINT,  MVT::v2i32, Custom);
+    if (!Subtarget.hasAVX10_2()) {
+      setOperationAction(ISD::FP_TO_SINT_SAT, MVT::v4i32, Custom);
+      setOperationAction(ISD::FP_TO_UINT_SAT, MVT::v4i32, Custom);
+    }
 
     // Custom legalize these to avoid over promotion or custom promotion.
     for (auto VT : {MVT::v2i8, MVT::v4i8, MVT::v8i8, MVT::v2i16, MVT::v4i16}) {
@@ -1548,8 +1549,10 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
     setOperationPromotedToType(ISD::STRICT_FP_TO_UINT, MVT::v8i16, MVT::v8i32);
     setOperationAction(ISD::FP_TO_SINT,                MVT::v8i32, Custom);
     setOperationAction(ISD::FP_TO_UINT,                MVT::v8i32, Custom);
-    setOperationAction(ISD::FP_TO_SINT_SAT,            MVT::v8i32, Custom);
-    setOperationAction(ISD::FP_TO_UINT_SAT,            MVT::v8i32, Custom);
+    if (!Subtarget.hasAVX10_2()) {
+      setOperationAction(ISD::FP_TO_SINT_SAT, MVT::v8i32, Custom);
+      setOperationAction(ISD::FP_TO_UINT_SAT, MVT::v8i32, Custom);
+    }
     setOperationAction(ISD::STRICT_FP_TO_SINT,         MVT::v8i32, Custom);
 
     setOperationAction(ISD::SINT_TO_FP,         MVT::v8i32, Custom);
@@ -1950,8 +1953,10 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
       setOperationAction(ISD::STRICT_FP_TO_UINT, VT, Custom);
     }
 
-    setOperationAction(ISD::FP_TO_SINT_SAT, MVT::v16i32, Custom);
-    setOperationAction(ISD::FP_TO_UINT_SAT, MVT::v16i32, Custom);
+    if (!Subtarget.hasAVX10_2()) {
+      setOperationAction(ISD::FP_TO_SINT_SAT, MVT::v16i32, Custom);
+      setOperationAction(ISD::FP_TO_UINT_SAT, MVT::v16i32, Custom);
+    }
 
     setOperationAction(ISD::SINT_TO_FP,        MVT::v16i32, Custom);
     setOperationAction(ISD::UINT_TO_FP,        MVT::v16i32, Custom);
@@ -22441,9 +22446,10 @@ X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
                               dl, VecI16VT, Src);
     return DAG.getNode(ISD::TRUNCATE, dl, DstVT, Res);
   }
-  if ((DstVT == MVT::v4i32 && Subtarget.hasSSE2()) ||
-      (DstVT == MVT::v8i32 && Subtarget.hasAVX()) ||
-      (DstVT == MVT::v16i32 && Subtarget.hasAVX512())) {
+  if (!Subtarget.hasAVX10_2() &&
+      ((DstVT == MVT::v4i32 && Subtarget.hasSSE2()) ||
+       (DstVT == MVT::v8i32 && Subtarget.hasAVX()) ||
+       (DstVT == MVT::v16i32 && Subtarget.hasAVX512()))) {
     unsigned SatWidth = SatVT.getScalarSizeInBits();
     assert(SatWidth <= 32 &&
            "Expected saturation width no wider than result element");



More information about the llvm-commits mailing list