diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index f1943702707..c7a9cff07ae 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -152,9 +152,7 @@ public: return NN; } - - SDOperand getSetCC(ISD::CondCode, MVT::ValueType VT, - SDOperand LHS, SDOperand RHS); + SDOperand getCondCode(ISD::CondCode Cond); /// getZeroExtendInReg - Return the expression required to zero extend the Op /// value assuming it was the smaller SrcTy value. @@ -178,7 +176,14 @@ public: SDOperand getNode(unsigned Opcode, std::vector &ResultTys, std::vector &Ops); - + /// getSetCC - Helper function to make it easier to build SetCC's if you just + /// have an ISD::CondCode instead of an SDOperand. + /// + SDOperand getSetCC(MVT::ValueType VT, SDOperand LHS, SDOperand RHS, + ISD::CondCode Cond) { + return getNode(ISD::SETCC, VT, LHS, RHS, getCondCode(Cond)); + } + /// getLoad - Loads are not normal binary operators: their result type is not /// determined by their operands, and they produce a value AND a token chain. /// @@ -199,16 +204,20 @@ public: private: void DeleteNodeIfDead(SDNode *N, void *NodeSet); + + // Try to simplify a setcc built with the specified operands and cc. If + // unable to simplify it, return a null SDOperand. + SDOperand SimplfySetCC(MVT::ValueType VT, SDOperand N1, + SDOperand N2, ISD::CondCode Cond); + // Maps to auto-CSE operations. std::map >, SDNode *> UnaryOps; std::map >, SDNode *> BinaryOps; - std::map, - std::pair >, - SetCCSDNode*> SetCCs; + std::vector CondCodeNodes; std::map >, SDNode *> Loads; diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index c666ab05e23..898041d6b16 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -55,7 +55,7 @@ namespace ISD { // Various leaf nodes. Constant, ConstantFP, GlobalAddress, FrameIndex, ConstantPool, - BasicBlock, ExternalSymbol, VALUETYPE, + BasicBlock, ExternalSymbol, VALUETYPE, CONDCODE, // CopyToReg - This node has chain and child nodes, and an associated // register number. The instruction selector must guarantee that the value @@ -107,9 +107,9 @@ namespace ISD { SELECT, // SetCC operator - This evaluates to a boolean (i1) true value if the - // condition is true. These nodes are instances of the - // SetCCSDNode class, which contains the condition code as extra - // state. + // condition is true. The operands to this are the left and right operands + // to compare (ops #0, and #1) and the condition code to compare them with + // (op #2) as a CondCodeSDNode. SETCC, // ADD_PARTS/SUB_PARTS - These operators take two logical operands which are @@ -827,20 +827,20 @@ public: } }; -class SetCCSDNode : public SDNode { +class CondCodeSDNode : public SDNode { ISD::CondCode Condition; protected: friend class SelectionDAG; - SetCCSDNode(ISD::CondCode Cond, SDOperand LHS, SDOperand RHS) - : SDNode(ISD::SETCC, LHS, RHS), Condition(Cond) { + CondCodeSDNode(ISD::CondCode Cond) + : SDNode(ISD::CONDCODE, MVT::Other), Condition(Cond) { } public: - ISD::CondCode getCondition() const { return Condition; } + ISD::CondCode get() const { return Condition; } - static bool classof(const SetCCSDNode *) { return true; } + static bool classof(const CondCodeSDNode *) { return true; } static bool classof(const SDNode *N) { - return N->getOpcode() == ISD::SETCC; + return N->getOpcode() == ISD::CONDCODE; } }; diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index e3f8e0911e9..13fc5a656ba 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -163,10 +163,9 @@ SDOperand SelectionDAGLegalize::ExpandLegalUINT_TO_FP(SDOperand Op0, MVT::ValueType DestVT) { SDOperand Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op0); - SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(), - Op0, - DAG.getConstant(0, - Op0.getValueType())); + SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultTy(), Op0, + DAG.getConstant(0, Op0.getValueType()), + ISD::SETLT); SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4); SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(), SignSet, Four, Zero); @@ -945,8 +944,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) - Result = DAG.getSetCC(cast(Node)->getCondition(), - Node->getValueType(0), Tmp1, Tmp2); + Result = DAG.getNode(ISD::SETCC, Node->getValueType(0), Tmp1, Tmp2, + Node->getOperand(2)); break; case Promote: Tmp1 = PromoteOp(Node->getOperand(0)); // LHS @@ -961,7 +960,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { // that we could insert sign extends for ALL conditions, but zero extend // is cheaper on many machines (an AND instead of two shifts), so prefer // it. - switch (cast(Node)->getCondition()) { + switch (cast(Node->getOperand(2))->get()) { default: assert(0 && "Unknown integer comparison!"); case ISD::SETEQ: case ISD::SETNE: @@ -987,14 +986,14 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { } } - Result = DAG.getSetCC(cast(Node)->getCondition(), - Node->getValueType(0), Tmp1, Tmp2); + Result = DAG.getNode(ISD::SETCC, Node->getValueType(0), Tmp1, Tmp2, + Node->getOperand(2)); break; case Expand: SDOperand LHSLo, LHSHi, RHSLo, RHSHi; ExpandOp(Node->getOperand(0), LHSLo, LHSHi); ExpandOp(Node->getOperand(1), RHSLo, RHSHi); - switch (cast(Node)->getCondition()) { + switch (cast(Node->getOperand(2))->get()) { case ISD::SETEQ: case ISD::SETNE: if (RHSLo == RHSHi) @@ -1002,32 +1001,32 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { if (RHSCST->isAllOnesValue()) { // Comparison to -1. Tmp1 = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi); - Result = DAG.getSetCC(cast(Node)->getCondition(), - Node->getValueType(0), Tmp1, RHSLo); + Result = DAG.getNode(ISD::SETCC, Node->getValueType(0), Tmp1, + RHSLo, Node->getOperand(2)); break; } Tmp1 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo); Tmp2 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi); Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp2); - Result = DAG.getSetCC(cast(Node)->getCondition(), - Node->getValueType(0), Tmp1, - DAG.getConstant(0, Tmp1.getValueType())); + Result = DAG.getNode(ISD::SETCC, Node->getValueType(0), Tmp1, + DAG.getConstant(0, Tmp1.getValueType()), + Node->getOperand(2)); break; default: // If this is a comparison of the sign bit, just look at the top part. // X > -1, x < 0 if (ConstantSDNode *CST = dyn_cast(Node->getOperand(1))) - if ((cast(Node)->getCondition() == ISD::SETLT && + if ((cast(Node->getOperand(2))->get() == ISD::SETLT && CST->getValue() == 0) || // X < 0 - (cast(Node)->getCondition() == ISD::SETGT && + (cast(Node->getOperand(2))->get() == ISD::SETGT && (CST->isAllOnesValue()))) // X > -1 - return DAG.getSetCC(cast(Node)->getCondition(), - Node->getValueType(0), LHSHi, RHSHi); + return DAG.getNode(ISD::SETCC, Node->getValueType(0), LHSHi, RHSHi, + Node->getOperand(2)); // FIXME: This generated code sucks. ISD::CondCode LowCC; - switch (cast(Node)->getCondition()) { + switch (cast(Node->getOperand(2))->get()) { default: assert(0 && "Unknown integer setcc!"); case ISD::SETLT: case ISD::SETULT: LowCC = ISD::SETULT; break; @@ -1045,10 +1044,10 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { // NOTE: on targets without efficient SELECT of bools, we can always use // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3) - Tmp1 = DAG.getSetCC(LowCC, Node->getValueType(0), LHSLo, RHSLo); - Tmp2 = DAG.getSetCC(cast(Node)->getCondition(), - Node->getValueType(0), LHSHi, RHSHi); - Result = DAG.getSetCC(ISD::SETEQ, Node->getValueType(0), LHSHi, RHSHi); + Tmp1 = DAG.getSetCC(Node->getValueType(0), LHSLo, RHSLo, LowCC); + Tmp2 = DAG.getNode(ISD::SETCC, Node->getValueType(0), LHSHi, RHSHi, + Node->getOperand(2)); + Result = DAG.getSetCC(Node->getValueType(0), LHSHi, RHSHi, ISD::SETEQ); Result = DAG.getNode(ISD::SELECT, Tmp1.getValueType(), Result, Tmp1, Tmp2); break; @@ -1348,8 +1347,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { break; case ISD::CTTZ: //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT) - Tmp2 = DAG.getSetCC(ISD::SETEQ, TLI.getSetCCResultTy(), Tmp1, - DAG.getConstant(getSizeInBits(NVT), NVT)); + Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), Tmp1, + DAG.getConstant(getSizeInBits(NVT), NVT), + ISD::SETEQ); Result = DAG.getNode(ISD::SELECT, NVT, Tmp2, DAG.getConstant(getSizeInBits(OVT),NVT), Tmp1); break; @@ -1469,7 +1469,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { // Expand Y = FABS(X) -> Y = (X >u 0.0) ? X : fneg(X). MVT::ValueType VT = Node->getValueType(0); Tmp2 = DAG.getConstantFP(0.0, VT); - Tmp2 = DAG.getSetCC(ISD::SETUGT, TLI.getSetCCResultTy(), Tmp1, Tmp2); + Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), Tmp1, Tmp2, ISD::SETUGT); Tmp3 = DAG.getNode(ISD::FNEG, VT, Tmp1); Result = DAG.getNode(ISD::SELECT, VT, Tmp2, Tmp1, Tmp3); Result = LegalizeOp(Result); @@ -1764,9 +1764,8 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) { case ISD::SETCC: assert(getTypeAction(TLI.getSetCCResultTy()) == Legal && "SetCC type is not legal??"); - Result = DAG.getSetCC(cast(Node)->getCondition(), - TLI.getSetCCResultTy(), Node->getOperand(0), - Node->getOperand(1)); + Result = DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(),Node->getOperand(0), + Node->getOperand(1), Node->getOperand(2)); Result = LegalizeOp(Result); break; @@ -2038,8 +2037,8 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) { break; case ISD::CTTZ: //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT) - Tmp2 = DAG.getSetCC(ISD::SETEQ, MVT::i1, Tmp1, - DAG.getConstant(getSizeInBits(NVT), NVT)); + Tmp2 = DAG.getSetCC(MVT::i1, Tmp1, + DAG.getConstant(getSizeInBits(NVT), NVT), ISD::SETEQ); Result = DAG.getNode(ISD::SELECT, NVT, Tmp2, DAG.getConstant(getSizeInBits(VT),NVT), Tmp1); break; @@ -2216,8 +2215,8 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDOperand Op,SDOperand Amt, DAG.getConstant(NVTBits, ShTy), ShAmt); // Compare the unmasked shift amount against 32. - SDOperand Cond = DAG.getSetCC(ISD::SETGE, TLI.getSetCCResultTy(), ShAmt, - DAG.getConstant(NVTBits, ShTy)); + SDOperand Cond = DAG.getSetCC(TLI.getSetCCResultTy(), ShAmt, + DAG.getConstant(NVTBits, ShTy), ISD::SETGE); if (TLI.getShiftAmountFlavor() != TargetLowering::Mask) { ShAmt = DAG.getNode(ISD::AND, ShTy, ShAmt, // ShAmt &= 31 @@ -2236,9 +2235,9 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDOperand Op,SDOperand Amt, Lo = DAG.getNode(ISD::SELECT, NVT, Cond, DAG.getConstant(0, NVT), T2); } else { SDOperand HiLoPart = DAG.getNode(ISD::SELECT, NVT, - DAG.getSetCC(ISD::SETEQ, - TLI.getSetCCResultTy(), NAmt, - DAG.getConstant(32, ShTy)), + DAG.getSetCC(TLI.getSetCCResultTy(), NAmt, + DAG.getConstant(32, ShTy), + ISD::SETEQ), DAG.getConstant(0, NVT), DAG.getNode(ISD::SHL, NVT, InH, NAmt)); SDOperand T1 = DAG.getNode(ISD::OR, NVT,// T1 = (Hi << NAmt) | (Lo >> Amt) @@ -2468,8 +2467,9 @@ ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) { SDOperand SignedConv = ExpandIntToFP(true, DestTy, DAG.getNode(ISD::BUILD_PAIR, Source.getValueType(), Lo, Hi)); - SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(), Hi, - DAG.getConstant(0, Hi.getValueType())); + SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultTy(), Hi, + DAG.getConstant(0, Hi.getValueType()), + ISD::SETLT); SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4); SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(), SignSet, Four, Zero); @@ -2627,8 +2627,8 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ ExpandOp(Node->getOperand(0), Lo, Hi); SDOperand BitsC = DAG.getConstant(MVT::getSizeInBits(NVT), NVT); SDOperand HLZ = DAG.getNode(ISD::CTLZ, NVT, Hi); - SDOperand TopNotZero = DAG.getSetCC(ISD::SETNE, TLI.getSetCCResultTy(), - HLZ, BitsC); + SDOperand TopNotZero = DAG.getSetCC(TLI.getSetCCResultTy(), HLZ, BitsC, + ISD::SETNE); SDOperand LowPart = DAG.getNode(ISD::CTLZ, NVT, Lo); LowPart = DAG.getNode(ISD::ADD, NVT, LowPart, BitsC); @@ -2642,8 +2642,8 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ ExpandOp(Node->getOperand(0), Lo, Hi); SDOperand BitsC = DAG.getConstant(MVT::getSizeInBits(NVT), NVT); SDOperand LTZ = DAG.getNode(ISD::CTTZ, NVT, Lo); - SDOperand BotNotZero = DAG.getSetCC(ISD::SETNE, TLI.getSetCCResultTy(), - LTZ, BitsC); + SDOperand BotNotZero = DAG.getSetCC(TLI.getSetCCResultTy(), LTZ, BitsC, + ISD::SETNE); SDOperand HiPart = DAG.getNode(ISD::CTTZ, NVT, Hi); HiPart = DAG.getNode(ISD::ADD, NVT, HiPart, BitsC); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index a9907fa55a9..d321e7720d4 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -50,7 +50,7 @@ static bool isAssociativeBinOp(unsigned Opcode) { // inverse of this node. static bool isInvertibleForFree(SDOperand N) { if (isa(N.Val)) return true; - if (isa(N.Val) && N.Val->hasOneUse()) + if (N.Val->getOpcode() == ISD::SETCC && N.Val->hasOneUse()) return true; return false; } @@ -197,6 +197,11 @@ void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) { ConstantFPs.erase(std::make_pair(IV, N->getValueType(0))); break; } + case ISD::CONDCODE: + assert(CondCodeNodes[cast(N)->get()] && + "Cond code doesn't exist!"); + CondCodeNodes[cast(N)->get()] = 0; + break; case ISD::GlobalAddress: GlobalValues.erase(cast(N)->getGlobal()); break; @@ -225,13 +230,6 @@ void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) { std::make_pair(N->getOperand(0), N->getValueType(0)))); break; - case ISD::SETCC: - SetCCs.erase(std::make_pair(std::make_pair(N->getOperand(0), - N->getOperand(1)), - std::make_pair( - cast(N)->getCondition(), - N->getValueType(0)))); - break; default: if (N->getNumOperands() == 1) UnaryOps.erase(std::make_pair(N->getOpcode(), @@ -377,8 +375,17 @@ SDOperand SelectionDAG::getExternalSymbol(const char *Sym, MVT::ValueType VT) { return SDOperand(N, 0); } -SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, MVT::ValueType VT, - SDOperand N1, SDOperand N2) { +SDOperand SelectionDAG::getCondCode(ISD::CondCode Cond) { + if ((unsigned)Cond >= CondCodeNodes.size()) + CondCodeNodes.resize(Cond+1); + + if (CondCodeNodes[Cond] == 0) + CondCodeNodes[Cond] = new CondCodeSDNode(Cond); + return SDOperand(CondCodeNodes[Cond], 0); +} + +SDOperand SelectionDAG::SimplfySetCC(MVT::ValueType VT, SDOperand N1, + SDOperand N2, ISD::CondCode Cond) { // These setcc operations always fold. switch (Cond) { default: break; @@ -450,14 +457,14 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, MVT::ValueType VT, case ISD::SETUGE: case ISD::SETULT: case ISD::SETULE: - return getSetCC(Cond, VT, N1.getOperand(0), - getConstant(C2, N1.getOperand(0).getValueType())); + return getSetCC(VT, N1.getOperand(0), + getConstant(C2, N1.getOperand(0).getValueType()), + Cond); default: break; // todo, be more careful with signed comparisons } } - uint64_t MinVal, MaxVal; unsigned OperandBitSize = MVT::getSizeInBits(N2C->getValueType(0)); if (ISD::isSignedIntSetCC(Cond)) { @@ -493,16 +500,16 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, MVT::ValueType VT, // Canonicalize setgt X, Min --> setne X, Min if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C2 == MinVal) - return getSetCC(ISD::SETNE, VT, N1, N2); + return getSetCC(VT, N1, N2, ISD::SETNE); // If we have setult X, 1, turn it into seteq X, 0 if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C2 == MinVal+1) - return getSetCC(ISD::SETEQ, VT, N1, - getConstant(MinVal, N1.getValueType())); + return getSetCC(VT, N1, getConstant(MinVal, N1.getValueType()), + ISD::SETEQ); // If we have setugt X, Max-1, turn it into seteq X, Max else if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C2 == MaxVal-1) - return getSetCC(ISD::SETEQ, VT, N1, - getConstant(MaxVal, N1.getValueType())); + return getSetCC(VT, N1, getConstant(MaxVal, N1.getValueType()), + ISD::SETEQ); // If we have "setcc X, C1", check to see if we can shrink the immediate // by changing cc. @@ -510,7 +517,7 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, MVT::ValueType VT, // SETUGT X, SINTMAX -> SETLT X, 0 if (Cond == ISD::SETUGT && OperandBitSize != 1 && C2 == (~0ULL >> (65-OperandBitSize))) - return getSetCC(ISD::SETLT, VT, N1, getConstant(0, N2.getValueType())); + return getSetCC(VT, N1, getConstant(0, N2.getValueType()), ISD::SETLT); // FIXME: Implement the rest of these. @@ -539,7 +546,7 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, MVT::ValueType VT, } } else if (isa(N1.Val)) { // Ensure that the constant occurs on the RHS. - return getSetCC(ISD::getSetCCSwappedOperands(Cond), VT, N2, N1); + return getSetCC(VT, N2, N1, ISD::getSetCCSwappedOperands(Cond)); } if (ConstantFPSDNode *N1C = dyn_cast(N1.Val)) @@ -582,15 +589,15 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, MVT::ValueType VT, // Simplify (X+Y) == (X+Z) --> Y == Z if (N1.getOpcode() == N2.getOpcode()) { if (N1.getOperand(0) == N2.getOperand(0)) - return getSetCC(Cond, VT, N1.getOperand(1), N2.getOperand(1)); + return getSetCC(VT, N1.getOperand(1), N2.getOperand(1), Cond); if (N1.getOperand(1) == N2.getOperand(1)) - return getSetCC(Cond, VT, N1.getOperand(0), N2.getOperand(0)); + return getSetCC(VT, N1.getOperand(0), N2.getOperand(0), Cond); if (isCommutativeBinOp(N1.getOpcode())) { // If X op Y == Y op X, try other combinations. if (N1.getOperand(0) == N2.getOperand(1)) - return getSetCC(Cond, VT, N1.getOperand(1), N2.getOperand(0)); + return getSetCC(VT, N1.getOperand(1), N2.getOperand(0), Cond); if (N1.getOperand(1) == N2.getOperand(0)) - return getSetCC(Cond, VT, N1.getOperand(1), N2.getOperand(1)); + return getSetCC(VT, N1.getOperand(1), N2.getOperand(1), Cond); } } @@ -598,18 +605,19 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, MVT::ValueType VT, // Simplify (X+Z) == X --> Z == 0 if (N1.getOperand(0) == N2) - return getSetCC(Cond, VT, N1.getOperand(1), - getConstant(0, N1.getValueType())); + return getSetCC(VT, N1.getOperand(1), + getConstant(0, N1.getValueType()), Cond); if (N1.getOperand(1) == N2) { if (isCommutativeBinOp(N1.getOpcode())) - return getSetCC(Cond, VT, N1.getOperand(0), - getConstant(0, N1.getValueType())); + return getSetCC(VT, N1.getOperand(0), + getConstant(0, N1.getValueType()), Cond); else { assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!"); // (Z-X) == X --> Z == X<<1 - return getSetCC(Cond, VT, N1.getOperand(0), + return getSetCC(VT, N1.getOperand(0), getNode(ISD::SHL, N2.getValueType(), - N2, getConstant(1, TLI.getShiftAmountTy()))); + N2, getConstant(1, TLI.getShiftAmountTy())), + Cond); } } } @@ -618,11 +626,11 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, MVT::ValueType VT, N2.getOpcode() == ISD::XOR) { // Simplify X == (X+Z) --> Z == 0 if (N2.getOperand(0) == N1) - return getSetCC(Cond, VT, N2.getOperand(1), - getConstant(0, N2.getValueType())); + return getSetCC(VT, N2.getOperand(1), + getConstant(0, N2.getValueType()), Cond); else if (N2.getOperand(1) == N1) - return getSetCC(Cond, VT, N2.getOperand(0), - getConstant(0, N2.getValueType())); + return getSetCC(VT, N2.getOperand(0), getConstant(0, N2.getValueType()), + Cond); } } @@ -664,14 +672,8 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, MVT::ValueType VT, return N1; } - - SetCCSDNode *&N = SetCCs[std::make_pair(std::make_pair(N1, N2), - std::make_pair(Cond, VT))]; - if (N) return SDOperand(N, 0); - N = new SetCCSDNode(Cond, N1, N2); - N->setValueTypes(VT); - AllNodes.push_back(N); - return SDOperand(N, 0); + // Could not fold it. + return SDOperand(); } @@ -1059,12 +1061,14 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, case ISD::XOR: if (!C2) return N1; // X xor 0 -> X if (N2C->isAllOnesValue()) { - if (SetCCSDNode *SetCC = dyn_cast(N1.Val)){ + if (N1.Val->getOpcode() == ISD::SETCC){ + SDNode *SetCC = N1.Val; // !(X op Y) -> (X !op Y) bool isInteger = MVT::isInteger(SetCC->getOperand(0).getValueType()); - return getSetCC(ISD::getSetCCInverse(SetCC->getCondition(),isInteger), - SetCC->getValueType(0), - SetCC->getOperand(0), SetCC->getOperand(1)); + ISD::CondCode CC = cast(SetCC->getOperand(2))->get(); + return getSetCC(SetCC->getValueType(0), + SetCC->getOperand(0), SetCC->getOperand(1), + ISD::getSetCCInverse(CC, isInteger)); } else if (N1.getOpcode() == ISD::AND || N1.getOpcode() == ISD::OR) { SDNode *Op = N1.Val; // !(X or Y) -> (!X and !Y) iff X or Y are freely invertible @@ -1131,61 +1135,61 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, case ISD::AND: case ISD::OR: - if (SetCCSDNode *LHS = dyn_cast(N1.Val)) - if (SetCCSDNode *RHS = dyn_cast(N2.Val)) { - SDOperand LL = LHS->getOperand(0), RL = RHS->getOperand(0); - SDOperand LR = LHS->getOperand(1), RR = RHS->getOperand(1); - ISD::CondCode Op2 = RHS->getCondition(); + if (N1.Val->getOpcode() == ISD::SETCC && N2.Val->getOpcode() == ISD::SETCC){ + SDNode *LHS = N1.Val, *RHS = N2.Val; + SDOperand LL = LHS->getOperand(0), RL = RHS->getOperand(0); + SDOperand LR = LHS->getOperand(1), RR = RHS->getOperand(1); + ISD::CondCode Op1 = cast(LHS->getOperand(2))->get(); + ISD::CondCode Op2 = cast(RHS->getOperand(2))->get(); - if (LR == RR && isa(LR) && - Op2 == LHS->getCondition() && MVT::isInteger(LL.getValueType())) { - // (X != 0) | (Y != 0) -> (X|Y != 0) - // (X == 0) & (Y == 0) -> (X|Y == 0) - // (X < 0) | (Y < 0) -> (X|Y < 0) - if (cast(LR)->getValue() == 0 && - ((Op2 == ISD::SETEQ && Opcode == ISD::AND) || - (Op2 == ISD::SETNE && Opcode == ISD::OR) || - (Op2 == ISD::SETLT && Opcode == ISD::OR))) - return getSetCC(Op2, VT, - getNode(ISD::OR, LR.getValueType(), LL, RL), LR); + if (LR == RR && isa(LR) && + Op2 == Op1 && MVT::isInteger(LL.getValueType())) { + // (X != 0) | (Y != 0) -> (X|Y != 0) + // (X == 0) & (Y == 0) -> (X|Y == 0) + // (X < 0) | (Y < 0) -> (X|Y < 0) + if (cast(LR)->getValue() == 0 && + ((Op2 == ISD::SETEQ && Opcode == ISD::AND) || + (Op2 == ISD::SETNE && Opcode == ISD::OR) || + (Op2 == ISD::SETLT && Opcode == ISD::OR))) + return getSetCC(VT, getNode(ISD::OR, LR.getValueType(), LL, RL), LR, + Op2); - if (cast(LR)->isAllOnesValue()) { - // (X == -1) & (Y == -1) -> (X&Y == -1) - // (X != -1) | (Y != -1) -> (X&Y != -1) - // (X > -1) | (Y > -1) -> (X&Y > -1) - if ((Opcode == ISD::AND && Op2 == ISD::SETEQ) || - (Opcode == ISD::OR && Op2 == ISD::SETNE) || - (Opcode == ISD::OR && Op2 == ISD::SETGT)) - return getSetCC(Op2, VT, - getNode(ISD::AND, LR.getValueType(), LL, RL), LR); - // (X > -1) & (Y > -1) -> (X|Y > -1) - if (Opcode == ISD::AND && Op2 == ISD::SETGT) - return getSetCC(Op2, VT, - getNode(ISD::OR, LR.getValueType(), LL, RL), LR); - } - } - - // (X op1 Y) | (Y op2 X) -> (X op1 Y) | (X swapop2 Y) - if (LL == RR && LR == RL) { - Op2 = ISD::getSetCCSwappedOperands(Op2); - goto MatchedBackwards; - } - - if (LL == RL && LR == RR) { - MatchedBackwards: - ISD::CondCode Result; - bool isInteger = MVT::isInteger(LL.getValueType()); - if (Opcode == ISD::OR) - Result = ISD::getSetCCOrOperation(LHS->getCondition(), Op2, - isInteger); - else - Result = ISD::getSetCCAndOperation(LHS->getCondition(), Op2, - isInteger); - if (Result != ISD::SETCC_INVALID) - return getSetCC(Result, LHS->getValueType(0), LL, LR); + if (cast(LR)->isAllOnesValue()) { + // (X == -1) & (Y == -1) -> (X&Y == -1) + // (X != -1) | (Y != -1) -> (X&Y != -1) + // (X > -1) | (Y > -1) -> (X&Y > -1) + if ((Opcode == ISD::AND && Op2 == ISD::SETEQ) || + (Opcode == ISD::OR && Op2 == ISD::SETNE) || + (Opcode == ISD::OR && Op2 == ISD::SETGT)) + return getSetCC(VT, getNode(ISD::AND, LR.getValueType(), LL, RL), + LR, Op2); + // (X > -1) & (Y > -1) -> (X|Y > -1) + if (Opcode == ISD::AND && Op2 == ISD::SETGT) + return getSetCC(VT, getNode(ISD::OR, LR.getValueType(), LL, RL), + LR, Op2); } } + // (X op1 Y) | (Y op2 X) -> (X op1 Y) | (X swapop2 Y) + if (LL == RR && LR == RL) { + Op2 = ISD::getSetCCSwappedOperands(Op2); + goto MatchedBackwards; + } + + if (LL == RL && LR == RR) { + MatchedBackwards: + ISD::CondCode Result; + bool isInteger = MVT::isInteger(LL.getValueType()); + if (Opcode == ISD::OR) + Result = ISD::getSetCCOrOperation(Op1, Op2, isInteger); + else + Result = ISD::getSetCCAndOperation(Op1, Op2, isInteger); + + if (Result != ISD::SETCC_INVALID) + return getSetCC(LHS->getValueType(0), LL, LR, Result); + } + } + // and/or zext(a), zext(b) -> zext(and/or a, b) if (N1.getOpcode() == ISD::ZERO_EXTEND && N2.getOpcode() == ISD::ZERO_EXTEND && @@ -1348,6 +1352,12 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, ConstantSDNode *N2C = dyn_cast(N2.Val); ConstantSDNode *N3C = dyn_cast(N3.Val); switch (Opcode) { + case ISD::SETCC: { + // Use SimplifySetCC to simplify SETCC's. + SDOperand Simp = SimplfySetCC(VT, N1, N2, cast(N3)->get()); + if (Simp.Val) return Simp; + break; + } case ISD::SELECT: if (N1C) if (N1C->getValue()) @@ -1381,20 +1391,20 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, } // If this is a selectcc, check to see if we can simplify the result. - if (SetCCSDNode *SetCC = dyn_cast(N1)) { + if (N1.Val->getOpcode() == ISD::SETCC) { + SDNode *SetCC = N1.Val; + ISD::CondCode CC = cast(SetCC->getOperand(2))->get(); if (ConstantFPSDNode *CFP = dyn_cast(SetCC->getOperand(1))) if (CFP->getValue() == 0.0) { // Allow either -0.0 or 0.0 // select (setg[te] X, +/-0.0), X, fneg(X) -> fabs - if ((SetCC->getCondition() == ISD::SETGE || - SetCC->getCondition() == ISD::SETGT) && + if ((CC == ISD::SETGE || CC == ISD::SETGT) && N2 == SetCC->getOperand(0) && N3.getOpcode() == ISD::FNEG && N3.getOperand(0) == N2) return getNode(ISD::FABS, VT, N2); // select (setl[te] X, +/-0.0), fneg(X), X -> fabs - if ((SetCC->getCondition() == ISD::SETLT || - SetCC->getCondition() == ISD::SETLE) && + if ((CC == ISD::SETLT || CC == ISD::SETLE) && N3 == SetCC->getOperand(0) && N2.getOpcode() == ISD::FNEG && N2.getOperand(0) == N3) return getNode(ISD::FABS, VT, N3); @@ -1403,7 +1413,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, if (ConstantSDNode *CN = dyn_cast(SetCC->getOperand(1))) if (CN->getValue() == 0 && N3C && N3C->getValue() == 0) - if (SetCC->getCondition() == ISD::SETLT) { + if (CC == ISD::SETLT) { MVT::ValueType XType = SetCC->getOperand(0).getValueType(); MVT::ValueType AType = N2.getValueType(); if (XType >= AType) { @@ -1680,7 +1690,8 @@ const char *SDNode::getOperationName() const { case ISD::SRA: return "sra"; case ISD::SRL: return "srl"; - case ISD::SELECT: return "select"; + case ISD::SETCC: return "setcc"; + case ISD::SELECT: return "select"; case ISD::ADD_PARTS: return "add_parts"; case ISD::SUB_PARTS: return "sub_parts"; case ISD::SHL_PARTS: return "shl_parts"; @@ -1737,32 +1748,31 @@ const char *SDNode::getOperationName() const { case ISD::READIO: return "readio"; case ISD::WRITEIO: return "writeio"; - case ISD::SETCC: - const SetCCSDNode *SetCC = cast(this); - switch (SetCC->getCondition()) { + case ISD::CONDCODE: + switch (cast(this)->get()) { default: assert(0 && "Unknown setcc condition!"); - case ISD::SETOEQ: return "setcc:setoeq"; - case ISD::SETOGT: return "setcc:setogt"; - case ISD::SETOGE: return "setcc:setoge"; - case ISD::SETOLT: return "setcc:setolt"; - case ISD::SETOLE: return "setcc:setole"; - case ISD::SETONE: return "setcc:setone"; + case ISD::SETOEQ: return "setoeq"; + case ISD::SETOGT: return "setogt"; + case ISD::SETOGE: return "setoge"; + case ISD::SETOLT: return "setolt"; + case ISD::SETOLE: return "setole"; + case ISD::SETONE: return "setone"; - case ISD::SETO: return "setcc:seto"; - case ISD::SETUO: return "setcc:setuo"; - case ISD::SETUEQ: return "setcc:setue"; - case ISD::SETUGT: return "setcc:setugt"; - case ISD::SETUGE: return "setcc:setuge"; - case ISD::SETULT: return "setcc:setult"; - case ISD::SETULE: return "setcc:setule"; - case ISD::SETUNE: return "setcc:setune"; + case ISD::SETO: return "seto"; + case ISD::SETUO: return "setuo"; + case ISD::SETUEQ: return "setue"; + case ISD::SETUGT: return "setugt"; + case ISD::SETUGE: return "setuge"; + case ISD::SETULT: return "setult"; + case ISD::SETULE: return "setule"; + case ISD::SETUNE: return "setune"; - case ISD::SETEQ: return "setcc:seteq"; - case ISD::SETGT: return "setcc:setgt"; - case ISD::SETGE: return "setcc:setge"; - case ISD::SETLT: return "setcc:setlt"; - case ISD::SETLE: return "setcc:setle"; - case ISD::SETNE: return "setcc:setne"; + case ISD::SETEQ: return "seteq"; + case ISD::SETGT: return "setgt"; + case ISD::SETGE: return "setge"; + case ISD::SETLT: return "setlt"; + case ISD::SETLE: return "setle"; + case ISD::SETNE: return "setne"; } } } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 2b53723d3d1..512a62deff8 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -482,7 +482,7 @@ void SelectionDAGLowering::visitSetCC(User &I,ISD::CondCode SignedOpcode, ISD::CondCode Opcode = SignedOpcode; if (I.getOperand(0)->getType()->isUnsigned()) Opcode = UnsignedOpcode; - setValue(&I, DAG.getSetCC(Opcode, MVT::i1, Op1, Op2)); + setValue(&I, DAG.getSetCC(MVT::i1, Op1, Op2, Opcode)); } void SelectionDAGLowering::visitSelect(User &I) { @@ -504,7 +504,7 @@ void SelectionDAGLowering::visitCast(User &I) { // Cast to bool is a comparison against zero, not truncation to zero. SDOperand Zero = isInteger(SrcTy) ? DAG.getConstant(0, N.getValueType()) : DAG.getConstantFP(0.0, N.getValueType()); - setValue(&I, DAG.getSetCC(ISD::SETNE, MVT::i1, N, Zero)); + setValue(&I, DAG.getSetCC(MVT::i1, N, Zero, ISD::SETNE)); } else if (isInteger(SrcTy)) { if (isInteger(DestTy)) { // Int -> Int cast if (DestTy < SrcTy) // Truncating cast? @@ -738,8 +738,8 @@ void SelectionDAGLowering::visitCall(CallInst &I) { return; case Intrinsic::isunordered: - setValue(&I, DAG.getSetCC(ISD::SETUO, MVT::i1,getValue(I.getOperand(1)), - getValue(I.getOperand(2)))); + setValue(&I, DAG.getSetCC(MVT::i1,getValue(I.getOperand(1)), + getValue(I.getOperand(2)), ISD::SETUO)); return; case Intrinsic::sqrt: