From f6b23bfc79cf9f605a2e74942c90799ff4f1a17e Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Wed, 27 May 2009 03:33:44 +0000 Subject: [PATCH] Remove more special cases from LegalizeDAG. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72456 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 355 +++++++++-------------- 1 file changed, 145 insertions(+), 210 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 58e51780b07..bc9fa53bd72 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -154,6 +154,12 @@ private: } SDValue ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned); + SDValue ExpandFPLibCall(SDNode *Node, RTLIB::Libcall Call_F32, + RTLIB::Libcall Call_F64, RTLIB::Libcall Call_F80, + RTLIB::Libcall Call_PPCF128); + SDValue ExpandIntLibCall(SDNode *Node, bool isSigned, RTLIB::Libcall Call_I16, + RTLIB::Libcall Call_I32, RTLIB::Libcall Call_I64, + RTLIB::Libcall Call_I128); SDValue EmitStackConvert(SDValue SrcOp, MVT SlotVT, MVT DestVT, DebugLoc dl); SDValue ExpandBUILD_VECTOR(SDNode *Node); @@ -625,20 +631,6 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, return DAG.getMergeValues(Ops, 2, dl); } -/// GetFPLibCall - Return the right libcall for the given floating point type. -static RTLIB::Libcall GetFPLibCall(MVT VT, - RTLIB::Libcall Call_F32, - RTLIB::Libcall Call_F64, - RTLIB::Libcall Call_F80, - RTLIB::Libcall Call_PPCF128) { - return - VT == MVT::f32 ? Call_F32 : - VT == MVT::f64 ? Call_F64 : - VT == MVT::f80 ? Call_F80 : - VT == MVT::ppcf128 ? Call_PPCF128 : - RTLIB::UNKNOWN_LIBCALL; -} - /// PerformInsertVectorEltInMemory - Some target cannot handle a variable /// insertion index for the INSERT_VECTOR_ELT instruction. In this case, it /// is necessary to spill the vector being inserted into to memory, perform @@ -772,8 +764,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::CALLSEQ_END: case ISD::SELECT_CC: case ISD::SETCC: - case ISD::EXCEPTIONADDR: - case ISD::EHSELECTION: // These instructions have properties that aren't modeled in the // generic codepath SimpleFinishLegalizing = false; @@ -790,6 +780,10 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::MERGE_VALUES: case ISD::EH_RETURN: case ISD::FRAME_TO_ARGS_OFFSET: + case ISD::EXCEPTIONADDR: + case ISD::EHSELECTION: + // These operations lie about being legal: when they claim to be legal, + // they should actually be expanded. Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); if (Action == TargetLowering::Legal) Action = TargetLowering::Expand; @@ -797,6 +791,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::TRAMPOLINE: case ISD::FRAMEADDR: case ISD::RETURNADDR: + // These operations lie about being legal: they must always be + // custom-lowered. Action = TargetLowering::Custom; break; case ISD::BUILD_VECTOR: @@ -2059,35 +2055,15 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { break; // Binary operators - case ISD::ADD: case ISD::SUB: case ISD::MUL: case ISD::MULHS: case ISD::MULHU: case ISD::UDIV: case ISD::SDIV: - case ISD::AND: - case ISD::OR: - case ISD::XOR: - case ISD::SHL: - case ISD::SRL: - case ISD::SRA: - case ISD::FADD: - case ISD::FSUB: - case ISD::FMUL: - case ISD::FDIV: - case ISD::FPOW: Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS - if ((Node->getOpcode() == ISD::SHL || - Node->getOpcode() == ISD::SRL || - Node->getOpcode() == ISD::SRA) && - !Node->getValueType(0).isVector()) - Tmp2 = DAG.getShiftAmountOperand(Tmp2); - - Tmp2 = LegalizeOp(Tmp2); // Legalize the RHS. - Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { @@ -2189,14 +2165,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { else if (VT == MVT::i128) LC = RTLIB::MUL_I128; break; - case ISD::FPOW: - LC = GetFPLibCall(VT, RTLIB::POW_F32, RTLIB::POW_F64, RTLIB::POW_F80, - RTLIB::POW_PPCF128); - break; - case ISD::FDIV: - LC = GetFPLibCall(VT, RTLIB::DIV_F32, RTLIB::DIV_F64, RTLIB::DIV_F80, - RTLIB::DIV_PPCF128); - break; default: break; } if (LC != RTLIB::UNKNOWN_LIBCALL) { @@ -2207,25 +2175,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { assert(0 && "Cannot expand this binary operator!"); break; } - case TargetLowering::Promote: { - switch (Node->getOpcode()) { - default: assert(0 && "Do not know how to promote this BinOp!"); - case ISD::AND: - case ISD::OR: - case ISD::XOR: { - MVT OVT = Node->getValueType(0); - MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT); - assert(OVT.isVector() && "Cannot promote this BinOp!"); - // Bit convert each of the values to the new type. - Tmp1 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp1); - Tmp2 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp2); - Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); - // Bit convert the result back the original type. - Result = DAG.getNode(ISD::BIT_CONVERT, dl, OVT, Result); - break; - } - } - } } break; case ISD::FCOPYSIGN: // FCOPYSIGN does not require LHS/RHS to match type! @@ -2309,7 +2258,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::UREM: case ISD::SREM: - case ISD::FREM: Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS @@ -2369,11 +2317,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { else if (VT == MVT::i128) LC = (isSigned ? RTLIB::SREM_I128 : RTLIB::UREM_I128); break; - case ISD::FREM: - // Floating point mod -> fmod libcall. - LC = GetFPLibCall(VT, RTLIB::REM_F32, RTLIB::REM_F64, - RTLIB::REM_F80, RTLIB::REM_PPCF128); - break; } if (LC != RTLIB::UNKNOWN_LIBCALL) { @@ -2431,146 +2374,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { AddLegalizedOperand(SDValue(Node, 0), Result); AddLegalizedOperand(SDValue(Node, 1), Tmp1); return Op.getResNo() ? Tmp1 : Result; - } - // Unary operators - case ISD::FABS: - case ISD::FNEG: - case ISD::FSQRT: - case ISD::FSIN: - case ISD::FCOS: - case ISD::FLOG: - case ISD::FLOG2: - case ISD::FLOG10: - case ISD::FEXP: - case ISD::FEXP2: - case ISD::FTRUNC: - case ISD::FFLOOR: - case ISD::FCEIL: - case ISD::FRINT: - case ISD::FNEARBYINT: - Tmp1 = LegalizeOp(Node->getOperand(0)); - switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { - case TargetLowering::Promote: - case TargetLowering::Custom: - isCustom = true; - // FALLTHROUGH - case TargetLowering::Legal: - Result = DAG.UpdateNodeOperands(Result, Tmp1); - if (isCustom) { - Tmp1 = TLI.LowerOperation(Result, DAG); - if (Tmp1.getNode()) Result = Tmp1; - } - break; - case TargetLowering::Expand: - switch (Node->getOpcode()) { - default: assert(0 && "Unreachable!"); - case ISD::FNEG: - // Expand Y = FNEG(X) -> Y = SUB -0.0, X - Tmp2 = DAG.getConstantFP(-0.0, Node->getValueType(0)); - Result = DAG.getNode(ISD::FSUB, dl, Node->getValueType(0), Tmp2, Tmp1); - break; - case ISD::FABS: { - // Expand Y = FABS(X) -> Y = (X >u 0.0) ? X : fneg(X). - MVT VT = Node->getValueType(0); - Tmp2 = DAG.getConstantFP(0.0, VT); - Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()), - Tmp1, Tmp2, ISD::SETUGT); - Tmp3 = DAG.getNode(ISD::FNEG, dl, VT, Tmp1); - Result = DAG.getNode(ISD::SELECT, dl, VT, Tmp2, Tmp1, Tmp3); - break; - } - case ISD::FSQRT: - case ISD::FSIN: - case ISD::FCOS: - case ISD::FLOG: - case ISD::FLOG2: - case ISD::FLOG10: - case ISD::FEXP: - case ISD::FEXP2: - case ISD::FTRUNC: - case ISD::FFLOOR: - case ISD::FCEIL: - case ISD::FRINT: - case ISD::FNEARBYINT: { - MVT VT = Node->getValueType(0); - - assert(!VT.isVector() && "Vector shouldn't get here!"); - - RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; - switch(Node->getOpcode()) { - case ISD::FSQRT: - LC = GetFPLibCall(VT, RTLIB::SQRT_F32, RTLIB::SQRT_F64, - RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128); - break; - case ISD::FSIN: - LC = GetFPLibCall(VT, RTLIB::SIN_F32, RTLIB::SIN_F64, - RTLIB::SIN_F80, RTLIB::SIN_PPCF128); - break; - case ISD::FCOS: - LC = GetFPLibCall(VT, RTLIB::COS_F32, RTLIB::COS_F64, - RTLIB::COS_F80, RTLIB::COS_PPCF128); - break; - case ISD::FLOG: - LC = GetFPLibCall(VT, RTLIB::LOG_F32, RTLIB::LOG_F64, - RTLIB::LOG_F80, RTLIB::LOG_PPCF128); - break; - case ISD::FLOG2: - LC = GetFPLibCall(VT, RTLIB::LOG2_F32, RTLIB::LOG2_F64, - RTLIB::LOG2_F80, RTLIB::LOG2_PPCF128); - break; - case ISD::FLOG10: - LC = GetFPLibCall(VT, RTLIB::LOG10_F32, RTLIB::LOG10_F64, - RTLIB::LOG10_F80, RTLIB::LOG10_PPCF128); - break; - case ISD::FEXP: - LC = GetFPLibCall(VT, RTLIB::EXP_F32, RTLIB::EXP_F64, - RTLIB::EXP_F80, RTLIB::EXP_PPCF128); - break; - case ISD::FEXP2: - LC = GetFPLibCall(VT, RTLIB::EXP2_F32, RTLIB::EXP2_F64, - RTLIB::EXP2_F80, RTLIB::EXP2_PPCF128); - break; - case ISD::FTRUNC: - LC = GetFPLibCall(VT, RTLIB::TRUNC_F32, RTLIB::TRUNC_F64, - RTLIB::TRUNC_F80, RTLIB::TRUNC_PPCF128); - break; - case ISD::FFLOOR: - LC = GetFPLibCall(VT, RTLIB::FLOOR_F32, RTLIB::FLOOR_F64, - RTLIB::FLOOR_F80, RTLIB::FLOOR_PPCF128); - break; - case ISD::FCEIL: - LC = GetFPLibCall(VT, RTLIB::CEIL_F32, RTLIB::CEIL_F64, - RTLIB::CEIL_F80, RTLIB::CEIL_PPCF128); - break; - case ISD::FRINT: - LC = GetFPLibCall(VT, RTLIB::RINT_F32, RTLIB::RINT_F64, - RTLIB::RINT_F80, RTLIB::RINT_PPCF128); - break; - case ISD::FNEARBYINT: - LC = GetFPLibCall(VT, RTLIB::NEARBYINT_F32, RTLIB::NEARBYINT_F64, - RTLIB::NEARBYINT_F80, RTLIB::NEARBYINT_PPCF128); - break; - break; - default: assert(0 && "Unreachable!"); - } - Result = ExpandLibCall(LC, Node, false/*sign irrelevant*/); - break; - } - } - break; - } - break; - case ISD::FPOWI: { - MVT VT = Node->getValueType(0); - - // Expand unsupported unary vector operators by unrolling them. - assert(!VT.isVector() && "Vector shouldn't get here!"); - - // We always lower FPOWI into a libcall. No target support for it yet. - RTLIB::Libcall LC = GetFPLibCall(VT, RTLIB::POWI_F32, RTLIB::POWI_F64, - RTLIB::POWI_F80, RTLIB::POWI_PPCF128); - Result = ExpandLibCall(LC, Node, false/*sign irrelevant*/); - break; } case ISD::SADDO: case ISD::SSUBO: { @@ -3025,6 +2828,38 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, return CallInfo.first; } +SDValue SelectionDAGLegalize::ExpandFPLibCall(SDNode* Node, + RTLIB::Libcall Call_F32, + RTLIB::Libcall Call_F64, + RTLIB::Libcall Call_F80, + RTLIB::Libcall Call_PPCF128) { + RTLIB::Libcall LC; + switch (Node->getValueType(0).getSimpleVT()) { + default: assert(0 && "Unexpected request for libcall!"); + case MVT::f32: LC = Call_F32; break; + case MVT::f64: LC = Call_F64; break; + case MVT::f80: LC = Call_F80; break; + case MVT::ppcf128: LC = Call_PPCF128; break; + } + return ExpandLibCall(LC, Node, false); +} + +SDValue SelectionDAGLegalize::ExpandIntLibCall(SDNode* Node, bool isSigned, + RTLIB::Libcall Call_I16, + RTLIB::Libcall Call_I32, + RTLIB::Libcall Call_I64, + RTLIB::Libcall Call_I128) { + RTLIB::Libcall LC; + switch (Node->getValueType(0).getSimpleVT()) { + default: assert(0 && "Unexpected request for libcall!"); + case MVT::i16: LC = Call_I16; break; + case MVT::i32: LC = Call_I32; break; + case MVT::i64: LC = Call_I64; break; + case MVT::i128: LC = Call_I128; break; + } + return ExpandLibCall(LC, Node, isSigned); +} + /// ExpandLegalINT_TO_FP - This function is responsible for legalizing a /// INT_TO_FP operation of the specified operand when the target requests that /// we expand it. At this point, we know that the result and operand types are @@ -3375,7 +3210,7 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op, void SelectionDAGLegalize::ExpandNode(SDNode *Node, SmallVectorImpl &Results) { DebugLoc dl = Node->getDebugLoc(); - SDValue Tmp1, Tmp2; + SDValue Tmp1, Tmp2, Tmp3; switch (Node->getOpcode()) { case ISD::CTPOP: case ISD::CTLZ: @@ -3563,6 +3398,95 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node, Results.push_back(Node->getOperand(0)); } break; + case ISD::FNEG: + // Expand Y = FNEG(X) -> Y = SUB -0.0, X + Tmp1 = DAG.getConstantFP(-0.0, Node->getValueType(0)); + Tmp1 = DAG.getNode(ISD::FSUB, dl, Node->getValueType(0), Tmp1, + Node->getOperand(0)); + Results.push_back(Tmp1); + break; + case ISD::FABS: { + // Expand Y = FABS(X) -> Y = (X >u 0.0) ? X : fneg(X). + MVT VT = Node->getValueType(0); + Tmp1 = Node->getOperand(0); + Tmp2 = DAG.getConstantFP(0.0, VT); + Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()), + Tmp1, Tmp2, ISD::SETUGT); + Tmp3 = DAG.getNode(ISD::FNEG, dl, VT, Tmp1); + Tmp1 = DAG.getNode(ISD::SELECT, dl, VT, Tmp2, Tmp1, Tmp3); + Results.push_back(Tmp1); + break; + } + case ISD::FSQRT: + Results.push_back(ExpandFPLibCall(Node, RTLIB::SQRT_F32, RTLIB::SQRT_F64, + RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128)); + break; + case ISD::FSIN: + Results.push_back(ExpandFPLibCall(Node, RTLIB::SIN_F32, RTLIB::SIN_F64, + RTLIB::SIN_F80, RTLIB::SIN_PPCF128)); + break; + case ISD::FCOS: + Results.push_back(ExpandFPLibCall(Node, RTLIB::COS_F32, RTLIB::COS_F64, + RTLIB::COS_F80, RTLIB::COS_PPCF128)); + break; + case ISD::FLOG: + Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG_F32, RTLIB::LOG_F64, + RTLIB::LOG_F80, RTLIB::LOG_PPCF128)); + break; + case ISD::FLOG2: + Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG2_F32, RTLIB::LOG2_F64, + RTLIB::LOG2_F80, RTLIB::LOG2_PPCF128)); + break; + case ISD::FLOG10: + Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG10_F32, RTLIB::LOG10_F64, + RTLIB::LOG10_F80, RTLIB::LOG10_PPCF128)); + break; + case ISD::FEXP: + Results.push_back(ExpandFPLibCall(Node, RTLIB::EXP_F32, RTLIB::EXP_F64, + RTLIB::EXP_F80, RTLIB::EXP_PPCF128)); + break; + case ISD::FEXP2: + Results.push_back(ExpandFPLibCall(Node, RTLIB::EXP2_F32, RTLIB::EXP2_F64, + RTLIB::EXP2_F80, RTLIB::EXP2_PPCF128)); + break; + case ISD::FTRUNC: + Results.push_back(ExpandFPLibCall(Node, RTLIB::TRUNC_F32, RTLIB::TRUNC_F64, + RTLIB::TRUNC_F80, RTLIB::TRUNC_PPCF128)); + break; + case ISD::FFLOOR: + Results.push_back(ExpandFPLibCall(Node, RTLIB::FLOOR_F32, RTLIB::FLOOR_F64, + RTLIB::FLOOR_F80, RTLIB::FLOOR_PPCF128)); + break; + case ISD::FCEIL: + Results.push_back(ExpandFPLibCall(Node, RTLIB::CEIL_F32, RTLIB::CEIL_F64, + RTLIB::CEIL_F80, RTLIB::CEIL_PPCF128)); + break; + case ISD::FRINT: + Results.push_back(ExpandFPLibCall(Node, RTLIB::RINT_F32, RTLIB::RINT_F64, + RTLIB::RINT_F80, RTLIB::RINT_PPCF128)); + break; + case ISD::FNEARBYINT: + Results.push_back(ExpandFPLibCall(Node, RTLIB::NEARBYINT_F32, + RTLIB::NEARBYINT_F64, + RTLIB::NEARBYINT_F80, + RTLIB::NEARBYINT_PPCF128)); + break; + case ISD::FPOWI: + Results.push_back(ExpandFPLibCall(Node, RTLIB::POWI_F32, RTLIB::POWI_F64, + RTLIB::POWI_F80, RTLIB::POWI_PPCF128)); + break; + case ISD::FPOW: + Results.push_back(ExpandFPLibCall(Node, RTLIB::POW_F32, RTLIB::POW_F64, + RTLIB::POW_F80, RTLIB::POW_PPCF128)); + break; + case ISD::FDIV: + Results.push_back(ExpandFPLibCall(Node, RTLIB::DIV_F32, RTLIB::DIV_F64, + RTLIB::DIV_F80, RTLIB::DIV_PPCF128)); + break; + case ISD::FREM: + Results.push_back(ExpandFPLibCall(Node, RTLIB::REM_F32, RTLIB::REM_F64, + RTLIB::REM_F80, RTLIB::REM_PPCF128)); + break; case ISD::GLOBAL_OFFSET_TABLE: case ISD::GlobalAddress: case ISD::GlobalTLSAddress: @@ -3632,6 +3556,17 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node, Node->getOpcode() == ISD::SINT_TO_FP, dl); Results.push_back(Tmp1); break; + case ISD::AND: + case ISD::OR: + case ISD::XOR: + assert(OVT.isVector() && "Don't know how to promote scalar logic ops"); + // Bit convert each of the values to the new type. + Tmp1 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Node->getOperand(0)); + Tmp2 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Node->getOperand(1)); + Tmp1 = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); + // Bit convert the result back the original type. + Results.push_back(DAG.getNode(ISD::BIT_CONVERT, dl, OVT, Tmp1)); + break; } } -- 2.34.1