Fix some load/store logic that would be wrong for
authorDuncan Sands <baldrick@free.fr>
Fri, 9 Nov 2007 08:57:19 +0000 (08:57 +0000)
committerDuncan Sands <baldrick@free.fr>
Fri, 9 Nov 2007 08:57:19 +0000 (08:57 +0000)
apints on big-endian machines if the bitwidth is
not a multiple of 8.  Introduce a new helper,
MVT::getStoreSizeInBits, and use it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43934 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/ValueTypes.h
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp

index 780482b0793358614d365f15947ba0a23fa06aa1..6edf97a52c101ff7c11b698c61044378c1e0ccf2 100644 (file)
@@ -243,6 +243,13 @@ namespace MVT {  // MVT = Machine Value Types
     }
   }
 
+  /// MVT::getStoreSizeInBits - Return the number of bits overwritten by a
+  /// store of the specified value type.
+  ///
+  static inline unsigned getStoreSizeInBits(ValueType VT) {
+    return (getSizeInBits(VT) + 7)/8*8;
+  }
+
   /// MVT::getIntegerType - Returns the ValueType that represents an integer
   /// with the given number of bits.
   ///
index 73d7db413f14af2c785e07518a0d33f5bed919a1..7a6e55e984942958dbe654cce8d1e9112ad46bdf 100644 (file)
@@ -1713,8 +1713,9 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
         // 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.
-        unsigned PtrOff =
-          (MVT::getSizeInBits(LoadedVT) - MVT::getSizeInBits(EVT)) / 8;
+        unsigned LVTStoreBytes = MVT::getStoreSizeInBits(LoadedVT)/8;
+        unsigned EVTStoreBytes = MVT::getStoreSizeInBits(EVT)/8;
+        unsigned PtrOff = LVTStoreBytes - EVTStoreBytes;
         unsigned Alignment = LN0->getAlignment();
         SDOperand NewPtr = LN0->getBasePtr();
         if (!TLI.isLittleEndian()) {
@@ -2991,8 +2992,11 @@ SDOperand DAGCombiner::ReduceLoadWidth(SDNode *N) {
     MVT::ValueType PtrType = N0.getOperand(1).getValueType();
     // For big endian targets, we need to adjust the offset to the pointer to
     // load the correct bytes.
-    if (!TLI.isLittleEndian())
-      ShAmt = MVT::getSizeInBits(N0.getValueType()) - ShAmt - EVTBits;
+    if (!TLI.isLittleEndian()) {
+      unsigned LVTStoreBits = MVT::getStoreSizeInBits(N0.getValueType());
+      unsigned EVTStoreBits = MVT::getStoreSizeInBits(EVT);
+      ShAmt = LVTStoreBits - EVTStoreBits - ShAmt;
+    }
     uint64_t PtrOff =  ShAmt / 8;
     unsigned NewAlign = MinAlign(LN0->getAlignment(), PtrOff);
     SDOperand NewPtr = DAG.getNode(ISD::ADD, PtrType, LN0->getBasePtr(),
index 11431ee086193bf0f77a1f6ddac09c943099ffc0..825134130c360eb15d08745e650bc8a0c7dffd00 100644 (file)
@@ -1036,7 +1036,7 @@ void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N,
     // Big-endian - high bits are at low addresses.  Favor aligned loads at
     // the cost of some bit-fiddling.
     MVT::ValueType EVT = N->getLoadedVT();
-    unsigned EBytes = (MVT::getSizeInBits(EVT) + 7)/8;
+    unsigned EBytes = MVT::getStoreSizeInBits(EVT)/8;
     unsigned IncrementSize = MVT::getSizeInBits(NVT)/8;
     unsigned ExcessBits = (EBytes - IncrementSize)*8;
 
@@ -2069,7 +2069,7 @@ SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) {
     GetExpandedOp(N->getValue(), Lo, Hi);
 
     MVT::ValueType EVT = N->getStoredVT();
-    unsigned EBytes = (MVT::getSizeInBits(EVT) + 7)/8;
+    unsigned EBytes = MVT::getStoreSizeInBits(EVT)/8;
     unsigned IncrementSize = MVT::getSizeInBits(NVT)/8;
     unsigned ExcessBits = (EBytes - IncrementSize)*8;
     MVT::ValueType HiVT =