aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-02-28 06:49:37 +0000
committerChris Lattner <sabre@nondot.org>2006-02-28 06:49:37 +0000
commit35a9f5a24114f65002504b2276ee1b553f282058 (patch)
treec97e80102f111fe14180219090ee0513ffacef9d
parentf4c8575c271c70edffd48a5c23276f18a0b5900d (diff)
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26419 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp27
1 files changed, 17 insertions, 10 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 82b8720ea1..15baeab626 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/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,