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