diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -1492,6 +1492,7 @@ 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/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -278,6 +278,19 @@ } } + 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); @@ -21198,6 +21211,155 @@ 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(); @@ -29486,6 +29648,8 @@ 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/test/CodeGen/X86/fptosi-sat-scalar.ll b/llvm/test/CodeGen/X86/fptosi-sat-scalar.ll --- a/llvm/test/CodeGen/X86/fptosi-sat-scalar.ll +++ b/llvm/test/CodeGen/X86/fptosi-sat-scalar.ll @@ -73,31 +73,20 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ -733,14 +675,11 @@ ; 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 @@ -1156,31 +1095,20 @@ ; 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) @@ -1238,31 +1166,20 @@ ; 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) @@ -1321,31 +1238,20 @@ ; 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) @@ -1404,31 +1310,20 @@ ; 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) @@ -1487,30 +1382,22 @@ ; 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 @@ -1568,30 +1455,22 @@ ; 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 @@ -1698,16 +1577,12 @@ ; ; 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 @@ -1816,14 +1691,11 @@ ; 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 @@ -2246,16 +2118,10 @@ ; 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 @@ -2265,16 +2131,11 @@ ; X64-NEXT: pushq %rax ; X64-NEXT: movzwl %di, %edi ; X64-NEXT: callq __gnu_h2f_ieee -; 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 @@ -2340,16 +2201,10 @@ ; 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 @@ -2359,16 +2214,11 @@ ; X64-NEXT: pushq %rax ; X64-NEXT: movzwl %di, %edi ; X64-NEXT: callq __gnu_h2f_ieee +; 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 @@ -2435,16 +2285,10 @@ ; 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 @@ -2454,16 +2298,11 @@ ; X64-NEXT: pushq %rax ; X64-NEXT: movzwl %di, %edi ; X64-NEXT: callq __gnu_h2f_ieee +; 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 @@ -2530,16 +2369,10 @@ ; 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 @@ -2549,16 +2382,11 @@ ; X64-NEXT: pushq %rax ; X64-NEXT: movzwl %di, %edi ; X64-NEXT: callq __gnu_h2f_ieee +; 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 @@ -2625,16 +2453,12 @@ ; 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 ; @@ -2643,16 +2467,12 @@ ; X64-NEXT: pushq %rax ; X64-NEXT: movzwl %di, %edi ; X64-NEXT: callq __gnu_h2f_ieee -; 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) @@ -2720,14 +2540,11 @@ ; 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 ; @@ -2738,14 +2555,11 @@ ; X64-NEXT: callq __gnu_h2f_ieee ; 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) @@ -2990,14 +2804,11 @@ ; X64-NEXT: callq __gnu_h2f_ieee ; 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 --- a/llvm/test/CodeGen/X86/fptoui-sat-scalar.ll +++ b/llvm/test/CodeGen/X86/fptoui-sat-scalar.ll @@ -60,28 +60,21 @@ ; ; 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 @@ ; ; 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 @@ ; ; 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 @@ ; ; 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 @@ ; 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 @@ -560,15 +517,7 @@ ; ; 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 @@ -1055,28 +1004,21 @@ ; ; 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) @@ -1125,28 +1067,21 @@ ; ; 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) @@ -1194,28 +1129,21 @@ ; ; 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) @@ -1263,28 +1191,21 @@ ; ; 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) @@ -1333,33 +1254,18 @@ ; 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 @@ -1407,33 +1313,27 @@ ; 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 @@ -1555,22 +1455,10 @@ ; ; 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 @@ -2057,15 +1945,11 @@ ; 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 @@ -2075,14 +1959,11 @@ ; X64-NEXT: pushq %rax ; X64-NEXT: movzwl %di, %edi ; X64-NEXT: callq __gnu_h2f_ieee -; 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 @@ -2139,15 +2020,11 @@ ; 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 @@ -2157,14 +2034,11 @@ ; X64-NEXT: pushq %rax ; X64-NEXT: movzwl %di, %edi ; X64-NEXT: callq __gnu_h2f_ieee -; 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 @@ -2220,15 +2094,11 @@ ; 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 @@ -2238,14 +2108,11 @@ ; X64-NEXT: pushq %rax ; X64-NEXT: movzwl %di, %edi ; X64-NEXT: callq __gnu_h2f_ieee -; 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 @@ -2301,15 +2168,11 @@ ; 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 @@ -2319,14 +2182,11 @@ ; X64-NEXT: pushq %rax ; X64-NEXT: movzwl %di, %edi ; X64-NEXT: callq __gnu_h2f_ieee -; 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 @@ -2383,21 +2243,10 @@ ; 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 ; @@ -2406,14 +2255,10 @@ ; X64-NEXT: pushq %rax ; X64-NEXT: movzwl %di, %edi ; X64-NEXT: callq __gnu_h2f_ieee -; 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) @@ -2631,15 +2476,7 @@ ; X64-NEXT: pushq %rax ; X64-NEXT: movzwl %di, %edi ; X64-NEXT: callq __gnu_h2f_ieee -; 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