Support operations like fp_to_uint with a vector
authorDuncan Sands <baldrick@free.fr>
Mon, 20 Oct 2008 16:31:21 +0000 (16:31 +0000)
committerDuncan Sands <baldrick@free.fr>
Mon, 20 Oct 2008 16:31:21 +0000 (16:31 +0000)
result type when the result type is legal but
not the operand type.  Add additional support
for EXTRACT_SUBVECTOR and CONCAT_VECTORS,
needed to handle such cases.

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

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

index 21cad45d401bc0591002a56a4c9018fba0facfca..8e1fa1b342f75fedc8295a6fc7a8bc2513cdde75 100644 (file)
@@ -416,6 +416,7 @@ private:
   SDValue ScalarizeVecRes_UnaryOp(SDNode *N);
 
   SDValue ScalarizeVecRes_BIT_CONVERT(SDNode *N);
+  SDValue ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N);
   SDValue ScalarizeVecRes_FPOWI(SDNode *N);
   SDValue ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N);
   SDValue ScalarizeVecRes_LOAD(LoadSDNode *N);
@@ -427,6 +428,7 @@ private:
   // Vector Operand Scalarization: <1 x ty> -> ty.
   bool ScalarizeVectorOperand(SDNode *N, unsigned OpNo);
   SDValue ScalarizeVecOp_BIT_CONVERT(SDNode *N);
+  SDValue ScalarizeVecOp_CONCAT_VECTORS(SDNode *N);
   SDValue ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N);
   SDValue ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo);
 
@@ -455,6 +457,7 @@ private:
 
   // Vector Operand Splitting: <128 x ty> -> 2 x <64 x ty>.
   bool SplitVectorOperand(SDNode *N, unsigned OpNo);
+  SDValue SplitVecOp_UnaryOp(SDNode *N);
 
   SDValue SplitVecOp_BIT_CONVERT(SDNode *N);
   SDValue SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N);
index 54436f15636d5e30afece1729328da7af43973af..0b9645db271cb372c618ae4d0d33ac38c7b20933 100644 (file)
@@ -43,6 +43,7 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
 
   case ISD::BIT_CONVERT:    R = ScalarizeVecRes_BIT_CONVERT(N); break;
   case ISD::BUILD_VECTOR:   R = N->getOperand(0); break;
+  case ISD::EXTRACT_SUBVECTOR: R = ScalarizeVecRes_EXTRACT_SUBVECTOR(N); break;
   case ISD::FPOWI:          R = ScalarizeVecRes_FPOWI(N); break;
   case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break;
   case ISD::LOAD:           R = ScalarizeVecRes_LOAD(cast<LoadSDNode>(N));break;
@@ -67,6 +68,7 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
   case ISD::FRINT:
   case ISD::FNEARBYINT:
   case ISD::SINT_TO_FP:
+  case ISD::TRUNCATE:
   case ISD::UINT_TO_FP: R = ScalarizeVecRes_UnaryOp(N); break;
 
   case ISD::ADD:
@@ -103,6 +105,12 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_BIT_CONVERT(SDNode *N) {
   return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0));
 }
 
+SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N) {
+  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
+                     N->getValueType(0).getVectorElementType(),
+                     N->getOperand(0), N->getOperand(1));
+}
+
 SDValue DAGTypeLegalizer::ScalarizeVecRes_FPOWI(SDNode *N) {
   SDValue Op = GetScalarizedVector(N->getOperand(0));
   return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1));
@@ -139,7 +147,7 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) {
 
 SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(SDNode *N) {
   // Get the dest type - it doesn't always match the input type, e.g. int_to_fp.
-  MVT DestVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  MVT DestVT = N->getValueType(0).getVectorElementType();
   SDValue Op = GetScalarizedVector(N->getOperand(0));
   return DAG.getNode(N->getOpcode(), DestVT, Op);
 }
@@ -199,6 +207,9 @@ bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) {
     case ISD::BIT_CONVERT:
       Res = ScalarizeVecOp_BIT_CONVERT(N); break;
 
+    case ISD::CONCAT_VECTORS:
+      Res = ScalarizeVecOp_CONCAT_VECTORS(N); break;
+
     case ISD::EXTRACT_VECTOR_ELT:
       Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(N); break;
 
@@ -234,6 +245,16 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_BIT_CONVERT(SDNode *N) {
   return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Elt);
 }
 
+/// ScalarizeVecOp_CONCAT_VECTORS - The vectors to concatenate have length one -
+/// use a BUILD_VECTOR instead.
+SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(SDNode *N) {
+  SmallVector<SDValue, 8> Ops(N->getNumOperands());
+  for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i)
+    Ops[i] = GetScalarizedVector(N->getOperand(i));
+  return DAG.getNode(ISD::BUILD_VECTOR, N->getValueType(0),
+                     &Ops[0], Ops.size());
+}
+
 /// ScalarizeVecOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to
 /// be scalarized, it must be <1 x ty>, so just return the element, ignoring the
 /// index.
@@ -313,6 +334,7 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
   case ISD::FP_TO_SINT:
   case ISD::FP_TO_UINT:
   case ISD::SINT_TO_FP:
+  case ISD::TRUNCATE:
   case ISD::UINT_TO_FP: SplitVecRes_UnaryOp(N, Lo, Hi); break;
 
   case ISD::ADD:
@@ -636,6 +658,15 @@ bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) {
     case ISD::STORE:             Res = SplitVecOp_STORE(cast<StoreSDNode>(N),
                                                         OpNo); break;
     case ISD::VECTOR_SHUFFLE:    Res = SplitVecOp_VECTOR_SHUFFLE(N, OpNo);break;
+
+    case ISD::CTTZ:
+    case ISD::CTLZ:
+    case ISD::CTPOP:
+    case ISD::FP_TO_SINT:
+    case ISD::FP_TO_UINT:
+    case ISD::SINT_TO_FP:
+    case ISD::TRUNCATE:
+    case ISD::UINT_TO_FP: Res = SplitVecOp_UnaryOp(N); break;
     }
   }
 
@@ -659,6 +690,24 @@ bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) {
   return false;
 }
 
+SDValue DAGTypeLegalizer::SplitVecOp_UnaryOp(SDNode *N) {
+  // The result has a legal vector type, but the input needs splitting.
+  MVT ResVT = N->getValueType(0);
+  SDValue Lo, Hi;
+  GetSplitVector(N->getOperand(0), Lo, Hi);
+  assert(Lo.getValueType() == Hi.getValueType() &&
+         "Returns legal non-power-of-two vector type?");
+  MVT InVT = Lo.getValueType();
+
+  MVT OutVT = MVT::getVectorVT(ResVT.getVectorElementType(),
+                               InVT.getVectorNumElements());
+
+  Lo = DAG.getNode(N->getOpcode(), OutVT, Lo);
+  Hi = DAG.getNode(N->getOpcode(), OutVT, Hi);
+
+  return DAG.getNode(ISD::CONCAT_VECTORS, ResVT, Lo, Hi);
+}
+
 SDValue DAGTypeLegalizer::SplitVecOp_BIT_CONVERT(SDNode *N) {
   // For example, i64 = BIT_CONVERT v4i16 on alpha.  Typically the vector will
   // end up being split all the way down to individual components.  Convert the