Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -13516,6 +13516,119 @@ %a = load i16, i16* @x, align 2 %res = call float @llvm.convert.from.fp16(i16 %a) +Saturating floating-point to integer conversions +------------------------------------------------ + +The ``fptoui`` and ``fptosi`` instructions return a +:ref:`poison value ` if the rounded-towards-zero value is not +representable by the result type. These intrinsics provide an alternative +conversion, which will saturate towards the smallest and largest representable +integer values instead. + +'``llvm.fptoui.sat.*``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. You can use ``llvm.fptoui.sat`` on any +floating-point argument type and any integer result type, or vectors thereof. +Not all targets may support all types, however. + +:: + + declare i32 @llvm.fptoui.sat.i32.f32(float %f) + declare i19 @llvm.fptoui.sat.i19.f64(double %f) + declare <4 x i100> @llvm.fptoui.sat.v4i100.v4f128(<4 x fp128> %f) + +Overview: +""""""""" + +This intrinsic converts the argument into an unsigned integer using saturating +semantics. + +Arguments: +"""""""""" + +The argument may be any floating-point or vector of floating-point type. The +return value may be any integer or vector of integer type. The number of vector +elements in argument and return must be same. + +Semantics: +"""""""""" + +The conversion to integer is performed subject to the following rules: + +- If the argument is any NaN, zero is returned. +- If the argument is smaller than zero, zero is returned. +- If the argument is larger than the largest representable integer of the + result type (this includes positive infinity), the largest representable + integer is returned. +- Otherwise, the result of rounding the argument towards zero is returned. + +Example: +"""""""" + +.. code-block:: text + + %a = call i8 @llvm.fptoui.sat.i8.f32(float 123.9) ; yields i8: 123 + %b = call i8 @llvm.fptoui.sat.i8.f32(float -5.7) ; yields i8: 0 + %c = call i8 @llvm.fptoui.sat.i8.f32(float 377.0) ; yields i8: 255 + %d = call i8 @llvm.fptoui.sat.i8.f32(float 0xFFF8000000000000) ; yields i8: 0 + +'``llvm.fptosi.sat.*``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. You can use ``llvm.fptosi.sat`` on any +floating-point argument type and any integer result type, or vectors thereof. +Not all targets may support all types, however. + +:: + + declare i32 @llvm.fptosi.sat.i32.f32(float %f) + declare i19 @llvm.fptosi.sat.i19.f64(double %f) + declare <4 x i100> @llvm.fptosi.sat.v4i100.v4f128(<4 x fp128> %f) + +Overview: +""""""""" + +This intrinsic converts the argument into a signed integer using saturating +semantics. + +Arguments: +"""""""""" + +The argument may be any floating-point or vector of floating-point type. The +return value may be any integer or vector of integer type. The number of vector +elements in argument and return must be same. + +Semantics: +"""""""""" + +The conversion to integer is performed subject to the following rules: + +- If the argument is any NaN, zero is returned. +- If the argument is smaller than the smallest representable integer of the + result type (this includes negative infinity), the smallest representable + integer is returned. +- If the argument is larger than the largest representable integer of the + result type (this includes positive infinity), the largest representable + integer is returned. +- Otherwise, the result of rounding the argument towards zero is returned. + +Example: +"""""""" + +.. code-block:: text + + %a = call i8 @llvm.fptosi.sat.i8.f32(float 23.9) ; yields i8: 23 + %b = call i8 @llvm.fptosi.sat.i8.f32(float -130.8) ; yields i8: -128 + %c = call i8 @llvm.fptosi.sat.i8.f32(float 999.0) ; yields i8: 127 + %d = call i8 @llvm.fptosi.sat.i8.f32(float 0xFFF8000000000000) ; yields i8: 0 + .. _dbg_intrinsics: Debugger Intrinsics Index: include/llvm/CodeGen/ISDOpcodes.h =================================================================== --- include/llvm/CodeGen/ISDOpcodes.h +++ include/llvm/CodeGen/ISDOpcodes.h @@ -524,6 +524,17 @@ FP_TO_SINT, FP_TO_UINT, + /// FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a + /// signed or unsigned integer type given in operand 1. If the FP value cannot + /// fit in the integer type, then if the FP value is NaN return 0, otherwise + /// return the largest/smallest integer value, if the FP value is + /// larger/smaller (or +INF/-INF) than the largest/smallest integer value. + /// + /// The type in operand 1 may be smaller than the result type as a result of + /// integer type legalization. + FP_TO_SINT_SAT, + FP_TO_UINT_SAT, + /// X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type /// down to the precision of the destination VT. TRUNC is a flag, which is /// always an integer that is zero or one. If TRUNC is 0, this is a Index: include/llvm/CodeGen/TargetLowering.h =================================================================== --- include/llvm/CodeGen/TargetLowering.h +++ include/llvm/CodeGen/TargetLowering.h @@ -3754,6 +3754,11 @@ /// Expand fminnum/fmaxnum into fminnum_ieee/fmaxnum_ieee with quieted inputs. SDValue expandFMINNUM_FMAXNUM(SDNode *N, SelectionDAG &DAG) const; + /// Expand FP_TO_[US]INT_SAT into FP_TO_[US]INT and selects or min/max. + /// \param N Node to expand + /// \returns The expansion result + SDValue expandFP_TO_INT_SAT(SDNode *N, SelectionDAG &DAG) const; + /// Expand CTPOP nodes. Expands vector/scalar CTPOP nodes, /// vector nodes can only succeed if all operations are legal/custom. /// \param N Node to expand Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -981,6 +981,13 @@ def int_convert_from_fp16 : Intrinsic<[llvm_anyfloat_ty], [llvm_i16_ty]>; } +// Saturating floating point to integer intrinsics +def int_fptoui_sat : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty], + [IntrNoMem, IntrSpeculatable]>; + +def int_fptosi_sat : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty], + [IntrNoMem, IntrSpeculatable]>; + // Clear cache intrinsic, default to ignore (ie. emit nothing) // maps to void __clear_cache() on supporting platforms def int_clear_cache : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], Index: include/llvm/Target/TargetSelectionDAG.td =================================================================== --- include/llvm/Target/TargetSelectionDAG.td +++ include/llvm/Target/TargetSelectionDAG.td @@ -162,6 +162,9 @@ def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int SDTCisInt<0>, SDTCisFP<1>, SDTCisSameNumEltsAs<0, 1> ]>; +def SDTFPToIntSatOp : SDTypeProfile<1, 2, [ // fp_to_[su]int_sat + SDTCisInt<0>, SDTCisFP<1>, SDTCisVT<2, OtherVT>, SDTCisSameNumEltsAs<0, 1> +]>; def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>, SDTCisVTSmallerThanOp<2, 1> @@ -452,6 +455,8 @@ def uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>; def fp_to_sint : SDNode<"ISD::FP_TO_SINT" , SDTFPToIntOp>; def fp_to_uint : SDNode<"ISD::FP_TO_UINT" , SDTFPToIntOp>; +def fp_to_sint_sat : SDNode<"ISD::FP_TO_SINT_SAT" , SDTFPToIntSatOp>; +def fp_to_uint_sat : SDNode<"ISD::FP_TO_UINT_SAT" , SDTFPToIntSatOp>; def f16_to_fp : SDNode<"ISD::FP16_TO_FP" , SDTIntToFPOp>; def fp_to_f16 : SDNode<"ISD::FP_TO_FP16" , SDTFPToIntOp>; Index: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -173,6 +173,7 @@ const SDLoc &dl); SDValue PromoteLegalFP_TO_INT(SDValue LegalOp, EVT DestVT, bool isSigned, const SDLoc &dl); + SDValue PromoteLegalFP_TO_INT_SAT(SDNode *Node, const SDLoc &dl); SDValue ExpandBITREVERSE(SDValue Op, const SDLoc &dl); SDValue ExpandBSWAP(SDValue Op, const SDLoc &dl); @@ -1124,10 +1125,11 @@ case ISD::SADDSAT: case ISD::UADDSAT: case ISD::SSUBSAT: - case ISD::USUBSAT: { + case ISD::USUBSAT: + case ISD::FP_TO_SINT_SAT: + case ISD::FP_TO_UINT_SAT: Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); break; - } case ISD::SMULFIX: { unsigned Scale = Node->getConstantOperandVal(2); Action = TLI.getFixedPointOperationAction(Node->getOpcode(), @@ -2517,6 +2519,30 @@ return DAG.getNode(ISD::TRUNCATE, dl, DestVT, Operation); } +/// Promote FP_TO_*INT_SAT operation to a larger result type. At this point +/// the result and operand types are legal and there must be a legal +/// FP_TO_*INT_SAT operation for a larger result type. +SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT_SAT(SDNode *Node, + const SDLoc &dl) { + unsigned Opcode = Node->getOpcode(); + + // Scan for the appropriate larger type to use. + EVT NewOutTy = Node->getValueType(0); + while (true) { + NewOutTy = (MVT::SimpleValueType)(NewOutTy.getSimpleVT().SimpleTy+1); + assert(NewOutTy.isInteger() && "Ran out of possibilities!"); + + if (TLI.isOperationLegalOrCustom(Opcode, NewOutTy)) + break; + } + + // Saturation width is determined by second operand, so we don't have to + // perform any fixup and can directly truncate the result. + SDValue Result = DAG.getNode(Opcode, dl, NewOutTy, + Node->getOperand(0), Node->getOperand(1)); + return DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Result); +} + /// Legalize a BITREVERSE scalar/vector operation as a series of mask + shifts. SDValue SelectionDAGLegalize::ExpandBITREVERSE(SDValue Op, const SDLoc &dl) { EVT VT = Op.getValueType(); @@ -2871,6 +2897,10 @@ if (TLI.expandFP_TO_UINT(Node, Tmp1, DAG)) Results.push_back(Tmp1); break; + case ISD::FP_TO_SINT_SAT: + case ISD::FP_TO_UINT_SAT: + Results.push_back(TLI.expandFP_TO_INT_SAT(Node, DAG)); + break; case ISD::VAARG: Results.push_back(DAG.expandVAArg(Node)); Results.push_back(Results[0].getValue(1)); @@ -4162,6 +4192,10 @@ Node->getOpcode() == ISD::FP_TO_SINT, dl); Results.push_back(Tmp1); break; + case ISD::FP_TO_UINT_SAT: + case ISD::FP_TO_SINT_SAT: + Results.push_back(PromoteLegalFP_TO_INT_SAT(Node, dl)); + break; case ISD::UINT_TO_FP: case ISD::SINT_TO_FP: Tmp1 = PromoteLegalINT_TO_FP(Node->getOperand(0), Node->getValueType(0), Index: lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -763,6 +763,8 @@ case ISD::FP_ROUND: Res = SoftenFloatOp_FP_ROUND(N); break; case ISD::FP_TO_SINT: case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_XINT(N); break; + case ISD::FP_TO_SINT_SAT: + case ISD::FP_TO_UINT_SAT: Res = SoftenFloatOp_FP_TO_XINT_SAT(N); break; case ISD::SELECT: Res = SoftenFloatOp_SELECT(N); break; case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break; case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break; @@ -955,6 +957,11 @@ return DAG.getNode(ISD::TRUNCATE, dl, RVT, Res); } +SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_XINT_SAT(SDNode *N) { + llvm_unreachable("fp_to_xint soften float op not implemented yet"); + return SDValue(); +} + SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT(SDNode *N) { SDValue Op1 = GetSoftenedFloat(N->getOperand(1)); SDValue Op2 = GetSoftenedFloat(N->getOperand(2)); @@ -1768,6 +1775,9 @@ case ISD::FCOPYSIGN: R = PromoteFloatOp_FCOPYSIGN(N, OpNo); break; case ISD::FP_TO_SINT: case ISD::FP_TO_UINT: R = PromoteFloatOp_FP_TO_XINT(N, OpNo); break; + case ISD::FP_TO_SINT_SAT: + case ISD::FP_TO_UINT_SAT: + R = PromoteFloatOp_FP_TO_XINT_SAT(N, OpNo); break; case ISD::FP_EXTEND: R = PromoteFloatOp_FP_EXTEND(N, OpNo); break; case ISD::SELECT_CC: R = PromoteFloatOp_SELECT_CC(N, OpNo); break; case ISD::SETCC: R = PromoteFloatOp_SETCC(N, OpNo); break; @@ -1811,6 +1821,12 @@ return DAG.getNode(N->getOpcode(), SDLoc(N), N->getValueType(0), Op); } +SDValue DAGTypeLegalizer::PromoteFloatOp_FP_TO_XINT_SAT(SDNode *N, unsigned OpNo) { + SDValue Op = GetPromotedFloat(N->getOperand(0)); + return DAG.getNode( + N->getOpcode(), SDLoc(N), N->getValueType(0), Op, N->getOperand(1)); +} + SDValue DAGTypeLegalizer::PromoteFloatOp_FP_EXTEND(SDNode *N, unsigned OpNo) { SDValue Op = GetPromotedFloat(N->getOperand(0)); EVT VT = N->getValueType(0); Index: lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -116,6 +116,10 @@ case ISD::FP_TO_SINT: case ISD::FP_TO_UINT: Res = PromoteIntRes_FP_TO_XINT(N); break; + case ISD::FP_TO_SINT_SAT: + case ISD::FP_TO_UINT_SAT: + Res = PromoteIntRes_FP_TO_XINT_SAT(N); break; + case ISD::FP_TO_FP16: Res = PromoteIntRes_FP_TO_FP16(N); break; case ISD::FLT_ROUNDS_: Res = PromoteIntRes_FLT_ROUNDS(N); break; @@ -471,6 +475,14 @@ DAG.getValueType(N->getValueType(0).getScalarType())); } +SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT_SAT(SDNode *N) { + // Promote the result type, while keeping the original type in Op1. + EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); + SDLoc dl(N); + return DAG.getNode( + N->getOpcode(), dl, NVT, N->getOperand(0), N->getOperand(1)); +} + SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_FP16(SDNode *N) { EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); SDLoc dl(N); @@ -1503,6 +1515,8 @@ case ISD::FLT_ROUNDS_: ExpandIntRes_FLT_ROUNDS(N, Lo, Hi); break; case ISD::FP_TO_SINT: ExpandIntRes_FP_TO_SINT(N, Lo, Hi); break; case ISD::FP_TO_UINT: ExpandIntRes_FP_TO_UINT(N, Lo, Hi); break; + case ISD::FP_TO_SINT_SAT: + case ISD::FP_TO_UINT_SAT: ExpandIntRes_FP_TO_XINT_SAT(N, Lo, Hi); break; case ISD::LOAD: ExpandIntRes_LOAD(cast(N), Lo, Hi); break; case ISD::MUL: ExpandIntRes_MUL(N, Lo, Hi); break; case ISD::READCYCLECOUNTER: ExpandIntRes_READCYCLECOUNTER(N, Lo, Hi); break; @@ -2339,6 +2353,11 @@ Lo, Hi); } +void DAGTypeLegalizer::ExpandIntRes_FP_TO_XINT_SAT(SDNode *N, SDValue &Lo, + SDValue &Hi) { + llvm_unreachable("fp_to_xint_sat expand int res not implemented yet"); +} + void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, SDValue &Lo, SDValue &Hi) { if (ISD::isNormalLoad(N)) { Index: lib/CodeGen/SelectionDAG/LegalizeTypes.h =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -320,6 +320,7 @@ SDValue PromoteIntRes_CTTZ(SDNode *N); SDValue PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N); SDValue PromoteIntRes_FP_TO_XINT(SDNode *N); + SDValue PromoteIntRes_FP_TO_XINT_SAT(SDNode *N); SDValue PromoteIntRes_FP_TO_FP16(SDNode *N); SDValue PromoteIntRes_INT_EXTEND(SDNode *N); SDValue PromoteIntRes_LOAD(LoadSDNode *N); @@ -414,6 +415,7 @@ void ExpandIntRes_FLT_ROUNDS (SDNode *N, SDValue &Lo, SDValue &Hi); void ExpandIntRes_FP_TO_SINT (SDNode *N, SDValue &Lo, SDValue &Hi); void ExpandIntRes_FP_TO_UINT (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandIntRes_FP_TO_XINT_SAT (SDNode *N, SDValue &Lo, SDValue &Hi); void ExpandIntRes_Logical (SDNode *N, SDValue &Lo, SDValue &Hi); void ExpandIntRes_ADDSUB (SDNode *N, SDValue &Lo, SDValue &Hi); @@ -548,6 +550,7 @@ SDValue SoftenFloatOp_FP_EXTEND(SDNode *N); SDValue SoftenFloatOp_FP_ROUND(SDNode *N); SDValue SoftenFloatOp_FP_TO_XINT(SDNode *N); + SDValue SoftenFloatOp_FP_TO_XINT_SAT(SDNode *N); SDValue SoftenFloatOp_SELECT(SDNode *N); SDValue SoftenFloatOp_SELECT_CC(SDNode *N); SDValue SoftenFloatOp_SETCC(SDNode *N); @@ -647,6 +650,7 @@ SDValue PromoteFloatOp_FCOPYSIGN(SDNode *N, unsigned OpNo); SDValue PromoteFloatOp_FP_EXTEND(SDNode *N, unsigned OpNo); SDValue PromoteFloatOp_FP_TO_XINT(SDNode *N, unsigned OpNo); + SDValue PromoteFloatOp_FP_TO_XINT_SAT(SDNode *N, unsigned OpNo); SDValue PromoteFloatOp_STORE(SDNode *N, unsigned OpNo); SDValue PromoteFloatOp_SELECT_CC(SDNode *N, unsigned OpNo); SDValue PromoteFloatOp_SETCC(SDNode *N, unsigned OpNo); @@ -690,6 +694,7 @@ SDValue ScalarizeVecRes_SETCC(SDNode *N); SDValue ScalarizeVecRes_UNDEF(SDNode *N); SDValue ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N); + SDValue ScalarizeVecRes_FP_TO_XINT_SAT(SDNode *N); SDValue ScalarizeVecRes_SMULFIX(SDNode *N); @@ -703,6 +708,7 @@ SDValue ScalarizeVecOp_VSETCC(SDNode *N); SDValue ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo); SDValue ScalarizeVecOp_FP_ROUND(SDNode *N, unsigned OpNo); + SDValue ScalarizeVecOp_FP_TO_XINT_SAT(SDNode *N); //===--------------------------------------------------------------------===// // Vector Splitting Support: LegalizeVectorTypes.cpp @@ -745,6 +751,7 @@ void SplitVecRes_SETCC(SDNode *N, SDValue &Lo, SDValue &Hi); void SplitVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N, SDValue &Lo, SDValue &Hi); + void SplitVecRes_FP_TO_XINT_SAT(SDNode *N, SDValue &Lo, SDValue &Hi); // Vector Operand Splitting: <128 x ty> -> 2 x <64 x ty>. bool SplitVectorOperand(SDNode *N, unsigned OpNo); @@ -765,6 +772,7 @@ SDValue SplitVecOp_VSETCC(SDNode *N); SDValue SplitVecOp_FP_ROUND(SDNode *N); SDValue SplitVecOp_FCOPYSIGN(SDNode *N); + SDValue SplitVecOp_FP_TO_XINT_SAT(SDNode *N); //===--------------------------------------------------------------------===// // Vector Widening Support: LegalizeVectorTypes.cpp @@ -809,6 +817,7 @@ SDValue WidenVecRes_BinaryCanTrap(SDNode *N); SDValue WidenVecRes_StrictFP(SDNode *N); SDValue WidenVecRes_Convert(SDNode *N); + SDValue WidenVecRes_FP_TO_XINT_SAT(SDNode *N); SDValue WidenVecRes_FCOPYSIGN(SDNode *N); SDValue WidenVecRes_POWI(SDNode *N); SDValue WidenVecRes_Shift(SDNode *N); @@ -829,6 +838,7 @@ SDValue WidenVecOp_SETCC(SDNode* N); SDValue WidenVecOp_Convert(SDNode *N); + SDValue WidenVecOp_FP_TO_XINT_SAT(SDNode *N); SDValue WidenVecOp_FCOPYSIGN(SDNode *N); //===--------------------------------------------------------------------===// Index: lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -413,6 +413,8 @@ case ISD::UADDSAT: case ISD::SSUBSAT: case ISD::USUBSAT: + case ISD::FP_TO_SINT_SAT: + case ISD::FP_TO_UINT_SAT: Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); break; case ISD::SMULFIX: { Index: lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -174,6 +174,9 @@ break; case ISD::SMULFIX: R = ScalarizeVecRes_SMULFIX(N); + case ISD::FP_TO_UINT_SAT: + case ISD::FP_TO_SINT_SAT: + R = ScalarizeVecRes_FP_TO_XINT_SAT(N); break; } @@ -510,6 +513,11 @@ return DAG.getNode(ExtendCode, DL, NVT, Res); } +SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(SDNode *N) { + llvm_unreachable("fp_to_xint_sat scalarize vec res not implemented yet"); + return SDValue(); +} + //===----------------------------------------------------------------------===// // Operand Vector Scalarization <1 x ty> -> ty. @@ -543,6 +551,10 @@ case ISD::UINT_TO_FP: Res = ScalarizeVecOp_UnaryOp(N); break; + case ISD::FP_TO_SINT_SAT: + case ISD::FP_TO_UINT_SAT: + Res = ScalarizeVecOp_FP_TO_XINT_SAT(N); + break; case ISD::CONCAT_VECTORS: Res = ScalarizeVecOp_CONCAT_VECTORS(N); break; @@ -691,6 +703,11 @@ return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res); } +SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_TO_XINT_SAT(SDNode *N) { + llvm_unreachable("fp_to_xint_sat scalarize vec op not implemented yet"); + return SDValue(); +} + //===----------------------------------------------------------------------===// // Result Vector Splitting //===----------------------------------------------------------------------===// @@ -861,6 +878,9 @@ break; case ISD::SMULFIX: SplitVecRes_SMULFIX(N, Lo, Hi); + case ISD::FP_TO_UINT_SAT: + case ISD::FP_TO_SINT_SAT: + SplitVecRes_FP_TO_XINT_SAT(N, Lo, Hi); break; } @@ -1669,6 +1689,11 @@ } } +void DAGTypeLegalizer::SplitVecRes_FP_TO_XINT_SAT(SDNode *N, SDValue &Lo, + SDValue &Hi) { + llvm_unreachable("fp_to_xint_sat scalarize vec res not implemented yet"); +} + //===----------------------------------------------------------------------===// // Operand Vector Splitting @@ -1742,6 +1767,10 @@ case ISD::FCANONICALIZE: Res = SplitVecOp_UnaryOp(N); break; + case ISD::FP_TO_SINT_SAT: + case ISD::FP_TO_UINT_SAT: + Res = SplitVecOp_FP_TO_XINT_SAT(N); + break; case ISD::ANY_EXTEND_VECTOR_INREG: case ISD::SIGN_EXTEND_VECTOR_INREG: @@ -2361,6 +2390,10 @@ return DAG.UnrollVectorOp(N, N->getValueType(0).getVectorNumElements()); } +SDValue DAGTypeLegalizer::SplitVecOp_FP_TO_XINT_SAT(SDNode *N) { + llvm_unreachable("fp_to_xint_sat split vec op not implemented yet"); + return SDValue(); +} //===----------------------------------------------------------------------===// // Result Vector Widening @@ -2501,6 +2534,11 @@ Res = WidenVecRes_Convert(N); break; + case ISD::FP_TO_SINT_SAT: + case ISD::FP_TO_UINT_SAT: + Res = WidenVecRes_FP_TO_XINT_SAT(N); + break; + case ISD::FABS: case ISD::FCEIL: case ISD::FCOS: @@ -2925,6 +2963,11 @@ return DAG.getBuildVector(WidenVT, DL, Ops); } +SDValue DAGTypeLegalizer::WidenVecRes_FP_TO_XINT_SAT(SDNode *N) { + llvm_unreachable("fp_to_xint_sat widen vec res not implemented yet"); + return SDValue(); +} + SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(SDNode *N) { unsigned Opcode = N->getOpcode(); SDValue InOp = N->getOperand(0); @@ -3710,6 +3753,11 @@ case ISD::TRUNCATE: Res = WidenVecOp_Convert(N); break; + + case ISD::FP_TO_SINT_SAT: + case ISD::FP_TO_UINT_SAT: + Res = WidenVecOp_FP_TO_XINT_SAT(N); + break; } // If Res is null, the sub-method took care of registering the result. @@ -3834,6 +3882,11 @@ return DAG.getBuildVector(VT, dl, Ops); } +SDValue DAGTypeLegalizer::WidenVecOp_FP_TO_XINT_SAT(SDNode *N) { + llvm_unreachable("fp_to_xint_sat widen vec op not implemented yet"); + return SDValue(); +} + SDValue DAGTypeLegalizer::WidenVecOp_BITCAST(SDNode *N) { EVT VT = N->getValueType(0); SDValue InOp = GetWidenedVector(N->getOperand(0)); Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -8817,7 +8817,9 @@ Operands[1]))); break; case ISD::SIGN_EXTEND_INREG: - case ISD::FP_ROUND_INREG: { + case ISD::FP_ROUND_INREG: + case ISD::FP_TO_SINT_SAT: + case ISD::FP_TO_UINT_SAT: { EVT ExtVT = cast(Operands[1])->getVT().getVectorElementType(); Scalars.push_back(getNode(N->getOpcode(), dl, EltVT, Operands[0], Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5691,6 +5691,20 @@ DAG.getNode(ISD::BITCAST, sdl, MVT::f16, getValue(I.getArgOperand(0))))); return nullptr; + case Intrinsic::fptosi_sat: { + EVT Type = TLI.getValueType(DAG.getDataLayout(), I.getType()); + setValue(&I, DAG.getNode(ISD::FP_TO_SINT_SAT, sdl, Type, + getValue(I.getArgOperand(0)), + DAG.getValueType(Type))); + return nullptr; + } + case Intrinsic::fptoui_sat: { + EVT Type = TLI.getValueType(DAG.getDataLayout(), I.getType()); + setValue(&I, DAG.getNode(ISD::FP_TO_UINT_SAT, sdl, Type, + getValue(I.getArgOperand(0)), + DAG.getValueType(Type))); + return nullptr; + } case Intrinsic::pcmarker: { SDValue Tmp = getValue(I.getArgOperand(0)); DAG.setRoot(DAG.getNode(ISD::PCMARKER, sdl, MVT::Other, getRoot(), Tmp)); Index: lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp @@ -317,6 +317,8 @@ case ISD::UINT_TO_FP: return "uint_to_fp"; case ISD::FP_TO_SINT: return "fp_to_sint"; case ISD::FP_TO_UINT: return "fp_to_uint"; + case ISD::FP_TO_SINT_SAT: return "fp_to_sint_sat"; + case ISD::FP_TO_UINT_SAT: return "fp_to_uint_sat"; case ISD::BITCAST: return "bitcast"; case ISD::ADDRSPACECAST: return "addrspacecast"; case ISD::FP16_TO_FP: return "fp16_to_fp"; Index: lib/CodeGen/SelectionDAG/TargetLowering.cpp =================================================================== --- lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -5324,3 +5324,100 @@ DAG.getConstant(VT.getScalarSizeInBits() - Scale, dl, ShiftTy)); return DAG.getNode(ISD::OR, dl, VT, Lo, Hi); } + +SDValue TargetLowering::expandFP_TO_INT_SAT( + SDNode *Node, SelectionDAG &DAG) const { + bool IsSigned = Node->getOpcode() == ISD::FP_TO_SINT_SAT; + SDLoc dl(SDValue(Node, 0)); + SDValue Src = Node->getOperand(0); + + // DstVT is the result type, while SatVT is the size to which we saturate + EVT SrcVT = Src.getValueType(); + EVT SatVT = cast(Node->getOperand(1))->getVT(); + EVT DstVT = Node->getValueType(0); + + unsigned SatWidth = SatVT.getScalarSizeInBits(); + unsigned DstWidth = DstVT.getScalarSizeInBits(); + assert(SatWidth <= DstWidth && + "Expected saturation width smaller than result width"); + + // 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 and min/max are + // legal, emit a min+max+fptoi sequence. Otherwise we have to use a sequence + // of comparisons and selects. + bool MinMaxLegal = isOperationLegal(ISD::FMINNUM, SrcVT) && + isOperationLegal(ISD::FMAXNUM, SrcVT); + if (AreExactFloatBounds && MinMaxLegal) { + SDValue Clamped = Src; + + // Clamp Src by MinFloat from below. If Src is NaN the result is MinFloat. + Clamped = DAG.getNode(ISD::FMAXNUM, dl, SrcVT, Clamped, MinFloatNode); + // Clamp by MaxFloat from above. NaN cannot occur. + Clamped = DAG.getNode(ISD::FMINNUM, dl, SrcVT, Clamped, MaxFloatNode); + // Convert clamped value to integer. + SDValue FpToInt = DAG.getNode( + IsSigned ? ISD::FP_TO_SINT : ISD::FP_TO_UINT, dl, DstVT, Clamped); + + // In the unsigned case we're done, because we mapped NaN to MinFloat, + // which will cast to zero. + if (!IsSigned) + return FpToInt; + + // Otherwise, select 0 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. The assumption here is that the operation is + // non-trapping and it's fine to apply it to an out-of-range value if we + // select it away later. + SDValue FpToInt = DAG.getNode( + IsSigned ? ISD::FP_TO_SINT : ISD::FP_TO_UINT, dl, DstVT, Src); + + SDValue Select = FpToInt; + + // 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. + if (!IsSigned) + 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); +} Index: lib/CodeGen/TargetLoweringBase.cpp =================================================================== --- lib/CodeGen/TargetLoweringBase.cpp +++ lib/CodeGen/TargetLoweringBase.cpp @@ -617,6 +617,8 @@ setOperationAction(ISD::SSUBSAT, VT, Expand); setOperationAction(ISD::USUBSAT, VT, Expand); setOperationAction(ISD::SMULFIX, VT, Expand); + setOperationAction(ISD::FP_TO_SINT_SAT, VT, Expand); + setOperationAction(ISD::FP_TO_UINT_SAT, VT, Expand); // Overflow operations default to expand setOperationAction(ISD::SADDO, VT, Expand); Index: test/CodeGen/AArch64/fptosi-sat-scalar.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/fptosi-sat-scalar.ll @@ -0,0 +1,535 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=aarch64 < %s | FileCheck %s + +; +; 32-bit float to signed integer +; + +declare i1 @llvm.fptosi.sat.i1.f32 (float) +declare i8 @llvm.fptosi.sat.i8.f32 (float) +declare i13 @llvm.fptosi.sat.i13.f32 (float) +declare i16 @llvm.fptosi.sat.i16.f32 (float) +declare i19 @llvm.fptosi.sat.i19.f32 (float) +declare i32 @llvm.fptosi.sat.i32.f32 (float) +declare i50 @llvm.fptosi.sat.i50.f32 (float) +declare i64 @llvm.fptosi.sat.i64.f32 (float) +declare i100 @llvm.fptosi.sat.i100.f32(float) +declare i128 @llvm.fptosi.sat.i128.f32(float) + +define i1 @test_signed_i1_f32(float %f) { +; CHECK-LABEL: test_signed_i1_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov s1, #-1.00000000 +; CHECK-NEXT: fmov s2, wzr +; CHECK-NEXT: fmaxnm s1, s0, s1 +; CHECK-NEXT: fminnm s1, s1, s2 +; CHECK-NEXT: fcvtzs w8, s1 +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: csel w8, wzr, w8, vs +; CHECK-NEXT: and w0, w8, #0x1 +; CHECK-NEXT: ret + %x = call i1 @llvm.fptosi.sat.i1.f32(float %f) + ret i1 %x +} + +define i8 @test_signed_i8_f32(float %f) { +; CHECK-LABEL: test_signed_i8_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI1_0 +; CHECK-NEXT: adrp x9, .LCPI1_1 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI1_0] +; CHECK-NEXT: ldr s2, [x9, :lo12:.LCPI1_1] +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: fmaxnm s1, s0, s1 +; CHECK-NEXT: fminnm s1, s1, s2 +; CHECK-NEXT: fcvtzs w8, s1 +; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: ret + %x = call i8 @llvm.fptosi.sat.i8.f32(float %f) + ret i8 %x +} + +define i13 @test_signed_i13_f32(float %f) { +; CHECK-LABEL: test_signed_i13_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI2_0 +; CHECK-NEXT: adrp x9, .LCPI2_1 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI2_0] +; CHECK-NEXT: ldr s2, [x9, :lo12:.LCPI2_1] +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: fmaxnm s1, s0, s1 +; CHECK-NEXT: fminnm s1, s1, s2 +; CHECK-NEXT: fcvtzs w8, s1 +; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: ret + %x = call i13 @llvm.fptosi.sat.i13.f32(float %f) + ret i13 %x +} + +define i16 @test_signed_i16_f32(float %f) { +; CHECK-LABEL: test_signed_i16_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI3_0 +; CHECK-NEXT: adrp x9, .LCPI3_1 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI3_0] +; CHECK-NEXT: ldr s2, [x9, :lo12:.LCPI3_1] +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: fmaxnm s1, s0, s1 +; CHECK-NEXT: fminnm s1, s1, s2 +; CHECK-NEXT: fcvtzs w8, s1 +; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: ret + %x = call i16 @llvm.fptosi.sat.i16.f32(float %f) + ret i16 %x +} + +define i19 @test_signed_i19_f32(float %f) { +; CHECK-LABEL: test_signed_i19_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI4_0 +; CHECK-NEXT: adrp x9, .LCPI4_1 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI4_0] +; CHECK-NEXT: ldr s2, [x9, :lo12:.LCPI4_1] +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: fmaxnm s1, s0, s1 +; CHECK-NEXT: fminnm s1, s1, s2 +; CHECK-NEXT: fcvtzs w8, s1 +; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: ret + %x = call i19 @llvm.fptosi.sat.i19.f32(float %f) + ret i19 %x +} + +define i32 @test_signed_i32_f32(float %f) { +; CHECK-LABEL: test_signed_i32_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x9, .LCPI5_0 +; CHECK-NEXT: ldr s1, [x9, :lo12:.LCPI5_0] +; CHECK-NEXT: adrp x9, .LCPI5_1 +; CHECK-NEXT: ldr s2, [x9, :lo12:.LCPI5_1] +; CHECK-NEXT: fcvtzs w8, s0 +; CHECK-NEXT: orr w10, wzr, #0x80000000 +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: orr w9, wzr, #0x7fffffff +; CHECK-NEXT: csel w8, w10, w8, lt +; CHECK-NEXT: fcmp s0, s2 +; CHECK-NEXT: csel w8, w9, w8, gt +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: ret + %x = call i32 @llvm.fptosi.sat.i32.f32(float %f) + ret i32 %x +} + +define i50 @test_signed_i50_f32(float %f) { +; CHECK-LABEL: test_signed_i50_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x9, .LCPI6_0 +; CHECK-NEXT: ldr s1, [x9, :lo12:.LCPI6_0] +; CHECK-NEXT: adrp x9, .LCPI6_1 +; CHECK-NEXT: ldr s2, [x9, :lo12:.LCPI6_1] +; CHECK-NEXT: fcvtzs x8, s0 +; CHECK-NEXT: orr x10, xzr, #0xfffe000000000000 +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: orr x9, xzr, #0x1ffffffffffff +; CHECK-NEXT: csel x8, x10, x8, lt +; CHECK-NEXT: fcmp s0, s2 +; CHECK-NEXT: csel x8, x9, x8, gt +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: csel x0, xzr, x8, vs +; CHECK-NEXT: ret + %x = call i50 @llvm.fptosi.sat.i50.f32(float %f) + ret i50 %x +} + +define i64 @test_signed_i64_f32(float %f) { +; CHECK-LABEL: test_signed_i64_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x9, .LCPI7_0 +; CHECK-NEXT: ldr s1, [x9, :lo12:.LCPI7_0] +; CHECK-NEXT: adrp x9, .LCPI7_1 +; CHECK-NEXT: ldr s2, [x9, :lo12:.LCPI7_1] +; CHECK-NEXT: fcvtzs x8, s0 +; CHECK-NEXT: orr x10, xzr, #0x8000000000000000 +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: orr x9, xzr, #0x7fffffffffffffff +; CHECK-NEXT: csel x8, x10, x8, lt +; CHECK-NEXT: fcmp s0, s2 +; CHECK-NEXT: csel x8, x9, x8, gt +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: csel x0, xzr, x8, vs +; CHECK-NEXT: ret + %x = call i64 @llvm.fptosi.sat.i64.f32(float %f) + ret i64 %x +} + +;define i100 @test_signed_i100_f32(float %f) { +; %x = call i100 @llvm.fptosi.sat.i100.f32(float %f) +; ret i100 %x +;} +; +;define i128 @test_signed_i128_f32(float %f) { +; %x = call i128 @llvm.fptosi.sat.i128.f32(float %f) +; ret i128 %x +;} + +; +; 64-bit float to signed integer +; + +declare i1 @llvm.fptosi.sat.i1.f64 (double) +declare i8 @llvm.fptosi.sat.i8.f64 (double) +declare i13 @llvm.fptosi.sat.i13.f64 (double) +declare i16 @llvm.fptosi.sat.i16.f64 (double) +declare i19 @llvm.fptosi.sat.i19.f64 (double) +declare i32 @llvm.fptosi.sat.i32.f64 (double) +declare i50 @llvm.fptosi.sat.i50.f64 (double) +declare i64 @llvm.fptosi.sat.i64.f64 (double) +declare i100 @llvm.fptosi.sat.i100.f64(double) +declare i128 @llvm.fptosi.sat.i128.f64(double) + +define i1 @test_signed_i1_f64(double %f) { +; CHECK-LABEL: test_signed_i1_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov d1, #-1.00000000 +; CHECK-NEXT: fmov d2, xzr +; CHECK-NEXT: fmaxnm d1, d0, d1 +; CHECK-NEXT: fminnm d1, d1, d2 +; CHECK-NEXT: fcvtzs w8, d1 +; CHECK-NEXT: fcmp d0, d0 +; CHECK-NEXT: csel w8, wzr, w8, vs +; CHECK-NEXT: and w0, w8, #0x1 +; CHECK-NEXT: ret + %x = call i1 @llvm.fptosi.sat.i1.f64(double %f) + ret i1 %x +} + +define i8 @test_signed_i8_f64(double %f) { +; CHECK-LABEL: test_signed_i8_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI9_0 +; CHECK-NEXT: adrp x9, .LCPI9_1 +; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI9_0] +; CHECK-NEXT: ldr d2, [x9, :lo12:.LCPI9_1] +; CHECK-NEXT: fcmp d0, d0 +; CHECK-NEXT: fmaxnm d1, d0, d1 +; CHECK-NEXT: fminnm d1, d1, d2 +; CHECK-NEXT: fcvtzs w8, d1 +; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: ret + %x = call i8 @llvm.fptosi.sat.i8.f64(double %f) + ret i8 %x +} + +define i13 @test_signed_i13_f64(double %f) { +; CHECK-LABEL: test_signed_i13_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI10_0 +; CHECK-NEXT: adrp x9, .LCPI10_1 +; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI10_0] +; CHECK-NEXT: ldr d2, [x9, :lo12:.LCPI10_1] +; CHECK-NEXT: fcmp d0, d0 +; CHECK-NEXT: fmaxnm d1, d0, d1 +; CHECK-NEXT: fminnm d1, d1, d2 +; CHECK-NEXT: fcvtzs w8, d1 +; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: ret + %x = call i13 @llvm.fptosi.sat.i13.f64(double %f) + ret i13 %x +} + +define i16 @test_signed_i16_f64(double %f) { +; CHECK-LABEL: test_signed_i16_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI11_0 +; CHECK-NEXT: adrp x9, .LCPI11_1 +; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI11_0] +; CHECK-NEXT: ldr d2, [x9, :lo12:.LCPI11_1] +; CHECK-NEXT: fcmp d0, d0 +; CHECK-NEXT: fmaxnm d1, d0, d1 +; CHECK-NEXT: fminnm d1, d1, d2 +; CHECK-NEXT: fcvtzs w8, d1 +; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: ret + %x = call i16 @llvm.fptosi.sat.i16.f64(double %f) + ret i16 %x +} + +define i19 @test_signed_i19_f64(double %f) { +; CHECK-LABEL: test_signed_i19_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI12_0 +; CHECK-NEXT: adrp x9, .LCPI12_1 +; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI12_0] +; CHECK-NEXT: ldr d2, [x9, :lo12:.LCPI12_1] +; CHECK-NEXT: fcmp d0, d0 +; CHECK-NEXT: fmaxnm d1, d0, d1 +; CHECK-NEXT: fminnm d1, d1, d2 +; CHECK-NEXT: fcvtzs w8, d1 +; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: ret + %x = call i19 @llvm.fptosi.sat.i19.f64(double %f) + ret i19 %x +} + +define i32 @test_signed_i32_f64(double %f) { +; CHECK-LABEL: test_signed_i32_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI13_0 +; CHECK-NEXT: adrp x9, .LCPI13_1 +; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI13_0] +; CHECK-NEXT: ldr d2, [x9, :lo12:.LCPI13_1] +; CHECK-NEXT: fcmp d0, d0 +; CHECK-NEXT: fmaxnm d1, d0, d1 +; CHECK-NEXT: fminnm d1, d1, d2 +; CHECK-NEXT: fcvtzs w8, d1 +; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: ret + %x = call i32 @llvm.fptosi.sat.i32.f64(double %f) + ret i32 %x +} + +define i50 @test_signed_i50_f64(double %f) { +; CHECK-LABEL: test_signed_i50_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI14_0 +; CHECK-NEXT: adrp x9, .LCPI14_1 +; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI14_0] +; CHECK-NEXT: ldr d2, [x9, :lo12:.LCPI14_1] +; CHECK-NEXT: fcmp d0, d0 +; CHECK-NEXT: fmaxnm d1, d0, d1 +; CHECK-NEXT: fminnm d1, d1, d2 +; CHECK-NEXT: fcvtzs x8, d1 +; CHECK-NEXT: csel x0, xzr, x8, vs +; CHECK-NEXT: ret + %x = call i50 @llvm.fptosi.sat.i50.f64(double %f) + ret i50 %x +} + +define i64 @test_signed_i64_f64(double %f) { +; CHECK-LABEL: test_signed_i64_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x9, .LCPI15_0 +; CHECK-NEXT: ldr d1, [x9, :lo12:.LCPI15_0] +; CHECK-NEXT: adrp x9, .LCPI15_1 +; CHECK-NEXT: ldr d2, [x9, :lo12:.LCPI15_1] +; CHECK-NEXT: fcvtzs x8, d0 +; CHECK-NEXT: orr x10, xzr, #0x8000000000000000 +; CHECK-NEXT: fcmp d0, d1 +; CHECK-NEXT: orr x9, xzr, #0x7fffffffffffffff +; CHECK-NEXT: csel x8, x10, x8, lt +; CHECK-NEXT: fcmp d0, d2 +; CHECK-NEXT: csel x8, x9, x8, gt +; CHECK-NEXT: fcmp d0, d0 +; CHECK-NEXT: csel x0, xzr, x8, vs +; CHECK-NEXT: ret + %x = call i64 @llvm.fptosi.sat.i64.f64(double %f) + ret i64 %x +} + +;define i100 @test_signed_i100_f64(double %f) { +; %x = call i100 @llvm.fptosi.sat.i100.f64(double %f) +; ret i100 %x +;} +; +;define i128 @test_signed_i128_f64(double %f) { +; %x = call i128 @llvm.fptosi.sat.i128.f64(double %f) +; ret i128 %x +;} + +; +; 16-bit float to signed integer +; + +declare i1 @llvm.fptosi.sat.i1.f16 (half) +declare i8 @llvm.fptosi.sat.i8.f16 (half) +declare i13 @llvm.fptosi.sat.i13.f16 (half) +declare i16 @llvm.fptosi.sat.i16.f16 (half) +declare i19 @llvm.fptosi.sat.i19.f16 (half) +declare i32 @llvm.fptosi.sat.i32.f16 (half) +declare i50 @llvm.fptosi.sat.i50.f16 (half) +declare i64 @llvm.fptosi.sat.i64.f16 (half) +declare i100 @llvm.fptosi.sat.i100.f16(half) +declare i128 @llvm.fptosi.sat.i128.f16(half) + +define i1 @test_signed_i1_f16(half %f) { +; CHECK-LABEL: test_signed_i1_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: fmov s1, #-1.00000000 +; CHECK-NEXT: fcvtzs w8, s0 +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: csinv w8, w8, wzr, ge +; CHECK-NEXT: fcmp s0, #0.0 +; CHECK-NEXT: csel w8, wzr, w8, gt +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: csel w8, wzr, w8, vs +; CHECK-NEXT: and w0, w8, #0x1 +; CHECK-NEXT: ret + %x = call i1 @llvm.fptosi.sat.i1.f16(half %f) + ret i1 %x +} + +define i8 @test_signed_i8_f16(half %f) { +; CHECK-LABEL: test_signed_i8_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI17_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI17_0] +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: adrp x9, .LCPI17_1 +; CHECK-NEXT: orr w8, wzr, #0xffffff80 +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: ldr s1, [x9, :lo12:.LCPI17_1] +; CHECK-NEXT: fcvtzs w9, s0 +; CHECK-NEXT: csel w8, w8, w9, lt +; CHECK-NEXT: orr w9, wzr, #0x7f +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: csel w8, w9, w8, gt +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: ret + %x = call i8 @llvm.fptosi.sat.i8.f16(half %f) + ret i8 %x +} + +define i13 @test_signed_i13_f16(half %f) { +; CHECK-LABEL: test_signed_i13_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI18_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI18_0] +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: adrp x9, .LCPI18_1 +; CHECK-NEXT: orr w8, wzr, #0xfffff000 +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: ldr s1, [x9, :lo12:.LCPI18_1] +; CHECK-NEXT: fcvtzs w9, s0 +; CHECK-NEXT: csel w8, w8, w9, lt +; CHECK-NEXT: orr w9, wzr, #0xfff +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: csel w8, w9, w8, gt +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: ret + %x = call i13 @llvm.fptosi.sat.i13.f16(half %f) + ret i13 %x +} + +define i16 @test_signed_i16_f16(half %f) { +; CHECK-LABEL: test_signed_i16_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI19_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI19_0] +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: adrp x9, .LCPI19_1 +; CHECK-NEXT: orr w8, wzr, #0xffff8000 +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: ldr s1, [x9, :lo12:.LCPI19_1] +; CHECK-NEXT: fcvtzs w9, s0 +; CHECK-NEXT: csel w8, w8, w9, lt +; CHECK-NEXT: orr w9, wzr, #0x7fff +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: csel w8, w9, w8, gt +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: ret + %x = call i16 @llvm.fptosi.sat.i16.f16(half %f) + ret i16 %x +} + +define i19 @test_signed_i19_f16(half %f) { +; CHECK-LABEL: test_signed_i19_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI20_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI20_0] +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: adrp x9, .LCPI20_1 +; CHECK-NEXT: orr w8, wzr, #0xfffc0000 +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: ldr s1, [x9, :lo12:.LCPI20_1] +; CHECK-NEXT: fcvtzs w9, s0 +; CHECK-NEXT: csel w8, w8, w9, lt +; CHECK-NEXT: orr w9, wzr, #0x3ffff +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: csel w8, w9, w8, gt +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: ret + %x = call i19 @llvm.fptosi.sat.i19.f16(half %f) + ret i19 %x +} + +define i32 @test_signed_i32_f16(half %f) { +; CHECK-LABEL: test_signed_i32_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI21_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI21_0] +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: adrp x9, .LCPI21_1 +; CHECK-NEXT: orr w8, wzr, #0x80000000 +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: ldr s1, [x9, :lo12:.LCPI21_1] +; CHECK-NEXT: fcvtzs w9, s0 +; CHECK-NEXT: csel w8, w8, w9, lt +; CHECK-NEXT: orr w9, wzr, #0x7fffffff +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: csel w8, w9, w8, gt +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: csel w0, wzr, w8, vs +; CHECK-NEXT: ret + %x = call i32 @llvm.fptosi.sat.i32.f16(half %f) + ret i32 %x +} + +define i50 @test_signed_i50_f16(half %f) { +; CHECK-LABEL: test_signed_i50_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI22_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI22_0] +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: adrp x9, .LCPI22_1 +; CHECK-NEXT: orr x8, xzr, #0xfffe000000000000 +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: ldr s1, [x9, :lo12:.LCPI22_1] +; CHECK-NEXT: fcvtzs x9, s0 +; CHECK-NEXT: csel x8, x8, x9, lt +; CHECK-NEXT: orr x9, xzr, #0x1ffffffffffff +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: csel x8, x9, x8, gt +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: csel x0, xzr, x8, vs +; CHECK-NEXT: ret + %x = call i50 @llvm.fptosi.sat.i50.f16(half %f) + ret i50 %x +} + +define i64 @test_signed_i64_f16(half %f) { +; CHECK-LABEL: test_signed_i64_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI23_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI23_0] +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: adrp x9, .LCPI23_1 +; CHECK-NEXT: orr x8, xzr, #0x8000000000000000 +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: ldr s1, [x9, :lo12:.LCPI23_1] +; CHECK-NEXT: fcvtzs x9, s0 +; CHECK-NEXT: csel x8, x8, x9, lt +; CHECK-NEXT: orr x9, xzr, #0x7fffffffffffffff +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: csel x8, x9, x8, gt +; CHECK-NEXT: fcmp s0, s0 +; CHECK-NEXT: csel x0, xzr, x8, vs +; CHECK-NEXT: ret + %x = call i64 @llvm.fptosi.sat.i64.f16(half %f) + ret i64 %x +} + +;define i100 @test_signed_i100_f16(half %f) { +; %x = call i100 @llvm.fptosi.sat.i100.f16(half %f) +; ret i100 %x +;} +; +;define i128 @test_signed_i128_f16(half %f) { +; %x = call i128 @llvm.fptosi.sat.i128.f16(half %f) +; ret i128 %x +;} Index: test/CodeGen/AArch64/fptoui-sat-scalar.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/fptoui-sat-scalar.ll @@ -0,0 +1,439 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=aarch64 < %s | FileCheck %s + +; +; 32-bit float to unsigned integer +; + +declare i1 @llvm.fptoui.sat.i1.f32 (float) +declare i8 @llvm.fptoui.sat.i8.f32 (float) +declare i13 @llvm.fptoui.sat.i13.f32 (float) +declare i16 @llvm.fptoui.sat.i16.f32 (float) +declare i19 @llvm.fptoui.sat.i19.f32 (float) +declare i32 @llvm.fptoui.sat.i32.f32 (float) +declare i50 @llvm.fptoui.sat.i50.f32 (float) +declare i64 @llvm.fptoui.sat.i64.f32 (float) +declare i100 @llvm.fptoui.sat.i100.f32(float) +declare i128 @llvm.fptoui.sat.i128.f32(float) + +define i1 @test_unsigned_i1_f32(float %f) { +; CHECK-LABEL: test_unsigned_i1_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov s1, wzr +; CHECK-NEXT: fmaxnm s0, s0, s1 +; CHECK-NEXT: fmov s1, #1.00000000 +; CHECK-NEXT: fminnm s0, s0, s1 +; CHECK-NEXT: fcvtzu w8, s0 +; CHECK-NEXT: and w0, w8, #0x1 +; CHECK-NEXT: ret + %x = call i1 @llvm.fptoui.sat.i1.f32(float %f) + ret i1 %x +} + +define i8 @test_unsigned_i8_f32(float %f) { +; CHECK-LABEL: test_unsigned_i8_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI1_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI1_0] +; CHECK-NEXT: fmov s2, wzr +; CHECK-NEXT: fmaxnm s0, s0, s2 +; CHECK-NEXT: fminnm s0, s0, s1 +; CHECK-NEXT: fcvtzu w0, s0 +; CHECK-NEXT: ret + %x = call i8 @llvm.fptoui.sat.i8.f32(float %f) + ret i8 %x +} + +define i13 @test_unsigned_i13_f32(float %f) { +; CHECK-LABEL: test_unsigned_i13_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI2_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI2_0] +; CHECK-NEXT: fmov s2, wzr +; CHECK-NEXT: fmaxnm s0, s0, s2 +; CHECK-NEXT: fminnm s0, s0, s1 +; CHECK-NEXT: fcvtzu w0, s0 +; CHECK-NEXT: ret + %x = call i13 @llvm.fptoui.sat.i13.f32(float %f) + ret i13 %x +} + +define i16 @test_unsigned_i16_f32(float %f) { +; CHECK-LABEL: test_unsigned_i16_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI3_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI3_0] +; CHECK-NEXT: fmov s2, wzr +; CHECK-NEXT: fmaxnm s0, s0, s2 +; CHECK-NEXT: fminnm s0, s0, s1 +; CHECK-NEXT: fcvtzu w0, s0 +; CHECK-NEXT: ret + %x = call i16 @llvm.fptoui.sat.i16.f32(float %f) + ret i16 %x +} + +define i19 @test_unsigned_i19_f32(float %f) { +; CHECK-LABEL: test_unsigned_i19_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI4_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI4_0] +; CHECK-NEXT: fmov s2, wzr +; CHECK-NEXT: fmaxnm s0, s0, s2 +; CHECK-NEXT: fminnm s0, s0, s1 +; CHECK-NEXT: fcvtzu w0, s0 +; CHECK-NEXT: ret + %x = call i19 @llvm.fptoui.sat.i19.f32(float %f) + ret i19 %x +} + +define i32 @test_unsigned_i32_f32(float %f) { +; CHECK-LABEL: test_unsigned_i32_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI5_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI5_0] +; CHECK-NEXT: fcvtzu w8, s0 +; CHECK-NEXT: fcmp s0, #0.0 +; CHECK-NEXT: csel w8, wzr, w8, lt +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: csinv w0, w8, wzr, le +; CHECK-NEXT: ret + %x = call i32 @llvm.fptoui.sat.i32.f32(float %f) + ret i32 %x +} + +define i50 @test_unsigned_i50_f32(float %f) { +; CHECK-LABEL: test_unsigned_i50_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI6_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI6_0] +; CHECK-NEXT: fcvtzu x8, s0 +; CHECK-NEXT: fcmp s0, #0.0 +; CHECK-NEXT: csel x8, xzr, x8, lt +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: orr x9, xzr, #0x3ffffffffffff +; CHECK-NEXT: csel x0, x9, x8, gt +; CHECK-NEXT: ret + %x = call i50 @llvm.fptoui.sat.i50.f32(float %f) + ret i50 %x +} + +define i64 @test_unsigned_i64_f32(float %f) { +; CHECK-LABEL: test_unsigned_i64_f32: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI7_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI7_0] +; CHECK-NEXT: fcvtzu x8, s0 +; CHECK-NEXT: fcmp s0, #0.0 +; CHECK-NEXT: csel x8, xzr, x8, lt +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: csinv x0, x8, xzr, le +; CHECK-NEXT: ret + %x = call i64 @llvm.fptoui.sat.i64.f32(float %f) + ret i64 %x +} + +;define i100 @test_unsigned_i100_f32(float %f) { +; %x = call i100 @llvm.fptoui.sat.i100.f32(float %f) +; ret i100 %x +;} +; +;define i128 @test_unsigned_i128_f32(float %f) { +; %x = call i128 @llvm.fptoui.sat.i128.f32(float %f) +; ret i128 %x +;} + +; +; 64-bit float to unsigned integer +; + +declare i1 @llvm.fptoui.sat.i1.f64 (double) +declare i8 @llvm.fptoui.sat.i8.f64 (double) +declare i13 @llvm.fptoui.sat.i13.f64 (double) +declare i16 @llvm.fptoui.sat.i16.f64 (double) +declare i19 @llvm.fptoui.sat.i19.f64 (double) +declare i32 @llvm.fptoui.sat.i32.f64 (double) +declare i50 @llvm.fptoui.sat.i50.f64 (double) +declare i64 @llvm.fptoui.sat.i64.f64 (double) +declare i100 @llvm.fptoui.sat.i100.f64(double) +declare i128 @llvm.fptoui.sat.i128.f64(double) + +define i1 @test_unsigned_i1_f64(double %f) { +; CHECK-LABEL: test_unsigned_i1_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: fmov d1, xzr +; CHECK-NEXT: fmaxnm d0, d0, d1 +; CHECK-NEXT: fmov d1, #1.00000000 +; CHECK-NEXT: fminnm d0, d0, d1 +; CHECK-NEXT: fcvtzu w8, d0 +; CHECK-NEXT: and w0, w8, #0x1 +; CHECK-NEXT: ret + %x = call i1 @llvm.fptoui.sat.i1.f64(double %f) + ret i1 %x +} + +define i8 @test_unsigned_i8_f64(double %f) { +; CHECK-LABEL: test_unsigned_i8_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI9_0 +; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI9_0] +; CHECK-NEXT: fmov d2, xzr +; CHECK-NEXT: fmaxnm d0, d0, d2 +; CHECK-NEXT: fminnm d0, d0, d1 +; CHECK-NEXT: fcvtzu w0, d0 +; CHECK-NEXT: ret + %x = call i8 @llvm.fptoui.sat.i8.f64(double %f) + ret i8 %x +} + +define i13 @test_unsigned_i13_f64(double %f) { +; CHECK-LABEL: test_unsigned_i13_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI10_0 +; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI10_0] +; CHECK-NEXT: fmov d2, xzr +; CHECK-NEXT: fmaxnm d0, d0, d2 +; CHECK-NEXT: fminnm d0, d0, d1 +; CHECK-NEXT: fcvtzu w0, d0 +; CHECK-NEXT: ret + %x = call i13 @llvm.fptoui.sat.i13.f64(double %f) + ret i13 %x +} + +define i16 @test_unsigned_i16_f64(double %f) { +; CHECK-LABEL: test_unsigned_i16_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI11_0 +; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI11_0] +; CHECK-NEXT: fmov d2, xzr +; CHECK-NEXT: fmaxnm d0, d0, d2 +; CHECK-NEXT: fminnm d0, d0, d1 +; CHECK-NEXT: fcvtzu w0, d0 +; CHECK-NEXT: ret + %x = call i16 @llvm.fptoui.sat.i16.f64(double %f) + ret i16 %x +} + +define i19 @test_unsigned_i19_f64(double %f) { +; CHECK-LABEL: test_unsigned_i19_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI12_0 +; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI12_0] +; CHECK-NEXT: fmov d2, xzr +; CHECK-NEXT: fmaxnm d0, d0, d2 +; CHECK-NEXT: fminnm d0, d0, d1 +; CHECK-NEXT: fcvtzu w0, d0 +; CHECK-NEXT: ret + %x = call i19 @llvm.fptoui.sat.i19.f64(double %f) + ret i19 %x +} + +define i32 @test_unsigned_i32_f64(double %f) { +; CHECK-LABEL: test_unsigned_i32_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI13_0 +; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI13_0] +; CHECK-NEXT: fmov d2, xzr +; CHECK-NEXT: fmaxnm d0, d0, d2 +; CHECK-NEXT: fminnm d0, d0, d1 +; CHECK-NEXT: fcvtzu w0, d0 +; CHECK-NEXT: ret + %x = call i32 @llvm.fptoui.sat.i32.f64(double %f) + ret i32 %x +} + +define i50 @test_unsigned_i50_f64(double %f) { +; CHECK-LABEL: test_unsigned_i50_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI14_0 +; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI14_0] +; CHECK-NEXT: fmov d2, xzr +; CHECK-NEXT: fmaxnm d0, d0, d2 +; CHECK-NEXT: fminnm d0, d0, d1 +; CHECK-NEXT: fcvtzu x0, d0 +; CHECK-NEXT: ret + %x = call i50 @llvm.fptoui.sat.i50.f64(double %f) + ret i50 %x +} + +define i64 @test_unsigned_i64_f64(double %f) { +; CHECK-LABEL: test_unsigned_i64_f64: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI15_0 +; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI15_0] +; CHECK-NEXT: fcvtzu x8, d0 +; CHECK-NEXT: fcmp d0, #0.0 +; CHECK-NEXT: csel x8, xzr, x8, lt +; CHECK-NEXT: fcmp d0, d1 +; CHECK-NEXT: csinv x0, x8, xzr, le +; CHECK-NEXT: ret + %x = call i64 @llvm.fptoui.sat.i64.f64(double %f) + ret i64 %x +} + +;define i100 @test_unsigned_i100_f64(double %f) { +; %x = call i100 @llvm.fptoui.sat.i100.f64(double %f) +; ret i100 %x +;} +; +;define i128 @test_unsigned_i128_f64(double %f) { +; %x = call i128 @llvm.fptoui.sat.i128.f64(double %f) +; ret i128 %x +;} + +; +; 16-bit float to unsigned integer +; + +declare i1 @llvm.fptoui.sat.i1.f16 (half) +declare i8 @llvm.fptoui.sat.i8.f16 (half) +declare i13 @llvm.fptoui.sat.i13.f16 (half) +declare i16 @llvm.fptoui.sat.i16.f16 (half) +declare i19 @llvm.fptoui.sat.i19.f16 (half) +declare i32 @llvm.fptoui.sat.i32.f16 (half) +declare i50 @llvm.fptoui.sat.i50.f16 (half) +declare i64 @llvm.fptoui.sat.i64.f16 (half) +declare i100 @llvm.fptoui.sat.i100.f16(half) +declare i128 @llvm.fptoui.sat.i128.f16(half) + +define i1 @test_unsigned_i1_f16(half %f) { +; CHECK-LABEL: test_unsigned_i1_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: fmov s1, #1.00000000 +; CHECK-NEXT: fcvtzu w8, s0 +; CHECK-NEXT: fcmp s0, #0.0 +; CHECK-NEXT: csel w8, wzr, w8, lt +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: csinc w8, w8, wzr, le +; CHECK-NEXT: and w0, w8, #0x1 +; CHECK-NEXT: ret + %x = call i1 @llvm.fptoui.sat.i1.f16(half %f) + ret i1 %x +} + +define i8 @test_unsigned_i8_f16(half %f) { +; CHECK-LABEL: test_unsigned_i8_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI17_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI17_0] +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: fcvtzu w8, s0 +; CHECK-NEXT: fcmp s0, #0.0 +; CHECK-NEXT: csel w8, wzr, w8, lt +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: orr w9, wzr, #0xff +; CHECK-NEXT: csel w0, w9, w8, gt +; CHECK-NEXT: ret + %x = call i8 @llvm.fptoui.sat.i8.f16(half %f) + ret i8 %x +} + +define i13 @test_unsigned_i13_f16(half %f) { +; CHECK-LABEL: test_unsigned_i13_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI18_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI18_0] +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: fcvtzu w8, s0 +; CHECK-NEXT: fcmp s0, #0.0 +; CHECK-NEXT: csel w8, wzr, w8, lt +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: orr w9, wzr, #0x1fff +; CHECK-NEXT: csel w0, w9, w8, gt +; CHECK-NEXT: ret + %x = call i13 @llvm.fptoui.sat.i13.f16(half %f) + ret i13 %x +} + +define i16 @test_unsigned_i16_f16(half %f) { +; CHECK-LABEL: test_unsigned_i16_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI19_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI19_0] +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: fcvtzu w8, s0 +; CHECK-NEXT: fcmp s0, #0.0 +; CHECK-NEXT: csel w8, wzr, w8, lt +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: orr w9, wzr, #0xffff +; CHECK-NEXT: csel w0, w9, w8, gt +; CHECK-NEXT: ret + %x = call i16 @llvm.fptoui.sat.i16.f16(half %f) + ret i16 %x +} + +define i19 @test_unsigned_i19_f16(half %f) { +; CHECK-LABEL: test_unsigned_i19_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI20_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI20_0] +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: fcvtzu w8, s0 +; CHECK-NEXT: fcmp s0, #0.0 +; CHECK-NEXT: csel w8, wzr, w8, lt +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: orr w9, wzr, #0x7ffff +; CHECK-NEXT: csel w0, w9, w8, gt +; CHECK-NEXT: ret + %x = call i19 @llvm.fptoui.sat.i19.f16(half %f) + ret i19 %x +} + +define i32 @test_unsigned_i32_f16(half %f) { +; CHECK-LABEL: test_unsigned_i32_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI21_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI21_0] +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: fcvtzu w8, s0 +; CHECK-NEXT: fcmp s0, #0.0 +; CHECK-NEXT: csel w8, wzr, w8, lt +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: csinv w0, w8, wzr, le +; CHECK-NEXT: ret + %x = call i32 @llvm.fptoui.sat.i32.f16(half %f) + ret i32 %x +} + +define i50 @test_unsigned_i50_f16(half %f) { +; CHECK-LABEL: test_unsigned_i50_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI22_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI22_0] +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: fcvtzu x8, s0 +; CHECK-NEXT: fcmp s0, #0.0 +; CHECK-NEXT: csel x8, xzr, x8, lt +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: orr x9, xzr, #0x3ffffffffffff +; CHECK-NEXT: csel x0, x9, x8, gt +; CHECK-NEXT: ret + %x = call i50 @llvm.fptoui.sat.i50.f16(half %f) + ret i50 %x +} + +define i64 @test_unsigned_i64_f16(half %f) { +; CHECK-LABEL: test_unsigned_i64_f16: +; CHECK: // %bb.0: +; CHECK-NEXT: adrp x8, .LCPI23_0 +; CHECK-NEXT: ldr s1, [x8, :lo12:.LCPI23_0] +; CHECK-NEXT: fcvt s0, h0 +; CHECK-NEXT: fcvtzu x8, s0 +; CHECK-NEXT: fcmp s0, #0.0 +; CHECK-NEXT: csel x8, xzr, x8, lt +; CHECK-NEXT: fcmp s0, s1 +; CHECK-NEXT: csinv x0, x8, xzr, le +; CHECK-NEXT: ret + %x = call i64 @llvm.fptoui.sat.i64.f16(half %f) + ret i64 %x +} + +;define i100 @test_unsigned_i100_f16(half %f) { +; %x = call i100 @llvm.fptoui.sat.i100.f16(half %f) +; ret i100 %x +;} +; +;define i128 @test_unsigned_i128_f16(half %f) { +; %x = call i128 @llvm.fptoui.sat.i128.f16(half %f) +; ret i128 %x +;} Index: test/CodeGen/X86/fptosi-sat-scalar.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/fptosi-sat-scalar.ll @@ -0,0 +1,2738 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=i686-linux | FileCheck %s --check-prefix=X86 --check-prefix=X86-X87 +; RUN: llc < %s -mtriple=i686-linux -mattr=+sse2 | FileCheck %s --check-prefix=X86 --check-prefix=X86-SSE +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefix=X64 + +; +; 32-bit float to signed integer +; + +declare i1 @llvm.fptosi.sat.i1.f32 (float) +declare i8 @llvm.fptosi.sat.i8.f32 (float) +declare i13 @llvm.fptosi.sat.i13.f32 (float) +declare i16 @llvm.fptosi.sat.i16.f32 (float) +declare i19 @llvm.fptosi.sat.i19.f32 (float) +declare i32 @llvm.fptosi.sat.i32.f32 (float) +declare i50 @llvm.fptosi.sat.i50.f32 (float) +declare i64 @llvm.fptosi.sat.i64.f32 (float) +declare i100 @llvm.fptosi.sat.i100.f32(float) +declare i128 @llvm.fptosi.sat.i128.f32(float) + +define i1 @test_signed_i1_f32(float %f) { +; X86-X87-LABEL: test_signed_i1_f32: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %ebx +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 12 +; X86-X87-NEXT: .cfi_offset %ebx, -8 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: fld1 +; X86-X87-NEXT: fchs +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $-1, %dl +; X86-X87-NEXT: jb .LBB0_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %dl +; X86-X87-NEXT: .LBB0_2: +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $0, %ebx +; X86-X87-NEXT: ja .LBB0_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %edx, %ebx +; X86-X87-NEXT: .LBB0_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB0_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %ebx, %ecx +; X86-X87-NEXT: .LBB0_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: addl $4, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: popl %ebx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i1_f32: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: ucomiss {{\.LCPI.*}}, %xmm0 +; X86-SSE-NEXT: movb $-1, %cl +; X86-SSE-NEXT: jb .LBB0_2 +; X86-SSE-NEXT: # %bb.1: +; X86-SSE-NEXT: cvttss2si %xmm0, %ecx +; X86-SSE-NEXT: .LBB0_2: +; X86-SSE-NEXT: xorl %eax, %eax +; X86-SSE-NEXT: xorps %xmm1, %xmm1 +; X86-SSE-NEXT: ucomiss %xmm1, %xmm0 +; X86-SSE-NEXT: movl $0, %edx +; X86-SSE-NEXT: jbe .LBB0_3 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: ucomiss %xmm0, %xmm0 +; X86-SSE-NEXT: jnp .LBB0_5 +; X86-SSE-NEXT: .LBB0_6: +; X86-SSE-NEXT: # kill: def $al killed $al killed $eax +; X86-SSE-NEXT: retl +; X86-SSE-NEXT: .LBB0_3: +; X86-SSE-NEXT: movl %ecx, %edx +; X86-SSE-NEXT: ucomiss %xmm0, %xmm0 +; X86-SSE-NEXT: jp .LBB0_6 +; X86-SSE-NEXT: .LBB0_5: +; X86-SSE-NEXT: movl %edx, %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: ucomiss {{.*}}(%rip), %xmm0 +; X64-NEXT: movb $-1, %cl +; X64-NEXT: jb .LBB0_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: cvttss2si %xmm0, %ecx +; X64-NEXT: .LBB0_2: +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: xorps %xmm1, %xmm1 +; X64-NEXT: ucomiss %xmm1, %xmm0 +; X64-NEXT: movl $0, %edx +; X64-NEXT: jbe .LBB0_3 +; X64-NEXT: # %bb.4: +; X64-NEXT: ucomiss %xmm0, %xmm0 +; X64-NEXT: jnp .LBB0_5 +; X64-NEXT: .LBB0_6: +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: retq +; X64-NEXT: .LBB0_3: +; X64-NEXT: movl %ecx, %edx +; X64-NEXT: ucomiss %xmm0, %xmm0 +; X64-NEXT: jp .LBB0_6 +; X64-NEXT: .LBB0_5: +; X64-NEXT: movl %edx, %eax +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: retq + %x = call i1 @llvm.fptosi.sat.i1.f32(float %f) + ret i1 %x +} + +define i8 @test_signed_i8_f32(float %f) { +; X86-X87-LABEL: test_signed_i8_f32: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $-128, %dl +; X86-X87-NEXT: jb .LBB1_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %dl +; X86-X87-NEXT: .LBB1_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $127, %cl +; X86-X87-NEXT: ja .LBB1_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB1_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jnp .LBB1_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: .LBB1_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: popl %ecx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i8_f32: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: ucomiss {{\.LCPI.*}}, %xmm0 +; X86-SSE-NEXT: movb $-128, %cl +; X86-SSE-NEXT: jb .LBB1_2 +; X86-SSE-NEXT: # %bb.1: +; X86-SSE-NEXT: cvttss2si %xmm0, %ecx +; X86-SSE-NEXT: .LBB1_2: +; X86-SSE-NEXT: ucomiss {{\.LCPI.*}}, %xmm0 +; X86-SSE-NEXT: movb $127, %al +; X86-SSE-NEXT: jbe .LBB1_3 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: ucomiss %xmm0, %xmm0 +; X86-SSE-NEXT: jp .LBB1_5 +; X86-SSE-NEXT: .LBB1_6: +; X86-SSE-NEXT: # kill: def $al killed $al killed $eax +; X86-SSE-NEXT: retl +; X86-SSE-NEXT: .LBB1_3: +; X86-SSE-NEXT: movl %ecx, %eax +; X86-SSE-NEXT: ucomiss %xmm0, %xmm0 +; X86-SSE-NEXT: jnp .LBB1_6 +; X86-SSE-NEXT: .LBB1_5: +; X86-SSE-NEXT: xorl %eax, %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: ucomiss {{.*}}(%rip), %xmm0 +; X64-NEXT: movb $-128, %cl +; X64-NEXT: jb .LBB1_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: cvttss2si %xmm0, %ecx +; X64-NEXT: .LBB1_2: +; X64-NEXT: ucomiss {{.*}}(%rip), %xmm0 +; X64-NEXT: movb $127, %al +; X64-NEXT: jbe .LBB1_3 +; X64-NEXT: # %bb.4: +; X64-NEXT: ucomiss %xmm0, %xmm0 +; X64-NEXT: jp .LBB1_5 +; X64-NEXT: .LBB1_6: +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: retq +; X64-NEXT: .LBB1_3: +; X64-NEXT: movl %ecx, %eax +; X64-NEXT: ucomiss %xmm0, %xmm0 +; X64-NEXT: jnp .LBB1_6 +; X64-NEXT: .LBB1_5: +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: retq + %x = call i8 @llvm.fptosi.sat.i8.f32(float %f) + ret i8 %x +} + +define i13 @test_signed_i13_f32(float %f) { +; X86-X87-LABEL: test_signed_i13_f32: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movw $-4096, %cx # imm = 0xF000 +; X86-X87-NEXT: jb .LBB2_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB2_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $4095, %edx # imm = 0xFFF +; X86-X87-NEXT: ja .LBB2_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB2_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB2_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB2_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: popl %ecx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; 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: # kill: def $ax killed $ax killed $eax +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i13_f32: +; X64: # %bb.0: +; 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) + ret i13 %x +} + +define i16 @test_signed_i16_f32(float %f) { +; X86-X87-LABEL: test_signed_i16_f32: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movw $-32768, %cx # imm = 0x8000 +; X86-X87-NEXT: jb .LBB3_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB3_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $32767, %edx # imm = 0x7FFF +; X86-X87-NEXT: ja .LBB3_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB3_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB3_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB3_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: popl %ecx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; 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: # kill: def $ax killed $ax killed $eax +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i16_f32: +; X64: # %bb.0: +; 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) + ret i16 %x +} + +define i19 @test_signed_i19_f32(float %f) { +; X86-X87-LABEL: test_signed_i19_f32: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 12 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $-262144, %ecx # imm = 0xFFFC0000 +; X86-X87-NEXT: jb .LBB4_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB4_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $262143, %edx # imm = 0x3FFFF +; X86-X87-NEXT: ja .LBB4_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB4_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB4_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB4_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: addl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; 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: 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: retq + %x = call i19 @llvm.fptosi.sat.i19.f32(float %f) + ret i19 %x +} + +define i32 @test_signed_i32_f32(float %f) { +; X86-X87-LABEL: test_signed_i32_f32: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 12 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $-2147483648, %ecx # imm = 0x80000000 +; X86-X87-NEXT: jb .LBB5_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB5_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $2147483647, %edx # imm = 0x7FFFFFFF +; X86-X87-NEXT: ja .LBB5_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB5_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB5_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB5_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: addl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i32_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 $-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: xorl %eax, %eax +; X86-SSE-NEXT: ucomiss %xmm0, %xmm0 +; X86-SSE-NEXT: cmovnpl %edx, %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: xorl %eax, %eax +; X64-NEXT: ucomiss %xmm0, %xmm0 +; X64-NEXT: cmovnpl %edx, %eax +; X64-NEXT: retq + %x = call i32 @llvm.fptosi.sat.i32.f32(float %f) + ret i32 %x +} + +;define i50 @test_signed_i50_f32(float %f) { +; %x = call i50 @llvm.fptosi.sat.i50.f32(float %f) +; ret i50 %x +;} +; +;define i64 @test_signed_i64_f32(float %f) { +; %x = call i64 @llvm.fptosi.sat.i64.f32(float %f) +; ret i64 %x +;} +; +;define i100 @test_signed_i100_f32(float %f) { +; %x = call i100 @llvm.fptosi.sat.i100.f32(float %f) +; ret i100 %x +;} +; +;define i128 @test_signed_i128_f32(float %f) { +; %x = call i128 @llvm.fptosi.sat.i128.f32(float %f) +; ret i128 %x +;} + +; +; 64-bit float to signed integer +; + +declare i1 @llvm.fptosi.sat.i1.f64 (double) +declare i8 @llvm.fptosi.sat.i8.f64 (double) +declare i13 @llvm.fptosi.sat.i13.f64 (double) +declare i16 @llvm.fptosi.sat.i16.f64 (double) +declare i19 @llvm.fptosi.sat.i19.f64 (double) +declare i32 @llvm.fptosi.sat.i32.f64 (double) +declare i50 @llvm.fptosi.sat.i50.f64 (double) +declare i64 @llvm.fptosi.sat.i64.f64 (double) +declare i100 @llvm.fptosi.sat.i100.f64(double) +declare i128 @llvm.fptosi.sat.i128.f64(double) + +define i1 @test_signed_i1_f64(double %f) { +; X86-X87-LABEL: test_signed_i1_f64: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %ebx +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 12 +; X86-X87-NEXT: .cfi_offset %ebx, -8 +; X86-X87-NEXT: fldl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: fld1 +; X86-X87-NEXT: fchs +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $-1, %dl +; X86-X87-NEXT: jb .LBB6_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %dl +; X86-X87-NEXT: .LBB6_2: +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $0, %ebx +; X86-X87-NEXT: ja .LBB6_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %edx, %ebx +; X86-X87-NEXT: .LBB6_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB6_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %ebx, %ecx +; X86-X87-NEXT: .LBB6_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: addl $4, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: popl %ebx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i1_f64: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero +; X86-SSE-NEXT: ucomisd {{\.LCPI.*}}, %xmm0 +; X86-SSE-NEXT: movb $-1, %cl +; X86-SSE-NEXT: jb .LBB6_2 +; X86-SSE-NEXT: # %bb.1: +; X86-SSE-NEXT: cvttsd2si %xmm0, %ecx +; X86-SSE-NEXT: .LBB6_2: +; X86-SSE-NEXT: xorl %eax, %eax +; X86-SSE-NEXT: xorps %xmm1, %xmm1 +; X86-SSE-NEXT: ucomisd %xmm1, %xmm0 +; X86-SSE-NEXT: movl $0, %edx +; X86-SSE-NEXT: jbe .LBB6_3 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: ucomisd %xmm0, %xmm0 +; X86-SSE-NEXT: jnp .LBB6_5 +; X86-SSE-NEXT: .LBB6_6: +; X86-SSE-NEXT: # kill: def $al killed $al killed $eax +; X86-SSE-NEXT: retl +; X86-SSE-NEXT: .LBB6_3: +; X86-SSE-NEXT: movl %ecx, %edx +; X86-SSE-NEXT: ucomisd %xmm0, %xmm0 +; X86-SSE-NEXT: jp .LBB6_6 +; X86-SSE-NEXT: .LBB6_5: +; X86-SSE-NEXT: movl %edx, %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: ucomisd {{.*}}(%rip), %xmm0 +; X64-NEXT: movb $-1, %cl +; X64-NEXT: jb .LBB6_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: cvttsd2si %xmm0, %ecx +; X64-NEXT: .LBB6_2: +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: xorps %xmm1, %xmm1 +; X64-NEXT: ucomisd %xmm1, %xmm0 +; X64-NEXT: movl $0, %edx +; X64-NEXT: jbe .LBB6_3 +; X64-NEXT: # %bb.4: +; X64-NEXT: ucomisd %xmm0, %xmm0 +; X64-NEXT: jnp .LBB6_5 +; X64-NEXT: .LBB6_6: +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: retq +; X64-NEXT: .LBB6_3: +; X64-NEXT: movl %ecx, %edx +; X64-NEXT: ucomisd %xmm0, %xmm0 +; X64-NEXT: jp .LBB6_6 +; X64-NEXT: .LBB6_5: +; X64-NEXT: movl %edx, %eax +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: retq + %x = call i1 @llvm.fptosi.sat.i1.f64(double %f) + ret i1 %x +} + +define i8 @test_signed_i8_f64(double %f) { +; X86-X87-LABEL: test_signed_i8_f64: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: fldl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $-128, %dl +; X86-X87-NEXT: jb .LBB7_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %dl +; X86-X87-NEXT: .LBB7_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $127, %cl +; X86-X87-NEXT: ja .LBB7_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB7_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jnp .LBB7_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: .LBB7_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: popl %ecx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i8_f64: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero +; X86-SSE-NEXT: ucomisd {{\.LCPI.*}}, %xmm0 +; X86-SSE-NEXT: movb $-128, %cl +; X86-SSE-NEXT: jb .LBB7_2 +; X86-SSE-NEXT: # %bb.1: +; X86-SSE-NEXT: cvttsd2si %xmm0, %ecx +; X86-SSE-NEXT: .LBB7_2: +; X86-SSE-NEXT: ucomisd {{\.LCPI.*}}, %xmm0 +; X86-SSE-NEXT: movb $127, %al +; X86-SSE-NEXT: jbe .LBB7_3 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: ucomisd %xmm0, %xmm0 +; X86-SSE-NEXT: jp .LBB7_5 +; X86-SSE-NEXT: .LBB7_6: +; X86-SSE-NEXT: # kill: def $al killed $al killed $eax +; X86-SSE-NEXT: retl +; X86-SSE-NEXT: .LBB7_3: +; X86-SSE-NEXT: movl %ecx, %eax +; X86-SSE-NEXT: ucomisd %xmm0, %xmm0 +; X86-SSE-NEXT: jnp .LBB7_6 +; X86-SSE-NEXT: .LBB7_5: +; X86-SSE-NEXT: xorl %eax, %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: ucomisd {{.*}}(%rip), %xmm0 +; X64-NEXT: movb $-128, %cl +; X64-NEXT: jb .LBB7_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: cvttsd2si %xmm0, %ecx +; X64-NEXT: .LBB7_2: +; X64-NEXT: ucomisd {{.*}}(%rip), %xmm0 +; X64-NEXT: movb $127, %al +; X64-NEXT: jbe .LBB7_3 +; X64-NEXT: # %bb.4: +; X64-NEXT: ucomisd %xmm0, %xmm0 +; X64-NEXT: jp .LBB7_5 +; X64-NEXT: .LBB7_6: +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: retq +; X64-NEXT: .LBB7_3: +; X64-NEXT: movl %ecx, %eax +; X64-NEXT: ucomisd %xmm0, %xmm0 +; X64-NEXT: jnp .LBB7_6 +; X64-NEXT: .LBB7_5: +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: retq + %x = call i8 @llvm.fptosi.sat.i8.f64(double %f) + ret i8 %x +} + +define i13 @test_signed_i13_f64(double %f) { +; X86-X87-LABEL: test_signed_i13_f64: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: fldl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movw $-4096, %cx # imm = 0xF000 +; X86-X87-NEXT: jb .LBB8_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB8_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $4095, %edx # imm = 0xFFF +; X86-X87-NEXT: ja .LBB8_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB8_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB8_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB8_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: popl %ecx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; 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: # kill: def $ax killed $ax killed $eax +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i13_f64: +; X64: # %bb.0: +; 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) + ret i13 %x +} + +define i16 @test_signed_i16_f64(double %f) { +; X86-X87-LABEL: test_signed_i16_f64: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: fldl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movw $-32768, %cx # imm = 0x8000 +; X86-X87-NEXT: jb .LBB9_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB9_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $32767, %edx # imm = 0x7FFF +; X86-X87-NEXT: ja .LBB9_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB9_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB9_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB9_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: popl %ecx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; 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: # kill: def $ax killed $ax killed $eax +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i16_f64: +; X64: # %bb.0: +; 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) + ret i16 %x +} + +define i19 @test_signed_i19_f64(double %f) { +; X86-X87-LABEL: test_signed_i19_f64: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 12 +; X86-X87-NEXT: fldl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $-262144, %ecx # imm = 0xFFFC0000 +; X86-X87-NEXT: jb .LBB10_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB10_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $262143, %edx # imm = 0x3FFFF +; X86-X87-NEXT: ja .LBB10_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB10_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB10_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB10_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: addl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; 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: 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: retq + %x = call i19 @llvm.fptosi.sat.i19.f64(double %f) + ret i19 %x +} + +define i32 @test_signed_i32_f64(double %f) { +; X86-X87-LABEL: test_signed_i32_f64: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 12 +; X86-X87-NEXT: fldl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $-2147483648, %ecx # imm = 0x80000000 +; X86-X87-NEXT: jb .LBB11_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB11_2: +; X86-X87-NEXT: fldl {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $2147483647, %edx # imm = 0x7FFFFFFF +; X86-X87-NEXT: ja .LBB11_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB11_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB11_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB11_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: addl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; 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: 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: retq + %x = call i32 @llvm.fptosi.sat.i32.f64(double %f) + ret i32 %x +} + +;define i50 @test_signed_i50_f64(double %f) { +; %x = call i50 @llvm.fptosi.sat.i50.f64(double %f) +; ret i50 %x +;} +; +;define i64 @test_signed_i64_f64(double %f) { +; %x = call i64 @llvm.fptosi.sat.i64.f64(double %f) +; ret i64 %x +;} +; +;define i100 @test_signed_i100_f64(double %f) { +; %x = call i100 @llvm.fptosi.sat.i100.f64(double %f) +; ret i100 %x +;} +; +;define i128 @test_signed_i128_f64(double %f) { +; %x = call i128 @llvm.fptosi.sat.i128.f64(double %f) +; ret i128 %x +;} + +; +; 16-bit float to signed integer +; + +declare i1 @llvm.fptosi.sat.i1.f16 (half) +declare i8 @llvm.fptosi.sat.i8.f16 (half) +declare i13 @llvm.fptosi.sat.i13.f16 (half) +declare i16 @llvm.fptosi.sat.i16.f16 (half) +declare i19 @llvm.fptosi.sat.i19.f16 (half) +declare i32 @llvm.fptosi.sat.i32.f16 (half) +declare i50 @llvm.fptosi.sat.i50.f16 (half) +declare i64 @llvm.fptosi.sat.i64.f16 (half) +declare i100 @llvm.fptosi.sat.i100.f16(half) +declare i128 @llvm.fptosi.sat.i128.f16(half) + +define i1 @test_signed_i1_f16(half %f) { +; X86-X87-LABEL: test_signed_i1_f16: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %ebx +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: subl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 16 +; X86-X87-NEXT: .cfi_offset %ebx, -8 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fstps (%esp) +; X86-X87-NEXT: calll __gnu_f2h_ieee +; X86-X87-NEXT: movzwl %ax, %eax +; X86-X87-NEXT: movl %eax, (%esp) +; X86-X87-NEXT: calll __gnu_h2f_ieee +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fld1 +; X86-X87-NEXT: fchs +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $-1, %dl +; X86-X87-NEXT: jb .LBB12_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %dl +; X86-X87-NEXT: .LBB12_2: +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $0, %ebx +; X86-X87-NEXT: ja .LBB12_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %edx, %ebx +; X86-X87-NEXT: .LBB12_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB12_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %ebx, %ecx +; X86-X87-NEXT: .LBB12_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: addl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: popl %ebx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i1_f16: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 16 +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: movss %xmm0, (%esp) +; X86-SSE-NEXT: calll __gnu_f2h_ieee +; X86-SSE-NEXT: movzwl %ax, %eax +; 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: ucomiss {{\.LCPI.*}}, %xmm0 +; X86-SSE-NEXT: movb $-1, %cl +; X86-SSE-NEXT: jb .LBB12_2 +; X86-SSE-NEXT: # %bb.1: +; X86-SSE-NEXT: cvttss2si %xmm0, %ecx +; X86-SSE-NEXT: .LBB12_2: +; X86-SSE-NEXT: xorl %eax, %eax +; X86-SSE-NEXT: xorps %xmm1, %xmm1 +; X86-SSE-NEXT: ucomiss %xmm1, %xmm0 +; X86-SSE-NEXT: movl $0, %edx +; X86-SSE-NEXT: jbe .LBB12_3 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: ucomiss %xmm0, %xmm0 +; X86-SSE-NEXT: jnp .LBB12_5 +; X86-SSE-NEXT: .LBB12_6: +; X86-SSE-NEXT: # kill: def $al killed $al killed $eax +; X86-SSE-NEXT: addl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; X86-SSE-NEXT: .LBB12_3: +; X86-SSE-NEXT: .cfi_def_cfa_offset 16 +; X86-SSE-NEXT: movl %ecx, %edx +; X86-SSE-NEXT: ucomiss %xmm0, %xmm0 +; X86-SSE-NEXT: jp .LBB12_6 +; X86-SSE-NEXT: .LBB12_5: +; X86-SSE-NEXT: movl %edx, %eax +; X86-SSE-NEXT: # kill: def $al killed $al killed $eax +; X86-SSE-NEXT: addl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i1_f16: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: callq __gnu_f2h_ieee +; X64-NEXT: movzwl %ax, %edi +; X64-NEXT: callq __gnu_h2f_ieee +; X64-NEXT: ucomiss {{.*}}(%rip), %xmm0 +; X64-NEXT: movb $-1, %cl +; X64-NEXT: jb .LBB12_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: cvttss2si %xmm0, %ecx +; X64-NEXT: .LBB12_2: +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: xorps %xmm1, %xmm1 +; X64-NEXT: ucomiss %xmm1, %xmm0 +; X64-NEXT: movl $0, %edx +; X64-NEXT: jbe .LBB12_3 +; X64-NEXT: # %bb.4: +; X64-NEXT: ucomiss %xmm0, %xmm0 +; X64-NEXT: jnp .LBB12_5 +; X64-NEXT: .LBB12_6: +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: popq %rcx +; X64-NEXT: .cfi_def_cfa_offset 8 +; X64-NEXT: retq +; X64-NEXT: .LBB12_3: +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: movl %ecx, %edx +; X64-NEXT: ucomiss %xmm0, %xmm0 +; X64-NEXT: jp .LBB12_6 +; X64-NEXT: .LBB12_5: +; X64-NEXT: movl %edx, %eax +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: popq %rcx +; X64-NEXT: .cfi_def_cfa_offset 8 +; X64-NEXT: retq + %x = call i1 @llvm.fptosi.sat.i1.f16(half %f) + ret i1 %x +} + +define i8 @test_signed_i8_f16(half %f) { +; X86-X87-LABEL: test_signed_i8_f16: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 16 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fstps (%esp) +; X86-X87-NEXT: calll __gnu_f2h_ieee +; X86-X87-NEXT: movzwl %ax, %eax +; X86-X87-NEXT: movl %eax, (%esp) +; X86-X87-NEXT: calll __gnu_h2f_ieee +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $-128, %dl +; X86-X87-NEXT: jb .LBB13_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %dl +; X86-X87-NEXT: .LBB13_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $127, %cl +; X86-X87-NEXT: ja .LBB13_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB13_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jnp .LBB13_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: .LBB13_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: addl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i8_f16: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 16 +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: movss %xmm0, (%esp) +; X86-SSE-NEXT: calll __gnu_f2h_ieee +; X86-SSE-NEXT: movzwl %ax, %eax +; 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: ucomiss {{\.LCPI.*}}, %xmm0 +; X86-SSE-NEXT: movb $-128, %cl +; X86-SSE-NEXT: jb .LBB13_2 +; X86-SSE-NEXT: # %bb.1: +; X86-SSE-NEXT: cvttss2si %xmm0, %ecx +; X86-SSE-NEXT: .LBB13_2: +; X86-SSE-NEXT: ucomiss {{\.LCPI.*}}, %xmm0 +; X86-SSE-NEXT: movb $127, %al +; X86-SSE-NEXT: jbe .LBB13_3 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: ucomiss %xmm0, %xmm0 +; X86-SSE-NEXT: jp .LBB13_5 +; X86-SSE-NEXT: .LBB13_6: +; X86-SSE-NEXT: # kill: def $al killed $al killed $eax +; X86-SSE-NEXT: addl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; X86-SSE-NEXT: .LBB13_3: +; X86-SSE-NEXT: .cfi_def_cfa_offset 16 +; X86-SSE-NEXT: movl %ecx, %eax +; X86-SSE-NEXT: ucomiss %xmm0, %xmm0 +; X86-SSE-NEXT: jnp .LBB13_6 +; X86-SSE-NEXT: .LBB13_5: +; X86-SSE-NEXT: xorl %eax, %eax +; X86-SSE-NEXT: # kill: def $al killed $al killed $eax +; X86-SSE-NEXT: addl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i8_f16: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: callq __gnu_f2h_ieee +; X64-NEXT: movzwl %ax, %edi +; X64-NEXT: callq __gnu_h2f_ieee +; X64-NEXT: ucomiss {{.*}}(%rip), %xmm0 +; X64-NEXT: movb $-128, %cl +; X64-NEXT: jb .LBB13_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: cvttss2si %xmm0, %ecx +; X64-NEXT: .LBB13_2: +; X64-NEXT: ucomiss {{.*}}(%rip), %xmm0 +; X64-NEXT: movb $127, %al +; X64-NEXT: jbe .LBB13_3 +; X64-NEXT: # %bb.4: +; X64-NEXT: ucomiss %xmm0, %xmm0 +; X64-NEXT: jp .LBB13_5 +; X64-NEXT: .LBB13_6: +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: popq %rcx +; X64-NEXT: .cfi_def_cfa_offset 8 +; X64-NEXT: retq +; X64-NEXT: .LBB13_3: +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: movl %ecx, %eax +; X64-NEXT: ucomiss %xmm0, %xmm0 +; X64-NEXT: jnp .LBB13_6 +; X64-NEXT: .LBB13_5: +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: popq %rcx +; X64-NEXT: .cfi_def_cfa_offset 8 +; X64-NEXT: retq + %x = call i8 @llvm.fptosi.sat.i8.f16(half %f) + ret i8 %x +} + +define i13 @test_signed_i13_f16(half %f) { +; X86-X87-LABEL: test_signed_i13_f16: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 16 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fstps (%esp) +; X86-X87-NEXT: calll __gnu_f2h_ieee +; X86-X87-NEXT: movzwl %ax, %eax +; X86-X87-NEXT: movl %eax, (%esp) +; X86-X87-NEXT: calll __gnu_h2f_ieee +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movw $-4096, %cx # imm = 0xF000 +; X86-X87-NEXT: jb .LBB14_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB14_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $4095, %edx # imm = 0xFFF +; X86-X87-NEXT: ja .LBB14_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB14_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB14_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB14_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: addl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i13_f16: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 16 +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: movss %xmm0, (%esp) +; X86-SSE-NEXT: calll __gnu_f2h_ieee +; X86-SSE-NEXT: movzwl %ax, %eax +; 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: 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: # kill: def $ax killed $ax killed $eax +; X86-SSE-NEXT: addl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i13_f16: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: callq __gnu_f2h_ieee +; X64-NEXT: movzwl %ax, %edi +; X64-NEXT: callq __gnu_h2f_ieee +; 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: .cfi_def_cfa_offset 8 +; X64-NEXT: retq + %x = call i13 @llvm.fptosi.sat.i13.f16(half %f) + ret i13 %x +} + +define i16 @test_signed_i16_f16(half %f) { +; X86-X87-LABEL: test_signed_i16_f16: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 16 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fstps (%esp) +; X86-X87-NEXT: calll __gnu_f2h_ieee +; X86-X87-NEXT: movzwl %ax, %eax +; X86-X87-NEXT: movl %eax, (%esp) +; X86-X87-NEXT: calll __gnu_h2f_ieee +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movw $-32768, %cx # imm = 0x8000 +; X86-X87-NEXT: jb .LBB15_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB15_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $32767, %edx # imm = 0x7FFF +; X86-X87-NEXT: ja .LBB15_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB15_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB15_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB15_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: addl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i16_f16: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 16 +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: movss %xmm0, (%esp) +; X86-SSE-NEXT: calll __gnu_f2h_ieee +; X86-SSE-NEXT: movzwl %ax, %eax +; 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: 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: # kill: def $ax killed $ax killed $eax +; X86-SSE-NEXT: addl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i16_f16: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: callq __gnu_f2h_ieee +; X64-NEXT: movzwl %ax, %edi +; X64-NEXT: callq __gnu_h2f_ieee +; 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: .cfi_def_cfa_offset 8 +; X64-NEXT: retq + %x = call i16 @llvm.fptosi.sat.i16.f16(half %f) + ret i16 %x +} + +define i19 @test_signed_i19_f16(half %f) { +; X86-X87-LABEL: test_signed_i19_f16: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 16 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fstps (%esp) +; X86-X87-NEXT: calll __gnu_f2h_ieee +; X86-X87-NEXT: movzwl %ax, %eax +; X86-X87-NEXT: movl %eax, (%esp) +; X86-X87-NEXT: calll __gnu_h2f_ieee +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $-262144, %ecx # imm = 0xFFFC0000 +; X86-X87-NEXT: jb .LBB16_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB16_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $262143, %edx # imm = 0x3FFFF +; X86-X87-NEXT: ja .LBB16_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB16_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB16_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB16_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: addl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i19_f16: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 16 +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: movss %xmm0, (%esp) +; X86-SSE-NEXT: calll __gnu_f2h_ieee +; X86-SSE-NEXT: movzwl %ax, %eax +; 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: 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: addl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i19_f16: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: callq __gnu_f2h_ieee +; X64-NEXT: movzwl %ax, %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: popq %rcx +; X64-NEXT: .cfi_def_cfa_offset 8 +; X64-NEXT: retq + %x = call i19 @llvm.fptosi.sat.i19.f16(half %f) + ret i19 %x +} + +define i32 @test_signed_i32_f16(half %f) { +; X86-X87-LABEL: test_signed_i32_f16: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 16 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fstps (%esp) +; X86-X87-NEXT: calll __gnu_f2h_ieee +; X86-X87-NEXT: movzwl %ax, %eax +; X86-X87-NEXT: movl %eax, (%esp) +; X86-X87-NEXT: calll __gnu_h2f_ieee +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $-2147483648, %ecx # imm = 0x80000000 +; X86-X87-NEXT: jb .LBB17_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB17_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $2147483647, %edx # imm = 0x7FFFFFFF +; X86-X87-NEXT: ja .LBB17_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB17_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB17_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB17_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: addl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i32_f16: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 16 +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: movss %xmm0, (%esp) +; X86-SSE-NEXT: calll __gnu_f2h_ieee +; X86-SSE-NEXT: movzwl %ax, %eax +; 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: 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: xorl %eax, %eax +; X86-SSE-NEXT: ucomiss %xmm0, %xmm0 +; X86-SSE-NEXT: cmovnpl %edx, %eax +; X86-SSE-NEXT: addl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i32_f16: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: callq __gnu_f2h_ieee +; X64-NEXT: movzwl %ax, %edi +; 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: xorl %eax, %eax +; X64-NEXT: ucomiss %xmm0, %xmm0 +; X64-NEXT: cmovnpl %edx, %eax +; X64-NEXT: popq %rcx +; X64-NEXT: .cfi_def_cfa_offset 8 +; X64-NEXT: retq + %x = call i32 @llvm.fptosi.sat.i32.f16(half %f) + ret i32 %x +} + +;define i50 @test_signed_i50_f16(half %f) { +; %x = call i50 @llvm.fptosi.sat.i50.f16(half %f) +; ret i50 %x +;} +; +;define i64 @test_signed_i64_f16(half %f) { +; %x = call i64 @llvm.fptosi.sat.i64.f16(half %f) +; ret i64 %x +;} +; +;define i100 @test_signed_i100_f16(half %f) { +; %x = call i100 @llvm.fptosi.sat.i100.f16(half %f) +; ret i100 %x +;} +; +;define i128 @test_signed_i128_f16(half %f) { +; %x = call i128 @llvm.fptosi.sat.i128.f16(half %f) +; ret i128 %x +;} + +; +; 80-bit float to signed integer +; + +declare i1 @llvm.fptosi.sat.i1.f80 (x86_fp80) +declare i8 @llvm.fptosi.sat.i8.f80 (x86_fp80) +declare i13 @llvm.fptosi.sat.i13.f80 (x86_fp80) +declare i16 @llvm.fptosi.sat.i16.f80 (x86_fp80) +declare i19 @llvm.fptosi.sat.i19.f80 (x86_fp80) +declare i32 @llvm.fptosi.sat.i32.f80 (x86_fp80) +declare i50 @llvm.fptosi.sat.i50.f80 (x86_fp80) +declare i64 @llvm.fptosi.sat.i64.f80 (x86_fp80) +declare i100 @llvm.fptosi.sat.i100.f80(x86_fp80) +declare i128 @llvm.fptosi.sat.i128.f80(x86_fp80) + +define i1 @test_signed_i1_f80(x86_fp80 %f) { +; X86-X87-LABEL: test_signed_i1_f80: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %ebx +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 12 +; X86-X87-NEXT: .cfi_offset %ebx, -8 +; X86-X87-NEXT: fldt {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: fld1 +; X86-X87-NEXT: fchs +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $-1, %dl +; X86-X87-NEXT: jb .LBB18_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %dl +; X86-X87-NEXT: .LBB18_2: +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $0, %ebx +; X86-X87-NEXT: ja .LBB18_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %edx, %ebx +; X86-X87-NEXT: .LBB18_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB18_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %ebx, %ecx +; X86-X87-NEXT: .LBB18_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: addl $4, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: popl %ebx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i1_f80: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 12 +; X86-SSE-NEXT: fldt {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fistl {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fld1 +; X86-SSE-NEXT: fchs +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: movb $-1, %cl +; X86-SSE-NEXT: jb .LBB18_2 +; X86-SSE-NEXT: # %bb.1: +; X86-SSE-NEXT: movb {{[0-9]+}}(%esp), %cl +; X86-SSE-NEXT: .LBB18_2: +; X86-SSE-NEXT: xorl %eax, %eax +; X86-SSE-NEXT: fldz +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: movl $0, %edx +; X86-SSE-NEXT: jbe .LBB18_3 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: fucompi %st(0) +; X86-SSE-NEXT: jnp .LBB18_5 +; X86-SSE-NEXT: .LBB18_6: +; X86-SSE-NEXT: # kill: def $al killed $al killed $eax +; X86-SSE-NEXT: addl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; X86-SSE-NEXT: .LBB18_3: +; X86-SSE-NEXT: .cfi_def_cfa_offset 12 +; X86-SSE-NEXT: movl %ecx, %edx +; X86-SSE-NEXT: fucompi %st(0) +; X86-SSE-NEXT: jp .LBB18_6 +; X86-SSE-NEXT: .LBB18_5: +; X86-SSE-NEXT: movl %edx, %eax +; X86-SSE-NEXT: # kill: def $al killed $al killed $eax +; X86-SSE-NEXT: addl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i1_f80: +; X64: # %bb.0: +; X64-NEXT: fldt {{[0-9]+}}(%rsp) +; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: movw $3199, -{{[0-9]+}}(%rsp) # imm = 0xC7F +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp) +; X64-NEXT: fistl -{{[0-9]+}}(%rsp) +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: fld1 +; X64-NEXT: fchs +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: movb $-1, %cl +; X64-NEXT: jb .LBB18_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: movb -{{[0-9]+}}(%rsp), %cl +; X64-NEXT: .LBB18_2: +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: fldz +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: movl $0, %edx +; X64-NEXT: jbe .LBB18_3 +; X64-NEXT: # %bb.4: +; X64-NEXT: fucompi %st(0) +; X64-NEXT: jnp .LBB18_5 +; X64-NEXT: .LBB18_6: +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: retq +; X64-NEXT: .LBB18_3: +; X64-NEXT: movl %ecx, %edx +; X64-NEXT: fucompi %st(0) +; X64-NEXT: jp .LBB18_6 +; X64-NEXT: .LBB18_5: +; X64-NEXT: movl %edx, %eax +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: retq + %x = call i1 @llvm.fptosi.sat.i1.f80(x86_fp80 %f) + ret i1 %x +} + +define i8 @test_signed_i8_f80(x86_fp80 %f) { +; X86-X87-LABEL: test_signed_i8_f80: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: fldt {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $-128, %dl +; X86-X87-NEXT: jb .LBB19_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %dl +; X86-X87-NEXT: .LBB19_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $127, %cl +; X86-X87-NEXT: ja .LBB19_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB19_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jnp .LBB19_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: .LBB19_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: popl %ecx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i8_f80: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 12 +; X86-SSE-NEXT: fldt {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fistl {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: flds {{\.LCPI.*}} +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: movb $-128, %cl +; X86-SSE-NEXT: jb .LBB19_2 +; X86-SSE-NEXT: # %bb.1: +; X86-SSE-NEXT: movb {{[0-9]+}}(%esp), %cl +; X86-SSE-NEXT: .LBB19_2: +; X86-SSE-NEXT: flds {{\.LCPI.*}} +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: movb $127, %al +; X86-SSE-NEXT: jbe .LBB19_3 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: fucompi %st(0) +; X86-SSE-NEXT: jp .LBB19_5 +; X86-SSE-NEXT: .LBB19_6: +; X86-SSE-NEXT: # kill: def $al killed $al killed $eax +; X86-SSE-NEXT: addl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; X86-SSE-NEXT: .LBB19_3: +; X86-SSE-NEXT: .cfi_def_cfa_offset 12 +; X86-SSE-NEXT: movl %ecx, %eax +; X86-SSE-NEXT: fucompi %st(0) +; X86-SSE-NEXT: jnp .LBB19_6 +; X86-SSE-NEXT: .LBB19_5: +; X86-SSE-NEXT: xorl %eax, %eax +; X86-SSE-NEXT: # kill: def $al killed $al killed $eax +; X86-SSE-NEXT: addl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i8_f80: +; X64: # %bb.0: +; X64-NEXT: fldt {{[0-9]+}}(%rsp) +; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: movw $3199, -{{[0-9]+}}(%rsp) # imm = 0xC7F +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp) +; X64-NEXT: fistl -{{[0-9]+}}(%rsp) +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: flds {{.*}}(%rip) +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: movb $-128, %cl +; X64-NEXT: jb .LBB19_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: movb -{{[0-9]+}}(%rsp), %cl +; X64-NEXT: .LBB19_2: +; X64-NEXT: flds {{.*}}(%rip) +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: movb $127, %al +; X64-NEXT: jbe .LBB19_3 +; X64-NEXT: # %bb.4: +; X64-NEXT: fucompi %st(0) +; X64-NEXT: jp .LBB19_5 +; X64-NEXT: .LBB19_6: +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: retq +; X64-NEXT: .LBB19_3: +; X64-NEXT: movl %ecx, %eax +; X64-NEXT: fucompi %st(0) +; X64-NEXT: jnp .LBB19_6 +; X64-NEXT: .LBB19_5: +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: # kill: def $al killed $al killed $eax +; X64-NEXT: retq + %x = call i8 @llvm.fptosi.sat.i8.f80(x86_fp80 %f) + ret i8 %x +} + +define i13 @test_signed_i13_f80(x86_fp80 %f) { +; X86-X87-LABEL: test_signed_i13_f80: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: fldt {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movw $-4096, %cx # imm = 0xF000 +; X86-X87-NEXT: jb .LBB20_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB20_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $4095, %edx # imm = 0xFFF +; X86-X87-NEXT: ja .LBB20_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB20_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB20_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB20_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: popl %ecx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i13_f80: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 12 +; X86-SSE-NEXT: fldt {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fistl {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: flds {{\.LCPI.*}} +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: movl $61440, %eax # imm = 0xF000 +; X86-SSE-NEXT: jb .LBB20_2 +; X86-SSE-NEXT: # %bb.1: +; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: .LBB20_2: +; X86-SSE-NEXT: flds {{\.LCPI.*}} +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: movl $4095, %ecx # imm = 0xFFF +; X86-SSE-NEXT: cmovbel %eax, %ecx +; X86-SSE-NEXT: xorl %eax, %eax +; X86-SSE-NEXT: fucompi %st(0) +; X86-SSE-NEXT: cmovnpl %ecx, %eax +; X86-SSE-NEXT: # kill: def $ax killed $ax killed $eax +; X86-SSE-NEXT: addl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i13_f80: +; X64: # %bb.0: +; X64-NEXT: fldt {{[0-9]+}}(%rsp) +; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: movw $3199, -{{[0-9]+}}(%rsp) # imm = 0xC7F +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp) +; X64-NEXT: fistl -{{[0-9]+}}(%rsp) +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: flds {{.*}}(%rip) +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: movl $61440, %eax # imm = 0xF000 +; X64-NEXT: jb .LBB20_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: movl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: .LBB20_2: +; X64-NEXT: flds {{.*}}(%rip) +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: movl $4095, %ecx # imm = 0xFFF +; X64-NEXT: cmovbel %eax, %ecx +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: fucompi %st(0) +; X64-NEXT: cmovnpl %ecx, %eax +; X64-NEXT: # kill: def $ax killed $ax killed $eax +; X64-NEXT: retq + %x = call i13 @llvm.fptosi.sat.i13.f80(x86_fp80 %f) + ret i13 %x +} + +define i16 @test_signed_i16_f80(x86_fp80 %f) { +; X86-X87-LABEL: test_signed_i16_f80: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: fldt {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movw $-32768, %cx # imm = 0x8000 +; X86-X87-NEXT: jb .LBB21_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB21_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $32767, %edx # imm = 0x7FFF +; X86-X87-NEXT: ja .LBB21_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB21_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB21_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB21_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: popl %ecx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i16_f80: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 12 +; X86-SSE-NEXT: fldt {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fistl {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: flds {{\.LCPI.*}} +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: movl $32768, %eax # imm = 0x8000 +; X86-SSE-NEXT: jb .LBB21_2 +; X86-SSE-NEXT: # %bb.1: +; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: .LBB21_2: +; X86-SSE-NEXT: flds {{\.LCPI.*}} +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: movl $32767, %ecx # imm = 0x7FFF +; X86-SSE-NEXT: cmovbel %eax, %ecx +; X86-SSE-NEXT: xorl %eax, %eax +; X86-SSE-NEXT: fucompi %st(0) +; X86-SSE-NEXT: cmovnpl %ecx, %eax +; X86-SSE-NEXT: # kill: def $ax killed $ax killed $eax +; X86-SSE-NEXT: addl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i16_f80: +; X64: # %bb.0: +; X64-NEXT: fldt {{[0-9]+}}(%rsp) +; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: movw $3199, -{{[0-9]+}}(%rsp) # imm = 0xC7F +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp) +; X64-NEXT: fistl -{{[0-9]+}}(%rsp) +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: flds {{.*}}(%rip) +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: movl $32768, %eax # imm = 0x8000 +; X64-NEXT: jb .LBB21_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: movl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: .LBB21_2: +; X64-NEXT: flds {{.*}}(%rip) +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: movl $32767, %ecx # imm = 0x7FFF +; X64-NEXT: cmovbel %eax, %ecx +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: fucompi %st(0) +; X64-NEXT: cmovnpl %ecx, %eax +; X64-NEXT: # kill: def $ax killed $ax killed $eax +; X64-NEXT: retq + %x = call i16 @llvm.fptosi.sat.i16.f80(x86_fp80 %f) + ret i16 %x +} + +define i19 @test_signed_i19_f80(x86_fp80 %f) { +; X86-X87-LABEL: test_signed_i19_f80: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 12 +; X86-X87-NEXT: fldt {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $-262144, %ecx # imm = 0xFFFC0000 +; X86-X87-NEXT: jb .LBB22_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB22_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $262143, %edx # imm = 0x3FFFF +; X86-X87-NEXT: ja .LBB22_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB22_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB22_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB22_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: addl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i19_f80: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 12 +; X86-SSE-NEXT: fldt {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fistl {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: flds {{\.LCPI.*}} +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: movl $-262144, %eax # imm = 0xFFFC0000 +; X86-SSE-NEXT: jb .LBB22_2 +; X86-SSE-NEXT: # %bb.1: +; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: .LBB22_2: +; X86-SSE-NEXT: flds {{\.LCPI.*}} +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: movl $262143, %ecx # imm = 0x3FFFF +; X86-SSE-NEXT: cmovbel %eax, %ecx +; X86-SSE-NEXT: xorl %eax, %eax +; X86-SSE-NEXT: fucompi %st(0) +; X86-SSE-NEXT: cmovnpl %ecx, %eax +; X86-SSE-NEXT: addl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i19_f80: +; X64: # %bb.0: +; X64-NEXT: fldt {{[0-9]+}}(%rsp) +; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: movw $3199, -{{[0-9]+}}(%rsp) # imm = 0xC7F +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp) +; X64-NEXT: fistl -{{[0-9]+}}(%rsp) +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: flds {{.*}}(%rip) +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: movl $-262144, %eax # imm = 0xFFFC0000 +; X64-NEXT: jb .LBB22_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: movl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: .LBB22_2: +; X64-NEXT: flds {{.*}}(%rip) +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: movl $262143, %ecx # imm = 0x3FFFF +; X64-NEXT: cmovbel %eax, %ecx +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: fucompi %st(0) +; X64-NEXT: cmovnpl %ecx, %eax +; X64-NEXT: retq + %x = call i19 @llvm.fptosi.sat.i19.f80(x86_fp80 %f) + ret i19 %x +} + +define i32 @test_signed_i32_f80(x86_fp80 %f) { +; X86-X87-LABEL: test_signed_i32_f80: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 12 +; X86-X87-NEXT: fldt {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $-2147483648, %ecx # imm = 0x80000000 +; X86-X87-NEXT: jb .LBB23_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB23_2: +; X86-X87-NEXT: fldl {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $2147483647, %edx # imm = 0x7FFFFFFF +; X86-X87-NEXT: ja .LBB23_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %edx +; X86-X87-NEXT: .LBB23_4: +; X86-X87-NEXT: fucomp %st(0) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jp .LBB23_6 +; X86-X87-NEXT: # %bb.5: +; X86-X87-NEXT: movl %edx, %ecx +; X86-X87-NEXT: .LBB23_6: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: addl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_signed_i32_f80: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 12 +; X86-SSE-NEXT: fldt {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fistl {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: flds {{\.LCPI.*}} +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: movl $-2147483648, %eax # imm = 0x80000000 +; X86-SSE-NEXT: jb .LBB23_2 +; X86-SSE-NEXT: # %bb.1: +; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: .LBB23_2: +; X86-SSE-NEXT: fldl {{\.LCPI.*}} +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: movl $2147483647, %ecx # imm = 0x7FFFFFFF +; X86-SSE-NEXT: cmovbel %eax, %ecx +; X86-SSE-NEXT: xorl %eax, %eax +; X86-SSE-NEXT: fucompi %st(0) +; X86-SSE-NEXT: cmovnpl %ecx, %eax +; X86-SSE-NEXT: addl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_signed_i32_f80: +; X64: # %bb.0: +; X64-NEXT: fldt {{[0-9]+}}(%rsp) +; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: movw $3199, -{{[0-9]+}}(%rsp) # imm = 0xC7F +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp) +; X64-NEXT: fistl -{{[0-9]+}}(%rsp) +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: flds {{.*}}(%rip) +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: movl $-2147483648, %eax # imm = 0x80000000 +; X64-NEXT: jb .LBB23_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: movl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: .LBB23_2: +; X64-NEXT: fldl {{.*}}(%rip) +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: movl $2147483647, %ecx # imm = 0x7FFFFFFF +; X64-NEXT: cmovbel %eax, %ecx +; X64-NEXT: xorl %eax, %eax +; X64-NEXT: fucompi %st(0) +; X64-NEXT: cmovnpl %ecx, %eax +; X64-NEXT: retq + %x = call i32 @llvm.fptosi.sat.i32.f80(x86_fp80 %f) + ret i32 %x +} + +;define i50 @test_signed_i50_f80(x86_fp80 %f) { +; %x = call i50 @llvm.fptosi.sat.i50.f80(x86_fp80 %f) +; ret i50 %x +;} +; +;define i64 @test_signed_i64_f80(x86_fp80 %f) { +; %x = call i64 @llvm.fptosi.sat.i64.f80(x86_fp80 %f) +; ret i64 %x +;} +; +;define i100 @test_signed_i100_f80(x86_fp80 %f) { +; %x = call i100 @llvm.fptosi.sat.i100.f80(x86_fp80 %f) +; ret i100 %x +;} +; +;define i128 @test_signed_i128_f80(x86_fp80 %f) { +; %x = call i128 @llvm.fptosi.sat.i128.f80(x86_fp80 %f) +; ret i128 %x +;} Index: test/CodeGen/X86/fptoui-sat-scalar.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/fptoui-sat-scalar.ll @@ -0,0 +1,2322 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=i686-linux | FileCheck %s --check-prefix=X86 --check-prefix=X86-X87 +; RUN: llc < %s -mtriple=i686-linux -mattr=+sse2 | FileCheck %s --check-prefix=X86 --check-prefix=X86-SSE +; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefix=X64 + +; +; 32-bit float to unsigned integer +; + +declare i1 @llvm.fptoui.sat.i1.f32 (float) +declare i8 @llvm.fptoui.sat.i8.f32 (float) +declare i13 @llvm.fptoui.sat.i13.f32 (float) +declare i16 @llvm.fptoui.sat.i16.f32 (float) +declare i19 @llvm.fptoui.sat.i19.f32 (float) +declare i32 @llvm.fptoui.sat.i32.f32 (float) +declare i50 @llvm.fptoui.sat.i50.f32 (float) +declare i64 @llvm.fptoui.sat.i64.f32 (float) +declare i100 @llvm.fptoui.sat.i100.f32(float) +declare i128 @llvm.fptoui.sat.i128.f32(float) + +define i1 @test_unsigned_i1_f32(float %f) { +; X86-X87-LABEL: test_unsigned_i1_f32: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB0_1 +; X86-X87-NEXT: # %bb.2: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %cl +; X86-X87-NEXT: jmp .LBB0_3 +; X86-X87-NEXT: .LBB0_1: +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: .LBB0_3: +; X86-X87-NEXT: fld1 +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $1, %al +; X86-X87-NEXT: ja .LBB0_5 +; X86-X87-NEXT: # %bb.4: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB0_5: +; X86-X87-NEXT: popl %ecx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i1_f32: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: xorps %xmm1, %xmm1 +; X86-SSE-NEXT: ucomiss %xmm1, %xmm0 +; X86-SSE-NEXT: jb .LBB0_1 +; X86-SSE-NEXT: # %bb.2: +; X86-SSE-NEXT: cvttss2si %xmm0, %ecx +; X86-SSE-NEXT: jmp .LBB0_3 +; X86-SSE-NEXT: .LBB0_1: +; X86-SSE-NEXT: xorl %ecx, %ecx +; X86-SSE-NEXT: .LBB0_3: +; X86-SSE-NEXT: ucomiss {{\.LCPI.*}}, %xmm0 +; X86-SSE-NEXT: movb $1, %al +; X86-SSE-NEXT: ja .LBB0_5 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: movl %ecx, %eax +; X86-SSE-NEXT: .LBB0_5: +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i1_f32: +; X64: # %bb.0: +; X64-NEXT: xorps %xmm1, %xmm1 +; X64-NEXT: ucomiss %xmm1, %xmm0 +; X64-NEXT: jb .LBB0_1 +; X64-NEXT: # %bb.2: +; X64-NEXT: cvttss2si %xmm0, %ecx +; X64-NEXT: jmp .LBB0_3 +; X64-NEXT: .LBB0_1: +; X64-NEXT: xorl %ecx, %ecx +; X64-NEXT: .LBB0_3: +; X64-NEXT: ucomiss {{.*}}(%rip), %xmm0 +; X64-NEXT: movb $1, %al +; X64-NEXT: ja .LBB0_5 +; X64-NEXT: # %bb.4: +; X64-NEXT: movl %ecx, %eax +; X64-NEXT: .LBB0_5: +; X64-NEXT: retq + %x = call i1 @llvm.fptoui.sat.i1.f32(float %f) + ret i1 %x +} + +define i8 @test_unsigned_i8_f32(float %f) { +; X86-X87-LABEL: test_unsigned_i8_f32: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB1_1 +; X86-X87-NEXT: # %bb.2: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %cl +; X86-X87-NEXT: jmp .LBB1_3 +; X86-X87-NEXT: .LBB1_1: +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: .LBB1_3: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $-1, %al +; X86-X87-NEXT: ja .LBB1_5 +; X86-X87-NEXT: # %bb.4: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB1_5: +; X86-X87-NEXT: popl %ecx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i8_f32: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: xorps %xmm1, %xmm1 +; X86-SSE-NEXT: ucomiss %xmm1, %xmm0 +; X86-SSE-NEXT: jb .LBB1_1 +; X86-SSE-NEXT: # %bb.2: +; X86-SSE-NEXT: cvttss2si %xmm0, %ecx +; X86-SSE-NEXT: jmp .LBB1_3 +; X86-SSE-NEXT: .LBB1_1: +; X86-SSE-NEXT: xorl %ecx, %ecx +; X86-SSE-NEXT: .LBB1_3: +; X86-SSE-NEXT: ucomiss {{\.LCPI.*}}, %xmm0 +; X86-SSE-NEXT: movb $-1, %al +; X86-SSE-NEXT: ja .LBB1_5 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: movl %ecx, %eax +; X86-SSE-NEXT: .LBB1_5: +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i8_f32: +; X64: # %bb.0: +; X64-NEXT: xorps %xmm1, %xmm1 +; X64-NEXT: ucomiss %xmm1, %xmm0 +; X64-NEXT: jb .LBB1_1 +; X64-NEXT: # %bb.2: +; X64-NEXT: cvttss2si %xmm0, %ecx +; X64-NEXT: jmp .LBB1_3 +; X64-NEXT: .LBB1_1: +; X64-NEXT: xorl %ecx, %ecx +; X64-NEXT: .LBB1_3: +; X64-NEXT: ucomiss {{.*}}(%rip), %xmm0 +; X64-NEXT: movb $-1, %al +; X64-NEXT: ja .LBB1_5 +; X64-NEXT: # %bb.4: +; X64-NEXT: movl %ecx, %eax +; X64-NEXT: .LBB1_5: +; X64-NEXT: retq + %x = call i8 @llvm.fptoui.sat.i8.f32(float %f) + ret i8 %x +} + +define i13 @test_unsigned_i13_f32(float %f) { +; X86-X87-LABEL: test_unsigned_i13_f32: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 12 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB2_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB2_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $8191, %eax # imm = 0x1FFF +; X86-X87-NEXT: ja .LBB2_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB2_4: +; X86-X87-NEXT: # kill: def $ax killed $ax killed $eax +; X86-X87-NEXT: addl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; 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: # 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: # kill: def $ax killed $ax killed $eax +; X64-NEXT: retq + %x = call i13 @llvm.fptoui.sat.i13.f32(float %f) + ret i13 %x +} + +define i16 @test_unsigned_i16_f32(float %f) { +; X86-X87-LABEL: test_unsigned_i16_f32: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 12 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB3_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB3_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $65535, %eax # imm = 0xFFFF +; X86-X87-NEXT: ja .LBB3_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB3_4: +; X86-X87-NEXT: # kill: def $ax killed $ax killed $eax +; X86-X87-NEXT: addl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; 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: # 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: # kill: def $ax killed $ax killed $eax +; X64-NEXT: retq + %x = call i16 @llvm.fptoui.sat.i16.f32(float %f) + ret i16 %x +} + +define i19 @test_unsigned_i19_f32(float %f) { +; X86-X87-LABEL: test_unsigned_i19_f32: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $20, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 24 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fld %st(0) +; X86-X87-NEXT: fistpll {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB4_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB4_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $524287, %eax # imm = 0x7FFFF +; X86-X87-NEXT: ja .LBB4_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB4_4: +; X86-X87-NEXT: addl $20, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; 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: 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: retq + %x = call i19 @llvm.fptoui.sat.i19.f32(float %f) + ret i19 %x +} + +define i32 @test_unsigned_i32_f32(float %f) { +; X86-X87-LABEL: test_unsigned_i32_f32: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $20, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 24 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fld %st(0) +; X86-X87-NEXT: fistpll {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB5_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB5_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $-1, %eax +; X86-X87-NEXT: ja .LBB5_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB5_4: +; X86-X87-NEXT: addl $20, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i32_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 $-1, %eax +; X86-SSE-NEXT: cmovbel %edx, %eax +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i32_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 $-1, %eax +; X64-NEXT: cmovbel %ecx, %eax +; X64-NEXT: retq + %x = call i32 @llvm.fptoui.sat.i32.f32(float %f) + ret i32 %x +} + +;define i50 @test_unsigned_i50_f32(float %f) { +; %x = call i50 @llvm.fptoui.sat.i50.f32(float %f) +; ret i50 %x +;} +; +;define i64 @test_unsigned_i64_f32(float %f) { +; %x = call i64 @llvm.fptoui.sat.i64.f32(float %f) +; ret i64 %x +;} +; +;define i100 @test_unsigned_i100_f32(float %f) { +; %x = call i100 @llvm.fptoui.sat.i100.f32(float %f) +; ret i100 %x +;} +; +;define i128 @test_unsigned_i128_f32(float %f) { +; %x = call i128 @llvm.fptoui.sat.i128.f32(float %f) +; ret i128 %x +;} + +; +; 64-bit float to unsigned integer +; + +declare i1 @llvm.fptoui.sat.i1.f64 (double) +declare i8 @llvm.fptoui.sat.i8.f64 (double) +declare i13 @llvm.fptoui.sat.i13.f64 (double) +declare i16 @llvm.fptoui.sat.i16.f64 (double) +declare i19 @llvm.fptoui.sat.i19.f64 (double) +declare i32 @llvm.fptoui.sat.i32.f64 (double) +declare i50 @llvm.fptoui.sat.i50.f64 (double) +declare i64 @llvm.fptoui.sat.i64.f64 (double) +declare i100 @llvm.fptoui.sat.i100.f64(double) +declare i128 @llvm.fptoui.sat.i128.f64(double) + +define i1 @test_unsigned_i1_f64(double %f) { +; X86-X87-LABEL: test_unsigned_i1_f64: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: fldl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB6_1 +; X86-X87-NEXT: # %bb.2: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %cl +; X86-X87-NEXT: jmp .LBB6_3 +; X86-X87-NEXT: .LBB6_1: +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: .LBB6_3: +; X86-X87-NEXT: fld1 +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $1, %al +; X86-X87-NEXT: ja .LBB6_5 +; X86-X87-NEXT: # %bb.4: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB6_5: +; X86-X87-NEXT: popl %ecx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i1_f64: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero +; X86-SSE-NEXT: xorps %xmm1, %xmm1 +; X86-SSE-NEXT: ucomisd %xmm1, %xmm0 +; X86-SSE-NEXT: jb .LBB6_1 +; X86-SSE-NEXT: # %bb.2: +; X86-SSE-NEXT: cvttsd2si %xmm0, %ecx +; X86-SSE-NEXT: jmp .LBB6_3 +; X86-SSE-NEXT: .LBB6_1: +; X86-SSE-NEXT: xorl %ecx, %ecx +; X86-SSE-NEXT: .LBB6_3: +; X86-SSE-NEXT: ucomisd {{\.LCPI.*}}, %xmm0 +; X86-SSE-NEXT: movb $1, %al +; X86-SSE-NEXT: ja .LBB6_5 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: movl %ecx, %eax +; X86-SSE-NEXT: .LBB6_5: +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i1_f64: +; X64: # %bb.0: +; X64-NEXT: xorps %xmm1, %xmm1 +; X64-NEXT: ucomisd %xmm1, %xmm0 +; X64-NEXT: jb .LBB6_1 +; X64-NEXT: # %bb.2: +; X64-NEXT: cvttsd2si %xmm0, %ecx +; X64-NEXT: jmp .LBB6_3 +; X64-NEXT: .LBB6_1: +; X64-NEXT: xorl %ecx, %ecx +; X64-NEXT: .LBB6_3: +; X64-NEXT: ucomisd {{.*}}(%rip), %xmm0 +; X64-NEXT: movb $1, %al +; X64-NEXT: ja .LBB6_5 +; X64-NEXT: # %bb.4: +; X64-NEXT: movl %ecx, %eax +; X64-NEXT: .LBB6_5: +; X64-NEXT: retq + %x = call i1 @llvm.fptoui.sat.i1.f64(double %f) + ret i1 %x +} + +define i8 @test_unsigned_i8_f64(double %f) { +; X86-X87-LABEL: test_unsigned_i8_f64: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: fldl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB7_1 +; X86-X87-NEXT: # %bb.2: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %cl +; X86-X87-NEXT: jmp .LBB7_3 +; X86-X87-NEXT: .LBB7_1: +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: .LBB7_3: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $-1, %al +; X86-X87-NEXT: ja .LBB7_5 +; X86-X87-NEXT: # %bb.4: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB7_5: +; X86-X87-NEXT: popl %ecx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i8_f64: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero +; X86-SSE-NEXT: xorps %xmm1, %xmm1 +; X86-SSE-NEXT: ucomisd %xmm1, %xmm0 +; X86-SSE-NEXT: jb .LBB7_1 +; X86-SSE-NEXT: # %bb.2: +; X86-SSE-NEXT: cvttsd2si %xmm0, %ecx +; X86-SSE-NEXT: jmp .LBB7_3 +; X86-SSE-NEXT: .LBB7_1: +; X86-SSE-NEXT: xorl %ecx, %ecx +; X86-SSE-NEXT: .LBB7_3: +; X86-SSE-NEXT: ucomisd {{\.LCPI.*}}, %xmm0 +; X86-SSE-NEXT: movb $-1, %al +; X86-SSE-NEXT: ja .LBB7_5 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: movl %ecx, %eax +; X86-SSE-NEXT: .LBB7_5: +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i8_f64: +; X64: # %bb.0: +; X64-NEXT: xorps %xmm1, %xmm1 +; X64-NEXT: ucomisd %xmm1, %xmm0 +; X64-NEXT: jb .LBB7_1 +; X64-NEXT: # %bb.2: +; X64-NEXT: cvttsd2si %xmm0, %ecx +; X64-NEXT: jmp .LBB7_3 +; X64-NEXT: .LBB7_1: +; X64-NEXT: xorl %ecx, %ecx +; X64-NEXT: .LBB7_3: +; X64-NEXT: ucomisd {{.*}}(%rip), %xmm0 +; X64-NEXT: movb $-1, %al +; X64-NEXT: ja .LBB7_5 +; X64-NEXT: # %bb.4: +; X64-NEXT: movl %ecx, %eax +; X64-NEXT: .LBB7_5: +; X64-NEXT: retq + %x = call i8 @llvm.fptoui.sat.i8.f64(double %f) + ret i8 %x +} + +define i13 @test_unsigned_i13_f64(double %f) { +; X86-X87-LABEL: test_unsigned_i13_f64: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 12 +; X86-X87-NEXT: fldl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB8_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB8_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $8191, %eax # imm = 0x1FFF +; X86-X87-NEXT: ja .LBB8_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB8_4: +; X86-X87-NEXT: # kill: def $ax killed $ax killed $eax +; X86-X87-NEXT: addl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; 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: xorps %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: # 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: xorps %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: # kill: def $ax killed $ax killed $eax +; X64-NEXT: retq + %x = call i13 @llvm.fptoui.sat.i13.f64(double %f) + ret i13 %x +} + +define i16 @test_unsigned_i16_f64(double %f) { +; X86-X87-LABEL: test_unsigned_i16_f64: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 12 +; X86-X87-NEXT: fldl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB9_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB9_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $65535, %eax # imm = 0xFFFF +; X86-X87-NEXT: ja .LBB9_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB9_4: +; X86-X87-NEXT: # kill: def $ax killed $ax killed $eax +; X86-X87-NEXT: addl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; 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: xorps %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: # 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: xorps %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: # kill: def $ax killed $ax killed $eax +; X64-NEXT: retq + %x = call i16 @llvm.fptoui.sat.i16.f64(double %f) + ret i16 %x +} + +define i19 @test_unsigned_i19_f64(double %f) { +; X86-X87-LABEL: test_unsigned_i19_f64: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $20, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 24 +; X86-X87-NEXT: fldl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fld %st(0) +; X86-X87-NEXT: fistpll {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB10_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB10_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $524287, %eax # imm = 0x7FFFF +; X86-X87-NEXT: ja .LBB10_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB10_4: +; X86-X87-NEXT: addl $20, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; 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: retl +; +; X64-LABEL: test_unsigned_i19_f64: +; X64: # %bb.0: +; X64-NEXT: cvttsd2si %xmm0, %rax +; X64-NEXT: xorl %ecx, %ecx +; X64-NEXT: xorps %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: retq + %x = call i19 @llvm.fptoui.sat.i19.f64(double %f) + ret i19 %x +} + +define i32 @test_unsigned_i32_f64(double %f) { +; X86-X87-LABEL: test_unsigned_i32_f64: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $20, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 24 +; X86-X87-NEXT: fldl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fld %st(0) +; X86-X87-NEXT: fistpll {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB11_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB11_2: +; X86-X87-NEXT: fldl {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $-1, %eax +; X86-X87-NEXT: ja .LBB11_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB11_4: +; X86-X87-NEXT: addl $20, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i32_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 $-1, %eax +; X86-SSE-NEXT: cmovbel %edx, %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: xorps %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: retq + %x = call i32 @llvm.fptoui.sat.i32.f64(double %f) + ret i32 %x +} + +;define i50 @test_unsigned_i50_f64(double %f) { +; %x = call i50 @llvm.fptoui.sat.i50.f64(double %f) +; ret i50 %x +;} +; +;define i64 @test_unsigned_i64_f64(double %f) { +; %x = call i64 @llvm.fptoui.sat.i64.f64(double %f) +; ret i64 %x +;} +; +;define i100 @test_unsigned_i100_f64(double %f) { +; %x = call i100 @llvm.fptoui.sat.i100.f64(double %f) +; ret i100 %x +;} +; +;define i128 @test_unsigned_i128_f64(double %f) { +; %x = call i128 @llvm.fptoui.sat.i128.f64(double %f) +; ret i128 %x +;} + +; +; 16-bit float to unsigned integer +; + +declare i1 @llvm.fptoui.sat.i1.f16 (half) +declare i8 @llvm.fptoui.sat.i8.f16 (half) +declare i13 @llvm.fptoui.sat.i13.f16 (half) +declare i16 @llvm.fptoui.sat.i16.f16 (half) +declare i19 @llvm.fptoui.sat.i19.f16 (half) +declare i32 @llvm.fptoui.sat.i32.f16 (half) +declare i50 @llvm.fptoui.sat.i50.f16 (half) +declare i64 @llvm.fptoui.sat.i64.f16 (half) +declare i100 @llvm.fptoui.sat.i100.f16(half) +declare i128 @llvm.fptoui.sat.i128.f16(half) + +define i1 @test_unsigned_i1_f16(half %f) { +; X86-X87-LABEL: test_unsigned_i1_f16: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 16 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fstps (%esp) +; X86-X87-NEXT: calll __gnu_f2h_ieee +; X86-X87-NEXT: movzwl %ax, %eax +; X86-X87-NEXT: movl %eax, (%esp) +; X86-X87-NEXT: calll __gnu_h2f_ieee +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB12_1 +; X86-X87-NEXT: # %bb.2: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %cl +; X86-X87-NEXT: jmp .LBB12_3 +; X86-X87-NEXT: .LBB12_1: +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: .LBB12_3: +; X86-X87-NEXT: fld1 +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $1, %al +; X86-X87-NEXT: ja .LBB12_5 +; X86-X87-NEXT: # %bb.4: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB12_5: +; X86-X87-NEXT: addl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i1_f16: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 16 +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: movss %xmm0, (%esp) +; X86-SSE-NEXT: calll __gnu_f2h_ieee +; X86-SSE-NEXT: movzwl %ax, %eax +; 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: xorps %xmm1, %xmm1 +; X86-SSE-NEXT: ucomiss %xmm1, %xmm0 +; X86-SSE-NEXT: jb .LBB12_1 +; X86-SSE-NEXT: # %bb.2: +; X86-SSE-NEXT: cvttss2si %xmm0, %ecx +; X86-SSE-NEXT: jmp .LBB12_3 +; X86-SSE-NEXT: .LBB12_1: +; X86-SSE-NEXT: xorl %ecx, %ecx +; X86-SSE-NEXT: .LBB12_3: +; X86-SSE-NEXT: ucomiss {{\.LCPI.*}}, %xmm0 +; X86-SSE-NEXT: movb $1, %al +; X86-SSE-NEXT: ja .LBB12_5 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: movl %ecx, %eax +; X86-SSE-NEXT: .LBB12_5: +; X86-SSE-NEXT: addl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i1_f16: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: callq __gnu_f2h_ieee +; X64-NEXT: movzwl %ax, %edi +; X64-NEXT: callq __gnu_h2f_ieee +; X64-NEXT: xorps %xmm1, %xmm1 +; X64-NEXT: ucomiss %xmm1, %xmm0 +; X64-NEXT: jb .LBB12_1 +; X64-NEXT: # %bb.2: +; X64-NEXT: cvttss2si %xmm0, %ecx +; X64-NEXT: jmp .LBB12_3 +; X64-NEXT: .LBB12_1: +; X64-NEXT: xorl %ecx, %ecx +; X64-NEXT: .LBB12_3: +; X64-NEXT: ucomiss {{.*}}(%rip), %xmm0 +; X64-NEXT: movb $1, %al +; X64-NEXT: ja .LBB12_5 +; X64-NEXT: # %bb.4: +; X64-NEXT: movl %ecx, %eax +; X64-NEXT: .LBB12_5: +; X64-NEXT: popq %rcx +; X64-NEXT: .cfi_def_cfa_offset 8 +; X64-NEXT: retq + %x = call i1 @llvm.fptoui.sat.i1.f16(half %f) + ret i1 %x +} + +define i8 @test_unsigned_i8_f16(half %f) { +; X86-X87-LABEL: test_unsigned_i8_f16: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 16 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fstps (%esp) +; X86-X87-NEXT: calll __gnu_f2h_ieee +; X86-X87-NEXT: movzwl %ax, %eax +; X86-X87-NEXT: movl %eax, (%esp) +; X86-X87-NEXT: calll __gnu_h2f_ieee +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB13_1 +; X86-X87-NEXT: # %bb.2: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %cl +; X86-X87-NEXT: jmp .LBB13_3 +; X86-X87-NEXT: .LBB13_1: +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: .LBB13_3: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $-1, %al +; X86-X87-NEXT: ja .LBB13_5 +; X86-X87-NEXT: # %bb.4: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB13_5: +; X86-X87-NEXT: addl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i8_f16: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 16 +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: movss %xmm0, (%esp) +; X86-SSE-NEXT: calll __gnu_f2h_ieee +; X86-SSE-NEXT: movzwl %ax, %eax +; 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: xorps %xmm1, %xmm1 +; X86-SSE-NEXT: ucomiss %xmm1, %xmm0 +; X86-SSE-NEXT: jb .LBB13_1 +; X86-SSE-NEXT: # %bb.2: +; X86-SSE-NEXT: cvttss2si %xmm0, %ecx +; X86-SSE-NEXT: jmp .LBB13_3 +; X86-SSE-NEXT: .LBB13_1: +; X86-SSE-NEXT: xorl %ecx, %ecx +; X86-SSE-NEXT: .LBB13_3: +; X86-SSE-NEXT: ucomiss {{\.LCPI.*}}, %xmm0 +; X86-SSE-NEXT: movb $-1, %al +; X86-SSE-NEXT: ja .LBB13_5 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: movl %ecx, %eax +; X86-SSE-NEXT: .LBB13_5: +; X86-SSE-NEXT: addl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i8_f16: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: callq __gnu_f2h_ieee +; X64-NEXT: movzwl %ax, %edi +; X64-NEXT: callq __gnu_h2f_ieee +; X64-NEXT: xorps %xmm1, %xmm1 +; X64-NEXT: ucomiss %xmm1, %xmm0 +; X64-NEXT: jb .LBB13_1 +; X64-NEXT: # %bb.2: +; X64-NEXT: cvttss2si %xmm0, %ecx +; X64-NEXT: jmp .LBB13_3 +; X64-NEXT: .LBB13_1: +; X64-NEXT: xorl %ecx, %ecx +; X64-NEXT: .LBB13_3: +; X64-NEXT: ucomiss {{.*}}(%rip), %xmm0 +; X64-NEXT: movb $-1, %al +; X64-NEXT: ja .LBB13_5 +; X64-NEXT: # %bb.4: +; X64-NEXT: movl %ecx, %eax +; X64-NEXT: .LBB13_5: +; X64-NEXT: popq %rcx +; X64-NEXT: .cfi_def_cfa_offset 8 +; X64-NEXT: retq + %x = call i8 @llvm.fptoui.sat.i8.f16(half %f) + ret i8 %x +} + +define i13 @test_unsigned_i13_f16(half %f) { +; X86-X87-LABEL: test_unsigned_i13_f16: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 16 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fstps (%esp) +; X86-X87-NEXT: calll __gnu_f2h_ieee +; X86-X87-NEXT: movzwl %ax, %eax +; X86-X87-NEXT: movl %eax, (%esp) +; X86-X87-NEXT: calll __gnu_h2f_ieee +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB14_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB14_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $8191, %eax # imm = 0x1FFF +; X86-X87-NEXT: ja .LBB14_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB14_4: +; X86-X87-NEXT: # kill: def $ax killed $ax killed $eax +; X86-X87-NEXT: addl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i13_f16: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 16 +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: movss %xmm0, (%esp) +; X86-SSE-NEXT: calll __gnu_f2h_ieee +; X86-SSE-NEXT: movzwl %ax, %eax +; 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: # kill: def $ax killed $ax killed $eax +; X86-SSE-NEXT: addl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i13_f16: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: callq __gnu_f2h_ieee +; X64-NEXT: movzwl %ax, %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: # kill: def $ax killed $ax killed $eax +; X64-NEXT: popq %rcx +; X64-NEXT: .cfi_def_cfa_offset 8 +; X64-NEXT: retq + %x = call i13 @llvm.fptoui.sat.i13.f16(half %f) + ret i13 %x +} + +define i16 @test_unsigned_i16_f16(half %f) { +; X86-X87-LABEL: test_unsigned_i16_f16: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 16 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fstps (%esp) +; X86-X87-NEXT: calll __gnu_f2h_ieee +; X86-X87-NEXT: movzwl %ax, %eax +; X86-X87-NEXT: movl %eax, (%esp) +; X86-X87-NEXT: calll __gnu_h2f_ieee +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB15_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB15_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $65535, %eax # imm = 0xFFFF +; X86-X87-NEXT: ja .LBB15_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB15_4: +; X86-X87-NEXT: # kill: def $ax killed $ax killed $eax +; X86-X87-NEXT: addl $12, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i16_f16: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 16 +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: movss %xmm0, (%esp) +; X86-SSE-NEXT: calll __gnu_f2h_ieee +; X86-SSE-NEXT: movzwl %ax, %eax +; 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: # kill: def $ax killed $ax killed $eax +; X86-SSE-NEXT: addl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i16_f16: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: callq __gnu_f2h_ieee +; X64-NEXT: movzwl %ax, %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: # kill: def $ax killed $ax killed $eax +; X64-NEXT: popq %rcx +; X64-NEXT: .cfi_def_cfa_offset 8 +; X64-NEXT: retq + %x = call i16 @llvm.fptoui.sat.i16.f16(half %f) + ret i16 %x +} + +define i19 @test_unsigned_i19_f16(half %f) { +; X86-X87-LABEL: test_unsigned_i19_f16: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $28, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 32 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fstps (%esp) +; X86-X87-NEXT: calll __gnu_f2h_ieee +; X86-X87-NEXT: movzwl %ax, %eax +; X86-X87-NEXT: movl %eax, (%esp) +; X86-X87-NEXT: calll __gnu_h2f_ieee +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fld %st(0) +; X86-X87-NEXT: fistpll {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB16_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB16_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $524287, %eax # imm = 0x7FFFF +; X86-X87-NEXT: ja .LBB16_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB16_4: +; X86-X87-NEXT: addl $28, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i19_f16: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 16 +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: movss %xmm0, (%esp) +; X86-SSE-NEXT: calll __gnu_f2h_ieee +; X86-SSE-NEXT: movzwl %ax, %eax +; 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: 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: addl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i19_f16: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: callq __gnu_f2h_ieee +; X64-NEXT: movzwl %ax, %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: popq %rcx +; X64-NEXT: .cfi_def_cfa_offset 8 +; X64-NEXT: retq + %x = call i19 @llvm.fptoui.sat.i19.f16(half %f) + ret i19 %x +} + +define i32 @test_unsigned_i32_f16(half %f) { +; X86-X87-LABEL: test_unsigned_i32_f16: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $28, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 32 +; X86-X87-NEXT: flds {{[0-9]+}}(%esp) +; X86-X87-NEXT: fstps (%esp) +; X86-X87-NEXT: calll __gnu_f2h_ieee +; X86-X87-NEXT: movzwl %ax, %eax +; X86-X87-NEXT: movl %eax, (%esp) +; X86-X87-NEXT: calll __gnu_h2f_ieee +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fld %st(0) +; X86-X87-NEXT: fistpll {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB17_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB17_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $-1, %eax +; X86-X87-NEXT: ja .LBB17_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB17_4: +; X86-X87-NEXT: addl $28, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i32_f16: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 16 +; X86-SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X86-SSE-NEXT: movss %xmm0, (%esp) +; X86-SSE-NEXT: calll __gnu_f2h_ieee +; X86-SSE-NEXT: movzwl %ax, %eax +; 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: 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 $-1, %eax +; X86-SSE-NEXT: cmovbel %edx, %eax +; X86-SSE-NEXT: addl $12, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i32_f16: +; X64: # %bb.0: +; X64-NEXT: pushq %rax +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: callq __gnu_f2h_ieee +; X64-NEXT: movzwl %ax, %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 $-1, %eax +; X64-NEXT: cmovbel %ecx, %eax +; X64-NEXT: popq %rcx +; X64-NEXT: .cfi_def_cfa_offset 8 +; X64-NEXT: retq + %x = call i32 @llvm.fptoui.sat.i32.f16(half %f) + ret i32 %x +} + +;define i50 @test_unsigned_i50_f16(half %f) { +; %x = call i50 @llvm.fptoui.sat.i50.f16(half %f) +; ret i50 %x +;} +; +;define i64 @test_unsigned_i64_f16(half %f) { +; %x = call i64 @llvm.fptoui.sat.i64.f16(half %f) +; ret i64 %x +;} +; +;define i100 @test_unsigned_i100_f16(half %f) { +; %x = call i100 @llvm.fptoui.sat.i100.f16(half %f) +; ret i100 %x +;} +; +;define i128 @test_unsigned_i128_f16(half %f) { +; %x = call i128 @llvm.fptoui.sat.i128.f16(half %f) +; ret i128 %x +;} + +; +; 80-bit float to unsigned integer +; + +declare i1 @llvm.fptoui.sat.i1.f80 (x86_fp80) +declare i8 @llvm.fptoui.sat.i8.f80 (x86_fp80) +declare i13 @llvm.fptoui.sat.i13.f80 (x86_fp80) +declare i16 @llvm.fptoui.sat.i16.f80 (x86_fp80) +declare i19 @llvm.fptoui.sat.i19.f80 (x86_fp80) +declare i32 @llvm.fptoui.sat.i32.f80 (x86_fp80) +declare i50 @llvm.fptoui.sat.i50.f80 (x86_fp80) +declare i64 @llvm.fptoui.sat.i64.f80 (x86_fp80) +declare i100 @llvm.fptoui.sat.i100.f80(x86_fp80) +declare i128 @llvm.fptoui.sat.i128.f80(x86_fp80) + +define i1 @test_unsigned_i1_f80(x86_fp80 %f) { +; X86-X87-LABEL: test_unsigned_i1_f80: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: fldt {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB18_1 +; X86-X87-NEXT: # %bb.2: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %cl +; X86-X87-NEXT: jmp .LBB18_3 +; X86-X87-NEXT: .LBB18_1: +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: .LBB18_3: +; X86-X87-NEXT: fld1 +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $1, %al +; X86-X87-NEXT: ja .LBB18_5 +; X86-X87-NEXT: # %bb.4: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB18_5: +; X86-X87-NEXT: popl %ecx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i1_f80: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 12 +; X86-SSE-NEXT: fldt {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fistl {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fldz +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: jb .LBB18_1 +; X86-SSE-NEXT: # %bb.2: +; X86-SSE-NEXT: movb {{[0-9]+}}(%esp), %cl +; X86-SSE-NEXT: jmp .LBB18_3 +; X86-SSE-NEXT: .LBB18_1: +; X86-SSE-NEXT: xorl %ecx, %ecx +; X86-SSE-NEXT: .LBB18_3: +; X86-SSE-NEXT: fld1 +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucompi %st(1) +; X86-SSE-NEXT: fstp %st(0) +; X86-SSE-NEXT: movb $1, %al +; X86-SSE-NEXT: ja .LBB18_5 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: movl %ecx, %eax +; X86-SSE-NEXT: .LBB18_5: +; X86-SSE-NEXT: addl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i1_f80: +; X64: # %bb.0: +; X64-NEXT: fldt {{[0-9]+}}(%rsp) +; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: movw $3199, -{{[0-9]+}}(%rsp) # imm = 0xC7F +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp) +; X64-NEXT: fistl -{{[0-9]+}}(%rsp) +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: fldz +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: jb .LBB18_1 +; X64-NEXT: # %bb.2: +; X64-NEXT: movb -{{[0-9]+}}(%rsp), %cl +; X64-NEXT: jmp .LBB18_3 +; X64-NEXT: .LBB18_1: +; X64-NEXT: xorl %ecx, %ecx +; X64-NEXT: .LBB18_3: +; X64-NEXT: fld1 +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucompi %st(1) +; X64-NEXT: fstp %st(0) +; X64-NEXT: movb $1, %al +; X64-NEXT: ja .LBB18_5 +; X64-NEXT: # %bb.4: +; X64-NEXT: movl %ecx, %eax +; X64-NEXT: .LBB18_5: +; X64-NEXT: retq + %x = call i1 @llvm.fptoui.sat.i1.f80(x86_fp80 %f) + ret i1 %x +} + +define i8 @test_unsigned_i8_f80(x86_fp80 %f) { +; X86-X87-LABEL: test_unsigned_i8_f80: +; X86-X87: # %bb.0: +; X86-X87-NEXT: pushl %eax +; X86-X87-NEXT: .cfi_def_cfa_offset 8 +; X86-X87-NEXT: fldt {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw (%esp) +; X86-X87-NEXT: movzwl (%esp), %eax +; X86-X87-NEXT: movw $3199, (%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: movw %ax, (%esp) +; X86-X87-NEXT: fists {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw (%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB19_1 +; X86-X87-NEXT: # %bb.2: +; X86-X87-NEXT: movb {{[0-9]+}}(%esp), %cl +; X86-X87-NEXT: jmp .LBB19_3 +; X86-X87-NEXT: .LBB19_1: +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: .LBB19_3: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movb $-1, %al +; X86-X87-NEXT: ja .LBB19_5 +; X86-X87-NEXT: # %bb.4: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB19_5: +; X86-X87-NEXT: popl %ecx +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i8_f80: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 12 +; X86-SSE-NEXT: fldt {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fistl {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fldz +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: jb .LBB19_1 +; X86-SSE-NEXT: # %bb.2: +; X86-SSE-NEXT: movb {{[0-9]+}}(%esp), %cl +; X86-SSE-NEXT: jmp .LBB19_3 +; X86-SSE-NEXT: .LBB19_1: +; X86-SSE-NEXT: xorl %ecx, %ecx +; X86-SSE-NEXT: .LBB19_3: +; X86-SSE-NEXT: flds {{\.LCPI.*}} +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucompi %st(1) +; X86-SSE-NEXT: fstp %st(0) +; X86-SSE-NEXT: movb $-1, %al +; X86-SSE-NEXT: ja .LBB19_5 +; X86-SSE-NEXT: # %bb.4: +; X86-SSE-NEXT: movl %ecx, %eax +; X86-SSE-NEXT: .LBB19_5: +; X86-SSE-NEXT: addl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i8_f80: +; X64: # %bb.0: +; X64-NEXT: fldt {{[0-9]+}}(%rsp) +; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: movw $3199, -{{[0-9]+}}(%rsp) # imm = 0xC7F +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp) +; X64-NEXT: fistl -{{[0-9]+}}(%rsp) +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: fldz +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: jb .LBB19_1 +; X64-NEXT: # %bb.2: +; X64-NEXT: movb -{{[0-9]+}}(%rsp), %cl +; X64-NEXT: jmp .LBB19_3 +; X64-NEXT: .LBB19_1: +; X64-NEXT: xorl %ecx, %ecx +; X64-NEXT: .LBB19_3: +; X64-NEXT: flds {{.*}}(%rip) +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucompi %st(1) +; X64-NEXT: fstp %st(0) +; X64-NEXT: movb $-1, %al +; X64-NEXT: ja .LBB19_5 +; X64-NEXT: # %bb.4: +; X64-NEXT: movl %ecx, %eax +; X64-NEXT: .LBB19_5: +; X64-NEXT: retq + %x = call i8 @llvm.fptoui.sat.i8.f80(x86_fp80 %f) + ret i8 %x +} + +define i13 @test_unsigned_i13_f80(x86_fp80 %f) { +; X86-X87-LABEL: test_unsigned_i13_f80: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 12 +; X86-X87-NEXT: fldt {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB20_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB20_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $8191, %eax # imm = 0x1FFF +; X86-X87-NEXT: ja .LBB20_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB20_4: +; X86-X87-NEXT: # kill: def $ax killed $ax killed $eax +; X86-X87-NEXT: addl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i13_f80: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 12 +; X86-SSE-NEXT: fldt {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fistl {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: xorl %ecx, %ecx +; X86-SSE-NEXT: fldz +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: jb .LBB20_2 +; X86-SSE-NEXT: # %bb.1: +; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-SSE-NEXT: .LBB20_2: +; X86-SSE-NEXT: flds {{\.LCPI.*}} +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucompi %st(1) +; X86-SSE-NEXT: fstp %st(0) +; X86-SSE-NEXT: movl $8191, %eax # imm = 0x1FFF +; X86-SSE-NEXT: cmovbel %ecx, %eax +; X86-SSE-NEXT: # kill: def $ax killed $ax killed $eax +; X86-SSE-NEXT: addl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i13_f80: +; X64: # %bb.0: +; X64-NEXT: fldt {{[0-9]+}}(%rsp) +; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: movw $3199, -{{[0-9]+}}(%rsp) # imm = 0xC7F +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp) +; X64-NEXT: fistl -{{[0-9]+}}(%rsp) +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: xorl %ecx, %ecx +; X64-NEXT: fldz +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: jb .LBB20_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: movl -{{[0-9]+}}(%rsp), %ecx +; X64-NEXT: .LBB20_2: +; X64-NEXT: flds {{.*}}(%rip) +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucompi %st(1) +; X64-NEXT: fstp %st(0) +; X64-NEXT: movl $8191, %eax # imm = 0x1FFF +; X64-NEXT: cmovbel %ecx, %eax +; X64-NEXT: # kill: def $ax killed $ax killed $eax +; X64-NEXT: retq + %x = call i13 @llvm.fptoui.sat.i13.f80(x86_fp80 %f) + ret i13 %x +} + +define i16 @test_unsigned_i16_f80(x86_fp80 %f) { +; X86-X87-LABEL: test_unsigned_i16_f80: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 12 +; X86-X87-NEXT: fldt {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fistl {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB21_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB21_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $65535, %eax # imm = 0xFFFF +; X86-X87-NEXT: ja .LBB21_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB21_4: +; X86-X87-NEXT: # kill: def $ax killed $ax killed $eax +; X86-X87-NEXT: addl $8, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i16_f80: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 12 +; X86-SSE-NEXT: fldt {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fistl {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: xorl %ecx, %ecx +; X86-SSE-NEXT: fldz +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: jb .LBB21_2 +; X86-SSE-NEXT: # %bb.1: +; X86-SSE-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-SSE-NEXT: .LBB21_2: +; X86-SSE-NEXT: flds {{\.LCPI.*}} +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucompi %st(1) +; X86-SSE-NEXT: fstp %st(0) +; X86-SSE-NEXT: movl $65535, %eax # imm = 0xFFFF +; X86-SSE-NEXT: cmovbel %ecx, %eax +; X86-SSE-NEXT: # kill: def $ax killed $ax killed $eax +; X86-SSE-NEXT: addl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i16_f80: +; X64: # %bb.0: +; X64-NEXT: fldt {{[0-9]+}}(%rsp) +; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: movw $3199, -{{[0-9]+}}(%rsp) # imm = 0xC7F +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp) +; X64-NEXT: fistl -{{[0-9]+}}(%rsp) +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: xorl %ecx, %ecx +; X64-NEXT: fldz +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: jb .LBB21_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: movl -{{[0-9]+}}(%rsp), %ecx +; X64-NEXT: .LBB21_2: +; X64-NEXT: flds {{.*}}(%rip) +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucompi %st(1) +; X64-NEXT: fstp %st(0) +; X64-NEXT: movl $65535, %eax # imm = 0xFFFF +; X64-NEXT: cmovbel %ecx, %eax +; X64-NEXT: # kill: def $ax killed $ax killed $eax +; X64-NEXT: retq + %x = call i16 @llvm.fptoui.sat.i16.f80(x86_fp80 %f) + ret i16 %x +} + +define i19 @test_unsigned_i19_f80(x86_fp80 %f) { +; X86-X87-LABEL: test_unsigned_i19_f80: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $20, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 24 +; X86-X87-NEXT: fldt {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fld %st(0) +; X86-X87-NEXT: fistpll {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB22_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB22_2: +; X86-X87-NEXT: flds {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $524287, %eax # imm = 0x7FFFF +; X86-X87-NEXT: ja .LBB22_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB22_4: +; X86-X87-NEXT: addl $20, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i19_f80: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 12 +; X86-SSE-NEXT: fldt {{[0-9]+}}(%esp) +; X86-SSE-NEXT: flds {{\.LCPI.*}} +; X86-SSE-NEXT: fld %st(1) +; X86-SSE-NEXT: fsub %st(1) +; X86-SSE-NEXT: xorl %eax, %eax +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucompi %st(2) +; X86-SSE-NEXT: fcmovnbe %st(1), %st(0) +; X86-SSE-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movzwl {{[0-9]+}}(%esp), %ecx +; X86-SSE-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movw %cx, {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fistpl {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: setbe %al +; X86-SSE-NEXT: shll $31, %eax +; X86-SSE-NEXT: xorl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: xorl %ecx, %ecx +; X86-SSE-NEXT: fldz +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: cmovael %eax, %ecx +; X86-SSE-NEXT: flds {{\.LCPI.*}} +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucompi %st(1) +; X86-SSE-NEXT: fstp %st(0) +; X86-SSE-NEXT: movl $524287, %eax # imm = 0x7FFFF +; X86-SSE-NEXT: cmovbel %ecx, %eax +; X86-SSE-NEXT: addl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i19_f80: +; X64: # %bb.0: +; X64-NEXT: fldt {{[0-9]+}}(%rsp) +; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: movw $3199, -{{[0-9]+}}(%rsp) # imm = 0xC7F +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp) +; X64-NEXT: fld %st(0) +; X64-NEXT: fistpll -{{[0-9]+}}(%rsp) +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: xorl %ecx, %ecx +; X64-NEXT: fldz +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: jb .LBB22_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: movl -{{[0-9]+}}(%rsp), %ecx +; X64-NEXT: .LBB22_2: +; X64-NEXT: flds {{.*}}(%rip) +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucompi %st(1) +; X64-NEXT: fstp %st(0) +; X64-NEXT: movl $524287, %eax # imm = 0x7FFFF +; X64-NEXT: cmovbel %ecx, %eax +; X64-NEXT: retq + %x = call i19 @llvm.fptoui.sat.i19.f80(x86_fp80 %f) + ret i19 %x +} + +define i32 @test_unsigned_i32_f80(x86_fp80 %f) { +; X86-X87-LABEL: test_unsigned_i32_f80: +; X86-X87: # %bb.0: +; X86-X87-NEXT: subl $20, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 24 +; X86-X87-NEXT: fldt {{[0-9]+}}(%esp) +; X86-X87-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-X87-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: movw %ax, {{[0-9]+}}(%esp) +; X86-X87-NEXT: fld %st(0) +; X86-X87-NEXT: fistpll {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-X87-NEXT: fldz +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucom %st(1) +; X86-X87-NEXT: fstp %st(1) +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: xorl %ecx, %ecx +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: jb .LBB23_2 +; X86-X87-NEXT: # %bb.1: +; X86-X87-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-X87-NEXT: .LBB23_2: +; X86-X87-NEXT: fldl {{\.LCPI.*}} +; X86-X87-NEXT: fxch %st(1) +; X86-X87-NEXT: fucompp +; X86-X87-NEXT: fnstsw %ax +; X86-X87-NEXT: # kill: def $ah killed $ah killed $ax +; X86-X87-NEXT: sahf +; X86-X87-NEXT: movl $-1, %eax +; X86-X87-NEXT: ja .LBB23_4 +; X86-X87-NEXT: # %bb.3: +; X86-X87-NEXT: movl %ecx, %eax +; X86-X87-NEXT: .LBB23_4: +; X86-X87-NEXT: addl $20, %esp +; X86-X87-NEXT: .cfi_def_cfa_offset 4 +; X86-X87-NEXT: retl +; +; X86-SSE-LABEL: test_unsigned_i32_f80: +; X86-SSE: # %bb.0: +; X86-SSE-NEXT: subl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 12 +; X86-SSE-NEXT: fldt {{[0-9]+}}(%esp) +; X86-SSE-NEXT: flds {{\.LCPI.*}} +; X86-SSE-NEXT: fld %st(1) +; X86-SSE-NEXT: fsub %st(1) +; X86-SSE-NEXT: xorl %eax, %eax +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucompi %st(2) +; X86-SSE-NEXT: fcmovnbe %st(1), %st(0) +; X86-SSE-NEXT: fnstcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movzwl {{[0-9]+}}(%esp), %ecx +; X86-SSE-NEXT: movw $3199, {{[0-9]+}}(%esp) # imm = 0xC7F +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: movw %cx, {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fistpl {{[0-9]+}}(%esp) +; X86-SSE-NEXT: fldcw {{[0-9]+}}(%esp) +; X86-SSE-NEXT: setbe %al +; X86-SSE-NEXT: shll $31, %eax +; X86-SSE-NEXT: xorl {{[0-9]+}}(%esp), %eax +; X86-SSE-NEXT: xorl %ecx, %ecx +; X86-SSE-NEXT: fldz +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucomi %st(1) +; X86-SSE-NEXT: fstp %st(1) +; X86-SSE-NEXT: cmovael %eax, %ecx +; X86-SSE-NEXT: fldl {{\.LCPI.*}} +; X86-SSE-NEXT: fxch %st(1) +; X86-SSE-NEXT: fucompi %st(1) +; X86-SSE-NEXT: fstp %st(0) +; X86-SSE-NEXT: movl $-1, %eax +; X86-SSE-NEXT: cmovbel %ecx, %eax +; X86-SSE-NEXT: addl $8, %esp +; X86-SSE-NEXT: .cfi_def_cfa_offset 4 +; X86-SSE-NEXT: retl +; +; X64-LABEL: test_unsigned_i32_f80: +; X64: # %bb.0: +; X64-NEXT: fldt {{[0-9]+}}(%rsp) +; X64-NEXT: fnstcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movzwl -{{[0-9]+}}(%rsp), %eax +; X64-NEXT: movw $3199, -{{[0-9]+}}(%rsp) # imm = 0xC7F +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: movw %ax, -{{[0-9]+}}(%rsp) +; X64-NEXT: fld %st(0) +; X64-NEXT: fistpll -{{[0-9]+}}(%rsp) +; X64-NEXT: fldcw -{{[0-9]+}}(%rsp) +; X64-NEXT: xorl %ecx, %ecx +; X64-NEXT: fldz +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucomi %st(1) +; X64-NEXT: fstp %st(1) +; X64-NEXT: jb .LBB23_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: movl -{{[0-9]+}}(%rsp), %ecx +; X64-NEXT: .LBB23_2: +; X64-NEXT: fldl {{.*}}(%rip) +; X64-NEXT: fxch %st(1) +; X64-NEXT: fucompi %st(1) +; X64-NEXT: fstp %st(0) +; X64-NEXT: movl $-1, %eax +; X64-NEXT: cmovbel %ecx, %eax +; X64-NEXT: retq + %x = call i32 @llvm.fptoui.sat.i32.f80(x86_fp80 %f) + ret i32 %x +} + +;define i50 @test_unsigned_i50_f80(x86_fp80 %f) { +; %x = call i50 @llvm.fptoui.sat.i50.f80(x86_fp80 %f) +; ret i50 %x +;} +; +;define i64 @test_unsigned_i64_f80(x86_fp80 %f) { +; %x = call i64 @llvm.fptoui.sat.i64.f80(x86_fp80 %f) +; ret i64 %x +;} +; +;define i100 @test_unsigned_i100_f80(x86_fp80 %f) { +; %x = call i100 @llvm.fptoui.sat.i100.f80(x86_fp80 %f) +; ret i100 %x +;} +; +;define i128 @test_unsigned_i128_f80(x86_fp80 %f) { +; %x = call i128 @llvm.fptoui.sat.i128.f80(x86_fp80 %f) +; ret i128 %x +;}