mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-29 06:30:39 +00:00
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
This commit is contained in:
parent
8f16eb98ed
commit
51dabfb283
@ -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<std::vector<MVT::ValueType> > VTList;
|
||||
|
||||
|
@ -3586,27 +3586,7 @@ SDOperand DAGCombiner::SimplifySetCC(MVT::ValueType VT, SDOperand N0,
|
||||
if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val)) {
|
||||
uint64_t C1 = N1C->getValue();
|
||||
if (ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(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<ConstantSDNode>(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,22 +3797,10 @@ SDOperand DAGCombiner::SimplifySetCC(MVT::ValueType VT, SDOperand N0,
|
||||
return DAG.getSetCC(VT, N1, N0, ISD::getSetCCSwappedOperands(Cond));
|
||||
}
|
||||
|
||||
if (ConstantFPSDNode *N0C = dyn_cast<ConstantFPSDNode>(N0.Val))
|
||||
if (ConstantFPSDNode *N1C = dyn_cast<ConstantFPSDNode>(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<ConstantFPSDNode>(N0.Val)) {
|
||||
// Constant fold or commute setcc.
|
||||
SDOperand O = DAG.FoldSetCC(VT, N0, N1, Cond);
|
||||
if (O.Val) return O;
|
||||
}
|
||||
|
||||
if (N0 == N1) {
|
||||
|
@ -736,7 +736,7 @@ SDOperand SelectionDAG::getSrcValue(const Value *V, int Offset) {
|
||||
return SDOperand(N, 0);
|
||||
}
|
||||
|
||||
SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1,
|
||||
SDOperand SelectionDAG::FoldSetCC(MVT::ValueType VT, SDOperand N1,
|
||||
SDOperand N2, ISD::CondCode Cond) {
|
||||
// These setcc operations always fold.
|
||||
switch (Cond) {
|
||||
@ -784,152 +784,8 @@ 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<VTSDNode>(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<ConstantSDNode>(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<ConstantSDNode>(N1.Val)) {
|
||||
// Ensure that the constant occurs on the RHS.
|
||||
return getSetCC(VT, N2, N1, ISD::getSetCCSwappedOperands(Cond));
|
||||
}
|
||||
|
||||
if (ConstantFPSDNode *N1C = dyn_cast<ConstantFPSDNode>(N1.Val))
|
||||
if (ConstantFPSDNode *N2C = dyn_cast<ConstantFPSDNode>(N2.Val)) {
|
||||
double C1 = N1C->getValue(), C2 = N2C->getValue();
|
||||
@ -952,6 +808,7 @@ SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1,
|
||||
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<VTSDNode>(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<ConstantSDNode>(N3.Val);
|
||||
switch (Opcode) {
|
||||
case ISD::SETCC: {
|
||||
// Use SimplifySetCC to simplify SETCC's.
|
||||
SDOperand Simp = SimplifySetCC(VT, N1, N2, cast<CondCodeSDNode>(N3)->get());
|
||||
// Use FoldSetCC to simplify SETCC's.
|
||||
SDOperand Simp = FoldSetCC(VT, N1, N2, cast<CondCodeSDNode>(N3)->get());
|
||||
if (Simp.Val) return Simp;
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user