diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp | 37 | ||||
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 66 |
2 files changed, 44 insertions, 59 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index e28a3aa47ca..3f17d4d605e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -1658,18 +1658,6 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { EVT RVT = N->getValueType(0); SDLoc dl(N); - // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on - // PPC (the libcall is not available). FIXME: Do this in a less hacky way. - if (RVT == MVT::i32) { - assert(N->getOperand(0).getValueType() == MVT::ppcf128 && - "Logic only correct for ppcf128!"); - SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, dl, MVT::ppcf128, - N->getOperand(0), DAG.getValueType(MVT::f64)); - Res = DAG.getNode(ISD::FP_ROUND, dl, MVT::f64, Res, - DAG.getIntPtrConstant(1, dl)); - return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res); - } - RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); return TLI.makeLibCall(DAG, LC, RVT, N->getOperand(0), false, dl).first; @@ -1679,31 +1667,6 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) { EVT RVT = N->getValueType(0); SDLoc dl(N); - // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on - // PPC (the libcall is not available). FIXME: Do this in a less hacky way. - if (RVT == MVT::i32) { - assert(N->getOperand(0).getValueType() == MVT::ppcf128 && - "Logic only correct for ppcf128!"); - const uint64_t TwoE31[] = {0x41e0000000000000LL, 0}; - APFloat APF = APFloat(APFloat::PPCDoubleDouble(), APInt(128, TwoE31)); - SDValue Tmp = DAG.getConstantFP(APF, dl, MVT::ppcf128); - // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X - // FIXME: generated code sucks. - // TODO: Are there fast-math-flags to propagate to this FSUB? - return DAG.getSelectCC(dl, N->getOperand(0), Tmp, - DAG.getNode(ISD::ADD, dl, MVT::i32, - DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, - DAG.getNode(ISD::FSUB, dl, - MVT::ppcf128, - N->getOperand(0), - Tmp)), - DAG.getConstant(0x80000000, dl, - MVT::i32)), - DAG.getNode(ISD::FP_TO_SINT, dl, - MVT::i32, N->getOperand(0)), - ISD::SETGE); - } - RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); return TLI.makeLibCall(DAG, LC, N->getValueType(0), N->getOperand(0), diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 82f0334daa1..bf6e28c5020 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -201,9 +201,10 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM, addRegisterClass(MVT::i1, &PPC::CRBITRCRegClass); } - // This is used in the ppcf128->int sequence. Note it has different semantics - // from FP_ROUND: that rounds to nearest, this rounds to zero. - setOperationAction(ISD::FP_ROUND_INREG, MVT::ppcf128, Custom); + // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on + // PPC (the libcall is not available). + setOperationAction(ISD::FP_TO_SINT, MVT::ppcf128, Custom); + setOperationAction(ISD::FP_TO_UINT, MVT::ppcf128, Custom); // We do not currently implement these libm ops for PowerPC. setOperationAction(ISD::FFLOOR, MVT::ppcf128, Expand); @@ -6915,6 +6916,46 @@ SDValue PPCTargetLowering::LowerFP_TO_INTDirectMove(SDValue Op, SDValue PPCTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG, const SDLoc &dl) const { + // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on + // PPC (the libcall is not available). + if (Op.getOperand(0).getValueType() == MVT::ppcf128) { + if (Op.getValueType() == MVT::i32) { + if (Op.getOpcode() == ISD::FP_TO_SINT) { + SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, + MVT::f64, Op.getOperand(0), + DAG.getIntPtrConstant(0, dl)); + SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, + MVT::f64, Op.getOperand(0), + DAG.getIntPtrConstant(1, dl)); + + // Add the two halves of the long double in round-to-zero mode. + SDValue Res = DAG.getNode(PPCISD::FADDRTZ, dl, MVT::f64, Lo, Hi); + + // Now use a smaller FP_TO_SINT. + return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res); + } + if (Op.getOpcode() == ISD::FP_TO_UINT) { + const uint64_t TwoE31[] = {0x41e0000000000000LL, 0}; + APFloat APF = APFloat(APFloat::PPCDoubleDouble(), APInt(128, TwoE31)); + SDValue Tmp = DAG.getConstantFP(APF, dl, MVT::ppcf128); + // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X + // FIXME: generated code sucks. + // TODO: Are there fast-math-flags to propagate to this FSUB? + SDValue True = DAG.getNode(ISD::FSUB, dl, MVT::ppcf128, + Op.getOperand(0), Tmp); + True = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, True); + True = DAG.getNode(ISD::ADD, dl, MVT::i32, True, + DAG.getConstant(0x80000000, dl, MVT::i32)); + SDValue False = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, + Op.getOperand(0)); + return DAG.getSelectCC(dl, Op.getOperand(0), Tmp, True, False, + ISD::SETGE); + } + } + + return SDValue(); + } + if (Subtarget.hasDirectMove() && Subtarget.isPPC64()) return LowerFP_TO_INTDirectMove(Op, DAG, dl); @@ -9444,25 +9485,6 @@ void PPCTargetLowering::ReplaceNodeResults(SDNode *N, } return; } - case ISD::FP_ROUND_INREG: { - assert(N->getValueType(0) == MVT::ppcf128); - assert(N->getOperand(0).getValueType() == MVT::ppcf128); - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, - MVT::f64, N->getOperand(0), - DAG.getIntPtrConstant(0, dl)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, - MVT::f64, N->getOperand(0), - DAG.getIntPtrConstant(1, dl)); - - // Add the two halves of the long double in round-to-zero mode. - SDValue FPreg = DAG.getNode(PPCISD::FADDRTZ, dl, MVT::f64, Lo, Hi); - - // We know the low half is about to be thrown away, so just use something - // convenient. - Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::ppcf128, - FPreg, FPreg)); - return; - } case ISD::FP_TO_SINT: case ISD::FP_TO_UINT: // LowerFP_TO_INT() can only handle f32 and f64. |