diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index e254811de0c..547bee1bb8e 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -451,6 +451,9 @@ SDOperand DAGCombiner::visit(SDNode *N) { } SDOperand DAGCombiner::visitTokenFactor(SDNode *N) { + std::vector Ops; + bool Changed = false; + // If the token factor has two operands and one is the entry token, replace // the token factor with the other operand. if (N->getNumOperands() == 2) { @@ -459,6 +462,19 @@ SDOperand DAGCombiner::visitTokenFactor(SDNode *N) { if (N->getOperand(1).getOpcode() == ISD::EntryToken) return N->getOperand(0); } + // fold (tokenfactor (tokenfactor)) -> tokenfactor + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + SDOperand Op = N->getOperand(i); + if (Op.getOpcode() == ISD::TokenFactor && Op.hasOneUse()) { + Changed = true; + for (unsigned j = 0, e = Op.getNumOperands(); j != e; ++j) + Ops.push_back(Op.getOperand(j)); + } else { + Ops.push_back(Op); + } + } + if (Changed) + return DAG.getNode(ISD::TokenFactor, MVT::Other, Ops); return SDOperand(); } @@ -782,6 +798,40 @@ SDOperand DAGCombiner::visitAND(SDNode *N) { WorkList.push_back(ANDNode.Val); return DAG.getNode(N0.getOpcode(), VT, ANDNode, N0.getOperand(1)); } + // fold (zext_inreg (extload x)) -> (zextload x) + if (N1C && N0.getOpcode() == ISD::EXTLOAD) { + MVT::ValueType EVT = cast(N0.getOperand(3))->getVT(); + // If the type of the zext_inreg and the extload match, and we're running + // before Legalize, or the resulting zextload is legal on the target, then + // go ahead and do the fold. + if ((N1C->getValue() == (1ULL << MVT::getSizeInBits(EVT))-1) && + (!AfterLegalize || + TargetLowering::Legal == TLI.getOperationAction(ISD::ZEXTLOAD, EVT))) { + SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), + N0.getOperand(1), N0.getOperand(2), + EVT); + CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0)); + WorkList.push_back(N); + return SDOperand(); + } + } + // fold (zext_inreg (sextload x)) -> (zextload x) iff load has one use + if (N1C && N0.getOpcode() == ISD::SEXTLOAD && N0.Val->hasNUsesOfValue(1, 0)) { + MVT::ValueType EVT = cast(N0.getOperand(3))->getVT(); + // If the type of the zext_inreg and the extload match, and we're running + // before Legalize, or the resulting zextload is legal on the target, then + // go ahead and do the fold. + if ((N1C->getValue() == (1ULL << MVT::getSizeInBits(EVT))-1) && + (!AfterLegalize || + TargetLowering::Legal == TLI.getOperationAction(ISD::ZEXTLOAD, EVT))) { + SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), + N0.getOperand(1), N0.getOperand(2), + EVT); + CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0)); + WorkList.push_back(N); + return SDOperand(); + } + } return SDOperand(); } @@ -1272,6 +1322,30 @@ SDOperand DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { return DAG.getNode(ISD::SRA, N0.getValueType(), N0.getOperand(0), N0.getOperand(1)); } + // fold (sext_inreg (extload x)) -> (sextload x) + if (N0.getOpcode() == ISD::EXTLOAD && + EVT == cast(N0.getOperand(3))->getVT() && + (!AfterLegalize || + (TargetLowering::Legal == TLI.getOperationAction(ISD::SEXTLOAD, EVT)))) { + SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0), + N0.getOperand(1), N0.getOperand(2), + EVT); + CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0)); + WorkList.push_back(N); + return SDOperand(); + } + // fold (sext_inreg (zextload x)) -> (sextload x) iff load has one use + if (N0.getOpcode() == ISD::ZEXTLOAD && N0.Val->hasNUsesOfValue(1, 0) && + EVT == cast(N0.getOperand(3))->getVT() && + (!AfterLegalize || + (TargetLowering::Legal == TLI.getOperationAction(ISD::SEXTLOAD, EVT)))) { + SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0), + N0.getOperand(1), N0.getOperand(2), + EVT); + CombineTo(N0.Val, ExtLoad, ExtLoad.getOperand(0)); + WorkList.push_back(N); + return SDOperand(); + } return SDOperand(); } diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 0e071b18cad..0c08d5a525d 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -635,18 +635,11 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case ISD::TokenFactor: { std::vector Ops; bool Changed = false; + // Legalize the operands for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { SDOperand Op = Node->getOperand(i); - // Fold single-use TokenFactor nodes into this token factor as we go. - // FIXME: This is something that the DAGCombiner should do!! - if (Op.getOpcode() == ISD::TokenFactor && Op.hasOneUse()) { - Changed = true; - for (unsigned j = 0, e = Op.getNumOperands(); j != e; ++j) - Ops.push_back(LegalizeOp(Op.getOperand(j))); - } else { - Ops.push_back(LegalizeOp(Op)); // Legalize the operands - Changed |= Ops[i] != Op; - } + Ops.push_back(LegalizeOp(Op)); + Changed |= Ops[i] != Op; } if (Changed) Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Ops); @@ -2352,14 +2345,8 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) { case ISD::LOAD: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. - // FIXME: When the DAG combiner exists, change this to use EXTLOAD! - if (MVT::isInteger(NVT)) - Result = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Tmp1, Tmp2, - Node->getOperand(2), VT); - else - Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Tmp1, Tmp2, - Node->getOperand(2), VT); - + Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Tmp1, Tmp2, + Node->getOperand(2), VT); // Remember that we legalized the chain. AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); break; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index faeb440b4b4..a8489d29656 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -779,134 +779,6 @@ SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1, return SDOperand(); } -SDOperand SelectionDAG::SimplifySelectCC(SDOperand N1, SDOperand N2, - SDOperand N3, SDOperand N4, - ISD::CondCode CC) { - MVT::ValueType VT = N3.getValueType(); - ConstantSDNode *N1C = dyn_cast(N1.Val); - ConstantSDNode *N2C = dyn_cast(N2.Val); - ConstantSDNode *N3C = dyn_cast(N3.Val); - ConstantSDNode *N4C = dyn_cast(N4.Val); - - // Check to see if we can simplify the select into an fabs node - if (ConstantFPSDNode *CFP = dyn_cast(N2)) { - // Allow either -0.0 or 0.0 - if (CFP->getValue() == 0.0) { - // select (setg[te] X, +/-0.0), X, fneg(X) -> fabs - if ((CC == ISD::SETGE || CC == ISD::SETGT) && - N1 == N3 && N4.getOpcode() == ISD::FNEG && - N1 == N4.getOperand(0)) - return getNode(ISD::FABS, VT, N1); - - // select (setl[te] X, +/-0.0), fneg(X), X -> fabs - if ((CC == ISD::SETLT || CC == ISD::SETLE) && - N1 == N4 && N3.getOpcode() == ISD::FNEG && - N3.getOperand(0) == N4) - return getNode(ISD::FABS, VT, N4); - } - } - - // check to see if we're select_cc'ing a select_cc. - // this allows us to turn: - // select_cc set[eq,ne] (select_cc cc, lhs, rhs, 1, 0), 0, true, false -> - // select_cc cc, lhs, rhs, true, false - if ((N1C && N1C->isNullValue() && N2.getOpcode() == ISD::SELECT_CC) || - (N2C && N2C->isNullValue() && N1.getOpcode() == ISD::SELECT_CC) && - (CC == ISD::SETEQ || CC == ISD::SETNE)) { - SDOperand SCC = N1C ? N2 : N1; - ConstantSDNode *SCCT = dyn_cast(SCC.getOperand(2)); - ConstantSDNode *SCCF = dyn_cast(SCC.getOperand(3)); - if (SCCT && SCCF && SCCF->isNullValue() && SCCT->getValue() == 1ULL) { - if (CC == ISD::SETEQ) std::swap(N3, N4); - return getNode(ISD::SELECT_CC, N3.getValueType(), SCC.getOperand(0), - SCC.getOperand(1), N3, N4, SCC.getOperand(4)); - } - } - - // Check to see if we can perform the "gzip trick", transforming - // select_cc setlt X, 0, A, 0 -> and (sra X, size(X)-1), A - if (N2C && N2C->isNullValue() && N4C && N4C->isNullValue() && - MVT::isInteger(N1.getValueType()) && - MVT::isInteger(N3.getValueType()) && CC == ISD::SETLT) { - MVT::ValueType XType = N1.getValueType(); - MVT::ValueType AType = N3.getValueType(); - if (XType >= AType) { - // and (sra X, size(X)-1, A) -> "and (srl X, C2), A" iff A is a - // single-bit constant. FIXME: remove once the dag combiner - // exists. - if (N3C && ((N3C->getValue() & (N3C->getValue()-1)) == 0)) { - unsigned ShCtV = Log2_64(N3C->getValue()); - ShCtV = MVT::getSizeInBits(XType)-ShCtV-1; - SDOperand ShCt = getConstant(ShCtV, TLI.getShiftAmountTy()); - SDOperand Shift = getNode(ISD::SRL, XType, N1, ShCt); - if (XType > AType) - Shift = getNode(ISD::TRUNCATE, AType, Shift); - return getNode(ISD::AND, AType, Shift, N3); - } - SDOperand Shift = getNode(ISD::SRA, XType, N1, - getConstant(MVT::getSizeInBits(XType)-1, - TLI.getShiftAmountTy())); - if (XType > AType) - Shift = getNode(ISD::TRUNCATE, AType, Shift); - return getNode(ISD::AND, AType, Shift, N3); - } - } - - // Check to see if this is the equivalent of setcc - if (N4C && N4C->isNullValue() && N3C && (N3C->getValue() == 1ULL)) { - MVT::ValueType XType = N1.getValueType(); - if (TLI.isOperationLegal(ISD::SETCC, TLI.getSetCCResultTy())) { - SDOperand Res = getSetCC(TLI.getSetCCResultTy(), N1, N2, CC); - if (Res.getValueType() != VT) - Res = getNode(ISD::ZERO_EXTEND, VT, Res); - return Res; - } - - // seteq X, 0 -> srl (ctlz X, log2(size(X))) - if (N2C && N2C->isNullValue() && CC == ISD::SETEQ && - TLI.isOperationLegal(ISD::CTLZ, XType)) { - SDOperand Ctlz = getNode(ISD::CTLZ, XType, N1); - return getNode(ISD::SRL, XType, Ctlz, - getConstant(Log2_32(MVT::getSizeInBits(XType)), - TLI.getShiftAmountTy())); - } - // setgt X, 0 -> srl (and (-X, ~X), size(X)-1) - if (N2C && N2C->isNullValue() && CC == ISD::SETGT) { - SDOperand NegN1 = getNode(ISD::SUB, XType, getConstant(0, XType), N1); - SDOperand NotN1 = getNode(ISD::XOR, XType, N1, getConstant(~0ULL, XType)); - return getNode(ISD::SRL, XType, getNode(ISD::AND, XType, NegN1, NotN1), - getConstant(MVT::getSizeInBits(XType)-1, - TLI.getShiftAmountTy())); - } - // setgt X, -1 -> xor (srl (X, size(X)-1), 1) - if (N2C && N2C->isAllOnesValue() && CC == ISD::SETGT) { - SDOperand Sign = getNode(ISD::SRL, XType, N1, - getConstant(MVT::getSizeInBits(XType)-1, - TLI.getShiftAmountTy())); - return getNode(ISD::XOR, XType, Sign, getConstant(1, XType)); - } - } - - // Check to see if this is an integer abs. select_cc setl[te] X, 0, -X, X -> - // Y = sra (X, size(X)-1); xor (add (X, Y), Y) - if (N2C && N2C->isNullValue() && (CC == ISD::SETLT || CC == ISD::SETLE) && - N1 == N4 && N3.getOpcode() == ISD::SUB && N1 == N3.getOperand(1)) { - if (ConstantSDNode *SubC = dyn_cast(N3.getOperand(0))) { - MVT::ValueType XType = N1.getValueType(); - if (SubC->isNullValue() && MVT::isInteger(XType)) { - SDOperand Shift = getNode(ISD::SRA, XType, N1, - getConstant(MVT::getSizeInBits(XType)-1, - TLI.getShiftAmountTy())); - return getNode(ISD::XOR, XType, getNode(ISD::ADD, XType, N1, Shift), - Shift); - } - } - } - - // Could not fold it. - return SDOperand(); -} - /// getNode - Gets or creates the specified node. /// SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT) { @@ -1370,9 +1242,6 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, "True and False arms of SelectCC must have same type!"); assert(Ops[2].getValueType() == VT && "select_cc node must be of same type as true and false value!"); - SDOperand Simp = SimplifySelectCC(Ops[0], Ops[1], Ops[2], Ops[3], - cast(Ops[4])->get()); - if (Simp.Val) return Simp; break; } case ISD::BR_CC: {