From 51dabfb28375be7bc5848806ae31cd068b6133f8 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 14 Oct 2006 00:41:01 +0000 Subject: [PATCH] When SimplifySetCC was moved to the DAGCombiner, it was never removed from SelectionDAG and it has since bitrotted. Remove the copy from SelectionDAG. Next, remove the constant folding piece of DAGCombiner::SimplifySetCC into a new FoldSetCC method which can be used by getNode() and SimplifySetCC. This fixes obscure bugs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30952 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAG.h | 9 +- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 48 ++------- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 171 +++--------------------------- 3 files changed, 29 insertions(+), 199 deletions(-) diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 26241257830..65448c78a6d 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -449,6 +449,10 @@ public: void dump() const; + /// FoldSetCC - Constant fold a setcc to true or false. + SDOperand FoldSetCC(MVT::ValueType VT, SDOperand N1, + SDOperand N2, ISD::CondCode Cond); + private: void RemoveNodeFromCSEMaps(SDNode *N); SDNode *AddNonLeafNodeToCSEMaps(SDNode *N); @@ -460,11 +464,6 @@ private: void DeleteNodeNotInCSEMaps(SDNode *N); - /// SimplifySetCC - Try to simplify a setcc built with the specified operands - /// and cc. If unable to simplify it, return a null SDOperand. - SDOperand SimplifySetCC(MVT::ValueType VT, SDOperand N1, - SDOperand N2, ISD::CondCode Cond); - // List of non-single value types. std::list > VTList; diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index bb8fc4559ce..0c6fe66c402 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3586,27 +3586,7 @@ SDOperand DAGCombiner::SimplifySetCC(MVT::ValueType VT, SDOperand N0, if (ConstantSDNode *N1C = dyn_cast(N1.Val)) { uint64_t C1 = N1C->getValue(); if (ConstantSDNode *N0C = dyn_cast(N0.Val)) { - uint64_t C0 = N0C->getValue(); - - // Sign extend the operands if required - if (ISD::isSignedIntSetCC(Cond)) { - C0 = N0C->getSignExtended(); - C1 = N1C->getSignExtended(); - } - - switch (Cond) { - default: assert(0 && "Unknown integer setcc!"); - case ISD::SETEQ: return DAG.getConstant(C0 == C1, VT); - case ISD::SETNE: return DAG.getConstant(C0 != C1, VT); - case ISD::SETULT: return DAG.getConstant(C0 < C1, VT); - case ISD::SETUGT: return DAG.getConstant(C0 > C1, VT); - case ISD::SETULE: return DAG.getConstant(C0 <= C1, VT); - case ISD::SETUGE: return DAG.getConstant(C0 >= C1, VT); - case ISD::SETLT: return DAG.getConstant((int64_t)C0 < (int64_t)C1, VT); - case ISD::SETGT: return DAG.getConstant((int64_t)C0 > (int64_t)C1, VT); - case ISD::SETLE: return DAG.getConstant((int64_t)C0 <= (int64_t)C1, VT); - case ISD::SETGE: return DAG.getConstant((int64_t)C0 >= (int64_t)C1, VT); - } + return DAG.FoldSetCC(VT, N0, N1, Cond); } else { // If the LHS is '(srl (ctlz x), 5)', the RHS is 0/1, and this is an // equality comparison, then we're just comparing whether X itself is @@ -3797,7 +3777,7 @@ SDOperand DAGCombiner::SimplifySetCC(MVT::ValueType VT, SDOperand N0, dyn_cast(N0.getOperand(1))) { if (Cond == ISD::SETNE && C1 == 0) {// (X & 8) != 0 --> (X & 8) >> 3 // Perform the xform if the AND RHS is a single bit. - if ((AndRHS->getValue() & (AndRHS->getValue()-1)) == 0) { + if (isPowerOf2_64(AndRHS->getValue())) { return DAG.getNode(ISD::SRL, VT, N0, DAG.getConstant(Log2_64(AndRHS->getValue()), TLI.getShiftAmountTy())); @@ -3805,7 +3785,7 @@ SDOperand DAGCombiner::SimplifySetCC(MVT::ValueType VT, SDOperand N0, } else if (Cond == ISD::SETEQ && C1 == AndRHS->getValue()) { // (X & 8) == 8 --> (X & 8) >> 3 // Perform the xform if C1 is a single bit. - if ((C1 & (C1-1)) == 0) { + if (isPowerOf2_64(C1)) { return DAG.getNode(ISD::SRL, VT, N0, DAG.getConstant(Log2_64(C1),TLI.getShiftAmountTy())); } @@ -3817,23 +3797,11 @@ SDOperand DAGCombiner::SimplifySetCC(MVT::ValueType VT, SDOperand N0, return DAG.getSetCC(VT, N1, N0, ISD::getSetCCSwappedOperands(Cond)); } - if (ConstantFPSDNode *N0C = dyn_cast(N0.Val)) - if (ConstantFPSDNode *N1C = dyn_cast(N1.Val)) { - double C0 = N0C->getValue(), C1 = N1C->getValue(); - - switch (Cond) { - default: break; // FIXME: Implement the rest of these! - case ISD::SETEQ: return DAG.getConstant(C0 == C1, VT); - case ISD::SETNE: return DAG.getConstant(C0 != C1, VT); - case ISD::SETLT: return DAG.getConstant(C0 < C1, VT); - case ISD::SETGT: return DAG.getConstant(C0 > C1, VT); - case ISD::SETLE: return DAG.getConstant(C0 <= C1, VT); - case ISD::SETGE: return DAG.getConstant(C0 >= C1, VT); - } - } else { - // Ensure that the constant occurs on the RHS. - return DAG.getSetCC(VT, N1, N0, ISD::getSetCCSwappedOperands(Cond)); - } + if (ConstantFPSDNode *N0C = dyn_cast(N0.Val)) { + // Constant fold or commute setcc. + SDOperand O = DAG.FoldSetCC(VT, N0, N1, Cond); + if (O.Val) return O; + } if (N0 == N1) { // We can always fold X == Y for integer setcc's. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 00293814b06..5a0f5b1e99f 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -736,8 +736,8 @@ SDOperand SelectionDAG::getSrcValue(const Value *V, int Offset) { return SDOperand(N, 0); } -SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1, - SDOperand N2, ISD::CondCode Cond) { +SDOperand SelectionDAG::FoldSetCC(MVT::ValueType VT, SDOperand N1, + SDOperand N2, ISD::CondCode Cond) { // These setcc operations always fold. switch (Cond) { default: break; @@ -759,18 +759,18 @@ SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1, assert(!MVT::isInteger(N1.getValueType()) && "Illegal setcc for integer!"); break; } - + if (ConstantSDNode *N2C = dyn_cast(N2.Val)) { uint64_t C2 = N2C->getValue(); if (ConstantSDNode *N1C = dyn_cast(N1.Val)) { uint64_t C1 = N1C->getValue(); - + // Sign extend the operands if required if (ISD::isSignedIntSetCC(Cond)) { C1 = N1C->getSignExtended(); C2 = N2C->getSignExtended(); } - + switch (Cond) { default: assert(0 && "Unknown integer setcc!"); case ISD::SETEQ: return getConstant(C1 == C2, VT); @@ -784,156 +784,12 @@ SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1, case ISD::SETLE: return getConstant((int64_t)C1 <= (int64_t)C2, VT); case ISD::SETGE: return getConstant((int64_t)C1 >= (int64_t)C2, VT); } - } else { - // If the LHS is a ZERO_EXTEND, perform the comparison on the input. - if (N1.getOpcode() == ISD::ZERO_EXTEND) { - unsigned InSize = MVT::getSizeInBits(N1.getOperand(0).getValueType()); - - // If the comparison constant has bits in the upper part, the - // zero-extended value could never match. - if (C2 & (~0ULL << InSize)) { - unsigned VSize = MVT::getSizeInBits(N1.getValueType()); - switch (Cond) { - case ISD::SETUGT: - case ISD::SETUGE: - case ISD::SETEQ: return getConstant(0, VT); - case ISD::SETULT: - case ISD::SETULE: - case ISD::SETNE: return getConstant(1, VT); - case ISD::SETGT: - case ISD::SETGE: - // True if the sign bit of C2 is set. - return getConstant((C2 & (1ULL << VSize)) != 0, VT); - case ISD::SETLT: - case ISD::SETLE: - // True if the sign bit of C2 isn't set. - return getConstant((C2 & (1ULL << VSize)) == 0, VT); - default: - break; - } - } - - // Otherwise, we can perform the comparison with the low bits. - switch (Cond) { - case ISD::SETEQ: - case ISD::SETNE: - case ISD::SETUGT: - case ISD::SETUGE: - case ISD::SETULT: - case ISD::SETULE: - return getSetCC(VT, N1.getOperand(0), - getConstant(C2, N1.getOperand(0).getValueType()), - Cond); - default: - break; // todo, be more careful with signed comparisons - } - } else if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG && - (Cond == ISD::SETEQ || Cond == ISD::SETNE)) { - MVT::ValueType ExtSrcTy = cast(N1.getOperand(1))->getVT(); - unsigned ExtSrcTyBits = MVT::getSizeInBits(ExtSrcTy); - MVT::ValueType ExtDstTy = N1.getValueType(); - unsigned ExtDstTyBits = MVT::getSizeInBits(ExtDstTy); - - // If the extended part has any inconsistent bits, it cannot ever - // compare equal. In other words, they have to be all ones or all - // zeros. - uint64_t ExtBits = - (~0ULL >> (64-ExtSrcTyBits)) & (~0ULL << (ExtDstTyBits-1)); - if ((C2 & ExtBits) != 0 && (C2 & ExtBits) != ExtBits) - return getConstant(Cond == ISD::SETNE, VT); - - // Otherwise, make this a use of a zext. - return getSetCC(VT, getZeroExtendInReg(N1.getOperand(0), ExtSrcTy), - getConstant(C2 & (~0ULL>>(64-ExtSrcTyBits)), ExtDstTy), - Cond); - } - - uint64_t MinVal, MaxVal; - unsigned OperandBitSize = MVT::getSizeInBits(N2C->getValueType(0)); - if (ISD::isSignedIntSetCC(Cond)) { - MinVal = 1ULL << (OperandBitSize-1); - if (OperandBitSize != 1) // Avoid X >> 64, which is undefined. - MaxVal = ~0ULL >> (65-OperandBitSize); - else - MaxVal = 0; - } else { - MinVal = 0; - MaxVal = ~0ULL >> (64-OperandBitSize); - } - - // Canonicalize GE/LE comparisons to use GT/LT comparisons. - if (Cond == ISD::SETGE || Cond == ISD::SETUGE) { - if (C2 == MinVal) return getConstant(1, VT); // X >= MIN --> true - --C2; // X >= C1 --> X > (C1-1) - return getSetCC(VT, N1, getConstant(C2, N2.getValueType()), - (Cond == ISD::SETGE) ? ISD::SETGT : ISD::SETUGT); - } - - if (Cond == ISD::SETLE || Cond == ISD::SETULE) { - if (C2 == MaxVal) return getConstant(1, VT); // X <= MAX --> true - ++C2; // X <= C1 --> X < (C1+1) - return getSetCC(VT, N1, getConstant(C2, N2.getValueType()), - (Cond == ISD::SETLE) ? ISD::SETLT : ISD::SETULT); - } - - if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C2 == MinVal) - return getConstant(0, VT); // X < MIN --> false - - // Canonicalize setgt X, Min --> setne X, Min - if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C2 == MinVal) - 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(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(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. - - // SETUGT X, SINTMAX -> SETLT X, 0 - if (Cond == ISD::SETUGT && OperandBitSize != 1 && - C2 == (~0ULL >> (65-OperandBitSize))) - return getSetCC(VT, N1, getConstant(0, N2.getValueType()), ISD::SETLT); - - // FIXME: Implement the rest of these. - - - // Fold bit comparisons when we can. - if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) && - VT == N1.getValueType() && N1.getOpcode() == ISD::AND) - if (ConstantSDNode *AndRHS = - dyn_cast(N1.getOperand(1))) { - if (Cond == ISD::SETNE && C2 == 0) {// (X & 8) != 0 --> (X & 8) >> 3 - // Perform the xform if the AND RHS is a single bit. - if (isPowerOf2_64(AndRHS->getValue())) { - return getNode(ISD::SRL, VT, N1, - getConstant(Log2_64(AndRHS->getValue()), - TLI.getShiftAmountTy())); - } - } else if (Cond == ISD::SETEQ && C2 == AndRHS->getValue()) { - // (X & 8) == 8 --> (X & 8) >> 3 - // Perform the xform if C2 is a single bit. - if (isPowerOf2_64(C2)) { - return getNode(ISD::SRL, VT, N1, - getConstant(Log2_64(C2),TLI.getShiftAmountTy())); - } - } - } } - } else if (isa(N1.Val)) { - // Ensure that the constant occurs on the RHS. - return getSetCC(VT, N2, N1, ISD::getSetCCSwappedOperands(Cond)); } - if (ConstantFPSDNode *N1C = dyn_cast(N1.Val)) if (ConstantFPSDNode *N2C = dyn_cast(N2.Val)) { double C1 = N1C->getValue(), C2 = N2C->getValue(); - + switch (Cond) { default: break; // FIXME: Implement the rest of these! case ISD::SETEQ: return getConstant(C1 == C2, VT); @@ -947,11 +803,12 @@ SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1, // Ensure that the constant occurs on the RHS. return getSetCC(VT, N2, N1, ISD::getSetCCSwappedOperands(Cond)); } - + // Could not fold it. return SDOperand(); } + /// getNode - Gets or creates the specified node. /// SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT) { @@ -1369,8 +1226,14 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, } } - // Finally, fold operations that do not require constants. + // Fold operations. switch (Opcode) { + case ISD::AND: + // (X & 0) -> 0. This commonly occurs when legalizing i64 values, so it's + // worth handling here. + if (N2C && N2C->getValue() == 0) + return N2; + break; case ISD::FP_ROUND_INREG: if (cast(N2)->getVT() == VT) return N1; // Not actually rounding. break; @@ -1445,8 +1308,8 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, //ConstantSDNode *N3C = dyn_cast(N3.Val); switch (Opcode) { case ISD::SETCC: { - // Use SimplifySetCC to simplify SETCC's. - SDOperand Simp = SimplifySetCC(VT, N1, N2, cast(N3)->get()); + // Use FoldSetCC to simplify SETCC's. + SDOperand Simp = FoldSetCC(VT, N1, N2, cast(N3)->get()); if (Simp.Val) return Simp; break; } -- 2.11.0