Index: include/llvm/CodeGen/TargetLowering.h =================================================================== --- include/llvm/CodeGen/TargetLowering.h +++ include/llvm/CodeGen/TargetLowering.h @@ -2964,6 +2964,15 @@ bool isSigned, const SDLoc &dl, bool doesNotReturn = false, bool isReturnValueUsed = true, bool isPostTypeLegalization = false) const; + /// Returns a pair of (return value, chain) + /// This function also chains to the first operand in Ops. + std::pair makeLibCallChained( + SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, + ArrayRef Ops, + bool isSigned, const SDLoc &dl, bool doesNotReturn = false, + bool isReturnValueUsed = true, bool isPostTypeLegalization = false) const; + + /// Check whether parameters to a call that are passed in callee saved /// registers are the same as from the calling function. This needs to be /// checked for tail call eligibility. Index: lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -1123,9 +1123,9 @@ #endif llvm_unreachable("Do not know how to expand the result of this operator!"); - case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; - case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; - case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; + case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; + case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; + case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; case ISD::MERGE_VALUES: ExpandRes_MERGE_VALUES(N, ResNo, Lo, Hi); break; case ISD::BITCAST: ExpandRes_BITCAST(N, Lo, Hi); break; @@ -1134,38 +1134,63 @@ case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break; case ISD::VAARG: ExpandRes_VAARG(N, Lo, Hi); break; - case ISD::ConstantFP: ExpandFloatRes_ConstantFP(N, Lo, Hi); break; - case ISD::FABS: ExpandFloatRes_FABS(N, Lo, Hi); break; - case ISD::FMINNUM: ExpandFloatRes_FMINNUM(N, Lo, Hi); break; - case ISD::FMAXNUM: ExpandFloatRes_FMAXNUM(N, Lo, Hi); break; - case ISD::FADD: ExpandFloatRes_FADD(N, Lo, Hi); break; - case ISD::FCEIL: ExpandFloatRes_FCEIL(N, Lo, Hi); break; - case ISD::FCOPYSIGN: ExpandFloatRes_FCOPYSIGN(N, Lo, Hi); break; - case ISD::FCOS: ExpandFloatRes_FCOS(N, Lo, Hi); break; - case ISD::FDIV: ExpandFloatRes_FDIV(N, Lo, Hi); break; - case ISD::FEXP: ExpandFloatRes_FEXP(N, Lo, Hi); break; - case ISD::FEXP2: ExpandFloatRes_FEXP2(N, Lo, Hi); break; - case ISD::FFLOOR: ExpandFloatRes_FFLOOR(N, Lo, Hi); break; - case ISD::FLOG: ExpandFloatRes_FLOG(N, Lo, Hi); break; - case ISD::FLOG2: ExpandFloatRes_FLOG2(N, Lo, Hi); break; - case ISD::FLOG10: ExpandFloatRes_FLOG10(N, Lo, Hi); break; - case ISD::FMA: ExpandFloatRes_FMA(N, Lo, Hi); break; - case ISD::FMUL: ExpandFloatRes_FMUL(N, Lo, Hi); break; - case ISD::FNEARBYINT: ExpandFloatRes_FNEARBYINT(N, Lo, Hi); break; - case ISD::FNEG: ExpandFloatRes_FNEG(N, Lo, Hi); break; - case ISD::FP_EXTEND: ExpandFloatRes_FP_EXTEND(N, Lo, Hi); break; - case ISD::FPOW: ExpandFloatRes_FPOW(N, Lo, Hi); break; - case ISD::FPOWI: ExpandFloatRes_FPOWI(N, Lo, Hi); break; - case ISD::FRINT: ExpandFloatRes_FRINT(N, Lo, Hi); break; - case ISD::FROUND: ExpandFloatRes_FROUND(N, Lo, Hi); break; - case ISD::FSIN: ExpandFloatRes_FSIN(N, Lo, Hi); break; - case ISD::FSQRT: ExpandFloatRes_FSQRT(N, Lo, Hi); break; - case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break; - case ISD::FTRUNC: ExpandFloatRes_FTRUNC(N, Lo, Hi); break; - case ISD::LOAD: ExpandFloatRes_LOAD(N, Lo, Hi); break; + case ISD::ConstantFP: ExpandFloatRes_ConstantFP(N, Lo, Hi); break; + case ISD::FABS: ExpandFloatRes_FABS(N, Lo, Hi); break; + case ISD::FMINNUM: ExpandFloatRes_FMINNUM(N, Lo, Hi); break; + case ISD::STRICT_FMINNUM: ExpandFloatRes_STRICT_FMINNUM(N, Lo, Hi); break; + case ISD::FMAXNUM: ExpandFloatRes_FMAXNUM(N, Lo, Hi); break; + case ISD::STRICT_FMAXNUM: ExpandFloatRes_STRICT_FMAXNUM(N, Lo, Hi); break; + case ISD::FADD: ExpandFloatRes_FADD(N, Lo, Hi); break; + case ISD::STRICT_FADD: ExpandFloatRes_STRICT_FADD(N, Lo, Hi); break; + case ISD::FCEIL: ExpandFloatRes_FCEIL(N, Lo, Hi); break; + case ISD::STRICT_FCEIL: ExpandFloatRes_STRICT_FCEIL(N, Lo, Hi); break; + case ISD::FCOPYSIGN: ExpandFloatRes_FCOPYSIGN(N, Lo, Hi); break; + case ISD::FCOS: ExpandFloatRes_FCOS(N, Lo, Hi); break; + case ISD::STRICT_FCOS: ExpandFloatRes_STRICT_FCOS(N, Lo, Hi); break; + case ISD::FDIV: ExpandFloatRes_FDIV(N, Lo, Hi); break; + case ISD::STRICT_FDIV: ExpandFloatRes_STRICT_FDIV(N, Lo, Hi); break; + case ISD::FEXP: ExpandFloatRes_FEXP(N, Lo, Hi); break; + case ISD::STRICT_FEXP: ExpandFloatRes_STRICT_FEXP(N, Lo, Hi); break; + case ISD::FEXP2: ExpandFloatRes_FEXP2(N, Lo, Hi); break; + case ISD::STRICT_FEXP2: ExpandFloatRes_STRICT_FEXP2(N, Lo, Hi); break; + case ISD::FFLOOR: ExpandFloatRes_FFLOOR(N, Lo, Hi); break; + case ISD::STRICT_FFLOOR: ExpandFloatRes_STRICT_FFLOOR(N, Lo, Hi); break; + case ISD::FLOG: ExpandFloatRes_FLOG(N, Lo, Hi); break; + case ISD::STRICT_FLOG: ExpandFloatRes_STRICT_FLOG(N, Lo, Hi); break; + case ISD::FLOG2: ExpandFloatRes_FLOG2(N, Lo, Hi); break; + case ISD::STRICT_FLOG2: ExpandFloatRes_STRICT_FLOG2(N, Lo, Hi); break; + case ISD::FLOG10: ExpandFloatRes_FLOG10(N, Lo, Hi); break; + case ISD::STRICT_FLOG10: ExpandFloatRes_STRICT_FLOG10(N, Lo, Hi); break; + case ISD::FMA: ExpandFloatRes_FMA(N, Lo, Hi); break; + case ISD::STRICT_FMA: ExpandFloatRes_STRICT_FMA(N, Lo, Hi); break; + case ISD::FMUL: ExpandFloatRes_FMUL(N, Lo, Hi); break; + case ISD::STRICT_FMUL: ExpandFloatRes_STRICT_FMUL(N, Lo, Hi); break; + case ISD::FNEARBYINT: ExpandFloatRes_FNEARBYINT(N, Lo, Hi); break; + case ISD::STRICT_FNEARBYINT: ExpandFloatRes_STRICT_FNEARBYINT(N, Lo, Hi); break; + case ISD::FNEG: ExpandFloatRes_FNEG(N, Lo, Hi); break; + case ISD::FP_EXTEND: ExpandFloatRes_FP_EXTEND(N, Lo, Hi); break; + case ISD::STRICT_FP_EXTEND: ExpandFloatRes_STRICT_FP_EXTEND(N, Lo, Hi); break; + case ISD::FPOW: ExpandFloatRes_FPOW(N, Lo, Hi); break; + case ISD::STRICT_FPOW: ExpandFloatRes_STRICT_FPOW(N, Lo, Hi); break; + case ISD::FPOWI: ExpandFloatRes_FPOWI(N, Lo, Hi); break; + case ISD::STRICT_FPOWI: ExpandFloatRes_STRICT_FPOWI(N, Lo, Hi); break; + case ISD::FRINT: ExpandFloatRes_FRINT(N, Lo, Hi); break; + case ISD::STRICT_FRINT: ExpandFloatRes_STRICT_FRINT(N, Lo, Hi); break; + case ISD::FROUND: ExpandFloatRes_FROUND(N, Lo, Hi); break; + case ISD::STRICT_FROUND: ExpandFloatRes_STRICT_FROUND(N, Lo, Hi); break; + case ISD::FSIN: ExpandFloatRes_FSIN(N, Lo, Hi); break; + case ISD::STRICT_FSIN: ExpandFloatRes_STRICT_FSIN(N, Lo, Hi); break; + case ISD::FSQRT: ExpandFloatRes_FSQRT(N, Lo, Hi); break; + case ISD::STRICT_FSQRT: ExpandFloatRes_STRICT_FSQRT(N, Lo, Hi); break; + case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break; + case ISD::STRICT_FSUB: ExpandFloatRes_STRICT_FSUB(N, Lo, Hi); break; + case ISD::FTRUNC: ExpandFloatRes_FTRUNC(N, Lo, Hi); break; + case ISD::STRICT_FTRUNC: ExpandFloatRes_STRICT_FTRUNC(N, Lo, Hi); break; + case ISD::LOAD: ExpandFloatRes_LOAD(N, Lo, Hi); break; case ISD::SINT_TO_FP: - case ISD::UINT_TO_FP: ExpandFloatRes_XINT_TO_FP(N, Lo, Hi); break; - case ISD::FREM: ExpandFloatRes_FREM(N, Lo, Hi); break; + case ISD::UINT_TO_FP: ExpandFloatRes_XINT_TO_FP(N, Lo, Hi); break; + case ISD::FREM: ExpandFloatRes_FREM(N, Lo, Hi); break; + case ISD::STRICT_FREM: ExpandFloatRes_STRICT_FREM(N, Lo, Hi); break; } // If Lo/Hi is null, the sub-method took care of registering results etc. @@ -1212,16 +1237,33 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FMINNUM(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::FMIN_F32, RTLIB::FMIN_F64, + RTLIB::FMIN_F80, RTLIB::FMIN_F128, RTLIB::FMIN_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FMAXNUM(SDNode *N, SDValue &Lo, SDValue &Hi) { - SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), - RTLIB::FMAX_F32, RTLIB::FMAX_F64, - RTLIB::FMAX_F80, RTLIB::FMAX_F128, - RTLIB::FMAX_PPCF128), + SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), RTLIB::FMAX_F32, + RTLIB::FMAX_F64, RTLIB::FMAX_F80, + RTLIB::FMAX_F128, RTLIB::FMAX_PPCF128), N, false); GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FMAXNUM(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::FMAX_F32, RTLIB::FMAX_F64, + RTLIB::FMAX_F80, RTLIB::FMAX_F128, RTLIB::FMAX_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1232,6 +1274,16 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FADD(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::ADD_F32, RTLIB::ADD_F64, + RTLIB::ADD_F80, RTLIB::ADD_F128, RTLIB::ADD_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + + void DAGTypeLegalizer::ExpandFloatRes_FCEIL(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1242,6 +1294,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FCEIL(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::CEIL_F32, RTLIB::CEIL_F64, + RTLIB::CEIL_F80, RTLIB::CEIL_F128, RTLIB::CEIL_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1264,6 +1325,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FCOS(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::COS_F32, RTLIB::COS_F64, + RTLIB::COS_F80, RTLIB::COS_F128, RTLIB::COS_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; @@ -1278,6 +1348,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FDIV(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::DIV_F32, RTLIB::DIV_F64, + RTLIB::DIV_F80, RTLIB::DIV_F128, RTLIB::DIV_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FEXP(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1288,6 +1367,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FEXP(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::EXP_F32, RTLIB::EXP_F64, + RTLIB::EXP_F80, RTLIB::EXP_F128, RTLIB::EXP_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FEXP2(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1298,6 +1386,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FEXP2(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::EXP2_F32, RTLIB::EXP2_F64, + RTLIB::EXP2_F80, RTLIB::EXP2_F128, RTLIB::EXP2_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1308,6 +1405,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FFLOOR(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::FLOOR_F32, RTLIB::FLOOR_F64, + RTLIB::FLOOR_F80, RTLIB::FLOOR_F128, RTLIB::FLOOR_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FLOG(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1318,6 +1424,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FLOG(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::LOG_F32, RTLIB::LOG_F64, + RTLIB::LOG_F80, RTLIB::LOG_F128, RTLIB::LOG_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FLOG2(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1328,6 +1443,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FLOG2(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::LOG2_F32, RTLIB::LOG2_F64, + RTLIB::LOG2_F80, RTLIB::LOG2_F128, RTLIB::LOG2_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FLOG10(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1338,6 +1462,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FLOG10(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::LOG10_F32, RTLIB::LOG10_F64, + RTLIB::LOG10_F80, RTLIB::LOG10_F128, RTLIB::LOG10_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FMA(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Ops[3] = { N->getOperand(0), N->getOperand(1), N->getOperand(2) }; @@ -1352,6 +1485,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FMA(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::FMA_F32, RTLIB::FMA_F64, + RTLIB::FMA_F80, RTLIB::FMA_F128, RTLIB::FMA_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; @@ -1366,6 +1508,14 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FMUL(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::MUL_F32, RTLIB::MUL_F64, + RTLIB::MUL_F80, RTLIB::MUL_F128, RTLIB::MUL_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1378,6 +1528,16 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FNEARBYINT(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::NEARBYINT_F32, + RTLIB::NEARBYINT_F64, RTLIB::NEARBYINT_F80, + RTLIB::NEARBYINT_F128, RTLIB::NEARBYINT_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode *N, SDValue &Lo, SDValue &Hi) { SDLoc dl(N); @@ -1395,6 +1555,18 @@ APInt(NVT.getSizeInBits(), 0)), dl, NVT); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FP_EXTEND(SDNode *N, SDValue &Lo, + SDValue &Hi) { + EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); + SDLoc dl(N); + Hi = DAG.getNode(ISD::STRICT_FP_EXTEND, dl, {NVT, MVT::Other}, + {N->getOperand(0), N->getOperand(1)}); + Lo = DAG.getConstantFP( + APFloat(DAG.EVTToAPFloatSemantics(NVT), APInt(NVT.getSizeInBits(), 0)), + dl, NVT); + ReplaceValueWith(SDValue(N, 1), SDValue(Hi.getNode(), 1)); +} + void DAGTypeLegalizer::ExpandFloatRes_FPOW(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1405,6 +1577,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FPOW(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::POW_F32, RTLIB::POW_F64, + RTLIB::POW_F80, RTLIB::POW_F128, RTLIB::POW_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FPOWI(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1415,6 +1596,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FPOWI(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::POWI_F32, RTLIB::POWI_F64, + RTLIB::POWI_F80, RTLIB::POWI_F128, RTLIB::POWI_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FREM(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1425,6 +1615,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FREM(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::REM_F32, RTLIB::REM_F64, + RTLIB::REM_F80, RTLIB::REM_F128, RTLIB::REM_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FRINT(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1435,6 +1634,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FRINT(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::RINT_F32, RTLIB::RINT_F64, + RTLIB::RINT_F80, RTLIB::RINT_F128, RTLIB::RINT_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FROUND(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1447,6 +1655,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FROUND(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::ROUND_F32, RTLIB::ROUND_F64, + RTLIB::ROUND_F80, RTLIB::ROUND_F128, RTLIB::ROUND_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FSIN(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1457,6 +1674,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FSIN(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::SIN_F32, RTLIB::SIN_F64, + RTLIB::SIN_F80, RTLIB::SIN_F128, RTLIB::SIN_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FSQRT(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1467,6 +1693,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FSQRT(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::SQRT_F32, RTLIB::SQRT_F64, + RTLIB::SQRT_F80, RTLIB::SQRT_F128, RTLIB::SQRT_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; @@ -1481,6 +1716,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FSUB(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::SUB_F32, RTLIB::SUB_F64, + RTLIB::SUB_F80, RTLIB::SUB_F128, RTLIB::SUB_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), @@ -1491,6 +1735,15 @@ GetPairElements(Call, Lo, Hi); } +void DAGTypeLegalizer::ExpandFloatRes_STRICT_FTRUNC(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Call = LibCallifyStrictFP( + GetFPLibCall(N->getValueType(0), RTLIB::TRUNC_F32, RTLIB::TRUNC_F64, + RTLIB::TRUNC_F80, RTLIB::TRUNC_F128, RTLIB::TRUNC_PPCF128), + N, false); + GetPairElements(Call, Lo, Hi); +} + void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo, SDValue &Hi) { if (ISD::isNormalLoad(N)) { @@ -1625,18 +1878,19 @@ case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break; - case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(N); break; - case ISD::FCOPYSIGN: Res = ExpandFloatOp_FCOPYSIGN(N); break; - case ISD::FP_ROUND: Res = ExpandFloatOp_FP_ROUND(N); break; - case ISD::FP_TO_SINT: Res = ExpandFloatOp_FP_TO_SINT(N); break; - case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_UINT(N); break; - case ISD::LROUND: Res = ExpandFloatOp_LROUND(N); break; - case ISD::LLROUND: Res = ExpandFloatOp_LLROUND(N); break; - case ISD::LRINT: Res = ExpandFloatOp_LRINT(N); break; - case ISD::LLRINT: Res = ExpandFloatOp_LLRINT(N); break; - case ISD::SELECT_CC: Res = ExpandFloatOp_SELECT_CC(N); break; - case ISD::SETCC: Res = ExpandFloatOp_SETCC(N); break; - case ISD::STORE: Res = ExpandFloatOp_STORE(cast(N), + case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(N); break; + case ISD::FCOPYSIGN: Res = ExpandFloatOp_FCOPYSIGN(N); break; + case ISD::FP_ROUND: Res = ExpandFloatOp_FP_ROUND(N); break; + case ISD::STRICT_FP_ROUND: Res = ExpandFloatOp_STRICT_FP_ROUND(N); break; + case ISD::FP_TO_SINT: Res = ExpandFloatOp_FP_TO_SINT(N); break; + case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_UINT(N); break; + case ISD::LROUND: Res = ExpandFloatOp_LROUND(N); break; + case ISD::LLROUND: Res = ExpandFloatOp_LLROUND(N); break; + case ISD::LRINT: Res = ExpandFloatOp_LRINT(N); break; + case ISD::LLRINT: Res = ExpandFloatOp_LLRINT(N); break; + case ISD::SELECT_CC: Res = ExpandFloatOp_SELECT_CC(N); break; + case ISD::SETCC: Res = ExpandFloatOp_SETCC(N); break; + case ISD::STORE: Res = ExpandFloatOp_STORE(cast(N), OpNo); break; } @@ -1648,7 +1902,8 @@ if (Res.getNode() == N) return true; - assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && + assert(Res.getValueType() == N->getValueType(0) && + (N->getNumValues() == 1 || N->isStrictFPOpcode()) && "Invalid operand expansion"); ReplaceValueWith(SDValue(N, 0), Res); @@ -1726,6 +1981,28 @@ N->getValueType(0), Hi, N->getOperand(1)); } +SDValue DAGTypeLegalizer::ExpandFloatOp_STRICT_FP_ROUND(SDNode *N) { + assert(N->getOperand(1).getValueType() == MVT::ppcf128 && + "Logic only correct for ppcf128!"); + SDValue Lo, Hi; + GetExpandedFloat(N->getOperand(1), Lo, Hi); + + // Eliminate the node if the input float type is the same as the output float + // type. + if (Hi.getValueType() == N->getValueType(0)) { + // Connect the output chain to the input chain, unlinking the node. + ReplaceValueWith(SDValue(N, 1), N->getOperand(0)); + return Hi; + } + // Round it the rest of the way (e.g. to f32) if needed. + SDValue Expansion = DAG.getNode(ISD::STRICT_FP_ROUND, SDLoc(N), + {N->getValueType(0), N->getValueType(1)}, + {N->getOperand(0), Hi, N->getOperand(2)}); + // Replace the old chain with the new chain. + ReplaceValueWith(SDValue(N, 1), SDValue(Expansion.getNode(), 1)); + return Expansion; +} + SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { EVT RVT = N->getValueType(0); SDLoc dl(N); Index: lib/CodeGen/SelectionDAG/LegalizeTypes.h =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -225,6 +225,7 @@ SDValue JoinIntegers(SDValue Lo, SDValue Hi); SDValue LibCallify(RTLIB::Libcall LC, SDNode *N, bool isSigned); + SDValue LibCallifyStrictFP(RTLIB::Libcall LC, SDNode *N, bool isSigned); std::pair ExpandChainLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned); @@ -579,43 +580,69 @@ // Float Result Expansion. void ExpandFloatResult(SDNode *N, unsigned ResNo); - void ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FABS (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FMINNUM (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FMAXNUM (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FADD (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FCEIL (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FCOPYSIGN (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FCOS (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FDIV (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FEXP (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FEXP2 (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FFLOOR (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FLOG (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FLOG2 (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FLOG10 (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FMA (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FMUL (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FNEARBYINT(SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FNEG (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FP_EXTEND (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FPOW (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FPOWI (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FREM (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FRINT (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FROUND (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FSIN (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FSQRT (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FSUB (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_FTRUNC (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_LOAD (SDNode *N, SDValue &Lo, SDValue &Hi); - void ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_ConstantFP (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FABS (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FMINNUM (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FMINNUM (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FMAXNUM (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FMAXNUM (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FADD (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FADD (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FCEIL (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FCEIL (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FCOPYSIGN (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FCOS (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FCOS (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FDIV (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FDIV (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FEXP (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FEXP (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FEXP2 (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FEXP2 (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FFLOOR (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FFLOOR (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FLOG (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FLOG (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FLOG2 (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FLOG2 (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FLOG10 (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FLOG10 (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FMA (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FMA (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FMUL (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FMUL (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FNEARBYINT (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FNEARBYINT (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FNEG (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FP_EXTEND (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FP_EXTEND (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FPOW (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FPOW (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FPOWI (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FPOWI (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FREM (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FREM (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FRINT (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FRINT (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FROUND (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FROUND (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FSIN (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FSIN (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FSQRT (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FSQRT (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FSUB (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FSUB (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_FTRUNC (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_STRICT_FTRUNC (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_LOAD (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandFloatRes_XINT_TO_FP (SDNode *N, SDValue &Lo, SDValue &Hi); // Float Operand Expansion. bool ExpandFloatOperand(SDNode *N, unsigned OpNo); SDValue ExpandFloatOp_BR_CC(SDNode *N); SDValue ExpandFloatOp_FCOPYSIGN(SDNode *N); SDValue ExpandFloatOp_FP_ROUND(SDNode *N); + SDValue ExpandFloatOp_STRICT_FP_ROUND(SDNode *N); SDValue ExpandFloatOp_FP_TO_SINT(SDNode *N); SDValue ExpandFloatOp_FP_TO_UINT(SDNode *N); SDValue ExpandFloatOp_LROUND(SDNode *N); Index: lib/CodeGen/SelectionDAG/LegalizeTypes.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -1024,6 +1024,27 @@ return TLI.makeLibCall(DAG, LC, N->getValueType(0), Ops, isSigned, dl).first; } +///In order to expand a StrictFP Node into a libcall, we must make the +///nodes in the expansion use the original incoming and outgoing chain +///from the StrictFP Node. +SDValue DAGTypeLegalizer::LibCallifyStrictFP(RTLIB::Libcall LC, SDNode *N, + bool isSigned) { + unsigned NumOps = N->getNumOperands(); + SDLoc dl(N); + std::pair Call; + SmallVector Ops(NumOps); + for (unsigned i = 0; i < NumOps; ++i) + Ops[i] = N->getOperand(i); + + Call = TLI.makeLibCallChained(DAG, LC, N->getValueType(0), + Ops, isSigned, + dl); + //Make any nodes using the chain from the StrictFP node now use + //the chain from the expanded libcall. + DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), Call.second); + return Call.first; +} + /// Expand a node into a call to a libcall. Similar to ExpandLibCall except that /// the first operand is the in-chain. std::pair Index: lib/CodeGen/SelectionDAG/TargetLowering.cpp =================================================================== --- lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -156,6 +156,54 @@ return LowerCallTo(CLI); } +std::pair +TargetLowering::makeLibCallChained(SelectionDAG &DAG, + RTLIB::Libcall LC, EVT RetVT, + ArrayRef Ops, bool isSigned, + const SDLoc &dl, bool doesNotReturn, + bool isReturnValueUsed, + bool isPostTypeLegalization) const { + assert(Ops.size() >= 1 && Ops[0].getValueType() == MVT::Other && + "The first operand to the libcall must be the chain input."); + + TargetLowering::ArgListTy Args; + Args.reserve(Ops.size() - 1); + + SDValue Chain = Ops[0]; + + TargetLowering::ArgListEntry Entry; + ArrayRef::iterator OpIterator = Ops.begin(); + ArrayRef::iterator end = Ops.end(); + for (OpIterator++; //Skip the chain + OpIterator != end; + OpIterator++) { + SDValue Op = *OpIterator; + Entry.Node = Op; + Entry.Ty = Entry.Node.getValueType().getTypeForEVT(*DAG.getContext()); + Entry.IsSExt = shouldSignExtendTypeInLibCall(Op.getValueType(), isSigned); + Entry.IsZExt = !shouldSignExtendTypeInLibCall(Op.getValueType(), isSigned); + Args.push_back(Entry); + } + + if (LC == RTLIB::UNKNOWN_LIBCALL) + report_fatal_error("Unsupported library call operation!"); + SDValue Callee = DAG.getExternalSymbol(getLibcallName(LC), + getPointerTy(DAG.getDataLayout())); + + Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); + TargetLowering::CallLoweringInfo CLI(DAG); + bool signExtend = shouldSignExtendTypeInLibCall(RetVT, isSigned); + CLI.setDebugLoc(dl) + .setChain(Chain) + .setLibCallee(getLibcallCallingConv(LC), RetTy, Callee, std::move(Args)) + .setNoReturn(doesNotReturn) + .setDiscardResult(!isReturnValueUsed) + .setIsPostTypeLegalization(isPostTypeLegalization) + .setSExtResult(signExtend) + .setZExtResult(!signExtend); + return LowerCallTo(CLI); +} + bool TargetLowering::findOptimalMemOpLowering(std::vector &MemOps, unsigned Limit, uint64_t Size, Index: test/CodeGen/PowerPC/ppcf128-constrained-fp-instrinsics.ll =================================================================== --- test/CodeGen/PowerPC/ppcf128-constrained-fp-instrinsics.ll +++ test/CodeGen/PowerPC/ppcf128-constrained-fp-instrinsics.ll @@ -0,0 +1,1193 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -O3 -mtriple=powerpc64le-linux-gnu < %s | FileCheck --check-prefix=PC64LE %s +; RUN: llc -O3 -mtriple=powerpc64le-linux-gnu -mcpu=pwr9 < %s | FileCheck --check-prefix=PC64LE9 %s +; RUN: llc -O3 -mtriple=powerpc64-linux-gnu < %s | FileCheck --check-prefix=PC64 %s + +define ppc_fp128 @test_fadd_ppc_fp128(ppc_fp128 %first, ppc_fp128 %second) { +; PC64LE-LABEL: test_fadd_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl __gcc_qadd +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_fadd_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl __gcc_qadd +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_fadd_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl __gcc_qadd +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %add = call ppc_fp128 @llvm.experimental.constrained.fadd.ppcf128( + ppc_fp128 %first, + ppc_fp128 %second, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %add +} + +define ppc_fp128 @test_fsub_ppc_fp128(ppc_fp128 %first, ppc_fp128 %second) { +; PC64LE-LABEL: test_fsub_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl __gcc_qsub +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_fsub_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl __gcc_qsub +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_fsub_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl __gcc_qsub +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %sub = call ppc_fp128 @llvm.experimental.constrained.fsub.ppcf128( + ppc_fp128 %first, + ppc_fp128 %second, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %sub +} + +define ppc_fp128 @test_fmul_ppc_fp128(ppc_fp128 %first, ppc_fp128 %second) { +; PC64LE-LABEL: test_fmul_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl __gcc_qmul +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_fmul_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl __gcc_qmul +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_fmul_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl __gcc_qmul +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %mul = call ppc_fp128 @llvm.experimental.constrained.fmul.ppcf128( + ppc_fp128 %first, + ppc_fp128 %second, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %mul +} + +define ppc_fp128 @test_fdiv_ppc_fp128(ppc_fp128 %first, ppc_fp128 %second) { +; PC64LE-LABEL: test_fdiv_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl __gcc_qdiv +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_fdiv_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl __gcc_qdiv +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_fdiv_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl __gcc_qdiv +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %div = call ppc_fp128 @llvm.experimental.constrained.fdiv.ppcf128( + ppc_fp128 %first, + ppc_fp128 %second, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %div +} + +define ppc_fp128 @test_frem_ppc_fp128(ppc_fp128 %first, ppc_fp128 %second) { +; PC64LE-LABEL: test_frem_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl fmodl +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_frem_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl fmodl +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_frem_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl fmodl +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %rem = call ppc_fp128 @llvm.experimental.constrained.frem.ppcf128( + ppc_fp128 %first, + ppc_fp128 %second, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %rem +} + +define ppc_fp128 @test_fma_ppc_fp128(ppc_fp128 %first, ppc_fp128 %second, ppc_fp128 %third) { +; PC64LE-LABEL: test_fma_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl fmal +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_fma_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl fmal +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_fma_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl fmal +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %add = call ppc_fp128 @llvm.experimental.constrained.fma.ppcf128( + ppc_fp128 %first, + ppc_fp128 %second, + ppc_fp128 %third, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %add +} + +define ppc_fp128 @test_sqrt_ppc_fp128(ppc_fp128 %first) { +; PC64LE-LABEL: test_sqrt_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl sqrtl +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_sqrt_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl sqrtl +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_sqrt_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl sqrtl +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %sqrt = call ppc_fp128 @llvm.experimental.constrained.sqrt.ppcf128( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %sqrt +} + +define ppc_fp128 @test_pow_ppc_fp128(ppc_fp128 %first, ppc_fp128 %second) { +; PC64LE-LABEL: test_pow_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl powl +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_pow_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl powl +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_pow_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl powl +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %pow = call ppc_fp128 @llvm.experimental.constrained.pow.ppcf128( + ppc_fp128 %first, + ppc_fp128 %second, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %pow +} + +define ppc_fp128 @test_powi_ppc_fp128(ppc_fp128 %first, i32 %second) { +; PC64LE-LABEL: test_powi_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: clrldi 5, 5, 32 +; PC64LE: bl __powitf2 +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_powi_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9 : clrldi 5, 5, 32 +; PC64LE9: bl __powitf2 +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_powi_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: clrldi 5, 5, 32 +; PC64: bl __powitf2 +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %powi = call ppc_fp128 @llvm.experimental.constrained.powi.ppcf128( + ppc_fp128 %first, + i32 %second, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %powi +} + +define ppc_fp128 @test_sin_ppc_fp128(ppc_fp128 %first) { +; PC64LE-LABEL: test_sin_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl sinl +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_sin_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl sinl +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_sin_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl sinl +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %sin = call ppc_fp128 @llvm.experimental.constrained.sin.ppcf128( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %sin +} + +define ppc_fp128 @test_cos_ppc_fp128(ppc_fp128 %first) { +; PC64LE-LABEL: test_cos_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl cosl +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_cos_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl cosl +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_cos_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl cosl +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %cos = call ppc_fp128 @llvm.experimental.constrained.cos.ppcf128( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %cos +} + +define ppc_fp128 @test_exp_ppc_fp128(ppc_fp128 %first) { +; PC64LE-LABEL: test_exp_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl expl +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_exp_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl expl +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_exp_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl expl +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %exp = call ppc_fp128 @llvm.experimental.constrained.exp.ppcf128( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %exp +} + +define ppc_fp128 @test_exp2_ppc_fp128(ppc_fp128 %first) { +; PC64LE-LABEL: test_exp2_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl exp2l +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_exp2_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl exp2l +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_exp2_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl exp2l +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %exp2 = call ppc_fp128 @llvm.experimental.constrained.exp2.ppcf128( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %exp2 +} + +define ppc_fp128 @test_log_ppc_fp128(ppc_fp128 %first) { +; PC64LE-LABEL: test_log_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl logl +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_log_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl logl +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_log_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl logl +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %log = call ppc_fp128 @llvm.experimental.constrained.log.ppcf128( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %log +} + +define ppc_fp128 @test_log2_ppc_fp128(ppc_fp128 %first) { +; PC64LE-LABEL: test_log2_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl log2l +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_log2_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl log2l +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_log2_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl log2l +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %log2 = call ppc_fp128 @llvm.experimental.constrained.log2.ppcf128( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %log2 +} + +define ppc_fp128 @test_log10_ppc_fp128(ppc_fp128 %first) { +; PC64LE-LABEL: test_log10_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl log10l +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_log10_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl log10l +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_log10_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl log10l +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %log10 = call ppc_fp128 @llvm.experimental.constrained.log10.ppcf128( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %log10 +} + +define ppc_fp128 @test_rint_ppc_fp128(ppc_fp128 %first) { +; PC64LE-LABEL: test_rint_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl rintl +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_rint_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl rintl +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_rint_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl rintl +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %rint = call ppc_fp128 @llvm.experimental.constrained.rint.ppcf128( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %rint +} + +define ppc_fp128 @test_nearbyint_ppc_fp128(ppc_fp128 %first) { +; PC64LE-LABEL: test_nearbyint_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl nearbyintl +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_nearbyint_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl nearbyintl +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_nearbyint_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl nearbyintl +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %nearbyint = call ppc_fp128 @llvm.experimental.constrained.nearbyint.ppcf128( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %nearbyint +} + +define ppc_fp128 @test_maxnum_ppc_fp128(ppc_fp128 %first, ppc_fp128 %second) { +; PC64LE-LABEL: test_maxnum_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl fmaxl +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_maxnum_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl fmaxl +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_maxnum_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl fmaxl +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %maxnum = call ppc_fp128 @llvm.experimental.constrained.maxnum.ppcf128( + ppc_fp128 %first, + ppc_fp128 %second, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %maxnum +} + +define ppc_fp128 @test_minnum_ppc_fp128(ppc_fp128 %first, ppc_fp128 %second) { +; PC64LE-LABEL: test_minnum_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl fminl +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_minnum_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl fminl +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_minnum_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl fminl +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %minnum = call ppc_fp128 @llvm.experimental.constrained.minnum.ppcf128( + ppc_fp128 %first, + ppc_fp128 %second, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %minnum +} + +define ppc_fp128 @test_ceil_ppc_fp128(ppc_fp128 %first) { +; PC64LE-LABEL: test_ceil_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl ceill +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_ceil_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl ceill +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_ceil_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl ceill +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %ceil = call ppc_fp128 @llvm.experimental.constrained.ceil.ppcf128( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %ceil +} + +define ppc_fp128 @test_floor_ppc_fp128(ppc_fp128 %first) { +; PC64LE-LABEL: test_floor_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl floorl +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_floor_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl floorl +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_floor_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl floorl +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %floor = call ppc_fp128 @llvm.experimental.constrained.floor.ppcf128( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %floor +} + +define ppc_fp128 @test_round_ppc_fp128(ppc_fp128 %first) { +; PC64LE-LABEL: test_round_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl roundl +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_round_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl roundl +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_round_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl roundl +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %round = call ppc_fp128 @llvm.experimental.constrained.round.ppcf128( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %round +} + +define ppc_fp128 @test_trunc_ppc_fp128(ppc_fp128 %first) { +; PC64LE-LABEL: test_trunc_ppc_fp128: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: mflr 0 +; PC64LE: std 0, 16(1) +; PC64LE: stdu 1, -32(1) +; PC64LE: bl truncl +; PC64LE-NEXT: nop +; PC64LE-NEXT: addi 1, 1, 32 +; PC64LE-NEXT: ld 0, 16(1) +; PC64LE-NEXT: mtlr 0 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_trunc_ppc_fp128: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: mflr 0 +; PC64LE9: std 0, 16(1) +; PC64LE9: stdu 1, -32(1) +; PC64LE9: bl truncl +; PC64LE9-NEXT: nop +; PC64LE9-NEXT: addi 1, 1, 32 +; PC64LE9-NEXT: ld 0, 16(1) +; PC64LE9-NEXT: mtlr 0 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_trunc_ppc_fp128: +; PC64: # %bb.0: # %entry +; PC64-NEXT: mflr 0 +; PC64: std 0, 16(1) +; PC64: stdu 1, -112(1) +; PC64: bl truncl +; PC64-NEXT: nop +; PC64-NEXT: addi 1, 1, 112 +; PC64-NEXT: ld 0, 16(1) +; PC64-NEXT: mtlr 0 +; PC64-NEXT: blr +entry: + %trunc = call ppc_fp128 @llvm.experimental.constrained.trunc.ppcf128( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret ppc_fp128 %trunc +} + +define float @test_fptrunc_ppc_fp128_f32(ppc_fp128 %first) { +; PC64LE-LABEL: test_fptrunc_ppc_fp128_f32: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: frsp 1, 1 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_fptrunc_ppc_fp128_f32: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: frsp 1, 1 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_fptrunc_ppc_fp128_f32: +; PC64: # %bb.0: # %entry +; PC64-NEXT: frsp 1, 1 +; PC64-NEXT: blr +entry: + %fptrunc = call float @llvm.experimental.constrained.fptrunc.ppcf128.f32( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret float %fptrunc +} + +define double @test_fptrunc_ppc_fp128_f64(ppc_fp128 %first) { +; PC64LE-LABEL: test_fptrunc_ppc_fp128_f64: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_fptrunc_ppc_fp128_f64: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_fptrunc_ppc_fp128_f64: +; PC64: # %bb.0: # %entry +; PC64-NEXT: blr +entry: + %fptrunc = call double @llvm.experimental.constrained.fptrunc.ppcf128.f64( + ppc_fp128 %first, + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret double %fptrunc +} + +define ppc_fp128 @test_fpext_ppc_fp128_f32(float %first) { +; PC64LE-LABEL: test_fpext_ppc_fp128_f32: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: xxlxor 2, 2, 2 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_fpext_ppc_fp128_f32: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: xxlxor 2, 2, 2 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_fpext_ppc_fp128_f32: +; PC64: # %bb.0: # %entry +; PC64-NEXT: addis 3, 2, .LCPI26_0@toc@ha +; PC64-NEXT: lfs 2, .LCPI26_0@toc@l(3) +; PC64-NEXT: blr +entry: + %fpext = call ppc_fp128 @llvm.experimental.constrained.fpext.f32.ppcf128( + float %first, + metadata !"fpexcept.strict") + ret ppc_fp128 %fpext +} + +define ppc_fp128 @test_fpext_ppc_fp128_f64(double %first) { +; PC64LE-LABEL: test_fpext_ppc_fp128_f64: +; PC64LE: # %bb.0: # %entry +; PC64LE-NEXT: xxlxor 2, 2, 2 +; PC64LE-NEXT: blr +; +; PC64LE9-LABEL: test_fpext_ppc_fp128_f64: +; PC64LE9: # %bb.0: # %entry +; PC64LE9-NEXT: xxlxor 2, 2, 2 +; PC64LE9-NEXT: blr +; +; PC64-LABEL: test_fpext_ppc_fp128_f64: +; PC64: # %bb.0: # %entry +; PC64-NEXT: addis 3, 2, .LCPI27_0@toc@ha +; PC64-NEXT: lfs 2, .LCPI27_0@toc@l(3) +; PC64-NEXT: blr +entry: + %fpext = call ppc_fp128 @llvm.experimental.constrained.fpext.f64.ppcf128( + double %first, + metadata !"fpexcept.strict") + ret ppc_fp128 %fpext +} + + +declare ppc_fp128 @llvm.experimental.constrained.fadd.ppcf128(ppc_fp128, ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.ceil.ppcf128(ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.cos.ppcf128(ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.fdiv.ppcf128(ppc_fp128, ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.exp.ppcf128(ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.exp2.ppcf128(ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.floor.ppcf128(ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.fma.ppcf128(ppc_fp128, ppc_fp128, ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.fpext.f32.ppcf128(float, metadata) +declare ppc_fp128 @llvm.experimental.constrained.fpext.f64.ppcf128(double, metadata) +declare float @llvm.experimental.constrained.fptrunc.ppcf128.f32(ppc_fp128, metadata, metadata) +declare double @llvm.experimental.constrained.fptrunc.ppcf128.f64(ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.log.ppcf128(ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.log10.ppcf128(ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.log2.ppcf128(ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.maxnum.ppcf128(ppc_fp128, ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.minnum.ppcf128(ppc_fp128, ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.fmul.ppcf128(ppc_fp128, ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.nearbyint.ppcf128(ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.pow.ppcf128(ppc_fp128, ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.powi.ppcf128(ppc_fp128, i32, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.frem.ppcf128(ppc_fp128, ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.rint.ppcf128(ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.round.ppcf128(ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.sin.ppcf128(ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.sqrt.ppcf128(ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.fsub.ppcf128(ppc_fp128, ppc_fp128, metadata, metadata) +declare ppc_fp128 @llvm.experimental.constrained.trunc.ppcf128(ppc_fp128, metadata, metadata)