[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