[llvm-commits] [llvm] r47537 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeTypes.h LegalizeTypesExpand.cpp LegalizeTypesPromote.cpp

Duncan Sands baldrick at free.fr
Sat Feb 23 23:36:04 PST 2008


Author: baldrick
Date: Sun Feb 24 01:36:03 2008
New Revision: 47537

URL: http://llvm.org/viewvc/llvm-project?rev=47537&view=rev
Log:
Add support to LegalizeTypes for building legal vectors
out of illegal elements (BUILD_VECTOR).  Uses and beefs
up BUILD_PAIR, though it didn't really have to.  Like
most of LegalizeTypes, does not support soft-float.
This cures all "make check" vector building failures.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=47537&r1=47536&r2=47537&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Sun Feb 24 01:36:03 2008
@@ -159,6 +159,7 @@
     
   // Result Promotion.
   void PromoteResult(SDNode *N, unsigned ResNo);
+  SDOperand PromoteResult_BUILD_PAIR(SDNode *N);
   SDOperand PromoteResult_Constant(SDNode *N);
   SDOperand PromoteResult_CTLZ(SDNode *N);
   SDOperand PromoteResult_CTPOP(SDNode *N);
@@ -182,8 +183,10 @@
   // Operand Promotion.
   bool PromoteOperand(SDNode *N, unsigned OperandNo);
   SDOperand PromoteOperand_ANY_EXTEND(SDNode *N);
+  SDOperand PromoteOperand_BUILD_PAIR(SDNode *N);
   SDOperand PromoteOperand_BR_CC(SDNode *N, unsigned OpNo);
   SDOperand PromoteOperand_BRCOND(SDNode *N, unsigned OpNo);
+  SDOperand PromoteOperand_BUILD_VECTOR(SDNode *N);
   SDOperand PromoteOperand_FP_EXTEND(SDNode *N);
   SDOperand PromoteOperand_FP_ROUND(SDNode *N);
   SDOperand PromoteOperand_INT_TO_FP(SDNode *N);
@@ -240,6 +243,7 @@
   bool ExpandOperand(SDNode *N, unsigned OperandNo);
   SDOperand ExpandOperand_BIT_CONVERT(SDNode *N);
   SDOperand ExpandOperand_BR_CC(SDNode *N);
+  SDOperand ExpandOperand_BUILD_VECTOR(SDNode *N);
   SDOperand ExpandOperand_EXTRACT_ELEMENT(SDNode *N);
   SDOperand ExpandOperand_SETCC(SDNode *N);
   SDOperand ExpandOperand_SINT_TO_FP(SDOperand Source, MVT::ValueType DestTy);

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp?rev=47537&r1=47536&r2=47537&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp Sun Feb 24 01:36:03 2008
@@ -865,6 +865,8 @@
     case ISD::MEMSET:
     case ISD::MEMCPY:
     case ISD::MEMMOVE:     Res = HandleMemIntrinsic(N); break;
+
+    case ISD::BUILD_VECTOR: Res = ExpandOperand_BUILD_VECTOR(N); break;
     }
   }
   
@@ -1224,3 +1226,34 @@
   }
 }
 
+SDOperand DAGTypeLegalizer::ExpandOperand_BUILD_VECTOR(SDNode *N) {
+  // The vector type is legal but the element type needs expansion.
+  MVT::ValueType VecVT = N->getValueType(0);
+  unsigned NumElts = MVT::getVectorNumElements(VecVT);
+  MVT::ValueType OldVT = N->getOperand(0).getValueType();
+  MVT::ValueType NewVT = TLI.getTypeToTransformTo(OldVT);
+
+  assert(MVT::getSizeInBits(OldVT) == 2 * MVT::getSizeInBits(NewVT) &&
+         "Do not know how to expand this operand!");
+
+  // Build a vector of twice the length out of the expanded elements.
+  // For example <2 x i64> -> <4 x i32>.
+  std::vector<SDOperand> NewElts;
+  NewElts.reserve(NumElts*2);
+
+  for (unsigned i = 0; i < NumElts; ++i) {
+    SDOperand Lo, Hi;
+    GetExpandedOp(N->getOperand(i), Lo, Hi);
+    if (TLI.isBigEndian())
+      std::swap(Lo, Hi);
+    NewElts.push_back(Lo);
+    NewElts.push_back(Hi);
+  }
+
+  SDOperand NewVec = DAG.getNode(ISD::BUILD_VECTOR,
+                                 MVT::getVectorType(NewVT, NewElts.size()),
+                                 &NewElts[0], NewElts.size());
+
+  // Convert the new vector to the old vector type.
+  return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec);
+}

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp?rev=47537&r1=47536&r2=47537&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp Sun Feb 24 01:36:03 2008
@@ -49,6 +49,7 @@
   case ISD::FP_TO_UINT:  Result = PromoteResult_FP_TO_XINT(N); break;
   case ISD::SETCC:    Result = PromoteResult_SETCC(N); break;
   case ISD::LOAD:     Result = PromoteResult_LOAD(cast<LoadSDNode>(N)); break;
+  case ISD::BUILD_PAIR:  Result = PromoteResult_BUILD_PAIR(N); break;
 
   case ISD::AND:
   case ISD::OR:
@@ -200,6 +201,19 @@
   return Res;
 }
 
+SDOperand DAGTypeLegalizer::PromoteResult_BUILD_PAIR(SDNode *N) {
+  // The pair element type may be legal, or may not promote to the same type as
+  // the result, for example i16 = BUILD_PAIR (i8, i8) when i8 is legal but i16
+  // is not.  Handle all cases.
+  MVT::ValueType LVT = N->getOperand(0).getValueType();
+  MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  SDOperand Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, N->getOperand(0));
+  SDOperand Hi = DAG.getNode(ISD::ANY_EXTEND, NVT, N->getOperand(1));
+  Hi = DAG.getNode(ISD::SHL, NVT, Hi, DAG.getConstant(MVT::getSizeInBits(LVT),
+                                                      TLI.getShiftAmountTy()));
+  return DAG.getNode(ISD::OR, NVT, Lo, Hi);
+}
+
 SDOperand DAGTypeLegalizer::PromoteResult_SimpleIntBinOp(SDNode *N) {
   // The input may have strange things in the top bits of the registers, but
   // these operations don't care.  They may have weird bits going out, but
@@ -329,7 +343,8 @@
   case ISD::FP_ROUND:    Res = PromoteOperand_FP_ROUND(N); break;
   case ISD::SINT_TO_FP:
   case ISD::UINT_TO_FP:  Res = PromoteOperand_INT_TO_FP(N); break;
-    
+  case ISD::BUILD_PAIR:  Res = PromoteOperand_BUILD_PAIR(N); break;
+
   case ISD::SELECT:      Res = PromoteOperand_SELECT(N, OpNo); break;
   case ISD::BRCOND:      Res = PromoteOperand_BRCOND(N, OpNo); break;
   case ISD::BR_CC:       Res = PromoteOperand_BR_CC(N, OpNo); break;
@@ -341,6 +356,8 @@
   case ISD::MEMCPY:
   case ISD::MEMMOVE:     Res = HandleMemIntrinsic(N); break;
 
+  case ISD::BUILD_VECTOR: Res = PromoteOperand_BUILD_VECTOR(N); break;
+
   case ISD::RET:         Res = PromoteOperand_RET(N, OpNo); break;
   }
 
@@ -409,6 +426,20 @@
   return DAG.UpdateNodeOperands(SDOperand(N, 0), In);
 }
 
+SDOperand DAGTypeLegalizer::PromoteOperand_BUILD_PAIR(SDNode *N) {
+  // Since the result type is legal, the operands must promote to it.
+  MVT::ValueType OVT = N->getOperand(0).getValueType();
+  SDOperand Lo = GetPromotedOp(N->getOperand(0));
+  SDOperand Hi = GetPromotedOp(N->getOperand(1));
+  assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?");
+
+  Lo = DAG.getZeroExtendInReg(Lo, OVT);
+  Hi = DAG.getNode(ISD::SHL, N->getValueType(0), Hi,
+                   DAG.getConstant(MVT::getSizeInBits(OVT),
+                                   TLI.getShiftAmountTy()));
+  return DAG.getNode(ISD::OR, N->getValueType(0), Lo, Hi);
+}
+
 SDOperand DAGTypeLegalizer::PromoteOperand_SELECT(SDNode *N, unsigned OpNo) {
   assert(OpNo == 0 && "Only know how to promote condition");
   SDOperand Cond = GetPromotedOp(N->getOperand(0));  // Promote the condition.
@@ -527,6 +558,40 @@
                            isVolatile, Alignment);
 }
 
+SDOperand DAGTypeLegalizer::PromoteOperand_BUILD_VECTOR(SDNode *N) {
+  // The vector type is legal but the element type is not.  This implies
+  // that the vector is a power-of-two in length and that the element
+  // type does not have a strange size (eg: it is not i1).
+  MVT::ValueType VecVT = N->getValueType(0);
+  unsigned NumElts = MVT::getVectorNumElements(VecVT);
+  assert(!(NumElts & 1) && "Legal vector of one illegal element?");
+
+  // Build a vector of half the length out of elements of twice the bitwidth.
+  // For example <4 x i16> -> <2 x i32>.
+  MVT::ValueType OldVT = N->getOperand(0).getValueType();
+  MVT::ValueType NewVT = MVT::getIntegerType(2 * MVT::getSizeInBits(OldVT));
+  assert(!MVT::isExtendedVT(OldVT) && !MVT::isExtendedVT(NewVT));
+
+  std::vector<SDOperand> NewElts;
+  NewElts.reserve(NumElts/2);
+
+  for (unsigned i = 0; i < NumElts; i += 2) {
+    // Combine two successive elements into one promoted element.
+    SDOperand Lo = N->getOperand(i);
+    SDOperand Hi = N->getOperand(i+1);
+    if (TLI.isBigEndian())
+      std::swap(Lo, Hi);
+    NewElts.push_back(DAG.getNode(ISD::BUILD_PAIR, NewVT, Lo, Hi));
+  }
+
+  SDOperand NewVec = DAG.getNode(ISD::BUILD_VECTOR,
+                                 MVT::getVectorType(NewVT, NewElts.size()),
+                                 &NewElts[0], NewElts.size());
+
+  // Convert the new vector to the old vector type.
+  return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec);
+}
+
 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!");





More information about the llvm-commits mailing list