diff options
author | Nate Begeman <natebegeman@mac.com> | 2005-10-14 01:12:21 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2005-10-14 01:12:21 +0000 |
commit | d59e5a7abbb0f0d90f47495fc6a95e9d640ea7fa (patch) | |
tree | 12c041f20d5b6c4f7093a0338bec3eb0f09d3678 /llvm/lib | |
parent | a6d62322e5b32f5af72a5c78c99963865188d95d (diff) | |
download | bcm5719-llvm-d59e5a7abbb0f0d90f47495fc6a95e9d640ea7fa.tar.gz bcm5719-llvm-d59e5a7abbb0f0d90f47495fc6a95e9d640ea7fa.zip |
Relax the checking on zextload generation a bit, since as sabre pointed out
you could be AND'ing with the result of a shift that shifts out all the
bits you care about, in addition to a constant.
Also, move over an add/sub_parts fold from legalize to the dag combiner,
where it works for things other than constants. Woot!
llvm-svn: 23720
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 54 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 22 |
2 files changed, 49 insertions, 27 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 4e058640ff4..4997dba4680 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -147,11 +147,13 @@ namespace { SDOperand visitSELECT(SDNode *N); SDOperand visitSELECT_CC(SDNode *N); SDOperand visitSETCC(SDNode *N); + SDOperand visitADD_PARTS(SDNode *N); + SDOperand visitSUB_PARTS(SDNode *N); SDOperand visitSIGN_EXTEND(SDNode *N); SDOperand visitZERO_EXTEND(SDNode *N); SDOperand visitSIGN_EXTEND_INREG(SDNode *N); SDOperand visitTRUNCATE(SDNode *N); - + SDOperand visitFADD(SDNode *N); SDOperand visitFSUB(SDNode *N); SDOperand visitFMUL(SDNode *N); @@ -422,6 +424,8 @@ SDOperand DAGCombiner::visit(SDNode *N) { case ISD::SELECT: return visitSELECT(N); case ISD::SELECT_CC: return visitSELECT_CC(N); case ISD::SETCC: return visitSETCC(N); + case ISD::ADD_PARTS: return visitADD_PARTS(N); + case ISD::SUB_PARTS: return visitSUB_PARTS(N); case ISD::SIGN_EXTEND: return visitSIGN_EXTEND(N); case ISD::ZERO_EXTEND: return visitZERO_EXTEND(N); case ISD::SIGN_EXTEND_INREG: return visitSIGN_EXTEND_INREG(N); @@ -800,11 +804,11 @@ SDOperand DAGCombiner::visitAND(SDNode *N) { return DAG.getNode(N0.getOpcode(), VT, ANDNode, N0.getOperand(1)); } // fold (zext_inreg (extload x)) -> (zextload x) - if (N1C && N0.getOpcode() == ISD::EXTLOAD) { + if (N0.getOpcode() == ISD::EXTLOAD) { MVT::ValueType EVT = cast<VTSDNode>(N0.getOperand(3))->getVT(); // If we zero all the possible extended bits, then we can turn this into // a zextload if we are running before legalize or the operation is legal. - if (MaskedValueIsZero(SDOperand(N,0), ~0ULL<<MVT::getSizeInBits(EVT),TLI) && + if (MaskedValueIsZero(N1, ~0ULL << MVT::getSizeInBits(EVT), TLI) && (!AfterLegalize || TLI.isOperationLegal(ISD::ZEXTLOAD, EVT))) { SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), @@ -815,11 +819,11 @@ SDOperand DAGCombiner::visitAND(SDNode *N) { } } // fold (zext_inreg (sextload x)) -> (zextload x) iff load has one use - if (N1C && N0.getOpcode() == ISD::SEXTLOAD && N0.Val->hasNUsesOfValue(1, 0)) { + if (N0.getOpcode() == ISD::SEXTLOAD && N0.Val->hasNUsesOfValue(1, 0)) { MVT::ValueType EVT = cast<VTSDNode>(N0.getOperand(3))->getVT(); // If we zero all the possible extended bits, then we can turn this into // a zextload if we are running before legalize or the operation is legal. - if (MaskedValueIsZero(SDOperand(N,0), ~0ULL<<MVT::getSizeInBits(EVT),TLI) && + if (MaskedValueIsZero(N1, ~0ULL << MVT::getSizeInBits(EVT), TLI) && (!AfterLegalize || TLI.isOperationLegal(ISD::ZEXTLOAD, EVT))) { SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), N0.getOperand(1), N0.getOperand(2), @@ -1230,6 +1234,46 @@ SDOperand DAGCombiner::visitSETCC(SDNode *N) { cast<CondCodeSDNode>(N->getOperand(2))->get()); } +SDOperand DAGCombiner::visitADD_PARTS(SDNode *N) { + SDOperand LHSLo = N->getOperand(0); + SDOperand RHSLo = N->getOperand(2); + MVT::ValueType VT = LHSLo.getValueType(); + + // fold (a_Hi, 0) + (b_Hi, b_Lo) -> (b_Hi + a_Hi, b_Lo) + if (MaskedValueIsZero(LHSLo, (1ULL << MVT::getSizeInBits(VT))-1, TLI)) { + SDOperand Hi = DAG.getNode(ISD::ADD, VT, N->getOperand(1), + N->getOperand(3)); + WorkList.push_back(Hi.Val); + CombineTo(N, RHSLo, Hi); + return SDOperand(); + } + // fold (a_Hi, a_Lo) + (b_Hi, 0) -> (a_Hi + b_Hi, a_Lo) + if (MaskedValueIsZero(RHSLo, (1ULL << MVT::getSizeInBits(VT))-1, TLI)) { + SDOperand Hi = DAG.getNode(ISD::ADD, VT, N->getOperand(1), + N->getOperand(3)); + WorkList.push_back(Hi.Val); + CombineTo(N, LHSLo, Hi); + return SDOperand(); + } + return SDOperand(); +} + +SDOperand DAGCombiner::visitSUB_PARTS(SDNode *N) { + SDOperand LHSLo = N->getOperand(0); + SDOperand RHSLo = N->getOperand(2); + MVT::ValueType VT = LHSLo.getValueType(); + + // fold (a_Hi, a_Lo) - (b_Hi, 0) -> (a_Hi - b_Hi, a_Lo) + if (MaskedValueIsZero(RHSLo, (1ULL << MVT::getSizeInBits(VT))-1, TLI)) { + SDOperand Hi = DAG.getNode(ISD::SUB, VT, N->getOperand(1), + N->getOperand(3)); + WorkList.push_back(Hi.Val); + CombineTo(N, LHSLo, Hi); + return SDOperand(); + } + return SDOperand(); +} + SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) { SDOperand N0 = N->getOperand(0); ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 3363c3d1feb..b02fac1c049 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -2449,33 +2449,11 @@ ExpandByParts(unsigned NodeOp, SDOperand LHS, SDOperand RHS, ExpandOp(LHS, LHSL, LHSH); ExpandOp(RHS, RHSL, RHSH); - // FIXME: this should be moved to the dag combiner someday. - assert(NodeOp == ISD::ADD_PARTS || NodeOp == ISD::SUB_PARTS); - if (LHSL.getValueType() == MVT::i32) { - SDOperand LowEl = SDOperand(0,0); - if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(LHSL)) - if (C->getValue() == 0) - LowEl = RHSL; - if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHSL)) - if (C->getValue() == 0) - LowEl = LHSL; - if (LowEl.Val) { - // Turn this into an add/sub of the high part only. - SDOperand HiEl = - DAG.getNode(NodeOp == ISD::ADD_PARTS ? ISD::ADD : ISD::SUB, - LowEl.getValueType(), LHSH, RHSH); - Lo = LowEl; - Hi = HiEl; - return; - } - } - std::vector<SDOperand> Ops; Ops.push_back(LHSL); Ops.push_back(LHSH); Ops.push_back(RHSL); Ops.push_back(RHSH); - std::vector<MVT::ValueType> VTs(2, LHSL.getValueType()); Lo = DAG.getNode(NodeOp, VTs, Ops); Hi = Lo.getValue(1); |