LegalizeTypes support for scalarizing a vector store
authorDuncan Sands <baldrick@free.fr>
Wed, 20 Feb 2008 17:38:09 +0000 (17:38 +0000)
committerDuncan Sands <baldrick@free.fr>
Wed, 20 Feb 2008 17:38:09 +0000 (17:38 +0000)
and splitting extract_subvector.  This fixes nine
"make check" testcases, for example
2008-02-04-ExtractSubvector.ll and (partially)
CodeGen/Generic/vector.ll.

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

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

index acae44b2ac1ec60329f06122d292185e588442ff..3ebc2110587eba41061357eff82083c4ee22f0cd 100644 (file)
@@ -275,7 +275,8 @@ private:
   
   // Operand Vector Scalarization: <1 x ty> -> ty.
   bool ScalarizeOperand(SDNode *N, unsigned OpNo);
-  SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N, unsigned OpNo);
+  SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N);
+  SDOperand ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo);
 
   //===--------------------------------------------------------------------===//
   // Vector Splitting Support: LegalizeTypesSplit.cpp
@@ -303,9 +304,10 @@ private:
   
   // Operand Vector Scalarization: <128 x ty> -> 2 x <64 x ty>.
   bool SplitOperand(SDNode *N, unsigned OpNo);
-  
-  SDOperand SplitOp_STORE(StoreSDNode *N, unsigned OpNo);
+
+  SDOperand SplitOp_EXTRACT_SUBVECTOR(SDNode *N);
   SDOperand SplitOp_RET(SDNode *N, unsigned OpNo);
+  SDOperand SplitOp_STORE(StoreSDNode *N, unsigned OpNo);
 };
 
 } // end namespace llvm.
index 95306b99fab013a1ecd1980afb059c3bd048e6ad..da8fd807a4ee0d9d0d3dd2b2fdb58fb2c864991b 100644 (file)
@@ -166,8 +166,10 @@ bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) {
       abort();
       
     case ISD::EXTRACT_VECTOR_ELT:
-      Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N, OpNo);
-      break;
+      Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N); break;
+
+    case ISD::STORE:
+      Res = ScalarizeOp_STORE(cast<StoreSDNode>(N), OpNo); break;
     }
   }
   
@@ -193,10 +195,17 @@ bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) {
 }
 
 /// ScalarizeOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to be
-/// scalarized, it must be <1 x ty>, just return the operand, ignoring the
+/// scalarized, it must be <1 x ty>, so just return the element, ignoring the
 /// index.
-SDOperand DAGTypeLegalizer::ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N, 
-                                                           unsigned OpNo) {
+SDOperand DAGTypeLegalizer::ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N) {
   return GetScalarizedOp(N->getOperand(0));
 }
 
+/// ScalarizeOp_STORE - If the value to store is a vector that needs to be
+/// scalarized, it must be <1 x ty>.  Just store the element.
+SDOperand DAGTypeLegalizer::ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo) {
+  assert(OpNo == 1 && "Do not know how to scalarize this operand!");
+  return DAG.getStore(N->getChain(), GetScalarizedOp(N->getOperand(1)),
+                      N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(),
+                      N->isVolatile(), N->getAlignment());
+}
index 549afe9c6f4b408b292233234c13def0eee02d4f..489aea4c64c0a6451bda2c97debc00c62efb72de 100644 (file)
@@ -339,6 +339,8 @@ bool DAGTypeLegalizer::SplitOperand(SDNode *N, unsigned OpNo) {
       abort();
     case ISD::STORE: Res = SplitOp_STORE(cast<StoreSDNode>(N), OpNo); break;
     case ISD::RET:   Res = SplitOp_RET(N, OpNo); break;
+
+    case ISD::EXTRACT_SUBVECTOR: Res = SplitOp_EXTRACT_SUBVECTOR(N); break;
     }
   }
   
@@ -399,3 +401,24 @@ SDOperand DAGTypeLegalizer::SplitOp_RET(SDNode *N, unsigned OpNo) {
   
   return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Sign, Hi, Sign);
 }
+
+SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_SUBVECTOR(SDNode *N) {
+  // We know that the extracted result type is legal.  For now, assume the index
+  // is a constant.
+  MVT::ValueType SubVT = N->getValueType(0);
+  SDOperand Idx = N->getOperand(1);
+  SDOperand Lo, Hi;
+  GetSplitOp(N->getOperand(0), Lo, Hi);
+
+  uint64_t LoElts = MVT::getVectorNumElements(Lo.getValueType());
+  uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getValue();
+
+  if (IdxVal < LoElts) {
+    assert(IdxVal + MVT::getVectorNumElements(SubVT) <= LoElts &&
+           "Extracted subvector crosses vector split!");
+    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SubVT, Lo, Idx);
+  } else {
+    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SubVT, Hi,
+                       DAG.getConstant(IdxVal - LoElts, Idx.getValueType()));
+  }
+}
index ef28aa5a2b458e9aa82e06a073f2ac652868b40a..28f612d8cd1e3c30beec4f75c31754b96a507e40 100644 (file)
@@ -2145,6 +2145,10 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
       return getConstant(C->getValue() >> Shift, VT);
     }
     break;
+  case ISD::EXTRACT_SUBVECTOR:
+    if (N1.getValueType() == VT) // Trivial extraction.
+      return N1;
+    break;
   }
 
   if (N1C) {