LegalizeTypes support for INSERT_VECTOR_ELT.
authorDuncan Sands <baldrick@free.fr>
Wed, 27 Feb 2008 10:18:23 +0000 (10:18 +0000)
committerDuncan Sands <baldrick@free.fr>
Wed, 27 Feb 2008 10:18:23 +0000 (10:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47669 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAGNodes.h
lib/CodeGen/SelectionDAG/LegalizeTypes.h
lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp
lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp

index 56645f708eb64e70a88c8fb069108a42c9f1fc59..c467967b0fc2eb776364fb89e36b0c935d3b421a 100644 (file)
@@ -283,7 +283,8 @@ namespace ISD {
     BUILD_VECTOR,
     
     /// INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element
-    /// at IDX replaced with VAL.
+    /// at IDX replaced with VAL.  If the type of VAL is larger than the vector
+    /// element type then VAL is truncated before replacement.
     INSERT_VECTOR_ELT,
 
     /// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR
index 1947673dd8c1105d29c84992a9ce115b1faca099..d480fe707a2838a56aad9f315b9acce8efed1640 100644 (file)
@@ -190,6 +190,7 @@ private:
   SDOperand PromoteOperand_FP_EXTEND(SDNode *N);
   SDOperand PromoteOperand_FP_ROUND(SDNode *N);
   SDOperand PromoteOperand_INT_TO_FP(SDNode *N);
+  SDOperand PromoteOperand_INSERT_VECTOR_ELT(SDNode *N, unsigned OpNo);
   SDOperand PromoteOperand_MEMBARRIER(SDNode *N);
   SDOperand PromoteOperand_RET(SDNode *N, unsigned OpNo);
   SDOperand PromoteOperand_SELECT(SDNode *N, unsigned OpNo);
@@ -269,15 +270,17 @@ private:
     
   // Result Vector Scalarization: <1 x ty> -> ty.
   void ScalarizeResult(SDNode *N, unsigned OpNo);
-  SDOperand ScalarizeRes_UNDEF(SDNode *N);
-  SDOperand ScalarizeRes_LOAD(LoadSDNode *N);
   SDOperand ScalarizeRes_BinOp(SDNode *N);
   SDOperand ScalarizeRes_UnaryOp(SDNode *N);
-  SDOperand ScalarizeRes_FPOWI(SDNode *N);
-  SDOperand ScalarizeRes_VECTOR_SHUFFLE(SDNode *N);
+
   SDOperand ScalarizeRes_BIT_CONVERT(SDNode *N);
+  SDOperand ScalarizeRes_FPOWI(SDNode *N);
+  SDOperand ScalarizeRes_INSERT_VECTOR_ELT(SDNode *N);
+  SDOperand ScalarizeRes_LOAD(LoadSDNode *N);
   SDOperand ScalarizeRes_SELECT(SDNode *N);
-  
+  SDOperand ScalarizeRes_UNDEF(SDNode *N);
+  SDOperand ScalarizeRes_VECTOR_SHUFFLE(SDNode *N);
+
   // Operand Vector Scalarization: <1 x ty> -> ty.
   bool ScalarizeOperand(SDNode *N, unsigned OpNo);
   SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N);
index 41501398f2e08dddf176d17b8e3de5c0bd47dd00..c4eb059380572d6eff4d83f527492cf8a2a5f6b3 100644 (file)
@@ -357,6 +357,9 @@ bool DAGTypeLegalizer::PromoteOperand(SDNode *N, unsigned OpNo) {
   case ISD::MEMMOVE:     Res = HandleMemIntrinsic(N); break;
 
   case ISD::BUILD_VECTOR: Res = PromoteOperand_BUILD_VECTOR(N); break;
+  case ISD::INSERT_VECTOR_ELT:
+    Res = PromoteOperand_INSERT_VECTOR_ELT(N, OpNo);
+    break;
 
   case ISD::RET:         Res = PromoteOperand_RET(N, OpNo); break;
 
@@ -591,6 +594,30 @@ SDOperand DAGTypeLegalizer::PromoteOperand_BUILD_VECTOR(SDNode *N) {
   return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec);
 }
 
+SDOperand DAGTypeLegalizer::PromoteOperand_INSERT_VECTOR_ELT(SDNode *N,
+                                                             unsigned OpNo) {
+  if (OpNo == 1) {
+    // Promote the inserted value.  This is valid because the type does not
+    // have to match the vector element type.
+
+    // Check that any extra bits introduced will be truncated away.
+    assert(MVT::getSizeInBits(N->getOperand(1).getValueType()) >=
+           MVT::getSizeInBits(MVT::getVectorElementType(N->getValueType(0))) &&
+           "Type of inserted value narrower than vector element type!");
+    return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
+                                  GetPromotedOp(N->getOperand(1)),
+                                  N->getOperand(2));
+  }
+
+  assert(OpNo == 2 && "Different operand and result vector types?");
+
+  // Promote the index.
+  SDOperand Idx = N->getOperand(2);
+  Idx = DAG.getZeroExtendInReg(GetPromotedOp(Idx), Idx.getValueType());
+  return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
+                                N->getOperand(1), Idx);
+}
+
 SDOperand DAGTypeLegalizer::PromoteOperand_RET(SDNode *N, unsigned OpNo) {
   assert(!(OpNo & 1) && "Return values should be legally typed!");
   assert((N->getNumOperands() & 1) && "Wrong number of operands!");
index d386feb260707ed395baf954c10c1b5e776b94bc..72c1f484db4bb0ef744bca39b575dd07f4286962 100644 (file)
@@ -77,7 +77,7 @@ void DAGTypeLegalizer::ScalarizeResult(SDNode *N, unsigned ResNo) {
   case ISD::FCOS:              R = ScalarizeRes_UnaryOp(N); break;
   case ISD::FPOWI:             R = ScalarizeRes_FPOWI(N); break;
   case ISD::BUILD_VECTOR:      R = N->getOperand(0); break;
-  case ISD::INSERT_VECTOR_ELT: R = N->getOperand(1); break;
+  case ISD::INSERT_VECTOR_ELT: R = ScalarizeRes_INSERT_VECTOR_ELT(N); break;
   case ISD::VECTOR_SHUFFLE:    R = ScalarizeRes_VECTOR_SHUFFLE(N); break;
   case ISD::BIT_CONVERT:       R = ScalarizeRes_BIT_CONVERT(N); break;
   case ISD::SELECT:            R = ScalarizeRes_SELECT(N); break;
@@ -120,6 +120,17 @@ SDOperand DAGTypeLegalizer::ScalarizeRes_FPOWI(SDNode *N) {
   return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1));
 }
 
+SDOperand DAGTypeLegalizer::ScalarizeRes_INSERT_VECTOR_ELT(SDNode *N) {
+  // The value to insert may have a wider type than the vector element type,
+  // so be sure to truncate it to the element type if necessary.
+  SDOperand Op = N->getOperand(1);
+  MVT::ValueType EltVT = MVT::getVectorElementType(N->getValueType(0));
+  if (MVT::getSizeInBits(Op.getValueType()) > MVT::getSizeInBits(EltVT))
+    Op = DAG.getNode(ISD::TRUNCATE, EltVT, Op);
+  assert(Op.getValueType() == EltVT && "Invalid type for inserted value!");
+  return Op;
+}
+
 SDOperand DAGTypeLegalizer::ScalarizeRes_VECTOR_SHUFFLE(SDNode *N) {
   // Figure out if the scalar is the LHS or RHS and return it.
   SDOperand EltNum = N->getOperand(2).getOperand(0);