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

Nate Begeman natebegeman at mac.com
Fri Apr 25 11:07:40 PDT 2008


Author: sampo
Date: Fri Apr 25 13:07:40 2008
New Revision: 50273

URL: http://llvm.org/viewvc/llvm-project?rev=50273&view=rev
Log:
Pull the code to perform an INSERT_VECTOR_ELT in memory out into its own 
function, and then use it to fix a bug in SplitVectorOp that expected inserts
to always have constant insertion indices.

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=50273&r1=50272&r2=50273&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Apr 25 13:07:40 2008
@@ -155,6 +155,13 @@
   /// no way of lowering.  "Unroll" the vector, splitting out the scalars and
   /// operating on each element individually.
   SDOperand UnrollVectorOp(SDOperand O);
+  
+  /// PerformInsertVectorEltInMemory - Some target cannot handle a variable
+  /// insertion index for the INSERT_VECTOR_ELT instruction.  In this case, it
+  /// is necessary to spill the vector being inserted into to memory, perform
+  /// the insert there, and then read the result back.
+  SDOperand PerformInsertVectorEltInMemory(SDOperand Vec, SDOperand Val,
+                                           SDOperand Idx);
 
   /// PromoteOp - Given an operation that produces a value in an invalid type,
   /// promote it to compute the value into a larger type.  The produced value
@@ -757,6 +764,50 @@
     RTLIB::UNKNOWN_LIBCALL;
 }
 
+/// PerformInsertVectorEltInMemory - Some target cannot handle a variable
+/// insertion index for the INSERT_VECTOR_ELT instruction.  In this case, it
+/// is necessary to spill the vector being inserted into to memory, perform
+/// the insert there, and then read the result back.
+SDOperand SelectionDAGLegalize::
+PerformInsertVectorEltInMemory(SDOperand Vec, SDOperand Val, SDOperand Idx) {
+  SDOperand Tmp1 = Vec;
+  SDOperand Tmp2 = Val;
+  SDOperand Tmp3 = Idx;
+  
+  // If the target doesn't support this, we have to spill the input vector
+  // to a temporary stack slot, update the element, then reload it.  This is
+  // badness.  We could also load the value into a vector register (either
+  // with a "move to register" or "extload into register" instruction, then
+  // permute it into place, if the idx is a constant and if the idx is
+  // supported by the target.
+  MVT::ValueType VT    = Tmp1.getValueType();
+  MVT::ValueType EltVT = MVT::getVectorElementType(VT);
+  MVT::ValueType IdxVT = Tmp3.getValueType();
+  MVT::ValueType PtrVT = TLI.getPointerTy();
+  SDOperand StackPtr = DAG.CreateStackTemporary(VT);
+
+  FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(StackPtr.Val);
+  int SPFI = StackPtrFI->getIndex();
+
+  // Store the vector.
+  SDOperand Ch = DAG.getStore(DAG.getEntryNode(), Tmp1, StackPtr,
+                              PseudoSourceValue::getFixedStack(),
+                              SPFI);
+
+  // Truncate or zero extend offset to target pointer type.
+  unsigned CastOpc = (IdxVT > PtrVT) ? ISD::TRUNCATE : ISD::ZERO_EXTEND;
+  Tmp3 = DAG.getNode(CastOpc, PtrVT, Tmp3);
+  // Add the offset to the index.
+  unsigned EltSize = MVT::getSizeInBits(EltVT)/8;
+  Tmp3 = DAG.getNode(ISD::MUL, IdxVT, Tmp3,DAG.getConstant(EltSize, IdxVT));
+  SDOperand StackPtr2 = DAG.getNode(ISD::ADD, IdxVT, Tmp3, StackPtr);
+  // Store the scalar value.
+  Ch = DAG.getTruncStore(Ch, Tmp2, StackPtr2,
+                         PseudoSourceValue::getFixedStack(), SPFI, EltVT);
+  // Load the updated vector.
+  return DAG.getLoad(VT, Ch, StackPtr, PseudoSourceValue::getFixedStack(),SPFI);
+}
+
 /// LegalizeOp - We know that the specified value has a legal type, and
 /// that its operands are legal.  Now ensure that the operation itself
 /// is legal, recursively ensuring that the operands' operations remain
@@ -1404,40 +1455,7 @@
           break;
         }
       }
-      
-      // If the target doesn't support this, we have to spill the input vector
-      // to a temporary stack slot, update the element, then reload it.  This is
-      // badness.  We could also load the value into a vector register (either
-      // with a "move to register" or "extload into register" instruction, then
-      // permute it into place, if the idx is a constant and if the idx is
-      // supported by the target.
-      MVT::ValueType VT    = Tmp1.getValueType();
-      MVT::ValueType EltVT = MVT::getVectorElementType(VT);
-      MVT::ValueType IdxVT = Tmp3.getValueType();
-      MVT::ValueType PtrVT = TLI.getPointerTy();
-      SDOperand StackPtr = DAG.CreateStackTemporary(VT);
-
-      FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(StackPtr.Val);
-      int SPFI = StackPtrFI->getIndex();
-
-      // Store the vector.
-      SDOperand Ch = DAG.getStore(DAG.getEntryNode(), Tmp1, StackPtr,
-                                  PseudoSourceValue::getFixedStack(),
-                                  SPFI);
-
-      // Truncate or zero extend offset to target pointer type.
-      unsigned CastOpc = (IdxVT > PtrVT) ? ISD::TRUNCATE : ISD::ZERO_EXTEND;
-      Tmp3 = DAG.getNode(CastOpc, PtrVT, Tmp3);
-      // Add the offset to the index.
-      unsigned EltSize = MVT::getSizeInBits(EltVT)/8;
-      Tmp3 = DAG.getNode(ISD::MUL, IdxVT, Tmp3,DAG.getConstant(EltSize, IdxVT));
-      SDOperand StackPtr2 = DAG.getNode(ISD::ADD, IdxVT, Tmp3, StackPtr);
-      // Store the scalar value.
-      Ch = DAG.getTruncStore(Ch, Tmp2, StackPtr2,
-                             PseudoSourceValue::getFixedStack(), SPFI, EltVT);
-      // Load the updated vector.
-      Result = DAG.getLoad(VT, Ch, StackPtr,
-                           PseudoSourceValue::getFixedStack(), SPFI);
+      Result = PerformInsertVectorEltInMemory(Tmp1, Tmp2, Tmp3);
       break;
     }
     }
@@ -6714,15 +6732,22 @@
     Hi = Node->getOperand(1);
     break;
   case ISD::INSERT_VECTOR_ELT: {
-    SplitVectorOp(Node->getOperand(0), Lo, Hi);
-    unsigned Index = cast<ConstantSDNode>(Node->getOperand(2))->getValue();
-    SDOperand ScalarOp = Node->getOperand(1);
-    if (Index < NewNumElts_Lo)
-      Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Lo, Lo, ScalarOp,
-                       DAG.getIntPtrConstant(Index));
-    else
-      Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Hi, Hi, ScalarOp,
-                       DAG.getIntPtrConstant(Index - NewNumElts_Lo));
+    if (ConstantSDNode *Idx = dyn_cast<ConstantSDNode>(Node->getOperand(2))) {
+      SplitVectorOp(Node->getOperand(0), Lo, Hi);
+      unsigned Index = Idx->getValue();
+      SDOperand ScalarOp = Node->getOperand(1);
+      if (Index < NewNumElts_Lo)
+        Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Lo, Lo, ScalarOp,
+                         DAG.getIntPtrConstant(Index));
+      else
+        Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Hi, Hi, ScalarOp,
+                         DAG.getIntPtrConstant(Index - NewNumElts_Lo));
+      break;
+    }
+    SDOperand Tmp = PerformInsertVectorEltInMemory(Node->getOperand(0),
+                                                   Node->getOperand(1),
+                                                   Node->getOperand(2));
+    SplitVectorOp(Tmp, Lo, Hi);
     break;
   }
   case ISD::VECTOR_SHUFFLE: {





More information about the llvm-commits mailing list