[llvm-commits] [llvm] r43225 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp

Duncan Sands baldrick at free.fr
Mon Oct 22 12:00:05 PDT 2007


Author: baldrick
Date: Mon Oct 22 14:00:05 2007
New Revision: 43225

URL: http://llvm.org/viewvc/llvm-project?rev=43225&view=rev
Log:
Support for expanding extending loads of integers with
funky bit-widths.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=43225&r1=43224&r2=43225&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Mon Oct 22 14:00:05 2007
@@ -935,17 +935,19 @@
   int SVOffset = N->getSrcValueOffset();
   unsigned Alignment = N->getAlignment();
   bool isVolatile = N->isVolatile();
-  
+
+  assert(!(MVT::getSizeInBits(NVT) & 7) && "Expanded type not byte sized!");
+
   if (ExtType == ISD::NON_EXTLOAD) {
     Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
                      isVolatile, Alignment);
     // Increment the pointer to the other half.
-    unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8;
+    unsigned IncrementSize = MVT::getSizeInBits(NVT)/8;
     Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
                       getIntPtrConstant(IncrementSize));
     Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
                      isVolatile, std::max(Alignment, IncrementSize));
-    
+
     // Build a factor node to remember that this load is independent of the
     // other one.
     Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
@@ -954,19 +956,15 @@
     // Handle endianness of the load.
     if (!TLI.isLittleEndian())
       std::swap(Lo, Hi);
-  } else {
+  } else if (MVT::getSizeInBits(N->getLoadedVT()) <= MVT::getSizeInBits(NVT)) {
     MVT::ValueType EVT = N->getLoadedVT();
-    
-    if (EVT == NVT)
-      Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(),
-                       SVOffset, isVolatile, Alignment);
-    else
-      Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(),
-                          SVOffset, EVT, isVolatile,
-                          Alignment);
+
+    Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, EVT,
+                        isVolatile, Alignment);
+
     // Remember the chain.
     Ch = Lo.getValue(1);
-    
+
     if (ExtType == ISD::SEXTLOAD) {
       // The high part is obtained by SRA'ing all but one of the bits of the
       // lo part.
@@ -981,13 +979,70 @@
       // The high part is undefined.
       Hi = DAG.getNode(ISD::UNDEF, NVT);
     }
+  } else if (TLI.isLittleEndian()) {
+    // Little-endian - low bits are at low addresses.
+    Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
+                     isVolatile, Alignment);
+
+    unsigned ExcessBits =
+      MVT::getSizeInBits(N->getLoadedVT()) - MVT::getSizeInBits(NVT);
+    MVT::ValueType NEVT = MVT::getIntegerType(ExcessBits);
+
+    // Increment the pointer to the other half.
+    unsigned IncrementSize = MVT::getSizeInBits(NVT)/8;
+    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                      getIntPtrConstant(IncrementSize));
+    Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(),
+                        SVOffset+IncrementSize, NEVT,
+                        isVolatile, std::max(Alignment, IncrementSize));
+
+    // Build a factor node to remember that this load is independent of the
+    // other one.
+    Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+                     Hi.getValue(1));
+  } else {
+    // 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 IncrementSize = MVT::getSizeInBits(NVT)/8;
+    unsigned ExcessBits = (EBytes - IncrementSize)*8;
+
+    // Load both the high bits and maybe some of the low bits.
+    Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
+                        MVT::getIntegerType(MVT::getSizeInBits(EVT)-ExcessBits),
+                        isVolatile, Alignment);
+
+    // Increment the pointer to the other half.
+    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                      getIntPtrConstant(IncrementSize));
+    // Load the rest of the low bits.
+    Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Ch, Ptr, N->getSrcValue(),
+                        SVOffset+IncrementSize, MVT::getIntegerType(ExcessBits),
+                        isVolatile, std::max(Alignment, IncrementSize));
+
+    // Build a factor node to remember that this load is independent of the
+    // other one.
+    Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+                     Hi.getValue(1));
+
+    if (ExcessBits < MVT::getSizeInBits(NVT)) {
+      // Transfer low bits from the bottom of Hi to the top of Lo.
+      Lo = DAG.getNode(ISD::OR, NVT, Lo,
+                       DAG.getNode(ISD::SHL, NVT, Hi,
+                                   DAG.getConstant(ExcessBits,
+                                                   TLI.getShiftAmountTy())));
+      // Move high bits to the right position in Hi.
+      Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, NVT, Hi,
+                       DAG.getConstant(MVT::getSizeInBits(NVT) - ExcessBits,
+                                       TLI.getShiftAmountTy()));
+    }
   }
-  
+
   // Legalized the chain result - switch anything that used the old chain to
   // use the new one.
   ReplaceLegalValueWith(SDOperand(N, 1), Ch);
-}  
-
+}
 
 void DAGTypeLegalizer::ExpandResult_Logical(SDNode *N,
                                             SDOperand &Lo, SDOperand &Hi) {





More information about the llvm-commits mailing list