LegalizeTypes support for INSERT_VECTOR_ELT with
authorDuncan Sands <baldrick@free.fr>
Sun, 15 Jun 2008 20:00:14 +0000 (20:00 +0000)
committerDuncan Sands <baldrick@free.fr>
Sun, 15 Jun 2008 20:00:14 +0000 (20:00 +0000)
a non-constant index.

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

lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
lib/CodeGen/SelectionDAG/LegalizeTypes.h
lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp

index 16c86936a6c0375adb99c700d37887bfdf06299a..5b37c75f1feafa4078d2381512e3a5f13f380370 100644 (file)
@@ -577,6 +577,23 @@ SDOperand DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, MVT RetVT,
   return CallInfo.first;
 }
 
+SDOperand DAGTypeLegalizer::GetVectorElementPointer(SDOperand VecPtr, MVT EltVT,
+                                                    SDOperand Index) {
+  // Make sure the index type is big enough to compute in.
+  if (Index.getValueType().bitsGT(TLI.getPointerTy()))
+    Index = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), Index);
+  else
+    Index = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Index);
+
+  // Calculate the element offset and add it to the pointer.
+  unsigned EltSize = EltVT.getSizeInBits() / 8; // FIXME: should be ABI size.
+
+  Index = DAG.getNode(ISD::MUL, Index.getValueType(), Index,
+                      DAG.getConstant(EltSize, Index.getValueType()));
+  return DAG.getNode(ISD::ADD, Index.getValueType(), Index, VecPtr);
+}
+
+
 //===----------------------------------------------------------------------===//
 //  Entry Point
 //===----------------------------------------------------------------------===//
index 09ccfe99381183dacb5f7c5509d5eaac40d90a4c..ba8f10693533eb26f8223f04012656a719d006da 100644 (file)
@@ -169,14 +169,18 @@ private:
   void ExpungeNode(SDOperand N);
 
   // Common routines.
-  SDOperand BitConvertToInteger(SDOperand Op);
   SDOperand CreateStackStoreLoad(SDOperand Op, MVT DestVT);
+  SDOperand MakeLibCall(RTLIB::Libcall LC, MVT RetVT,
+                        const SDOperand *Ops, unsigned NumOps, bool isSigned);
+
+  SDOperand BitConvertToInteger(SDOperand Op);
   SDOperand JoinIntegers(SDOperand Lo, SDOperand Hi);
   void SplitInteger(SDOperand Op, SDOperand &Lo, SDOperand &Hi);
   void SplitInteger(SDOperand Op, MVT LoVT, MVT HiVT,
                     SDOperand &Lo, SDOperand &Hi);
-  SDOperand MakeLibCall(RTLIB::Libcall LC, MVT RetVT,
-                        const SDOperand *Ops, unsigned NumOps, bool isSigned);
+
+  SDOperand GetVectorElementPointer(SDOperand VecPtr, MVT EltVT,
+                                    SDOperand Index);
 
   //===--------------------------------------------------------------------===//
   // Promotion Support: LegalizeTypesPromote.cpp
index 0e3c00dd60fce79fda1905b144d656e3ee79416c..74aae7f4c82500093d02af294490f7ac7a520ee3 100644 (file)
@@ -162,16 +162,37 @@ void DAGTypeLegalizer::SplitRes_BUILD_PAIR(SDNode *N, SDOperand &Lo,
 
 void DAGTypeLegalizer::SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo,
                                                   SDOperand &Hi) {
-  GetSplitOp(N->getOperand(0), Lo, Hi);
-  unsigned Index = cast<ConstantSDNode>(N->getOperand(2))->getValue();
-  SDOperand ScalarOp = N->getOperand(1);
-  unsigned LoNumElts = Lo.getValueType().getVectorNumElements();
-  if (Index < LoNumElts)
-    Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, Lo.getValueType(), Lo, ScalarOp,
-                     N->getOperand(2));
-  else
-    Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, Hi.getValueType(), Hi, ScalarOp,
-                     DAG.getIntPtrConstant(Index - LoNumElts));
+  SDOperand Vec = N->getOperand(0);
+  SDOperand Elt = N->getOperand(1);
+  SDOperand Idx = N->getOperand(2);
+  GetSplitOp(Vec, Lo, Hi);
+
+  if (ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Idx)) {
+    unsigned IdxVal = CIdx->getValue();
+    unsigned LoNumElts = Lo.getValueType().getVectorNumElements();
+    if (IdxVal < LoNumElts)
+      Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, Lo.getValueType(), Lo, Elt, Idx);
+    else
+      Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, Hi.getValueType(), Hi, Elt,
+                       DAG.getIntPtrConstant(IdxVal - LoNumElts));
+    return;
+  }
+
+  // Spill the vector to the stack.
+  MVT VecVT = Vec.getValueType();
+  SDOperand StackPtr = DAG.CreateStackTemporary(VecVT);
+  SDOperand Store = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0);
+
+  // Store the new element.
+  SDOperand EltPtr = GetVectorElementPointer(StackPtr,
+                                             VecVT.getVectorElementType(), Idx);
+  Store = DAG.getStore(Store, Elt, EltPtr, NULL, 0);
+
+  // Reload the vector from the stack.
+  SDOperand Load = DAG.getLoad(VecVT, Store, StackPtr, NULL, 0);
+
+  // Split it.
+  SplitRes_LOAD(cast<LoadSDNode>(Load.Val), Lo, Hi);
 }
 
 void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N, 
@@ -473,22 +494,13 @@ SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_VECTOR_ELT(SDNode *N) {
                                                     Idx.getValueType()));
   }
 
-  // Store the vector to the stack and load back the required element.
+  // Store the vector to the stack.
+  MVT EltVT = VecVT.getVectorElementType();
   SDOperand StackPtr = DAG.CreateStackTemporary(VecVT);
   SDOperand Store = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0);
 
-  // Add the offset to the index.
-  MVT EltVT = VecVT.getVectorElementType();
-  unsigned EltSize = EltVT.getSizeInBits()/8; // FIXME: should be ABI size.
-  Idx = DAG.getNode(ISD::MUL, Idx.getValueType(), Idx,
-                    DAG.getConstant(EltSize, Idx.getValueType()));
-
-  if (Idx.getValueType().bitsGT(TLI.getPointerTy()))
-    Idx = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), Idx);
-  else
-    Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx);
-
-  StackPtr = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, StackPtr);
+  // Load back the required element.
+  StackPtr = GetVectorElementPointer(StackPtr, EltVT, Idx);
   return DAG.getLoad(EltVT, Store, StackPtr, NULL, 0);
 }