diff options
| author | Chris Lattner <sabre@nondot.org> | 2006-02-28 06:49:37 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2006-02-28 06:49:37 +0000 |
| commit | f0032b350cc40065c350753664f33893d426363d (patch) | |
| tree | cfbfd368a8bc1fb46e10d274117c702b000a37dd /llvm/lib/CodeGen/SelectionDAG | |
| parent | 872810da6c5701f78746e1c85b0da904098f51a3 (diff) | |
| download | bcm5719-llvm-f0032b350cc40065c350753664f33893d426363d.tar.gz bcm5719-llvm-f0032b350cc40065c350753664f33893d426363d.zip | |
Compile:
unsigned foo4(unsigned short *P) { return *P & 255; }
unsigned foo5(short *P) { return *P & 255; }
to:
_foo4:
lbz r3,1(r3)
blr
_foo5:
lbz r3,1(r3)
blr
not:
_foo4:
lhz r2, 0(r3)
rlwinm r3, r2, 0, 24, 31
blr
_foo5:
lhz r2, 0(r3)
rlwinm r3, r2, 0, 24, 31
blr
llvm-svn: 26419
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 82b8720ea17..15baeab626b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1043,9 +1043,13 @@ SDOperand DAGCombiner::visitAND(SDNode *N) { } } - // fold (and (load x), 255) -> (zextload x) - if (N1C && N0.getOpcode() == ISD::LOAD && N0.hasOneUse()) { - MVT::ValueType EVT; + // fold (and (load x), 255) -> (zextload x, i8) + // fold (and (extload x, i16), 255) -> (zextload x, i8) + if (N1C && + (N0.getOpcode() == ISD::LOAD || N0.getOpcode() == ISD::EXTLOAD || + N0.getOpcode() == ISD::ZEXTLOAD) && + N0.hasOneUse()) { + MVT::ValueType EVT, LoadedVT; if (N1C->getValue() == 255) EVT = MVT::i8; else if (N1C->getValue() == 65535) @@ -1054,17 +1058,20 @@ SDOperand DAGCombiner::visitAND(SDNode *N) { EVT = MVT::i32; else EVT = MVT::Other; - if (EVT != MVT::Other) { - assert(MVT::getSizeInBits(VT) > MVT::getSizeInBits(EVT) && - "Cannot zext to larger type!"); + + LoadedVT = N0.getOpcode() == ISD::LOAD ? VT : + cast<VTSDNode>(N0.getOperand(3))->getVT(); + if (EVT != MVT::Other && LoadedVT > EVT) { 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(VT) - MVT::getSizeInBits(EVT)) / 8; - SDOperand NewPtr = TLI.isLittleEndian() ? N0.getOperand(1) : - DAG.getNode(ISD::ADD, PtrType, N0.getOperand(1), - DAG.getConstant(PtrOff, PtrType)); + unsigned PtrOff = + (MVT::getSizeInBits(LoadedVT) - MVT::getSizeInBits(EVT)) / 8; + SDOperand NewPtr = N0.getOperand(1); + if (!TLI.isLittleEndian()) + NewPtr = DAG.getNode(ISD::ADD, PtrType, NewPtr, + DAG.getConstant(PtrOff, PtrType)); WorkList.push_back(NewPtr.Val); SDOperand Load = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), NewPtr, |

