diff options
| author | Chris Lattner <sabre@nondot.org> | 2006-02-28 06:35:35 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2006-02-28 06:35:35 +0000 |
| commit | bdbc4476d931ad66ac89d954787752d5c63d0e88 (patch) | |
| tree | fb7533f302c7253118273e414d8cd50396724860 /llvm | |
| parent | 0f8a727c49f3dd6d64926e9a1d76bbd71eb6801d (diff) | |
| download | bcm5719-llvm-bdbc4476d931ad66ac89d954787752d5c63d0e88.tar.gz bcm5719-llvm-bdbc4476d931ad66ac89d954787752d5c63d0e88.zip | |
Fold "and (LOAD P), 255" -> zextload. This allows us to compile:
unsigned foo3(unsigned *P) { return *P & 255; }
as:
_foo3:
lbz r3, 3(r3)
blr
instead of:
_foo3:
lwz r2, 0(r3)
rlwinm r3, r2, 0, 24, 31
blr
and:
unsigned short foo2(float a) { return a; }
as:
_foo2:
fctiwz f0, f1
stfd f0, -8(r1)
lhz r3, -2(r1)
blr
instead of:
_foo2:
fctiwz f0, f1
stfd f0, -8(r1)
lwz r2, -4(r1)
rlwinm r3, r2, 0, 16, 31
blr
llvm-svn: 26417
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index da63be3a1e1..82b8720ea17 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1042,6 +1042,39 @@ SDOperand DAGCombiner::visitAND(SDNode *N) { return SDOperand(); } } + + // fold (and (load x), 255) -> (zextload x) + if (N1C && N0.getOpcode() == ISD::LOAD && N0.hasOneUse()) { + MVT::ValueType EVT; + if (N1C->getValue() == 255) + EVT = MVT::i8; + else if (N1C->getValue() == 65535) + EVT = MVT::i16; + else if (N1C->getValue() == ~0U) + EVT = MVT::i32; + else + EVT = MVT::Other; + if (EVT != MVT::Other) { + assert(MVT::getSizeInBits(VT) > MVT::getSizeInBits(EVT) && + "Cannot zext to larger type!"); + 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)); + WorkList.push_back(NewPtr.Val); + SDOperand Load = + DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0), NewPtr, + N0.getOperand(2), EVT); + WorkList.push_back(N); + CombineTo(N0.Val, Load, Load.getValue(1)); + return SDOperand(); + } + } + return SDOperand(); } |

