Changes in directory llvm/lib/CodeGen/SelectionDAG:
DAGCombiner.cpp updated: 1.275 -> 1.276 --- Log message: fold (truncate (srl (load x), c)) -> (smaller load (x+c/vt bits)) --- Diffs of the changes: (+24 -6) DAGCombiner.cpp | 30 ++++++++++++++++++++++++------ 1 files changed, 24 insertions(+), 6 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.275 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.276 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.275 Wed Mar 7 02:07:03 2007 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Mar 21 15:14:05 2007 @@ -2298,6 +2298,7 @@ SDOperand DAGCombiner::visitTRUNCATE(SDNode *N) { SDOperand N0 = N->getOperand(0); MVT::ValueType VT = N->getValueType(0); + unsigned VTBits = MVT::getSizeInBits(VT); // noop truncate if (N0.getValueType() == N->getValueType(0)) @@ -2322,30 +2323,47 @@ // and the truncate return N0.getOperand(0); } + // fold (truncate (load x)) -> (smaller load x) + // fold (truncate (srl (load x), c)) -> (smaller load (x+c/evtbits)) + unsigned ShAmt = 0; + if (N0.getOpcode() == ISD::SRL && N0.hasOneUse()) { + if (ConstantSDNode *N01 = dyn_cast<ConstantSDNode>(N0.getOperand(1))) { + ShAmt = N01->getValue(); + // Is the shift amount a multiple of size of VT? + if ((ShAmt & (VTBits-1)) == 0) { + N0 = N0.getOperand(0); + if (MVT::getSizeInBits(N0.getValueType()) <= VTBits) + return SDOperand(); + ShAmt /= VTBits; + } + } + } if (ISD::isNON_EXTLoad(N0.Val) && N0.hasOneUse() && // Do not allow folding to i1 here. i1 is implicitly stored in memory in // zero extended form: by shrinking the load, we lose track of the fact // that it is already zero extended. // FIXME: This should be reevaluated. VT != MVT::i1) { - assert(MVT::getSizeInBits(N0.getValueType()) > MVT::getSizeInBits(VT) && + assert(MVT::getSizeInBits(N0.getValueType()) > VTBits && "Cannot truncate to larger type!"); LoadSDNode *LN0 = cast<LoadSDNode>(N0); MVT::ValueType PtrType = N0.getOperand(1).getValueType(); // For big endian targets, we need to add an offset to the pointer to load // the correct bytes. For little endian systems, we merely need to read // fewer bytes from the same pointer. - uint64_t PtrOff = - (MVT::getSizeInBits(N0.getValueType()) - MVT::getSizeInBits(VT)) / 8; - SDOperand NewPtr = TLI.isLittleEndian() ? LN0->getBasePtr() : - DAG.getNode(ISD::ADD, PtrType, LN0->getBasePtr(), - DAG.getConstant(PtrOff, PtrType)); + uint64_t PtrOff = ShAmt + ? ShAmt : (TLI.isLittleEndian() ? 0 + : (MVT::getSizeInBits(N0.getValueType()) - VTBits) / 8); + SDOperand NewPtr = DAG.getNode(ISD::ADD, PtrType, LN0->getBasePtr(), + DAG.getConstant(PtrOff, PtrType)); AddToWorkList(NewPtr.Val); SDOperand Load = DAG.getLoad(VT, LN0->getChain(), NewPtr, LN0->getSrcValue(), LN0->getSrcValueOffset()); AddToWorkList(N); CombineTo(N0.Val, Load, Load.getValue(1)); + if (ShAmt) + return DAG.getNode(ISD::TRUNCATE, VT, Load); return SDOperand(N, 0); // Return N so it doesn't get rechecked! } return SDOperand(); _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits