[llvm-commits] [llvm] r46249 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Duncan Sands baldrick at free.fr
Mon Jan 21 23:17:34 PST 2008


Author: baldrick
Date: Tue Jan 22 01:17:34 2008
New Revision: 46249

URL: http://llvm.org/viewvc/llvm-project?rev=46249&view=rev
Log:
The final piece needed for storing arbitrary precision
integers.  Handle truncstore of a legal type to an unusual
number of bits.  Most of this code is not reachable unless
the new legalize infrastructure is turned on.

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

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

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Jan 22 01:17:34 2008
@@ -2254,38 +2254,99 @@
         return DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
                                  SVOffset, MVT::i8, isVolatile, Alignment);
       }
-    
-      // Unconditionally promote TRUNCSTORE:i1 X -> TRUNCSTORE:i8 (and X, 1)
-      if (ST->getStoredVT() == MVT::i1) {
-        // Promote the bool to a mask then store.
-        Tmp3 = DAG.getNode(ISD::AND, Tmp3.getValueType(), Tmp3,
-                           DAG.getConstant(1, Tmp3.getValueType()));
+
+      MVT::ValueType StVT = ST->getStoredVT();
+      unsigned StWidth = MVT::getSizeInBits(StVT);
+
+      if (StWidth != MVT::getStoreSizeInBits(StVT)) {
+        // Promote to a byte-sized store with upper bits zero if not
+        // storing an integral number of bytes.  For example, promote
+        // TRUNCSTORE:i1 X -> TRUNCSTORE:i8 (and X, 1)
+        MVT::ValueType NVT = MVT::getIntegerType(MVT::getStoreSizeInBits(StVT));
+        Tmp3 = DAG.getZeroExtendInReg(Tmp3, StVT);
         Result = DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
-                                   SVOffset, MVT::i8,
-                                   isVolatile, Alignment);
-      } else if (Tmp1 != ST->getChain() || Tmp3 != ST->getValue() ||
-                 Tmp2 != ST->getBasePtr()) {
-        Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp3, Tmp2,
-                                        ST->getOffset());
-      }
+                                   SVOffset, NVT, isVolatile, Alignment);
+      } else if (StWidth & (StWidth - 1)) {
+        // If not storing a power-of-2 number of bits, expand as two stores.
+        assert(MVT::isExtendedVT(StVT) && !MVT::isVector(StVT) &&
+               "Unsupported truncstore!");
+        unsigned RoundWidth = 1 << Log2_32(StWidth);
+        assert(RoundWidth < StWidth);
+        unsigned ExtraWidth = StWidth - RoundWidth;
+        assert(ExtraWidth < RoundWidth);
+        assert(!(RoundWidth % 8) && !(ExtraWidth % 8) &&
+               "Store size not an integral number of bytes!");
+        MVT::ValueType RoundVT = MVT::getIntegerType(RoundWidth);
+        MVT::ValueType ExtraVT = MVT::getIntegerType(ExtraWidth);
+        SDOperand Lo, Hi;
+        unsigned IncrementSize;
+
+        if (TLI.isLittleEndian()) {
+          // TRUNCSTORE:i24 X -> TRUNCSTORE:i16 X, TRUNCSTORE at +2:i8 (srl X, 16)
+          // Store the bottom RoundWidth bits.
+          Lo = DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+                                 SVOffset, RoundVT,
+                                 isVolatile, Alignment);
+
+          // Store the remaining ExtraWidth bits.
+          IncrementSize = RoundWidth / 8;
+          Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
+                             DAG.getIntPtrConstant(IncrementSize));
+          Hi = DAG.getNode(ISD::SRL, Tmp3.getValueType(), Tmp3,
+                           DAG.getConstant(RoundWidth, TLI.getShiftAmountTy()));
+          Hi = DAG.getTruncStore(Tmp1, Hi, Tmp2, ST->getSrcValue(),
+                                 SVOffset + IncrementSize, ExtraVT, isVolatile,
+                                 MinAlign(Alignment, IncrementSize));
+        } else {
+          // Big endian - avoid unaligned stores.
+          // TRUNCSTORE:i24 X -> TRUNCSTORE:i16 (srl X, 8), TRUNCSTORE at +2:i8 X
+          // Store the top RoundWidth bits.
+          Hi = DAG.getNode(ISD::SRL, Tmp3.getValueType(), Tmp3,
+                           DAG.getConstant(ExtraWidth, TLI.getShiftAmountTy()));
+          Hi = DAG.getTruncStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset,
+                                 RoundVT, isVolatile, Alignment);
+
+          // Store the remaining ExtraWidth bits.
+          IncrementSize = RoundWidth / 8;
+          Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
+                             DAG.getIntPtrConstant(IncrementSize));
+          Lo = DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+                                 SVOffset + IncrementSize, ExtraVT, isVolatile,
+                                 MinAlign(Alignment, IncrementSize));
+        }
 
-      MVT::ValueType StVT = cast<StoreSDNode>(Result.Val)->getStoredVT();
-      switch (TLI.getTruncStoreAction(ST->getValue().getValueType(), StVT)) {
-      default: assert(0 && "This action is not supported yet!");
-      case TargetLowering::Legal:
-        // If this is an unaligned store and the target doesn't support it,
-        // expand it.
-        if (!TLI.allowsUnalignedMemoryAccesses()) {
-          unsigned ABIAlignment = TLI.getTargetData()->
-            getABITypeAlignment(MVT::getTypeForValueType(ST->getStoredVT()));
-          if (ST->getAlignment() < ABIAlignment)
-            Result = ExpandUnalignedStore(cast<StoreSDNode>(Result.Val), DAG,
-                                          TLI);
+        // The order of the stores doesn't matter.
+        Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+      } else {
+        if (Tmp1 != ST->getChain() || Tmp3 != ST->getValue() ||
+            Tmp2 != ST->getBasePtr())
+          Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp3, Tmp2,
+                                          ST->getOffset());
+
+        switch (TLI.getTruncStoreAction(ST->getValue().getValueType(), StVT)) {
+        default: assert(0 && "This action is not supported yet!");
+        case TargetLowering::Legal:
+          // If this is an unaligned store and the target doesn't support it,
+          // expand it.
+          if (!TLI.allowsUnalignedMemoryAccesses()) {
+            unsigned ABIAlignment = TLI.getTargetData()->
+              getABITypeAlignment(MVT::getTypeForValueType(ST->getStoredVT()));
+            if (ST->getAlignment() < ABIAlignment)
+              Result = ExpandUnalignedStore(cast<StoreSDNode>(Result.Val), DAG,
+                                            TLI);
+          }
+          break;
+        case TargetLowering::Custom:
+          Result = TLI.LowerOperation(Result, DAG);
+          break;
+        case Expand:
+          // TRUNCSTORE:i16 i32 -> STORE i16
+          assert(isTypeLegal(StVT) && "Do not know how to expand this store!");
+          Tmp3 = DAG.getNode(ISD::TRUNCATE, StVT, Tmp3);
+          Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), SVOffset,
+                                isVolatile, Alignment);
+          break;
         }
-        break;
-      case TargetLowering::Custom:
-        Result = TLI.LowerOperation(Result, DAG);
-        break;
       }
     }
     break;





More information about the llvm-commits mailing list