[llvm-branch-commits] [llvm] 07605ea - [X86] Improved lowering for saturating float to int.

Bjorn Pettersson via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Jan 12 06:50:11 PST 2021


Author: Bevin Hansson
Date: 2021-01-12T15:44:41+01:00
New Revision: 07605ea1f3c94e0a23450f5c9ab3902862d7ff03

URL: https://github.com/llvm/llvm-project/commit/07605ea1f3c94e0a23450f5c9ab3902862d7ff03
DIFF: https://github.com/llvm/llvm-project/commit/07605ea1f3c94e0a23450f5c9ab3902862d7ff03.diff

LOG: [X86] Improved lowering for saturating float to int.

Adapted from D54696 by @nikic.

This patch improves lowering of saturating float to
int conversions, FP_TO_[SU]INT_SAT, for X86.

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D86079

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86ISelLowering.cpp
    llvm/lib/Target/X86/X86ISelLowering.h
    llvm/test/CodeGen/X86/fptosi-sat-scalar.ll
    llvm/test/CodeGen/X86/fptoui-sat-scalar.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index f28e28689806..65b784f31842 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -284,6 +284,19 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
     }
   }
 
+  if (Subtarget.hasSSE2()) {
+    // Custom lowering for saturating float to int conversions.
+    // We handle promotion to larger result types manually.
+    for (MVT VT : { MVT::i8, MVT::i16, MVT::i32 }) {
+      setOperationAction(ISD::FP_TO_UINT_SAT, VT, Custom);
+      setOperationAction(ISD::FP_TO_SINT_SAT, VT, Custom);
+    }
+    if (Subtarget.is64Bit()) {
+      setOperationAction(ISD::FP_TO_UINT_SAT, MVT::i64, Custom);
+      setOperationAction(ISD::FP_TO_SINT_SAT, MVT::i64, Custom);
+    }
+  }
+
   // Handle address space casts between mixed sized pointers.
   setOperationAction(ISD::ADDRSPACECAST, MVT::i32, Custom);
   setOperationAction(ISD::ADDRSPACECAST, MVT::i64, Custom);
@@ -21428,6 +21441,155 @@ SDValue X86TargetLowering::LRINT_LLRINTHelper(SDNode *N,
   return DAG.getLoad(DstVT, DL, Chain, StackPtr, MPI);
 }
 
+SDValue
+X86TargetLowering::LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const {
+  // This is based on the TargetLowering::expandFP_TO_INT_SAT implementation,
+  // but making use of X86 specifics to produce better instruction sequences.
+  SDNode *Node = Op.getNode();
+  bool IsSigned = Node->getOpcode() == ISD::FP_TO_SINT_SAT;
+  unsigned FpToIntOpcode = IsSigned ? ISD::FP_TO_SINT : ISD::FP_TO_UINT;
+  SDLoc dl(SDValue(Node, 0));
+  SDValue Src = Node->getOperand(0);
+
+  // There are three types involved here: SrcVT is the source floating point
+  // type, DstVT is the type of the result, and TmpVT is the result of the
+  // intermediate FP_TO_*INT operation we'll use (which may be a promotion of
+  // DstVT).
+  EVT SrcVT = Src.getValueType();
+  EVT DstVT = Node->getValueType(0);
+  EVT TmpVT = DstVT;
+
+  // This code is only for floats and doubles. Fall back to generic code for
+  // anything else.
+  if (!isScalarFPTypeInSSEReg(SrcVT))
+    return SDValue();
+
+  unsigned SatWidth = Node->getConstantOperandVal(1);
+  unsigned DstWidth = DstVT.getScalarSizeInBits();
+  unsigned TmpWidth = TmpVT.getScalarSizeInBits();
+  assert(SatWidth <= DstWidth && SatWidth <= TmpWidth &&
+         "Expected saturation width smaller than result width");
+
+  // Promote result of FP_TO_*INT to at least 32 bits.
+  if (TmpWidth < 32) {
+    TmpVT = MVT::i32;
+    TmpWidth = 32;
+  }
+
+  // Promote conversions to unsigned 32-bit to 64-bit, because it will allow
+  // us to use a native signed conversion instead.
+  if (SatWidth == 32 && !IsSigned && Subtarget.is64Bit()) {
+    TmpVT = MVT::i64;
+    TmpWidth = 64;
+  }
+
+  // If the saturation width is smaller than the size of the temporary result,
+  // we can always use signed conversion, which is native.
+  if (SatWidth < TmpWidth)
+    FpToIntOpcode = ISD::FP_TO_SINT;
+
+  // Determine minimum and maximum integer values and their corresponding
+  // floating-point values.
+  APInt MinInt, MaxInt;
+  if (IsSigned) {
+    MinInt = APInt::getSignedMinValue(SatWidth).sextOrSelf(DstWidth);
+    MaxInt = APInt::getSignedMaxValue(SatWidth).sextOrSelf(DstWidth);
+  } else {
+    MinInt = APInt::getMinValue(SatWidth).zextOrSelf(DstWidth);
+    MaxInt = APInt::getMaxValue(SatWidth).zextOrSelf(DstWidth);
+  }
+
+  APFloat MinFloat(DAG.EVTToAPFloatSemantics(SrcVT));
+  APFloat MaxFloat(DAG.EVTToAPFloatSemantics(SrcVT));
+
+  APFloat::opStatus MinStatus = MinFloat.convertFromAPInt(
+    MinInt, IsSigned, APFloat::rmTowardZero);
+  APFloat::opStatus MaxStatus = MaxFloat.convertFromAPInt(
+    MaxInt, IsSigned, APFloat::rmTowardZero);
+  bool AreExactFloatBounds = !(MinStatus & APFloat::opStatus::opInexact)
+                          && !(MaxStatus & APFloat::opStatus::opInexact);
+
+  SDValue MinFloatNode = DAG.getConstantFP(MinFloat, dl, SrcVT);
+  SDValue MaxFloatNode = DAG.getConstantFP(MaxFloat, dl, SrcVT);
+
+  // If the integer bounds are exactly representable as floats, emit a
+  // min+max+fptoi sequence. Otherwise use comparisons and selects.
+  if (AreExactFloatBounds) {
+    if (DstVT != TmpVT) {
+      // Clamp by MinFloat from below. If Src is NaN, propagate NaN.
+      SDValue MinClamped = DAG.getNode(
+        X86ISD::FMAX, dl, SrcVT, MinFloatNode, Src);
+      // Clamp by MaxFloat from above. If Src is NaN, propagate NaN.
+      SDValue BothClamped = DAG.getNode(
+        X86ISD::FMIN, dl, SrcVT, MaxFloatNode, MinClamped);
+      // Convert clamped value to integer.
+      SDValue FpToInt = DAG.getNode(FpToIntOpcode, dl, TmpVT, BothClamped);
+
+      // NaN will become INDVAL, with the top bit set and the rest zero.
+      // Truncation will discard the top bit, resulting in zero.
+      return DAG.getNode(ISD::TRUNCATE, dl, DstVT, FpToInt);
+    }
+
+    // Clamp by MinFloat from below. If Src is NaN, the result is MinFloat.
+    SDValue MinClamped = DAG.getNode(
+      X86ISD::FMAX, dl, SrcVT, Src, MinFloatNode);
+    // Clamp by MaxFloat from above. NaN cannot occur.
+    SDValue BothClamped = DAG.getNode(
+      X86ISD::FMINC, dl, SrcVT, MinClamped, MaxFloatNode);
+    // Convert clamped value to integer.
+    SDValue FpToInt = DAG.getNode(FpToIntOpcode, dl, DstVT, BothClamped);
+
+    if (!IsSigned) {
+      // In the unsigned case we're done, because we mapped NaN to MinFloat,
+      // which is zero.
+      return FpToInt;
+    }
+
+    // Otherwise, select zero if Src is NaN.
+    SDValue ZeroInt = DAG.getConstant(0, dl, DstVT);
+    return DAG.getSelectCC(
+      dl, Src, Src, ZeroInt, FpToInt, ISD::CondCode::SETUO);
+  }
+
+  SDValue MinIntNode = DAG.getConstant(MinInt, dl, DstVT);
+  SDValue MaxIntNode = DAG.getConstant(MaxInt, dl, DstVT);
+
+  // Result of direct conversion, which may be selected away.
+  SDValue FpToInt = DAG.getNode(FpToIntOpcode, dl, TmpVT, Src);
+
+  if (DstVT != TmpVT) {
+    // NaN will become INDVAL, with the top bit set and the rest zero.
+    // Truncation will discard the top bit, resulting in zero.
+    FpToInt = DAG.getNode(ISD::TRUNCATE, dl, DstVT, FpToInt);
+  }
+
+  SDValue Select = FpToInt;
+  // For signed conversions where we saturate to the same size as the
+  // result type of the fptoi instructions, INDVAL coincides with integer
+  // minimum, so we don't need to explicitly check it.
+  if (!IsSigned || SatWidth != TmpVT.getScalarSizeInBits()) {
+    // If Src ULT MinFloat, select MinInt. In particular, this also selects
+    // MinInt if Src is NaN.
+    Select = DAG.getSelectCC(
+      dl, Src, MinFloatNode, MinIntNode, Select, ISD::CondCode::SETULT);
+  }
+
+  // If Src OGT MaxFloat, select MaxInt.
+  Select = DAG.getSelectCC(
+    dl, Src, MaxFloatNode, MaxIntNode, Select, ISD::CondCode::SETOGT);
+
+  // In the unsigned case we are done, because we mapped NaN to MinInt, which
+  // is already zero. The promoted case was already handled above.
+  if (!IsSigned || DstVT != TmpVT) {
+    return Select;
+  }
+
+  // Otherwise, select 0 if Src is NaN.
+  SDValue ZeroInt = DAG.getConstant(0, dl, DstVT);
+  return DAG.getSelectCC(
+    dl, Src, Src, ZeroInt, Select, ISD::CondCode::SETUO);
+}
+
 SDValue X86TargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
   bool IsStrict = Op->isStrictFPOpcode();
 
@@ -29807,6 +29969,8 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
   case ISD::STRICT_FP_TO_SINT:
   case ISD::FP_TO_UINT:
   case ISD::STRICT_FP_TO_UINT:  return LowerFP_TO_INT(Op, DAG);
+  case ISD::FP_TO_SINT_SAT:
+  case ISD::FP_TO_UINT_SAT:     return LowerFP_TO_INT_SAT(Op, DAG);
   case ISD::FP_EXTEND:
   case ISD::STRICT_FP_EXTEND:   return LowerFP_EXTEND(Op, DAG);
   case ISD::FP_ROUND:

diff  --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 668132239dd3..8b71c8394c01 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -1499,6 +1499,7 @@ namespace llvm {
     SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
+    SDValue LowerFP_TO_INT_SAT(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerLRINT_LLRINT(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerSETCCCARRY(SDValue Op, SelectionDAG &DAG) const;

diff  --git a/llvm/test/CodeGen/X86/fptosi-sat-scalar.ll b/llvm/test/CodeGen/X86/fptosi-sat-scalar.ll
index f7a26c6a90b7..23035a2f7e40 100644
--- a/llvm/test/CodeGen/X86/fptosi-sat-scalar.ll
+++ b/llvm/test/CodeGen/X86/fptosi-sat-scalar.ll
@@ -73,31 +73,20 @@ define i1 @test_signed_i1_f32(float %f) nounwind {
 ; X86-SSE-LABEL: test_signed_i1_f32:
 ; X86-SSE:       # %bb.0:
 ; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $255, %eax
-; X86-SSE-NEXT:    cmovael %ecx, %eax
-; X86-SSE-NEXT:    xorl %ecx, %ecx
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
 ; X86-SSE-NEXT:    xorps %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomiss %xmm1, %xmm0
-; X86-SSE-NEXT:    cmoval %ecx, %eax
-; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovpl %ecx, %eax
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $al killed $al killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_signed_i1_f32:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttss2si %xmm0, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $255, %eax
-; X64-NEXT:    cmovael %ecx, %eax
-; X64-NEXT:    xorl %ecx, %ecx
-; X64-NEXT:    xorps %xmm1, %xmm1
-; X64-NEXT:    ucomiss %xmm1, %xmm0
-; X64-NEXT:    cmoval %ecx, %eax
-; X64-NEXT:    ucomiss %xmm0, %xmm0
-; X64-NEXT:    cmovpl %ecx, %eax
+; X64-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    xorps %xmm0, %xmm0
+; X64-NEXT:    minss %xmm1, %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %eax
 ; X64-NEXT:    # kill: def $al killed $al killed $eax
 ; X64-NEXT:    retq
     %x = call i1 @llvm.fptosi.sat.i1.f32(float %f)
@@ -155,31 +144,20 @@ define i8 @test_signed_i8_f32(float %f) nounwind {
 ; X86-SSE-LABEL: test_signed_i8_f32:
 ; X86-SSE:       # %bb.0:
 ; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $128, %ecx
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $127, %edx
-; X86-SSE-NEXT:    cmovbel %ecx, %edx
-; X86-SSE-NEXT:    xorl %eax, %eax
-; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovnpl %edx, %eax
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $al killed $al killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_signed_i8_f32:
 ; X64:       # %bb.0:
+; X64-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X64-NEXT:    minss %xmm1, %xmm0
 ; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $128, %ecx
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $127, %edx
-; X64-NEXT:    cmovbel %ecx, %edx
-; X64-NEXT:    xorl %eax, %eax
-; X64-NEXT:    ucomiss %xmm0, %xmm0
-; X64-NEXT:    cmovnpl %edx, %eax
 ; X64-NEXT:    # kill: def $al killed $al killed $eax
 ; X64-NEXT:    retq
     %x = call i8 @llvm.fptosi.sat.i8.f32(float %f)
@@ -238,31 +216,20 @@ define i13 @test_signed_i13_f32(float %f) nounwind {
 ; X86-SSE-LABEL: test_signed_i13_f32:
 ; X86-SSE:       # %bb.0:
 ; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $61440, %ecx # imm = 0xF000
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $4095, %edx # imm = 0xFFF
-; X86-SSE-NEXT:    cmovbel %ecx, %edx
-; X86-SSE-NEXT:    xorl %eax, %eax
-; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovnpl %edx, %eax
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_signed_i13_f32:
 ; X64:       # %bb.0:
+; X64-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X64-NEXT:    minss %xmm1, %xmm0
 ; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $61440, %ecx # imm = 0xF000
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $4095, %edx # imm = 0xFFF
-; X64-NEXT:    cmovbel %ecx, %edx
-; X64-NEXT:    xorl %eax, %eax
-; X64-NEXT:    ucomiss %xmm0, %xmm0
-; X64-NEXT:    cmovnpl %edx, %eax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    retq
     %x = call i13 @llvm.fptosi.sat.i13.f32(float %f)
@@ -321,31 +288,20 @@ define i16 @test_signed_i16_f32(float %f) nounwind {
 ; X86-SSE-LABEL: test_signed_i16_f32:
 ; X86-SSE:       # %bb.0:
 ; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $32768, %ecx # imm = 0x8000
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $32767, %edx # imm = 0x7FFF
-; X86-SSE-NEXT:    cmovbel %ecx, %edx
-; X86-SSE-NEXT:    xorl %eax, %eax
-; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovnpl %edx, %eax
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_signed_i16_f32:
 ; X64:       # %bb.0:
+; X64-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X64-NEXT:    minss %xmm1, %xmm0
 ; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $32768, %ecx # imm = 0x8000
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $32767, %edx # imm = 0x7FFF
-; X64-NEXT:    cmovbel %ecx, %edx
-; X64-NEXT:    xorl %eax, %eax
-; X64-NEXT:    ucomiss %xmm0, %xmm0
-; X64-NEXT:    cmovnpl %edx, %eax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    retq
     %x = call i16 @llvm.fptosi.sat.i16.f32(float %f)
@@ -404,30 +360,22 @@ define i19 @test_signed_i19_f32(float %f) nounwind {
 ; X86-SSE-LABEL: test_signed_i19_f32:
 ; X86-SSE:       # %bb.0:
 ; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $-262144, %ecx # imm = 0xFFFC0000
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $262143, %edx # imm = 0x3FFFF
-; X86-SSE-NEXT:    cmovbel %ecx, %edx
 ; X86-SSE-NEXT:    xorl %eax, %eax
 ; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovnpl %edx, %eax
+; X86-SSE-NEXT:    maxss {{\.LCPI.*}}, %xmm0
+; X86-SSE-NEXT:    minss {{\.LCPI.*}}, %xmm0
+; X86-SSE-NEXT:    cvttss2si %xmm0, %ecx
+; X86-SSE-NEXT:    cmovnpl %ecx, %eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_signed_i19_f32:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $-262144, %ecx # imm = 0xFFFC0000
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $262143, %edx # imm = 0x3FFFF
-; X64-NEXT:    cmovbel %ecx, %edx
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    ucomiss %xmm0, %xmm0
-; X64-NEXT:    cmovnpl %edx, %eax
+; X64-NEXT:    maxss {{.*}}(%rip), %xmm0
+; X64-NEXT:    minss {{.*}}(%rip), %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %ecx
+; X64-NEXT:    cmovnpl %ecx, %eax
 ; X64-NEXT:    retq
     %x = call i19 @llvm.fptosi.sat.i19.f32(float %f)
     ret i19 %x
@@ -487,28 +435,22 @@ define i32 @test_signed_i32_f32(float %f) nounwind {
 ; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
 ; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $-2147483648, %ecx # imm = 0x80000000
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $2147483647, %edx # imm = 0x7FFFFFFF
-; X86-SSE-NEXT:    cmovbel %ecx, %edx
+; X86-SSE-NEXT:    movl $2147483647, %ecx # imm = 0x7FFFFFFF
+; X86-SSE-NEXT:    cmovbel %eax, %ecx
 ; X86-SSE-NEXT:    xorl %eax, %eax
 ; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovnpl %edx, %eax
+; X86-SSE-NEXT:    cmovnpl %ecx, %eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_signed_i32_f32:
 ; X64:       # %bb.0:
 ; X64-NEXT:    cvttss2si %xmm0, %eax
 ; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $-2147483648, %ecx # imm = 0x80000000
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $2147483647, %edx # imm = 0x7FFFFFFF
-; X64-NEXT:    cmovbel %ecx, %edx
+; X64-NEXT:    movl $2147483647, %ecx # imm = 0x7FFFFFFF
+; X64-NEXT:    cmovbel %eax, %ecx
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    ucomiss %xmm0, %xmm0
-; X64-NEXT:    cmovnpl %edx, %eax
+; X64-NEXT:    cmovnpl %ecx, %eax
 ; X64-NEXT:    retq
     %x = call i32 @llvm.fptosi.sat.i32.f32(float %f)
     ret i32 %x
@@ -731,14 +673,11 @@ define i64 @test_signed_i64_f32(float %f) nounwind {
 ; X64:       # %bb.0:
 ; X64-NEXT:    cvttss2si %xmm0, %rax
 ; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000
-; X64-NEXT:    cmovaeq %rax, %rcx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movabsq $9223372036854775807, %rdx # imm = 0x7FFFFFFFFFFFFFFF
-; X64-NEXT:    cmovbeq %rcx, %rdx
+; X64-NEXT:    movabsq $9223372036854775807, %rcx # imm = 0x7FFFFFFFFFFFFFFF
+; X64-NEXT:    cmovbeq %rax, %rcx
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    ucomiss %xmm0, %xmm0
-; X64-NEXT:    cmovnpq %rdx, %rax
+; X64-NEXT:    cmovnpq %rcx, %rax
 ; X64-NEXT:    retq
     %x = call i64 @llvm.fptosi.sat.i64.f32(float %f)
     ret i64 %x
@@ -1154,31 +1093,20 @@ define i1 @test_signed_i1_f64(double %f) nounwind {
 ; X86-SSE-LABEL: test_signed_i1_f64:
 ; X86-SSE:       # %bb.0:
 ; X86-SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; X86-SSE-NEXT:    cvttsd2si %xmm0, %ecx
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $255, %eax
-; X86-SSE-NEXT:    cmovael %ecx, %eax
-; X86-SSE-NEXT:    xorl %ecx, %ecx
+; X86-SSE-NEXT:    maxsd {{[0-9]+}}(%esp), %xmm0
 ; X86-SSE-NEXT:    xorpd %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomisd %xmm1, %xmm0
-; X86-SSE-NEXT:    cmoval %ecx, %eax
-; X86-SSE-NEXT:    ucomisd %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovpl %ecx, %eax
+; X86-SSE-NEXT:    minsd %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttsd2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $al killed $al killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_signed_i1_f64:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttsd2si %xmm0, %ecx
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $255, %eax
-; X64-NEXT:    cmovael %ecx, %eax
-; X64-NEXT:    xorl %ecx, %ecx
-; X64-NEXT:    xorpd %xmm1, %xmm1
-; X64-NEXT:    ucomisd %xmm1, %xmm0
-; X64-NEXT:    cmoval %ecx, %eax
-; X64-NEXT:    ucomisd %xmm0, %xmm0
-; X64-NEXT:    cmovpl %ecx, %eax
+; X64-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
+; X64-NEXT:    maxsd %xmm0, %xmm1
+; X64-NEXT:    xorpd %xmm0, %xmm0
+; X64-NEXT:    minsd %xmm1, %xmm0
+; X64-NEXT:    cvttsd2si %xmm0, %eax
 ; X64-NEXT:    # kill: def $al killed $al killed $eax
 ; X64-NEXT:    retq
     %x = call i1 @llvm.fptosi.sat.i1.f64(double %f)
@@ -1236,31 +1164,20 @@ define i8 @test_signed_i8_f64(double %f) nounwind {
 ; X86-SSE-LABEL: test_signed_i8_f64:
 ; X86-SSE:       # %bb.0:
 ; X86-SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; X86-SSE-NEXT:    cvttsd2si %xmm0, %eax
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $128, %ecx
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $127, %edx
-; X86-SSE-NEXT:    cmovbel %ecx, %edx
-; X86-SSE-NEXT:    xorl %eax, %eax
-; X86-SSE-NEXT:    ucomisd %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovnpl %edx, %eax
+; X86-SSE-NEXT:    maxsd {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
+; X86-SSE-NEXT:    minsd %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttsd2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $al killed $al killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_signed_i8_f64:
 ; X64:       # %bb.0:
+; X64-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
+; X64-NEXT:    maxsd %xmm0, %xmm1
+; X64-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; X64-NEXT:    minsd %xmm1, %xmm0
 ; X64-NEXT:    cvttsd2si %xmm0, %eax
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $128, %ecx
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $127, %edx
-; X64-NEXT:    cmovbel %ecx, %edx
-; X64-NEXT:    xorl %eax, %eax
-; X64-NEXT:    ucomisd %xmm0, %xmm0
-; X64-NEXT:    cmovnpl %edx, %eax
 ; X64-NEXT:    # kill: def $al killed $al killed $eax
 ; X64-NEXT:    retq
     %x = call i8 @llvm.fptosi.sat.i8.f64(double %f)
@@ -1319,31 +1236,20 @@ define i13 @test_signed_i13_f64(double %f) nounwind {
 ; X86-SSE-LABEL: test_signed_i13_f64:
 ; X86-SSE:       # %bb.0:
 ; X86-SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; X86-SSE-NEXT:    cvttsd2si %xmm0, %eax
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $61440, %ecx # imm = 0xF000
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $4095, %edx # imm = 0xFFF
-; X86-SSE-NEXT:    cmovbel %ecx, %edx
-; X86-SSE-NEXT:    xorl %eax, %eax
-; X86-SSE-NEXT:    ucomisd %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovnpl %edx, %eax
+; X86-SSE-NEXT:    maxsd {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
+; X86-SSE-NEXT:    minsd %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttsd2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_signed_i13_f64:
 ; X64:       # %bb.0:
+; X64-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
+; X64-NEXT:    maxsd %xmm0, %xmm1
+; X64-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; X64-NEXT:    minsd %xmm1, %xmm0
 ; X64-NEXT:    cvttsd2si %xmm0, %eax
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $61440, %ecx # imm = 0xF000
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $4095, %edx # imm = 0xFFF
-; X64-NEXT:    cmovbel %ecx, %edx
-; X64-NEXT:    xorl %eax, %eax
-; X64-NEXT:    ucomisd %xmm0, %xmm0
-; X64-NEXT:    cmovnpl %edx, %eax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    retq
     %x = call i13 @llvm.fptosi.sat.i13.f64(double %f)
@@ -1402,31 +1308,20 @@ define i16 @test_signed_i16_f64(double %f) nounwind {
 ; X86-SSE-LABEL: test_signed_i16_f64:
 ; X86-SSE:       # %bb.0:
 ; X86-SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; X86-SSE-NEXT:    cvttsd2si %xmm0, %eax
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $32768, %ecx # imm = 0x8000
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $32767, %edx # imm = 0x7FFF
-; X86-SSE-NEXT:    cmovbel %ecx, %edx
-; X86-SSE-NEXT:    xorl %eax, %eax
-; X86-SSE-NEXT:    ucomisd %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovnpl %edx, %eax
+; X86-SSE-NEXT:    maxsd {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
+; X86-SSE-NEXT:    minsd %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttsd2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_signed_i16_f64:
 ; X64:       # %bb.0:
+; X64-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
+; X64-NEXT:    maxsd %xmm0, %xmm1
+; X64-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; X64-NEXT:    minsd %xmm1, %xmm0
 ; X64-NEXT:    cvttsd2si %xmm0, %eax
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $32768, %ecx # imm = 0x8000
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $32767, %edx # imm = 0x7FFF
-; X64-NEXT:    cmovbel %ecx, %edx
-; X64-NEXT:    xorl %eax, %eax
-; X64-NEXT:    ucomisd %xmm0, %xmm0
-; X64-NEXT:    cmovnpl %edx, %eax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    retq
     %x = call i16 @llvm.fptosi.sat.i16.f64(double %f)
@@ -1485,30 +1380,22 @@ define i19 @test_signed_i19_f64(double %f) nounwind {
 ; X86-SSE-LABEL: test_signed_i19_f64:
 ; X86-SSE:       # %bb.0:
 ; X86-SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; X86-SSE-NEXT:    cvttsd2si %xmm0, %eax
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $-262144, %ecx # imm = 0xFFFC0000
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $262143, %edx # imm = 0x3FFFF
-; X86-SSE-NEXT:    cmovbel %ecx, %edx
 ; X86-SSE-NEXT:    xorl %eax, %eax
 ; X86-SSE-NEXT:    ucomisd %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovnpl %edx, %eax
+; X86-SSE-NEXT:    maxsd {{\.LCPI.*}}, %xmm0
+; X86-SSE-NEXT:    minsd {{\.LCPI.*}}, %xmm0
+; X86-SSE-NEXT:    cvttsd2si %xmm0, %ecx
+; X86-SSE-NEXT:    cmovnpl %ecx, %eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_signed_i19_f64:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttsd2si %xmm0, %eax
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $-262144, %ecx # imm = 0xFFFC0000
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $262143, %edx # imm = 0x3FFFF
-; X64-NEXT:    cmovbel %ecx, %edx
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    ucomisd %xmm0, %xmm0
-; X64-NEXT:    cmovnpl %edx, %eax
+; X64-NEXT:    maxsd {{.*}}(%rip), %xmm0
+; X64-NEXT:    minsd {{.*}}(%rip), %xmm0
+; X64-NEXT:    cvttsd2si %xmm0, %ecx
+; X64-NEXT:    cmovnpl %ecx, %eax
 ; X64-NEXT:    retq
     %x = call i19 @llvm.fptosi.sat.i19.f64(double %f)
     ret i19 %x
@@ -1566,30 +1453,22 @@ define i32 @test_signed_i32_f64(double %f) nounwind {
 ; X86-SSE-LABEL: test_signed_i32_f64:
 ; X86-SSE:       # %bb.0:
 ; X86-SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; X86-SSE-NEXT:    cvttsd2si %xmm0, %eax
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $-2147483648, %ecx # imm = 0x80000000
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $2147483647, %edx # imm = 0x7FFFFFFF
-; X86-SSE-NEXT:    cmovbel %ecx, %edx
 ; X86-SSE-NEXT:    xorl %eax, %eax
 ; X86-SSE-NEXT:    ucomisd %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovnpl %edx, %eax
+; X86-SSE-NEXT:    maxsd {{\.LCPI.*}}, %xmm0
+; X86-SSE-NEXT:    minsd {{\.LCPI.*}}, %xmm0
+; X86-SSE-NEXT:    cvttsd2si %xmm0, %ecx
+; X86-SSE-NEXT:    cmovnpl %ecx, %eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_signed_i32_f64:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttsd2si %xmm0, %eax
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $-2147483648, %ecx # imm = 0x80000000
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $2147483647, %edx # imm = 0x7FFFFFFF
-; X64-NEXT:    cmovbel %ecx, %edx
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    ucomisd %xmm0, %xmm0
-; X64-NEXT:    cmovnpl %edx, %eax
+; X64-NEXT:    maxsd {{.*}}(%rip), %xmm0
+; X64-NEXT:    minsd {{.*}}(%rip), %xmm0
+; X64-NEXT:    cvttsd2si %xmm0, %ecx
+; X64-NEXT:    cmovnpl %ecx, %eax
 ; X64-NEXT:    retq
     %x = call i32 @llvm.fptosi.sat.i32.f64(double %f)
     ret i32 %x
@@ -1695,16 +1574,12 @@ define i50 @test_signed_i50_f64(double %f) nounwind {
 ;
 ; X64-LABEL: test_signed_i50_f64:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttsd2si %xmm0, %rax
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movabsq $-562949953421312, %rcx # imm = 0xFFFE000000000000
-; X64-NEXT:    cmovaeq %rax, %rcx
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movabsq $562949953421311, %rdx # imm = 0x1FFFFFFFFFFFF
-; X64-NEXT:    cmovbeq %rcx, %rdx
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    ucomisd %xmm0, %xmm0
-; X64-NEXT:    cmovnpq %rdx, %rax
+; X64-NEXT:    maxsd {{.*}}(%rip), %xmm0
+; X64-NEXT:    minsd {{.*}}(%rip), %xmm0
+; X64-NEXT:    cvttsd2si %xmm0, %rcx
+; X64-NEXT:    cmovnpq %rcx, %rax
 ; X64-NEXT:    retq
     %x = call i50 @llvm.fptosi.sat.i50.f64(double %f)
     ret i50 %x
@@ -1812,14 +1687,11 @@ define i64 @test_signed_i64_f64(double %f) nounwind {
 ; X64:       # %bb.0:
 ; X64-NEXT:    cvttsd2si %xmm0, %rax
 ; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000
-; X64-NEXT:    cmovaeq %rax, %rcx
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movabsq $9223372036854775807, %rdx # imm = 0x7FFFFFFFFFFFFFFF
-; X64-NEXT:    cmovbeq %rcx, %rdx
+; X64-NEXT:    movabsq $9223372036854775807, %rcx # imm = 0x7FFFFFFFFFFFFFFF
+; X64-NEXT:    cmovbeq %rax, %rcx
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    ucomisd %xmm0, %xmm0
-; X64-NEXT:    cmovnpq %rdx, %rax
+; X64-NEXT:    cmovnpq %rcx, %rax
 ; X64-NEXT:    retq
     %x = call i64 @llvm.fptosi.sat.i64.f64(double %f)
     ret i64 %x
@@ -2242,16 +2114,10 @@ define i1 @test_signed_i1_f16(half %f) nounwind {
 ; X86-SSE-NEXT:    calll __gnu_h2f_ieee
 ; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $255, %eax
-; X86-SSE-NEXT:    cmovael %ecx, %eax
-; X86-SSE-NEXT:    xorl %ecx, %ecx
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
 ; X86-SSE-NEXT:    xorps %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomiss %xmm1, %xmm0
-; X86-SSE-NEXT:    cmoval %ecx, %eax
-; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovpl %ecx, %eax
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $al killed $al killed $eax
 ; X86-SSE-NEXT:    addl $12, %esp
 ; X86-SSE-NEXT:    retl
@@ -2261,16 +2127,11 @@ define i1 @test_signed_i1_f16(half %f) nounwind {
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    movzwl %di, %edi
 ; X64-NEXT:    callq __gnu_h2f_ieee at PLT
-; X64-NEXT:    cvttss2si %xmm0, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $255, %eax
-; X64-NEXT:    cmovael %ecx, %eax
-; X64-NEXT:    xorl %ecx, %ecx
-; X64-NEXT:    xorps %xmm1, %xmm1
-; X64-NEXT:    ucomiss %xmm1, %xmm0
-; X64-NEXT:    cmoval %ecx, %eax
-; X64-NEXT:    ucomiss %xmm0, %xmm0
-; X64-NEXT:    cmovpl %ecx, %eax
+; X64-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    xorps %xmm0, %xmm0
+; X64-NEXT:    minss %xmm1, %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %eax
 ; X64-NEXT:    # kill: def $al killed $al killed $eax
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
@@ -2336,16 +2197,10 @@ define i8 @test_signed_i8_f16(half %f) nounwind {
 ; X86-SSE-NEXT:    calll __gnu_h2f_ieee
 ; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $128, %ecx
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $127, %edx
-; X86-SSE-NEXT:    cmovbel %ecx, %edx
-; X86-SSE-NEXT:    xorl %eax, %eax
-; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovnpl %edx, %eax
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $al killed $al killed $eax
 ; X86-SSE-NEXT:    addl $12, %esp
 ; X86-SSE-NEXT:    retl
@@ -2355,16 +2210,11 @@ define i8 @test_signed_i8_f16(half %f) nounwind {
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    movzwl %di, %edi
 ; X64-NEXT:    callq __gnu_h2f_ieee at PLT
+; X64-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X64-NEXT:    minss %xmm1, %xmm0
 ; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $128, %ecx
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $127, %edx
-; X64-NEXT:    cmovbel %ecx, %edx
-; X64-NEXT:    xorl %eax, %eax
-; X64-NEXT:    ucomiss %xmm0, %xmm0
-; X64-NEXT:    cmovnpl %edx, %eax
 ; X64-NEXT:    # kill: def $al killed $al killed $eax
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
@@ -2431,16 +2281,10 @@ define i13 @test_signed_i13_f16(half %f) nounwind {
 ; X86-SSE-NEXT:    calll __gnu_h2f_ieee
 ; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $61440, %ecx # imm = 0xF000
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $4095, %edx # imm = 0xFFF
-; X86-SSE-NEXT:    cmovbel %ecx, %edx
-; X86-SSE-NEXT:    xorl %eax, %eax
-; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovnpl %edx, %eax
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-SSE-NEXT:    addl $12, %esp
 ; X86-SSE-NEXT:    retl
@@ -2450,16 +2294,11 @@ define i13 @test_signed_i13_f16(half %f) nounwind {
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    movzwl %di, %edi
 ; X64-NEXT:    callq __gnu_h2f_ieee at PLT
+; X64-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X64-NEXT:    minss %xmm1, %xmm0
 ; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $61440, %ecx # imm = 0xF000
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $4095, %edx # imm = 0xFFF
-; X64-NEXT:    cmovbel %ecx, %edx
-; X64-NEXT:    xorl %eax, %eax
-; X64-NEXT:    ucomiss %xmm0, %xmm0
-; X64-NEXT:    cmovnpl %edx, %eax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
@@ -2526,16 +2365,10 @@ define i16 @test_signed_i16_f16(half %f) nounwind {
 ; X86-SSE-NEXT:    calll __gnu_h2f_ieee
 ; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $32768, %ecx # imm = 0x8000
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $32767, %edx # imm = 0x7FFF
-; X86-SSE-NEXT:    cmovbel %ecx, %edx
-; X86-SSE-NEXT:    xorl %eax, %eax
-; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovnpl %edx, %eax
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-SSE-NEXT:    addl $12, %esp
 ; X86-SSE-NEXT:    retl
@@ -2545,16 +2378,11 @@ define i16 @test_signed_i16_f16(half %f) nounwind {
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    movzwl %di, %edi
 ; X64-NEXT:    callq __gnu_h2f_ieee at PLT
+; X64-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X64-NEXT:    minss %xmm1, %xmm0
 ; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $32768, %ecx # imm = 0x8000
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $32767, %edx # imm = 0x7FFF
-; X64-NEXT:    cmovbel %ecx, %edx
-; X64-NEXT:    xorl %eax, %eax
-; X64-NEXT:    ucomiss %xmm0, %xmm0
-; X64-NEXT:    cmovnpl %edx, %eax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
@@ -2621,16 +2449,12 @@ define i19 @test_signed_i19_f16(half %f) nounwind {
 ; X86-SSE-NEXT:    calll __gnu_h2f_ieee
 ; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $-262144, %ecx # imm = 0xFFFC0000
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $262143, %edx # imm = 0x3FFFF
-; X86-SSE-NEXT:    cmovbel %ecx, %edx
 ; X86-SSE-NEXT:    xorl %eax, %eax
 ; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovnpl %edx, %eax
+; X86-SSE-NEXT:    maxss {{\.LCPI.*}}, %xmm0
+; X86-SSE-NEXT:    minss {{\.LCPI.*}}, %xmm0
+; X86-SSE-NEXT:    cvttss2si %xmm0, %ecx
+; X86-SSE-NEXT:    cmovnpl %ecx, %eax
 ; X86-SSE-NEXT:    addl $12, %esp
 ; X86-SSE-NEXT:    retl
 ;
@@ -2639,16 +2463,12 @@ define i19 @test_signed_i19_f16(half %f) nounwind {
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    movzwl %di, %edi
 ; X64-NEXT:    callq __gnu_h2f_ieee at PLT
-; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $-262144, %ecx # imm = 0xFFFC0000
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $262143, %edx # imm = 0x3FFFF
-; X64-NEXT:    cmovbel %ecx, %edx
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    ucomiss %xmm0, %xmm0
-; X64-NEXT:    cmovnpl %edx, %eax
+; X64-NEXT:    maxss {{.*}}(%rip), %xmm0
+; X64-NEXT:    minss {{.*}}(%rip), %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %ecx
+; X64-NEXT:    cmovnpl %ecx, %eax
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
     %x = call i19 @llvm.fptosi.sat.i19.f16(half %f)
@@ -2716,14 +2536,11 @@ define i32 @test_signed_i32_f16(half %f) nounwind {
 ; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
 ; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $-2147483648, %ecx # imm = 0x80000000
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $2147483647, %edx # imm = 0x7FFFFFFF
-; X86-SSE-NEXT:    cmovbel %ecx, %edx
+; X86-SSE-NEXT:    movl $2147483647, %ecx # imm = 0x7FFFFFFF
+; X86-SSE-NEXT:    cmovbel %eax, %ecx
 ; X86-SSE-NEXT:    xorl %eax, %eax
 ; X86-SSE-NEXT:    ucomiss %xmm0, %xmm0
-; X86-SSE-NEXT:    cmovnpl %edx, %eax
+; X86-SSE-NEXT:    cmovnpl %ecx, %eax
 ; X86-SSE-NEXT:    addl $12, %esp
 ; X86-SSE-NEXT:    retl
 ;
@@ -2734,14 +2551,11 @@ define i32 @test_signed_i32_f16(half %f) nounwind {
 ; X64-NEXT:    callq __gnu_h2f_ieee at PLT
 ; X64-NEXT:    cvttss2si %xmm0, %eax
 ; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $-2147483648, %ecx # imm = 0x80000000
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $2147483647, %edx # imm = 0x7FFFFFFF
-; X64-NEXT:    cmovbel %ecx, %edx
+; X64-NEXT:    movl $2147483647, %ecx # imm = 0x7FFFFFFF
+; X64-NEXT:    cmovbel %eax, %ecx
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    ucomiss %xmm0, %xmm0
-; X64-NEXT:    cmovnpl %edx, %eax
+; X64-NEXT:    cmovnpl %ecx, %eax
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
     %x = call i32 @llvm.fptosi.sat.i32.f16(half %f)
@@ -2984,14 +2798,11 @@ define i64 @test_signed_i64_f16(half %f) nounwind {
 ; X64-NEXT:    callq __gnu_h2f_ieee at PLT
 ; X64-NEXT:    cvttss2si %xmm0, %rax
 ; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000
-; X64-NEXT:    cmovaeq %rax, %rcx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movabsq $9223372036854775807, %rdx # imm = 0x7FFFFFFFFFFFFFFF
-; X64-NEXT:    cmovbeq %rcx, %rdx
+; X64-NEXT:    movabsq $9223372036854775807, %rcx # imm = 0x7FFFFFFFFFFFFFFF
+; X64-NEXT:    cmovbeq %rax, %rcx
 ; X64-NEXT:    xorl %eax, %eax
 ; X64-NEXT:    ucomiss %xmm0, %xmm0
-; X64-NEXT:    cmovnpq %rdx, %rax
+; X64-NEXT:    cmovnpq %rcx, %rax
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
     %x = call i64 @llvm.fptosi.sat.i64.f16(half %f)

diff  --git a/llvm/test/CodeGen/X86/fptoui-sat-scalar.ll b/llvm/test/CodeGen/X86/fptoui-sat-scalar.ll
index 3b74e639eb42..294189815c49 100644
--- a/llvm/test/CodeGen/X86/fptoui-sat-scalar.ll
+++ b/llvm/test/CodeGen/X86/fptoui-sat-scalar.ll
@@ -60,28 +60,21 @@ define i1 @test_unsigned_i1_f32(float %f) nounwind {
 ;
 ; X86-SSE-LABEL: test_unsigned_i1_f32:
 ; X86-SSE:       # %bb.0:
-; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    xorl %ecx, %ecx
-; X86-SSE-NEXT:    xorps %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomiss %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $1, %eax
-; X86-SSE-NEXT:    cmovbel %ecx, %eax
+; X86-SSE-NEXT:    xorps %xmm0, %xmm0
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $al killed $al killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_unsigned_i1_f32:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorps %xmm1, %xmm1
-; X64-NEXT:    ucomiss %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $1, %eax
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X64-NEXT:    minss %xmm1, %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %eax
 ; X64-NEXT:    # kill: def $al killed $al killed $eax
 ; X64-NEXT:    retq
     %x = call i1 @llvm.fptoui.sat.i1.f32(float %f)
@@ -130,28 +123,21 @@ define i8 @test_unsigned_i8_f32(float %f) nounwind {
 ;
 ; X86-SSE-LABEL: test_unsigned_i8_f32:
 ; X86-SSE:       # %bb.0:
-; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    xorl %ecx, %ecx
-; X86-SSE-NEXT:    xorps %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomiss %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $255, %eax
-; X86-SSE-NEXT:    cmovbel %ecx, %eax
+; X86-SSE-NEXT:    xorps %xmm0, %xmm0
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $al killed $al killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_unsigned_i8_f32:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorps %xmm1, %xmm1
-; X64-NEXT:    ucomiss %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $255, %eax
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X64-NEXT:    minss %xmm1, %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %eax
 ; X64-NEXT:    # kill: def $al killed $al killed $eax
 ; X64-NEXT:    retq
     %x = call i8 @llvm.fptoui.sat.i8.f32(float %f)
@@ -199,28 +185,21 @@ define i13 @test_unsigned_i13_f32(float %f) nounwind {
 ;
 ; X86-SSE-LABEL: test_unsigned_i13_f32:
 ; X86-SSE:       # %bb.0:
-; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    xorl %ecx, %ecx
-; X86-SSE-NEXT:    xorps %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomiss %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $8191, %eax # imm = 0x1FFF
-; X86-SSE-NEXT:    cmovbel %ecx, %eax
+; X86-SSE-NEXT:    xorps %xmm0, %xmm0
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_unsigned_i13_f32:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorps %xmm1, %xmm1
-; X64-NEXT:    ucomiss %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $8191, %eax # imm = 0x1FFF
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X64-NEXT:    minss %xmm1, %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %eax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    retq
     %x = call i13 @llvm.fptoui.sat.i13.f32(float %f)
@@ -268,28 +247,21 @@ define i16 @test_unsigned_i16_f32(float %f) nounwind {
 ;
 ; X86-SSE-LABEL: test_unsigned_i16_f32:
 ; X86-SSE:       # %bb.0:
-; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    xorl %ecx, %ecx
-; X86-SSE-NEXT:    xorps %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomiss %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $65535, %eax # imm = 0xFFFF
-; X86-SSE-NEXT:    cmovbel %ecx, %eax
+; X86-SSE-NEXT:    xorps %xmm0, %xmm0
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_unsigned_i16_f32:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorps %xmm1, %xmm1
-; X64-NEXT:    ucomiss %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $65535, %eax # imm = 0xFFFF
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X64-NEXT:    minss %xmm1, %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %eax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    retq
     %x = call i16 @llvm.fptoui.sat.i16.f32(float %f)
@@ -338,33 +310,18 @@ define i19 @test_unsigned_i19_f32(float %f) nounwind {
 ; X86-SSE-LABEL: test_unsigned_i19_f32:
 ; X86-SSE:       # %bb.0:
 ; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    movaps %xmm0, %xmm2
-; X86-SSE-NEXT:    subss %xmm1, %xmm2
-; X86-SSE-NEXT:    cvttss2si %xmm2, %eax
-; X86-SSE-NEXT:    xorl $-2147483648, %eax # imm = 0x80000000
-; X86-SSE-NEXT:    cvttss2si %xmm0, %ecx
-; X86-SSE-NEXT:    ucomiss %xmm0, %xmm1
-; X86-SSE-NEXT:    cmovbel %eax, %ecx
-; X86-SSE-NEXT:    xorl %edx, %edx
 ; X86-SSE-NEXT:    xorps %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomiss %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %ecx, %edx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $524287, %eax # imm = 0x7FFFF
-; X86-SSE-NEXT:    cmovbel %edx, %eax
+; X86-SSE-NEXT:    maxss %xmm1, %xmm0
+; X86-SSE-NEXT:    minss {{\.LCPI.*}}, %xmm0
+; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_unsigned_i19_f32:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttss2si %xmm0, %rax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorps %xmm1, %xmm1
-; X64-NEXT:    ucomiss %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $524287, %eax # imm = 0x7FFFF
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxss %xmm1, %xmm0
+; X64-NEXT:    minss {{.*}}(%rip), %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %eax
 ; X64-NEXT:    retq
     %x = call i19 @llvm.fptoui.sat.i19.f32(float %f)
     ret i19 %x
@@ -557,15 +514,7 @@ define i50 @test_unsigned_i50_f32(float %f) nounwind {
 ;
 ; X64-LABEL: test_unsigned_i50_f32:
 ; X64:       # %bb.0:
-; X64-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
-; X64-NEXT:    movaps %xmm0, %xmm2
-; X64-NEXT:    subss %xmm1, %xmm2
-; X64-NEXT:    cvttss2si %xmm2, %rax
-; X64-NEXT:    movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000
-; X64-NEXT:    xorq %rax, %rcx
 ; X64-NEXT:    cvttss2si %xmm0, %rax
-; X64-NEXT:    ucomiss %xmm1, %xmm0
-; X64-NEXT:    cmovaeq %rcx, %rax
 ; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorps %xmm1, %xmm1
 ; X64-NEXT:    ucomiss %xmm1, %xmm0
@@ -1047,28 +996,21 @@ define i1 @test_unsigned_i1_f64(double %f) nounwind {
 ;
 ; X86-SSE-LABEL: test_unsigned_i1_f64:
 ; X86-SSE:       # %bb.0:
-; X86-SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; X86-SSE-NEXT:    cvttsd2si %xmm0, %eax
-; X86-SSE-NEXT:    xorl %ecx, %ecx
-; X86-SSE-NEXT:    xorpd %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomisd %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $1, %eax
-; X86-SSE-NEXT:    cmovbel %ecx, %eax
+; X86-SSE-NEXT:    xorpd %xmm0, %xmm0
+; X86-SSE-NEXT:    maxsd {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
+; X86-SSE-NEXT:    minsd %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttsd2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $al killed $al killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_unsigned_i1_f64:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttsd2si %xmm0, %eax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorpd %xmm1, %xmm1
-; X64-NEXT:    ucomisd %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $1, %eax
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxsd %xmm0, %xmm1
+; X64-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; X64-NEXT:    minsd %xmm1, %xmm0
+; X64-NEXT:    cvttsd2si %xmm0, %eax
 ; X64-NEXT:    # kill: def $al killed $al killed $eax
 ; X64-NEXT:    retq
     %x = call i1 @llvm.fptoui.sat.i1.f64(double %f)
@@ -1117,28 +1059,21 @@ define i8 @test_unsigned_i8_f64(double %f) nounwind {
 ;
 ; X86-SSE-LABEL: test_unsigned_i8_f64:
 ; X86-SSE:       # %bb.0:
-; X86-SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; X86-SSE-NEXT:    cvttsd2si %xmm0, %eax
-; X86-SSE-NEXT:    xorl %ecx, %ecx
-; X86-SSE-NEXT:    xorpd %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomisd %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $255, %eax
-; X86-SSE-NEXT:    cmovbel %ecx, %eax
+; X86-SSE-NEXT:    xorpd %xmm0, %xmm0
+; X86-SSE-NEXT:    maxsd {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
+; X86-SSE-NEXT:    minsd %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttsd2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $al killed $al killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_unsigned_i8_f64:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttsd2si %xmm0, %eax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorpd %xmm1, %xmm1
-; X64-NEXT:    ucomisd %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $255, %eax
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxsd %xmm0, %xmm1
+; X64-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; X64-NEXT:    minsd %xmm1, %xmm0
+; X64-NEXT:    cvttsd2si %xmm0, %eax
 ; X64-NEXT:    # kill: def $al killed $al killed $eax
 ; X64-NEXT:    retq
     %x = call i8 @llvm.fptoui.sat.i8.f64(double %f)
@@ -1186,28 +1121,21 @@ define i13 @test_unsigned_i13_f64(double %f) nounwind {
 ;
 ; X86-SSE-LABEL: test_unsigned_i13_f64:
 ; X86-SSE:       # %bb.0:
-; X86-SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; X86-SSE-NEXT:    cvttsd2si %xmm0, %eax
-; X86-SSE-NEXT:    xorl %ecx, %ecx
-; X86-SSE-NEXT:    xorpd %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomisd %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $8191, %eax # imm = 0x1FFF
-; X86-SSE-NEXT:    cmovbel %ecx, %eax
+; X86-SSE-NEXT:    xorpd %xmm0, %xmm0
+; X86-SSE-NEXT:    maxsd {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
+; X86-SSE-NEXT:    minsd %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttsd2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_unsigned_i13_f64:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttsd2si %xmm0, %eax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorpd %xmm1, %xmm1
-; X64-NEXT:    ucomisd %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $8191, %eax # imm = 0x1FFF
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxsd %xmm0, %xmm1
+; X64-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; X64-NEXT:    minsd %xmm1, %xmm0
+; X64-NEXT:    cvttsd2si %xmm0, %eax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    retq
     %x = call i13 @llvm.fptoui.sat.i13.f64(double %f)
@@ -1255,28 +1183,21 @@ define i16 @test_unsigned_i16_f64(double %f) nounwind {
 ;
 ; X86-SSE-LABEL: test_unsigned_i16_f64:
 ; X86-SSE:       # %bb.0:
-; X86-SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; X86-SSE-NEXT:    cvttsd2si %xmm0, %eax
-; X86-SSE-NEXT:    xorl %ecx, %ecx
-; X86-SSE-NEXT:    xorpd %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomisd %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $65535, %eax # imm = 0xFFFF
-; X86-SSE-NEXT:    cmovbel %ecx, %eax
+; X86-SSE-NEXT:    xorpd %xmm0, %xmm0
+; X86-SSE-NEXT:    maxsd {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
+; X86-SSE-NEXT:    minsd %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttsd2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_unsigned_i16_f64:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttsd2si %xmm0, %eax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorpd %xmm1, %xmm1
-; X64-NEXT:    ucomisd %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $65535, %eax # imm = 0xFFFF
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxsd %xmm0, %xmm1
+; X64-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; X64-NEXT:    minsd %xmm1, %xmm0
+; X64-NEXT:    cvttsd2si %xmm0, %eax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    retq
     %x = call i16 @llvm.fptoui.sat.i16.f64(double %f)
@@ -1325,33 +1246,18 @@ define i19 @test_unsigned_i19_f64(double %f) nounwind {
 ; X86-SSE-LABEL: test_unsigned_i19_f64:
 ; X86-SSE:       # %bb.0:
 ; X86-SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; X86-SSE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
-; X86-SSE-NEXT:    movapd %xmm0, %xmm2
-; X86-SSE-NEXT:    subsd %xmm1, %xmm2
-; X86-SSE-NEXT:    cvttsd2si %xmm2, %eax
-; X86-SSE-NEXT:    xorl $-2147483648, %eax # imm = 0x80000000
-; X86-SSE-NEXT:    cvttsd2si %xmm0, %ecx
-; X86-SSE-NEXT:    ucomisd %xmm0, %xmm1
-; X86-SSE-NEXT:    cmovbel %eax, %ecx
-; X86-SSE-NEXT:    xorl %edx, %edx
 ; X86-SSE-NEXT:    xorpd %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomisd %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %ecx, %edx
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $524287, %eax # imm = 0x7FFFF
-; X86-SSE-NEXT:    cmovbel %edx, %eax
+; X86-SSE-NEXT:    maxsd %xmm1, %xmm0
+; X86-SSE-NEXT:    minsd {{\.LCPI.*}}, %xmm0
+; X86-SSE-NEXT:    cvttsd2si %xmm0, %eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_unsigned_i19_f64:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttsd2si %xmm0, %rax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorpd %xmm1, %xmm1
-; X64-NEXT:    ucomisd %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $524287, %eax # imm = 0x7FFFF
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxsd %xmm1, %xmm0
+; X64-NEXT:    minsd {{.*}}(%rip), %xmm0
+; X64-NEXT:    cvttsd2si %xmm0, %eax
 ; X64-NEXT:    retq
     %x = call i19 @llvm.fptoui.sat.i19.f64(double %f)
     ret i19 %x
@@ -1399,33 +1305,27 @@ define i32 @test_unsigned_i32_f64(double %f) nounwind {
 ; X86-SSE-LABEL: test_unsigned_i32_f64:
 ; X86-SSE:       # %bb.0:
 ; X86-SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; X86-SSE-NEXT:    xorpd %xmm1, %xmm1
+; X86-SSE-NEXT:    maxsd %xmm1, %xmm0
+; X86-SSE-NEXT:    minsd {{\.LCPI.*}}, %xmm0
+; X86-SSE-NEXT:    cvttsd2si %xmm0, %ecx
 ; X86-SSE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
 ; X86-SSE-NEXT:    movapd %xmm0, %xmm2
 ; X86-SSE-NEXT:    subsd %xmm1, %xmm2
 ; X86-SSE-NEXT:    cvttsd2si %xmm2, %eax
 ; X86-SSE-NEXT:    xorl $-2147483648, %eax # imm = 0x80000000
-; X86-SSE-NEXT:    cvttsd2si %xmm0, %ecx
-; X86-SSE-NEXT:    ucomisd %xmm0, %xmm1
-; X86-SSE-NEXT:    cmovbel %eax, %ecx
-; X86-SSE-NEXT:    xorl %edx, %edx
-; X86-SSE-NEXT:    xorpd %xmm1, %xmm1
 ; X86-SSE-NEXT:    ucomisd %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %ecx, %edx
-; X86-SSE-NEXT:    ucomisd {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $-1, %eax
-; X86-SSE-NEXT:    cmovbel %edx, %eax
+; X86-SSE-NEXT:    cmovbl %ecx, %eax
 ; X86-SSE-NEXT:    retl
 ;
 ; X64-LABEL: test_unsigned_i32_f64:
 ; X64:       # %bb.0:
-; X64-NEXT:    cvttsd2si %xmm0, %rax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorpd %xmm1, %xmm1
-; X64-NEXT:    ucomisd %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $-1, %eax
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxsd %xmm0, %xmm1
+; X64-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; X64-NEXT:    minsd %xmm1, %xmm0
+; X64-NEXT:    cvttsd2si %xmm0, %rax
+; X64-NEXT:    # kill: def $eax killed $eax killed $rax
 ; X64-NEXT:    retq
     %x = call i32 @llvm.fptoui.sat.i32.f64(double %f)
     ret i32 %x
@@ -1544,22 +1444,10 @@ define i50 @test_unsigned_i50_f64(double %f) nounwind {
 ;
 ; X64-LABEL: test_unsigned_i50_f64:
 ; X64:       # %bb.0:
-; X64-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
-; X64-NEXT:    movapd %xmm0, %xmm2
-; X64-NEXT:    subsd %xmm1, %xmm2
-; X64-NEXT:    cvttsd2si %xmm2, %rax
-; X64-NEXT:    movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000
-; X64-NEXT:    xorq %rax, %rcx
-; X64-NEXT:    cvttsd2si %xmm0, %rax
-; X64-NEXT:    ucomisd %xmm1, %xmm0
-; X64-NEXT:    cmovaeq %rcx, %rax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorpd %xmm1, %xmm1
-; X64-NEXT:    ucomisd %xmm1, %xmm0
-; X64-NEXT:    cmovaeq %rax, %rcx
-; X64-NEXT:    ucomisd {{.*}}(%rip), %xmm0
-; X64-NEXT:    movabsq $1125899906842623, %rax # imm = 0x3FFFFFFFFFFFF
-; X64-NEXT:    cmovbeq %rcx, %rax
+; X64-NEXT:    maxsd %xmm1, %xmm0
+; X64-NEXT:    minsd {{.*}}(%rip), %xmm0
+; X64-NEXT:    cvttsd2si %xmm0, %rax
 ; X64-NEXT:    retq
     %x = call i50 @llvm.fptoui.sat.i50.f64(double %f)
     ret i50 %x
@@ -2041,15 +1929,11 @@ define i1 @test_unsigned_i1_f16(half %f) nounwind {
 ; X86-SSE-NEXT:    movl %eax, (%esp)
 ; X86-SSE-NEXT:    calll __gnu_h2f_ieee
 ; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    xorl %ecx, %ecx
-; X86-SSE-NEXT:    xorps %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomiss %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $1, %eax
-; X86-SSE-NEXT:    cmovbel %ecx, %eax
+; X86-SSE-NEXT:    xorps %xmm0, %xmm0
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $al killed $al killed $eax
 ; X86-SSE-NEXT:    addl $12, %esp
 ; X86-SSE-NEXT:    retl
@@ -2059,14 +1943,11 @@ define i1 @test_unsigned_i1_f16(half %f) nounwind {
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    movzwl %di, %edi
 ; X64-NEXT:    callq __gnu_h2f_ieee at PLT
-; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorps %xmm1, %xmm1
-; X64-NEXT:    ucomiss %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $1, %eax
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X64-NEXT:    minss %xmm1, %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %eax
 ; X64-NEXT:    # kill: def $al killed $al killed $eax
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
@@ -2123,15 +2004,11 @@ define i8 @test_unsigned_i8_f16(half %f) nounwind {
 ; X86-SSE-NEXT:    movl %eax, (%esp)
 ; X86-SSE-NEXT:    calll __gnu_h2f_ieee
 ; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    xorl %ecx, %ecx
-; X86-SSE-NEXT:    xorps %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomiss %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $255, %eax
-; X86-SSE-NEXT:    cmovbel %ecx, %eax
+; X86-SSE-NEXT:    xorps %xmm0, %xmm0
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $al killed $al killed $eax
 ; X86-SSE-NEXT:    addl $12, %esp
 ; X86-SSE-NEXT:    retl
@@ -2141,14 +2018,11 @@ define i8 @test_unsigned_i8_f16(half %f) nounwind {
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    movzwl %di, %edi
 ; X64-NEXT:    callq __gnu_h2f_ieee at PLT
-; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorps %xmm1, %xmm1
-; X64-NEXT:    ucomiss %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $255, %eax
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X64-NEXT:    minss %xmm1, %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %eax
 ; X64-NEXT:    # kill: def $al killed $al killed $eax
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
@@ -2204,15 +2078,11 @@ define i13 @test_unsigned_i13_f16(half %f) nounwind {
 ; X86-SSE-NEXT:    movl %eax, (%esp)
 ; X86-SSE-NEXT:    calll __gnu_h2f_ieee
 ; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    xorl %ecx, %ecx
-; X86-SSE-NEXT:    xorps %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomiss %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $8191, %eax # imm = 0x1FFF
-; X86-SSE-NEXT:    cmovbel %ecx, %eax
+; X86-SSE-NEXT:    xorps %xmm0, %xmm0
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-SSE-NEXT:    addl $12, %esp
 ; X86-SSE-NEXT:    retl
@@ -2222,14 +2092,11 @@ define i13 @test_unsigned_i13_f16(half %f) nounwind {
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    movzwl %di, %edi
 ; X64-NEXT:    callq __gnu_h2f_ieee at PLT
-; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorps %xmm1, %xmm1
-; X64-NEXT:    ucomiss %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $8191, %eax # imm = 0x1FFF
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X64-NEXT:    minss %xmm1, %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %eax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
@@ -2285,15 +2152,11 @@ define i16 @test_unsigned_i16_f16(half %f) nounwind {
 ; X86-SSE-NEXT:    movl %eax, (%esp)
 ; X86-SSE-NEXT:    calll __gnu_h2f_ieee
 ; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
-; X86-SSE-NEXT:    xorl %ecx, %ecx
-; X86-SSE-NEXT:    xorps %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomiss %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $65535, %eax # imm = 0xFFFF
-; X86-SSE-NEXT:    cmovbel %ecx, %eax
+; X86-SSE-NEXT:    xorps %xmm0, %xmm0
+; X86-SSE-NEXT:    maxss {{[0-9]+}}(%esp), %xmm0
+; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-SSE-NEXT:    minss %xmm0, %xmm1
+; X86-SSE-NEXT:    cvttss2si %xmm1, %eax
 ; X86-SSE-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-SSE-NEXT:    addl $12, %esp
 ; X86-SSE-NEXT:    retl
@@ -2303,14 +2166,11 @@ define i16 @test_unsigned_i16_f16(half %f) nounwind {
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    movzwl %di, %edi
 ; X64-NEXT:    callq __gnu_h2f_ieee at PLT
-; X64-NEXT:    cvttss2si %xmm0, %eax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorps %xmm1, %xmm1
-; X64-NEXT:    ucomiss %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $65535, %eax # imm = 0xFFFF
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxss %xmm0, %xmm1
+; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X64-NEXT:    minss %xmm1, %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %eax
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
@@ -2367,21 +2227,10 @@ define i19 @test_unsigned_i19_f16(half %f) nounwind {
 ; X86-SSE-NEXT:    calll __gnu_h2f_ieee
 ; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    movaps %xmm0, %xmm2
-; X86-SSE-NEXT:    subss %xmm1, %xmm2
-; X86-SSE-NEXT:    cvttss2si %xmm2, %eax
-; X86-SSE-NEXT:    xorl $-2147483648, %eax # imm = 0x80000000
-; X86-SSE-NEXT:    cvttss2si %xmm0, %ecx
-; X86-SSE-NEXT:    ucomiss %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %eax, %ecx
-; X86-SSE-NEXT:    xorl %edx, %edx
 ; X86-SSE-NEXT:    xorps %xmm1, %xmm1
-; X86-SSE-NEXT:    ucomiss %xmm1, %xmm0
-; X86-SSE-NEXT:    cmovael %ecx, %edx
-; X86-SSE-NEXT:    ucomiss {{\.LCPI.*}}, %xmm0
-; X86-SSE-NEXT:    movl $524287, %eax # imm = 0x7FFFF
-; X86-SSE-NEXT:    cmovbel %edx, %eax
+; X86-SSE-NEXT:    maxss %xmm1, %xmm0
+; X86-SSE-NEXT:    minss {{\.LCPI.*}}, %xmm0
+; X86-SSE-NEXT:    cvttss2si %xmm0, %eax
 ; X86-SSE-NEXT:    addl $12, %esp
 ; X86-SSE-NEXT:    retl
 ;
@@ -2390,14 +2239,10 @@ define i19 @test_unsigned_i19_f16(half %f) nounwind {
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    movzwl %di, %edi
 ; X64-NEXT:    callq __gnu_h2f_ieee at PLT
-; X64-NEXT:    cvttss2si %xmm0, %rax
-; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorps %xmm1, %xmm1
-; X64-NEXT:    ucomiss %xmm1, %xmm0
-; X64-NEXT:    cmovael %eax, %ecx
-; X64-NEXT:    ucomiss {{.*}}(%rip), %xmm0
-; X64-NEXT:    movl $524287, %eax # imm = 0x7FFFF
-; X64-NEXT:    cmovbel %ecx, %eax
+; X64-NEXT:    maxss %xmm1, %xmm0
+; X64-NEXT:    minss {{.*}}(%rip), %xmm0
+; X64-NEXT:    cvttss2si %xmm0, %eax
 ; X64-NEXT:    popq %rcx
 ; X64-NEXT:    retq
     %x = call i19 @llvm.fptoui.sat.i19.f16(half %f)
@@ -2612,15 +2457,7 @@ define i50 @test_unsigned_i50_f16(half %f) nounwind {
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    movzwl %di, %edi
 ; X64-NEXT:    callq __gnu_h2f_ieee at PLT
-; X64-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
-; X64-NEXT:    movaps %xmm0, %xmm2
-; X64-NEXT:    subss %xmm1, %xmm2
-; X64-NEXT:    cvttss2si %xmm2, %rax
-; X64-NEXT:    movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000
-; X64-NEXT:    xorq %rax, %rcx
 ; X64-NEXT:    cvttss2si %xmm0, %rax
-; X64-NEXT:    ucomiss %xmm1, %xmm0
-; X64-NEXT:    cmovaeq %rcx, %rax
 ; X64-NEXT:    xorl %ecx, %ecx
 ; X64-NEXT:    xorps %xmm1, %xmm1
 ; X64-NEXT:    ucomiss %xmm1, %xmm0


        


More information about the llvm-branch-commits mailing list