From: Nate Begeman Date: Fri, 9 Sep 2005 19:49:52 +0000 (+0000) Subject: Last round of 2-node folds from SD.cpp. Will move on to 3 node ops such X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=39ee1ac7e58a66aff7f6986c04878bb7e1bc5b5d;p=oota-llvm.git Last round of 2-node folds from SD.cpp. Will move on to 3 node ops such as setcc and select next. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23295 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 67c5762f1d5..bffc176e40e 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -574,6 +574,7 @@ SDOperand DAGCombiner::visitMULHU(SDNode *N) { SDOperand DAGCombiner::visitAND(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); + SDOperand LL, LR, RL, RR, CC0, CC1; ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); MVT::ValueType VT = N1.getValueType(); @@ -620,12 +621,60 @@ SDOperand DAGCombiner::visitAND(SDNode *N) { if (ConstantSDNode *ORI = dyn_cast(N0.getOperand(1))) if ((ORI->getValue() & N1C->getValue()) == N1C->getValue()) return N1; + // fold (and (setcc x), (setcc y)) -> (setcc (and x, y)) + if (isSetCCEquivalent(N0, LL, LR, CC0) && isSetCCEquivalent(N1, RL, RR, CC1)){ + ISD::CondCode Op0 = cast(CC0)->get(); + ISD::CondCode Op1 = cast(CC1)->get(); + + if (LR == RR && isa(LR) && Op0 == Op1 && + MVT::isInteger(LL.getValueType())) { + // fold (X == 0) & (Y == 0) -> (X|Y == 0) + if (cast(LR)->getValue() == 0 && Op1 == ISD::SETEQ) { + SDOperand ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL); + WorkList.push_back(ORNode.Val); + return DAG.getSetCC(VT, ORNode, LR, Op1); + } + // fold (X == -1) & (Y == -1) -> (X&Y == -1) + if (cast(LR)->isAllOnesValue() && Op1 == ISD::SETEQ) { + SDOperand ANDNode = DAG.getNode(ISD::AND, LR.getValueType(), LL, RL); + WorkList.push_back(ANDNode.Val); + return DAG.getSetCC(VT, ANDNode, LR, Op1); + } + // fold (X > -1) & (Y > -1) -> (X|Y > -1) + if (cast(LR)->isAllOnesValue() && Op1 == ISD::SETGT) { + SDOperand ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL); + WorkList.push_back(ORNode.Val); + return DAG.getSetCC(VT, ORNode, LR, Op1); + } + } + // canonicalize equivalent to ll == rl + if (LL == RR && LR == RL) { + Op1 = ISD::getSetCCSwappedOperands(Op1); + std::swap(RL, RR); + } + if (LL == RL && LR == RR) { + bool isInteger = MVT::isInteger(LL.getValueType()); + ISD::CondCode Result = ISD::getSetCCAndOperation(Op0, Op1, isInteger); + if (Result != ISD::SETCC_INVALID) + return DAG.getSetCC(N0.getValueType(), LL, LR, Result); + } + } + // fold (and (zext x), (zext y)) -> (zext (and x, y)) + if (N0.getOpcode() == ISD::ZERO_EXTEND && + N1.getOpcode() == ISD::ZERO_EXTEND && + N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) { + SDOperand ANDNode = DAG.getNode(ISD::AND, N0.getOperand(0).getValueType(), + N0.getOperand(0), N1.getOperand(0)); + WorkList.push_back(ANDNode.Val); + return DAG.getNode(ISD::ZERO_EXTEND, VT, ANDNode); + } return SDOperand(); } SDOperand DAGCombiner::visitOR(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); + SDOperand LL, LR, RL, RR, CC0, CC1; ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); MVT::ValueType VT = N1.getValueType(); @@ -661,6 +710,51 @@ SDOperand DAGCombiner::visitOR(SDNode *N) { return DAG.getNode(ISD::OR, VT, N0.getOperand(0), DAG.getConstant(N1C->getValue()|N01C->getValue(), VT)); } + // fold (or (setcc x), (setcc y)) -> (setcc (or x, y)) + if (isSetCCEquivalent(N0, LL, LR, CC0) && isSetCCEquivalent(N1, RL, RR, CC1)){ + ISD::CondCode Op0 = cast(CC0)->get(); + ISD::CondCode Op1 = cast(CC1)->get(); + + if (LR == RR && isa(LR) && Op0 == Op1 && + MVT::isInteger(LL.getValueType())) { + // fold (X != 0) | (Y != 0) -> (X|Y != 0) + // fold (X < 0) | (Y < 0) -> (X|Y < 0) + if (cast(LR)->getValue() == 0 && + (Op1 == ISD::SETNE || Op1 == ISD::SETLT)) { + SDOperand ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL); + WorkList.push_back(ORNode.Val); + return DAG.getSetCC(VT, ORNode, LR, Op1); + } + // fold (X != -1) | (Y != -1) -> (X&Y != -1) + // fold (X > -1) | (Y > -1) -> (X&Y > -1) + if (cast(LR)->isAllOnesValue() && + (Op1 == ISD::SETNE || Op1 == ISD::SETGT)) { + SDOperand ANDNode = DAG.getNode(ISD::AND, LR.getValueType(), LL, RL); + WorkList.push_back(ANDNode.Val); + return DAG.getSetCC(VT, ANDNode, LR, Op1); + } + } + // canonicalize equivalent to ll == rl + if (LL == RR && LR == RL) { + Op1 = ISD::getSetCCSwappedOperands(Op1); + std::swap(RL, RR); + } + if (LL == RL && LR == RR) { + bool isInteger = MVT::isInteger(LL.getValueType()); + ISD::CondCode Result = ISD::getSetCCOrOperation(Op0, Op1, isInteger); + if (Result != ISD::SETCC_INVALID) + return DAG.getSetCC(N0.getValueType(), LL, LR, Result); + } + } + // fold (or (zext x), (zext y)) -> (zext (or x, y)) + if (N0.getOpcode() == ISD::ZERO_EXTEND && + N1.getOpcode() == ISD::ZERO_EXTEND && + N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) { + SDOperand ORNode = DAG.getNode(ISD::OR, N0.getOperand(0).getValueType(), + N0.getOperand(0), N1.getOperand(0)); + WorkList.push_back(ORNode.Val); + return DAG.getNode(ISD::ZERO_EXTEND, VT, ORNode); + } return SDOperand(); } @@ -733,6 +827,15 @@ SDOperand DAGCombiner::visitXOR(SDNode *N) { // fold (xor x, x) -> 0 if (N0 == N1) return DAG.getConstant(0, VT); + // fold (xor (zext x), (zext y)) -> (zext (xor x, y)) + if (N0.getOpcode() == ISD::ZERO_EXTEND && + N1.getOpcode() == ISD::ZERO_EXTEND && + N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) { + SDOperand XORNode = DAG.getNode(ISD::XOR, N0.getOperand(0).getValueType(), + N0.getOperand(0), N1.getOperand(0)); + WorkList.push_back(XORNode.Val); + return DAG.getNode(ISD::ZERO_EXTEND, VT, XORNode); + } return SDOperand(); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 055caad70a2..ae0c2c8d712 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1310,10 +1310,10 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, } } + if (!CombinerEnabled) { if (N2C) { uint64_t C2 = N2C->getValue(); - if (!CombinerEnabled) { switch (Opcode) { case ISD::ADD: if (!C2) return N1; // add X, 0 -> X @@ -1486,7 +1486,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, if (ConstantSDNode *N3C = dyn_cast(N1.Val->getOperand(1))) return getNode(Opcode, VT, N1.Val->getOperand(0), getNode(Opcode, VT, N2, N1.Val->getOperand(1))); - } + } } ConstantFPSDNode *N1CFP = dyn_cast(N1.Val); @@ -1533,6 +1533,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, case ISD::AND: case ISD::OR: + if (!CombinerEnabled) { 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); @@ -1595,6 +1596,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, return getNode(ISD::ZERO_EXTEND, VT, getNode(Opcode, N1.getOperand(0).getValueType(), N1.getOperand(0), N2.getOperand(0))); + } break; case ISD::XOR: if (!CombinerEnabled) {