fold (truncate (srl (load x), c)) -> (smaller load (x+c/vt bits))

llvm-svn: 35239
This commit is contained in:
Evan Cheng 2007-03-21 20:14:05 +00:00
parent 2f8fa50bb3
commit d63baead9b
1 changed files with 24 additions and 6 deletions

View File

@ -2298,6 +2298,7 @@ SDOperand DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
SDOperand DAGCombiner::visitTRUNCATE(SDNode *N) { SDOperand DAGCombiner::visitTRUNCATE(SDNode *N) {
SDOperand N0 = N->getOperand(0); SDOperand N0 = N->getOperand(0);
MVT::ValueType VT = N->getValueType(0); MVT::ValueType VT = N->getValueType(0);
unsigned VTBits = MVT::getSizeInBits(VT);
// noop truncate // noop truncate
if (N0.getValueType() == N->getValueType(0)) if (N0.getValueType() == N->getValueType(0))
@ -2322,30 +2323,47 @@ SDOperand DAGCombiner::visitTRUNCATE(SDNode *N) {
// and the truncate // and the truncate
return N0.getOperand(0); return N0.getOperand(0);
} }
// fold (truncate (load x)) -> (smaller load x) // 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() && if (ISD::isNON_EXTLoad(N0.Val) && N0.hasOneUse() &&
// Do not allow folding to i1 here. i1 is implicitly stored in memory in // 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 // zero extended form: by shrinking the load, we lose track of the fact
// that it is already zero extended. // that it is already zero extended.
// FIXME: This should be reevaluated. // FIXME: This should be reevaluated.
VT != MVT::i1) { VT != MVT::i1) {
assert(MVT::getSizeInBits(N0.getValueType()) > MVT::getSizeInBits(VT) && assert(MVT::getSizeInBits(N0.getValueType()) > VTBits &&
"Cannot truncate to larger type!"); "Cannot truncate to larger type!");
LoadSDNode *LN0 = cast<LoadSDNode>(N0); LoadSDNode *LN0 = cast<LoadSDNode>(N0);
MVT::ValueType PtrType = N0.getOperand(1).getValueType(); MVT::ValueType PtrType = N0.getOperand(1).getValueType();
// For big endian targets, we need to add an offset to the pointer to load // 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 // the correct bytes. For little endian systems, we merely need to read
// fewer bytes from the same pointer. // fewer bytes from the same pointer.
uint64_t PtrOff = uint64_t PtrOff = ShAmt
(MVT::getSizeInBits(N0.getValueType()) - MVT::getSizeInBits(VT)) / 8; ? ShAmt : (TLI.isLittleEndian() ? 0
SDOperand NewPtr = TLI.isLittleEndian() ? LN0->getBasePtr() : : (MVT::getSizeInBits(N0.getValueType()) - VTBits) / 8);
DAG.getNode(ISD::ADD, PtrType, LN0->getBasePtr(), SDOperand NewPtr = DAG.getNode(ISD::ADD, PtrType, LN0->getBasePtr(),
DAG.getConstant(PtrOff, PtrType)); DAG.getConstant(PtrOff, PtrType));
AddToWorkList(NewPtr.Val); AddToWorkList(NewPtr.Val);
SDOperand Load = DAG.getLoad(VT, LN0->getChain(), NewPtr, SDOperand Load = DAG.getLoad(VT, LN0->getChain(), NewPtr,
LN0->getSrcValue(), LN0->getSrcValueOffset()); LN0->getSrcValue(), LN0->getSrcValueOffset());
AddToWorkList(N); AddToWorkList(N);
CombineTo(N0.Val, Load, Load.getValue(1)); 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(N, 0); // Return N so it doesn't get rechecked!
} }
return SDOperand(); return SDOperand();