LLVM API Documentation

LegalizeVectorTypes.cpp

Go to the documentation of this file.
00001 //===------- LegalizeVectorTypes.cpp - Legalization of vector types -------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file performs vector type splitting and scalarization for LegalizeTypes.
00011 // Scalarization is the act of changing a computation in an illegal one-element
00012 // vector type to be a computation in its scalar element type.  For example,
00013 // implementing <1 x f32> arithmetic in a scalar f32 register.  This is needed
00014 // as a base case when scalarizing vector arithmetic like <4 x f32>, which
00015 // eventually decomposes to scalars if the target doesn't support v4f32 or v2f32
00016 // types.
00017 // Splitting is the act of changing a computation in an invalid vector type to
00018 // be a computation in multiple vectors of a smaller type.  For example,
00019 // implementing <128 x f32> operations in terms of two <64 x f32> operations.
00020 //
00021 //===----------------------------------------------------------------------===//
00022 
00023 #include "LegalizeTypes.h"
00024 #include "llvm/CodeGen/PseudoSourceValue.h"
00025 #include "llvm/Target/TargetData.h"
00026 using namespace llvm;
00027 
00028 //===----------------------------------------------------------------------===//
00029 //  Result Vector Scalarization: <1 x ty> -> ty.
00030 //===----------------------------------------------------------------------===//
00031 
00032 void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
00033   DEBUG(cerr << "Scalarize node result " << ResNo << ": "; N->dump(&DAG);
00034         cerr << "\n");
00035   SDValue R = SDValue();
00036 
00037   switch (N->getOpcode()) {
00038   default:
00039 #ifndef NDEBUG
00040     cerr << "ScalarizeVectorResult #" << ResNo << ": ";
00041     N->dump(&DAG); cerr << "\n";
00042 #endif
00043     assert(0 && "Do not know how to scalarize the result of this operator!");
00044     abort();
00045 
00046   case ISD::BIT_CONVERT:       R = ScalarizeVecRes_BIT_CONVERT(N); break;
00047   case ISD::BUILD_VECTOR:      R = N->getOperand(0); break;
00048   case ISD::CONVERT_RNDSAT:    R = ScalarizeVecRes_CONVERT_RNDSAT(N); break;
00049   case ISD::EXTRACT_SUBVECTOR: R = ScalarizeVecRes_EXTRACT_SUBVECTOR(N); break;
00050   case ISD::FPOWI:             R = ScalarizeVecRes_FPOWI(N); break;
00051   case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break;
00052   case ISD::LOAD:           R = ScalarizeVecRes_LOAD(cast<LoadSDNode>(N));break;
00053   case ISD::SCALAR_TO_VECTOR:  R = ScalarizeVecRes_SCALAR_TO_VECTOR(N); break;
00054   case ISD::SELECT:            R = ScalarizeVecRes_SELECT(N); break;
00055   case ISD::SELECT_CC:         R = ScalarizeVecRes_SELECT_CC(N); break;
00056   case ISD::UNDEF:             R = ScalarizeVecRes_UNDEF(N); break;
00057   case ISD::VECTOR_SHUFFLE:    R = ScalarizeVecRes_VECTOR_SHUFFLE(N); break;
00058   case ISD::VSETCC:            R = ScalarizeVecRes_VSETCC(N); break;
00059 
00060   case ISD::CTLZ:
00061   case ISD::CTPOP:
00062   case ISD::CTTZ:
00063   case ISD::FABS:
00064   case ISD::FCOS:
00065   case ISD::FNEG:
00066   case ISD::FP_TO_SINT:
00067   case ISD::FP_TO_UINT:
00068   case ISD::FSIN:
00069   case ISD::FSQRT:
00070   case ISD::FTRUNC:
00071   case ISD::FFLOOR:
00072   case ISD::FCEIL:
00073   case ISD::FRINT:
00074   case ISD::FNEARBYINT:
00075   case ISD::SINT_TO_FP:
00076   case ISD::TRUNCATE:
00077   case ISD::UINT_TO_FP: R = ScalarizeVecRes_UnaryOp(N); break;
00078 
00079   case ISD::ADD:
00080   case ISD::AND:
00081   case ISD::FADD:
00082   case ISD::FDIV:
00083   case ISD::FMUL:
00084   case ISD::FPOW:
00085   case ISD::FREM:
00086   case ISD::FSUB:
00087   case ISD::MUL:
00088   case ISD::OR:
00089   case ISD::SDIV:
00090   case ISD::SREM:
00091   case ISD::SUB:
00092   case ISD::UDIV:
00093   case ISD::UREM:
00094   case ISD::XOR:  R = ScalarizeVecRes_BinOp(N); break;
00095 
00096   case ISD::SHL:
00097   case ISD::SRA:
00098   case ISD::SRL: R = ScalarizeVecRes_ShiftOp(N); break;
00099   }
00100 
00101   // If R is null, the sub-method took care of registering the result.
00102   if (R.getNode())
00103     SetScalarizedVector(SDValue(N, ResNo), R);
00104 }
00105 
00106 SDValue DAGTypeLegalizer::ScalarizeVecRes_BinOp(SDNode *N) {
00107   SDValue LHS = GetScalarizedVector(N->getOperand(0));
00108   SDValue RHS = GetScalarizedVector(N->getOperand(1));
00109   return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
00110                      LHS.getValueType(), LHS, RHS);
00111 }
00112 
00113 SDValue DAGTypeLegalizer::ScalarizeVecRes_ShiftOp(SDNode *N) {
00114   SDValue LHS = GetScalarizedVector(N->getOperand(0));
00115   SDValue ShiftAmt = GetScalarizedVector(N->getOperand(1));
00116   return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
00117                      LHS.getValueType(), LHS, ShiftAmt);
00118 }
00119 
00120 SDValue DAGTypeLegalizer::ScalarizeVecRes_BIT_CONVERT(SDNode *N) {
00121   MVT NewVT = N->getValueType(0).getVectorElementType();
00122   return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(),
00123                      NewVT, N->getOperand(0));
00124 }
00125 
00126 SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_RNDSAT(SDNode *N) {
00127   MVT NewVT = N->getValueType(0).getVectorElementType();
00128   SDValue Op0 = GetScalarizedVector(N->getOperand(0));
00129   return DAG.getConvertRndSat(NewVT, Op0, DAG.getValueType(NewVT),
00130                               DAG.getValueType(Op0.getValueType()),
00131                               N->getOperand(3),
00132                               N->getOperand(4),
00133                               cast<CvtRndSatSDNode>(N)->getCvtCode());
00134 }
00135 
00136 SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N) {
00137   return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, N->getDebugLoc(),
00138                      N->getValueType(0).getVectorElementType(),
00139                      N->getOperand(0), N->getOperand(1));
00140 }
00141 
00142 SDValue DAGTypeLegalizer::ScalarizeVecRes_FPOWI(SDNode *N) {
00143   SDValue Op = GetScalarizedVector(N->getOperand(0));
00144   return DAG.getNode(ISD::FPOWI, N->getDebugLoc(),
00145                      Op.getValueType(), Op, N->getOperand(1));
00146 }
00147 
00148 SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N) {
00149   // The value to insert may have a wider type than the vector element type,
00150   // so be sure to truncate it to the element type if necessary.
00151   SDValue Op = N->getOperand(1);
00152   MVT EltVT = N->getValueType(0).getVectorElementType();
00153   if (Op.getValueType() != EltVT)
00154     // FIXME: Can this happen for floating point types?
00155     Op = DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), EltVT, Op);
00156   return Op;
00157 }
00158 
00159 SDValue DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) {
00160   assert(N->isUnindexed() && "Indexed vector load?");
00161 
00162   SDValue Result = DAG.getLoad(ISD::UNINDEXED, N->getDebugLoc(),
00163                                N->getExtensionType(),
00164                                N->getValueType(0).getVectorElementType(),
00165                                N->getChain(), N->getBasePtr(),
00166                                DAG.getNode(ISD::UNDEF, N->getDebugLoc(),
00167                                            N->getBasePtr().getValueType()),
00168                                N->getSrcValue(), N->getSrcValueOffset(),
00169                                N->getMemoryVT().getVectorElementType(),
00170                                N->isVolatile(), N->getAlignment());
00171 
00172   // Legalized the chain result - switch anything that used the old chain to
00173   // use the new one.
00174   ReplaceValueWith(SDValue(N, 1), Result.getValue(1));
00175   return Result;
00176 }
00177 
00178 SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(SDNode *N) {
00179   // Get the dest type - it doesn't always match the input type, e.g. int_to_fp.
00180   MVT DestVT = N->getValueType(0).getVectorElementType();
00181   SDValue Op = GetScalarizedVector(N->getOperand(0));
00182   return DAG.getNode(N->getOpcode(), N->getDebugLoc(), DestVT, Op);
00183 }
00184 
00185 SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N) {
00186   return N->getOperand(0);
00187 }
00188 
00189 SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT(SDNode *N) {
00190   SDValue LHS = GetScalarizedVector(N->getOperand(1));
00191   return DAG.getNode(ISD::SELECT, N->getDebugLoc(),
00192                      LHS.getValueType(), N->getOperand(0), LHS,
00193                      GetScalarizedVector(N->getOperand(2)));
00194 }
00195 
00196 SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT_CC(SDNode *N) {
00197   SDValue LHS = GetScalarizedVector(N->getOperand(2));
00198   return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), LHS.getValueType(),
00199                      N->getOperand(0), N->getOperand(1),
00200                      LHS, GetScalarizedVector(N->getOperand(3)),
00201                      N->getOperand(4));
00202 }
00203 
00204 SDValue DAGTypeLegalizer::ScalarizeVecRes_UNDEF(SDNode *N) {
00205   return DAG.getNode(ISD::UNDEF, N->getDebugLoc(),
00206                      N->getValueType(0).getVectorElementType());
00207 }
00208 
00209 SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N) {
00210   // Figure out if the scalar is the LHS or RHS and return it.
00211   SDValue Arg = N->getOperand(2).getOperand(0);
00212   if (Arg.getOpcode() == ISD::UNDEF)
00213     return DAG.getNode(ISD::UNDEF, N->getDebugLoc(),
00214                        N->getValueType(0).getVectorElementType());
00215   unsigned Op = !cast<ConstantSDNode>(Arg)->isNullValue();
00216   return GetScalarizedVector(N->getOperand(Op));
00217 }
00218 
00219 SDValue DAGTypeLegalizer::ScalarizeVecRes_VSETCC(SDNode *N) {
00220   SDValue LHS = GetScalarizedVector(N->getOperand(0));
00221   SDValue RHS = GetScalarizedVector(N->getOperand(1));
00222   MVT NVT = N->getValueType(0).getVectorElementType();
00223   MVT SVT = TLI.getSetCCResultType(LHS.getValueType());
00224   DebugLoc dl = N->getDebugLoc();
00225 
00226   // Turn it into a scalar SETCC.
00227   SDValue Res = DAG.getNode(ISD::SETCC, dl, SVT, LHS, RHS, N->getOperand(2));
00228 
00229   // VSETCC always returns a sign-extended value, while SETCC may not.  The
00230   // SETCC result type may not match the vector element type.  Correct these.
00231   if (NVT.bitsLE(SVT)) {
00232     // The SETCC result type is bigger than the vector element type.
00233     // Ensure the SETCC result is sign-extended.
00234     if (TLI.getBooleanContents() !=
00235         TargetLowering::ZeroOrNegativeOneBooleanContent)
00236       Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, SVT, Res,
00237                         DAG.getValueType(MVT::i1));
00238     // Truncate to the final type.
00239     return DAG.getNode(ISD::TRUNCATE, dl, NVT, Res);
00240   } else {
00241     // The SETCC result type is smaller than the vector element type.
00242     // If the SetCC result is not sign-extended, chop it down to MVT::i1.
00243     if (TLI.getBooleanContents() !=
00244         TargetLowering::ZeroOrNegativeOneBooleanContent)
00245       Res = DAG.getNode(ISD::TRUNCATE, dl, MVT::i1, Res);
00246     // Sign extend to the final type.
00247     return DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, Res);
00248   }
00249 }
00250 
00251 
00252 //===----------------------------------------------------------------------===//
00253 //  Operand Vector Scalarization <1 x ty> -> ty.
00254 //===----------------------------------------------------------------------===//
00255 
00256 bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) {
00257   DEBUG(cerr << "Scalarize node operand " << OpNo << ": "; N->dump(&DAG);
00258         cerr << "\n");
00259   SDValue Res = SDValue();
00260 
00261   if (Res.getNode() == 0) {
00262     switch (N->getOpcode()) {
00263     default:
00264 #ifndef NDEBUG
00265       cerr << "ScalarizeVectorOperand Op #" << OpNo << ": ";
00266       N->dump(&DAG); cerr << "\n";
00267 #endif
00268       assert(0 && "Do not know how to scalarize this operator's operand!");
00269       abort();
00270 
00271     case ISD::BIT_CONVERT:
00272       Res = ScalarizeVecOp_BIT_CONVERT(N); break;
00273 
00274     case ISD::CONCAT_VECTORS:
00275       Res = ScalarizeVecOp_CONCAT_VECTORS(N); break;
00276 
00277     case ISD::EXTRACT_VECTOR_ELT:
00278       Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(N); break;
00279 
00280     case ISD::STORE:
00281       Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(N), OpNo); break;
00282     }
00283   }
00284 
00285   // If the result is null, the sub-method took care of registering results etc.
00286   if (!Res.getNode()) return false;
00287 
00288   // If the result is N, the sub-method updated N in place.  Tell the legalizer
00289   // core about this.
00290   if (Res.getNode() == N)
00291     return true;
00292 
00293   assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
00294          "Invalid operand expansion");
00295 
00296   ReplaceValueWith(SDValue(N, 0), Res);
00297   return false;
00298 }
00299 
00300 /// ScalarizeVecOp_BIT_CONVERT - If the value to convert is a vector that needs
00301 /// to be scalarized, it must be <1 x ty>.  Convert the element instead.
00302 SDValue DAGTypeLegalizer::ScalarizeVecOp_BIT_CONVERT(SDNode *N) {
00303   SDValue Elt = GetScalarizedVector(N->getOperand(0));
00304   return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(),
00305                      N->getValueType(0), Elt);
00306 }
00307 
00308 /// ScalarizeVecOp_CONCAT_VECTORS - The vectors to concatenate have length one -
00309 /// use a BUILD_VECTOR instead.
00310 SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(SDNode *N) {
00311   SmallVector<SDValue, 8> Ops(N->getNumOperands());
00312   for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i)
00313     Ops[i] = GetScalarizedVector(N->getOperand(i));
00314   return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), N->getValueType(0),
00315                      &Ops[0], Ops.size());
00316 }
00317 
00318 /// ScalarizeVecOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to
00319 /// be scalarized, it must be <1 x ty>, so just return the element, ignoring the
00320 /// index.
00321 SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
00322   return GetScalarizedVector(N->getOperand(0));
00323 }
00324 
00325 /// ScalarizeVecOp_STORE - If the value to store is a vector that needs to be
00326 /// scalarized, it must be <1 x ty>.  Just store the element.
00327 SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){
00328   assert(N->isUnindexed() && "Indexed store of one-element vector?");
00329   assert(OpNo == 1 && "Do not know how to scalarize this operand!");
00330   DebugLoc dl = N->getDebugLoc();
00331 
00332   if (N->isTruncatingStore())
00333     return DAG.getTruncStore(N->getChain(), dl,
00334                              GetScalarizedVector(N->getOperand(1)),
00335                              N->getBasePtr(),
00336                              N->getSrcValue(), N->getSrcValueOffset(),
00337                              N->getMemoryVT().getVectorElementType(),
00338                              N->isVolatile(), N->getAlignment());
00339 
00340   return DAG.getStore(N->getChain(), dl, GetScalarizedVector(N->getOperand(1)),
00341                       N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(),
00342                       N->isVolatile(), N->getAlignment());
00343 }
00344 
00345 
00346 //===----------------------------------------------------------------------===//
00347 //  Result Vector Splitting
00348 //===----------------------------------------------------------------------===//
00349 
00350 /// SplitVectorResult - This method is called when the specified result of the
00351 /// specified node is found to need vector splitting.  At this point, the node
00352 /// may also have invalid operands or may have other results that need
00353 /// legalization, we just know that (at least) one result needs vector
00354 /// splitting.
00355 void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
00356   DEBUG(cerr << "Split node result: "; N->dump(&DAG); cerr << "\n");
00357   SDValue Lo, Hi;
00358 
00359   switch (N->getOpcode()) {
00360   default:
00361 #ifndef NDEBUG
00362     cerr << "SplitVectorResult #" << ResNo << ": ";
00363     N->dump(&DAG); cerr << "\n";
00364 #endif
00365     assert(0 && "Do not know how to split the result of this operator!");
00366     abort();
00367 
00368   case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break;
00369   case ISD::SELECT:       SplitRes_SELECT(N, Lo, Hi); break;
00370   case ISD::SELECT_CC:    SplitRes_SELECT_CC(N, Lo, Hi); break;
00371   case ISD::UNDEF:        SplitRes_UNDEF(N, Lo, Hi); break;
00372 
00373   case ISD::BIT_CONVERT:       SplitVecRes_BIT_CONVERT(N, Lo, Hi); break;
00374   case ISD::BUILD_VECTOR:      SplitVecRes_BUILD_VECTOR(N, Lo, Hi); break;
00375   case ISD::CONCAT_VECTORS:    SplitVecRes_CONCAT_VECTORS(N, Lo, Hi); break;
00376   case ISD::CONVERT_RNDSAT:    SplitVecRes_CONVERT_RNDSAT(N, Lo, Hi); break;
00377   case ISD::EXTRACT_SUBVECTOR: SplitVecRes_EXTRACT_SUBVECTOR(N, Lo, Hi); break;
00378   case ISD::FPOWI:             SplitVecRes_FPOWI(N, Lo, Hi); break;
00379   case ISD::INSERT_VECTOR_ELT: SplitVecRes_INSERT_VECTOR_ELT(N, Lo, Hi); break;
00380   case ISD::SCALAR_TO_VECTOR:  SplitVecRes_SCALAR_TO_VECTOR(N, Lo, Hi); break;
00381   case ISD::LOAD:              SplitVecRes_LOAD(cast<LoadSDNode>(N), Lo, Hi);break;
00382   case ISD::VECTOR_SHUFFLE:    SplitVecRes_VECTOR_SHUFFLE(N, Lo, Hi); break;
00383   case ISD::VSETCC:            SplitVecRes_VSETCC(N, Lo, Hi); break;
00384 
00385   case ISD::CTTZ:
00386   case ISD::CTLZ:
00387   case ISD::CTPOP:
00388   case ISD::FNEG:
00389   case ISD::FABS:
00390   case ISD::FSQRT:
00391   case ISD::FSIN:
00392   case ISD::FCOS:
00393   case ISD::FTRUNC:
00394   case ISD::FFLOOR:
00395   case ISD::FCEIL:
00396   case ISD::FRINT:
00397   case ISD::FNEARBYINT:
00398   case ISD::FP_TO_SINT:
00399   case ISD::FP_TO_UINT:
00400   case ISD::SINT_TO_FP:
00401   case ISD::TRUNCATE:
00402   case ISD::UINT_TO_FP: SplitVecRes_UnaryOp(N, Lo, Hi); break;
00403 
00404   case ISD::ADD:
00405   case ISD::SUB:
00406   case ISD::MUL:
00407   case ISD::FADD:
00408   case ISD::FSUB:
00409   case ISD::FMUL:
00410   case ISD::SDIV:
00411   case ISD::UDIV:
00412   case ISD::FDIV:
00413   case ISD::FPOW:
00414   case ISD::AND:
00415   case ISD::OR:
00416   case ISD::XOR:
00417   case ISD::SHL:
00418   case ISD::SRA:
00419   case ISD::SRL:
00420   case ISD::UREM:
00421   case ISD::SREM:
00422   case ISD::FREM: SplitVecRes_BinOp(N, Lo, Hi); break;
00423   }
00424 
00425   // If Lo/Hi is null, the sub-method took care of registering results etc.
00426   if (Lo.getNode())
00427     SetSplitVector(SDValue(N, ResNo), Lo, Hi);
00428 }
00429 
00430 void DAGTypeLegalizer::SplitVecRes_BinOp(SDNode *N, SDValue &Lo,
00431                                          SDValue &Hi) {
00432   SDValue LHSLo, LHSHi;
00433   GetSplitVector(N->getOperand(0), LHSLo, LHSHi);
00434   SDValue RHSLo, RHSHi;
00435   GetSplitVector(N->getOperand(1), RHSLo, RHSHi);
00436   DebugLoc dl = N->getDebugLoc();
00437 
00438   Lo = DAG.getNode(N->getOpcode(), dl, LHSLo.getValueType(), LHSLo, RHSLo);
00439   Hi = DAG.getNode(N->getOpcode(), dl, LHSHi.getValueType(), LHSHi, RHSHi);
00440 }
00441 
00442 void DAGTypeLegalizer::SplitVecRes_BIT_CONVERT(SDNode *N, SDValue &Lo,
00443                                                SDValue &Hi) {
00444   // We know the result is a vector.  The input may be either a vector or a
00445   // scalar value.
00446   MVT LoVT, HiVT;
00447   GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
00448   DebugLoc dl = N->getDebugLoc();
00449 
00450   SDValue InOp = N->getOperand(0);
00451   MVT InVT = InOp.getValueType();
00452 
00453   // Handle some special cases efficiently.
00454   switch (getTypeAction(InVT)) {
00455   default:
00456     assert(false && "Unknown type action!");
00457   case Legal:
00458   case PromoteInteger:
00459   case SoftenFloat:
00460   case ScalarizeVector:
00461     break;
00462   case ExpandInteger:
00463   case ExpandFloat:
00464     // A scalar to vector conversion, where the scalar needs expansion.
00465     // If the vector is being split in two then we can just convert the
00466     // expanded pieces.
00467     if (LoVT == HiVT) {
00468       GetExpandedOp(InOp, Lo, Hi);
00469       if (TLI.isBigEndian())
00470         std::swap(Lo, Hi);
00471       Lo = DAG.getNode(ISD::BIT_CONVERT, dl, LoVT, Lo);
00472       Hi = DAG.getNode(ISD::BIT_CONVERT, dl, HiVT, Hi);
00473       return;
00474     }
00475     break;
00476   case SplitVector:
00477     // If the input is a vector that needs to be split, convert each split
00478     // piece of the input now.
00479     GetSplitVector(InOp, Lo, Hi);
00480     Lo = DAG.getNode(ISD::BIT_CONVERT, dl, LoVT, Lo);
00481     Hi = DAG.getNode(ISD::BIT_CONVERT, dl, HiVT, Hi);
00482     return;
00483   }
00484 
00485   // In the general case, convert the input to an integer and split it by hand.
00486   MVT LoIntVT = MVT::getIntegerVT(LoVT.getSizeInBits());
00487   MVT HiIntVT = MVT::getIntegerVT(HiVT.getSizeInBits());
00488   if (TLI.isBigEndian())
00489     std::swap(LoIntVT, HiIntVT);
00490 
00491   SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT, Lo, Hi);
00492 
00493   if (TLI.isBigEndian())
00494     std::swap(Lo, Hi);
00495   Lo = DAG.getNode(ISD::BIT_CONVERT, dl, LoVT, Lo);
00496   Hi = DAG.getNode(ISD::BIT_CONVERT, dl, HiVT, Hi);
00497 }
00498 
00499 void DAGTypeLegalizer::SplitVecRes_BUILD_VECTOR(SDNode *N, SDValue &Lo,
00500                                                 SDValue &Hi) {
00501   MVT LoVT, HiVT;
00502   DebugLoc dl = N->getDebugLoc();
00503   GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
00504   unsigned LoNumElts = LoVT.getVectorNumElements();
00505   SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+LoNumElts);
00506   Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, LoVT, &LoOps[0], LoOps.size());
00507 
00508   SmallVector<SDValue, 8> HiOps(N->op_begin()+LoNumElts, N->op_end());
00509   Hi = DAG.getNode(ISD::BUILD_VECTOR, dl, HiVT, &HiOps[0], HiOps.size());
00510 }
00511 
00512 void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo,
00513                                                   SDValue &Hi) {
00514   assert(!(N->getNumOperands() & 1) && "Unsupported CONCAT_VECTORS");
00515   DebugLoc dl = N->getDebugLoc();
00516   unsigned NumSubvectors = N->getNumOperands() / 2;
00517   if (NumSubvectors == 1) {
00518     Lo = N->getOperand(0);
00519     Hi = N->getOperand(1);
00520     return;
00521   }
00522 
00523   MVT LoVT, HiVT;
00524   GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
00525 
00526   SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+NumSubvectors);
00527   Lo = DAG.getNode(ISD::CONCAT_VECTORS, dl, LoVT, &LoOps[0], LoOps.size());
00528 
00529   SmallVector<SDValue, 8> HiOps(N->op_begin()+NumSubvectors, N->op_end());
00530   Hi = DAG.getNode(ISD::CONCAT_VECTORS, dl, HiVT, &HiOps[0], HiOps.size());
00531 }
00532 
00533 void DAGTypeLegalizer::SplitVecRes_CONVERT_RNDSAT(SDNode *N, SDValue &Lo,
00534                                                   SDValue &Hi) {
00535   MVT LoVT, HiVT;
00536   GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
00537   SDValue VLo, VHi;
00538   GetSplitVector(N->getOperand(0), VLo, VHi);
00539   SDValue DTyOpLo =  DAG.getValueType(LoVT);
00540   SDValue DTyOpHi =  DAG.getValueType(HiVT);
00541   SDValue STyOpLo =  DAG.getValueType(VLo.getValueType());
00542   SDValue STyOpHi =  DAG.getValueType(VHi.getValueType());
00543 
00544   SDValue RndOp = N->getOperand(3);
00545   SDValue SatOp = N->getOperand(4);
00546   ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode();
00547 
00548   Lo = DAG.getConvertRndSat(LoVT, VLo, DTyOpLo, STyOpLo, RndOp, SatOp, CvtCode);
00549   Hi = DAG.getConvertRndSat(HiVT, VHi, DTyOpHi, STyOpHi, RndOp, SatOp, CvtCode);
00550 }
00551 
00552 void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo,
00553                                                      SDValue &Hi) {
00554   SDValue Vec = N->getOperand(0);
00555   SDValue Idx = N->getOperand(1);
00556   MVT IdxVT = Idx.getValueType();
00557   DebugLoc dl = N->getDebugLoc();
00558 
00559   MVT LoVT, HiVT;
00560   GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
00561   // The indices are not guaranteed to be a multiple of the new vector
00562   // size unless the original vector type was split in two.
00563   assert(LoVT == HiVT && "Non power-of-two vectors not supported!");
00564 
00565   Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, LoVT, Vec, Idx);
00566   Idx = DAG.getNode(ISD::ADD, dl, IdxVT, Idx,
00567                     DAG.getConstant(LoVT.getVectorNumElements(), IdxVT));
00568   Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HiVT, Vec, Idx);
00569 }
00570 
00571 void DAGTypeLegalizer::SplitVecRes_FPOWI(SDNode *N, SDValue &Lo,
00572                                          SDValue &Hi) {
00573   DebugLoc dl = N->getDebugLoc();
00574   GetSplitVector(N->getOperand(0), Lo, Hi);
00575   Lo = DAG.getNode(ISD::FPOWI, dl, Lo.getValueType(), Lo, N->getOperand(1));
00576   Hi = DAG.getNode(ISD::FPOWI, dl, Hi.getValueType(), Hi, N->getOperand(1));
00577 }
00578 
00579 void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
00580                                                      SDValue &Hi) {
00581   SDValue Vec = N->getOperand(0);
00582   SDValue Elt = N->getOperand(1);
00583   SDValue Idx = N->getOperand(2);
00584   DebugLoc dl = N->getDebugLoc();
00585   GetSplitVector(Vec, Lo, Hi);
00586 
00587   if (ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Idx)) {
00588     unsigned IdxVal = CIdx->getZExtValue();
00589     unsigned LoNumElts = Lo.getValueType().getVectorNumElements();
00590     if (IdxVal < LoNumElts)
00591       Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl,
00592                        Lo.getValueType(), Lo, Elt, Idx);
00593     else
00594       Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, Hi.getValueType(), Hi, Elt,
00595                        DAG.getIntPtrConstant(IdxVal - LoNumElts));
00596     return;
00597   }
00598 
00599   // Spill the vector to the stack.
00600   MVT VecVT = Vec.getValueType();
00601   MVT EltVT = VecVT.getVectorElementType();
00602   SDValue StackPtr = DAG.CreateStackTemporary(VecVT);
00603   SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0);
00604 
00605   // Store the new element.  This may be larger than the vector element type,
00606   // so use a truncating store.
00607   SDValue EltPtr = GetVectorElementPointer(StackPtr, EltVT, Idx);
00608   unsigned Alignment =
00609     TLI.getTargetData()->getPrefTypeAlignment(VecVT.getTypeForMVT());
00610   Store = DAG.getTruncStore(Store, dl, Elt, EltPtr, NULL, 0, EltVT);
00611 
00612   // Load the Lo part from the stack slot.
00613   Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, NULL, 0);
00614 
00615   // Increment the pointer to the other part.
00616   unsigned IncrementSize = Lo.getValueType().getSizeInBits() / 8;
00617   StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
00618                          DAG.getIntPtrConstant(IncrementSize));
00619 
00620   // Load the Hi part from the stack slot.
00621   Hi = DAG.getLoad(Hi.getValueType(), dl, Store, StackPtr, NULL, 0, false,
00622                    MinAlign(Alignment, IncrementSize));
00623 }
00624 
00625 void DAGTypeLegalizer::SplitVecRes_SCALAR_TO_VECTOR(SDNode *N, SDValue &Lo,
00626                                                     SDValue &Hi) {
00627   MVT LoVT, HiVT;
00628   DebugLoc dl = N->getDebugLoc();
00629   GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
00630   Lo = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, LoVT, N->getOperand(0));
00631   Hi = DAG.getNode(ISD::UNDEF, dl, HiVT);
00632 }
00633 
00634 void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo,
00635                                         SDValue &Hi) {
00636   assert(ISD::isUNINDEXEDLoad(LD) && "Indexed load during type legalization!");
00637   MVT LoVT, HiVT;
00638   DebugLoc dl = LD->getDebugLoc();
00639   GetSplitDestVTs(LD->getValueType(0), LoVT, HiVT);
00640 
00641   ISD::LoadExtType ExtType = LD->getExtensionType();
00642   SDValue Ch = LD->getChain();
00643   SDValue Ptr = LD->getBasePtr();
00644   SDValue Offset = DAG.getNode(ISD::UNDEF, Ptr.getValueType());
00645   const Value *SV = LD->getSrcValue();
00646   int SVOffset = LD->getSrcValueOffset();
00647   MVT MemoryVT = LD->getMemoryVT();
00648   unsigned Alignment = LD->getAlignment();
00649   bool isVolatile = LD->isVolatile();
00650 
00651   MVT LoMemVT, HiMemVT;
00652   GetSplitDestVTs(MemoryVT, LoMemVT, HiMemVT);
00653 
00654   Lo = DAG.getLoad(ISD::UNINDEXED, dl, ExtType, LoVT, Ch, Ptr, Offset,
00655                    SV, SVOffset, LoMemVT, isVolatile, Alignment);
00656 
00657   unsigned IncrementSize = LoMemVT.getSizeInBits()/8;
00658   Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
00659                     DAG.getIntPtrConstant(IncrementSize));
00660   SVOffset += IncrementSize;
00661   Alignment = MinAlign(Alignment, IncrementSize);
00662   Hi = DAG.getLoad(ISD::UNINDEXED, dl, ExtType, HiVT, Ch, Ptr, Offset,
00663                    SV, SVOffset, HiMemVT, isVolatile, Alignment);
00664 
00665   // Build a factor node to remember that this load is independent of the
00666   // other one.
00667   Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
00668                    Hi.getValue(1));
00669 
00670   // Legalized the chain result - switch anything that used the old chain to
00671   // use the new one.
00672   ReplaceValueWith(SDValue(LD, 1), Ch);
00673 }
00674 
00675 void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo,
00676                                            SDValue &Hi) {
00677   // Get the dest types - they may not match the input types, e.g. int_to_fp.
00678   MVT LoVT, HiVT;
00679   DebugLoc dl = N->getDebugLoc();
00680   GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
00681 
00682   // Split the input.
00683   MVT InVT = N->getOperand(0).getValueType();
00684   switch (getTypeAction(InVT)) {
00685   default: assert(0 && "Unexpected type action!");
00686   case Legal: {
00687     assert(LoVT == HiVT && "Legal non-power-of-two vector type?");
00688     MVT InNVT = MVT::getVectorVT(InVT.getVectorElementType(),
00689                                  LoVT.getVectorNumElements());
00690     Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InNVT, N->getOperand(0),
00691                      DAG.getIntPtrConstant(0));
00692     Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InNVT, N->getOperand(0),
00693                      DAG.getIntPtrConstant(InNVT.getVectorNumElements()));
00694     break;
00695   }
00696   case SplitVector:
00697     GetSplitVector(N->getOperand(0), Lo, Hi);
00698     break;
00699   }
00700 
00701   Lo = DAG.getNode(N->getOpcode(), dl, LoVT, Lo);
00702   Hi = DAG.getNode(N->getOpcode(), dl, HiVT, Hi);
00703 }
00704 
00705 void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo,
00706                                                   SDValue &Hi) {
00707   // The low and high parts of the original input give four input vectors.
00708   SDValue Inputs[4];
00709   DebugLoc dl = N->getDebugLoc();
00710   GetSplitVector(N->getOperand(0), Inputs[0], Inputs[1]);
00711   GetSplitVector(N->getOperand(1), Inputs[2], Inputs[3]);
00712   MVT NewVT = Inputs[0].getValueType();
00713   unsigned NewElts = NewVT.getVectorNumElements();
00714   assert(NewVT == Inputs[1].getValueType() &&
00715          "Non power-of-two vectors not supported!");
00716 
00717   // If Lo or Hi uses elements from at most two of the four input vectors, then
00718   // express it as a vector shuffle of those two inputs.  Otherwise extract the
00719   // input elements by hand and construct the Lo/Hi output using a BUILD_VECTOR.
00720   SDValue Mask = N->getOperand(2);
00721   MVT IdxVT = Mask.getValueType().getVectorElementType();
00722   SmallVector<SDValue, 16> Ops;
00723   Ops.reserve(NewElts);
00724   for (unsigned High = 0; High < 2; ++High) {
00725     SDValue &Output = High ? Hi : Lo;
00726 
00727     // Build a shuffle mask for the output, discovering on the fly which
00728     // input vectors to use as shuffle operands (recorded in InputUsed).
00729     // If building a suitable shuffle vector proves too hard, then bail
00730     // out with useBuildVector set.
00731     unsigned InputUsed[2] = { -1U, -1U }; // Not yet discovered.
00732     unsigned FirstMaskIdx = High * NewElts;
00733     bool useBuildVector = false;
00734     for (unsigned MaskOffset = 0; MaskOffset < NewElts; ++MaskOffset) {
00735       SDValue Arg = Mask.getOperand(FirstMaskIdx + MaskOffset);
00736 
00737       // The mask element.  This indexes into the input.
00738       unsigned Idx = Arg.getOpcode() == ISD::UNDEF ?
00739         -1U : cast<ConstantSDNode>(Arg)->getZExtValue();
00740 
00741       // The input vector this mask element indexes into.
00742       unsigned Input = Idx / NewElts;
00743 
00744       if (Input >= array_lengthof(Inputs)) {
00745         // The mask element does not index into any input vector.
00746         Ops.push_back(DAG.getNode(ISD::UNDEF, dl, IdxVT));
00747         continue;
00748       }
00749 
00750       // Turn the index into an offset from the start of the input vector.
00751       Idx -= Input * NewElts;
00752 
00753       // Find or create a shuffle vector operand to hold this input.
00754       unsigned OpNo;
00755       for (OpNo = 0; OpNo < array_lengthof(InputUsed); ++OpNo) {
00756         if (InputUsed[OpNo] == Input) {
00757           // This input vector is already an operand.
00758           break;
00759         } else if (InputUsed[OpNo] == -1U) {
00760           // Create a new operand for this input vector.
00761           InputUsed[OpNo] = Input;
00762           break;
00763         }
00764       }
00765 
00766       if (OpNo >= array_lengthof(InputUsed)) {
00767         // More than two input vectors used!  Give up on trying to create a
00768         // shuffle vector.  Insert all elements into a BUILD_VECTOR instead.
00769         useBuildVector = true;
00770         break;
00771       }
00772 
00773       // Add the mask index for the new shuffle vector.
00774       Ops.push_back(DAG.getConstant(Idx + OpNo * NewElts, IdxVT));
00775     }
00776 
00777     if (useBuildVector) {
00778       MVT EltVT = NewVT.getVectorElementType();
00779       Ops.clear();
00780 
00781       // Extract the input elements by hand.
00782       for (unsigned MaskOffset = 0; MaskOffset < NewElts; ++MaskOffset) {
00783         SDValue Arg = Mask.getOperand(FirstMaskIdx + MaskOffset);
00784 
00785         // The mask element.  This indexes into the input.
00786         unsigned Idx = Arg.getOpcode() == ISD::UNDEF ?
00787           -1U : cast<ConstantSDNode>(Arg)->getZExtValue();
00788 
00789         // The input vector this mask element indexes into.
00790         unsigned Input = Idx / NewElts;
00791 
00792         if (Input >= array_lengthof(Inputs)) {
00793           // The mask element is "undef" or indexes off the end of the input.
00794           Ops.push_back(DAG.getNode(ISD::UNDEF, dl, EltVT));
00795           continue;
00796         }
00797 
00798         // Turn the index into an offset from the start of the input vector.
00799         Idx -= Input * NewElts;
00800 
00801         // Extract the vector element by hand.
00802         Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT,
00803                                   Inputs[Input], DAG.getIntPtrConstant(Idx)));
00804       }
00805 
00806       // Construct the Lo/Hi output using a BUILD_VECTOR.
00807       Output = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT, &Ops[0], Ops.size());
00808     } else if (InputUsed[0] == -1U) {
00809       // No input vectors were used!  The result is undefined.
00810       Output = DAG.getNode(ISD::UNDEF, dl, NewVT);
00811     } else {
00812       // At least one input vector was used.  Create a new shuffle vector.
00813       SDValue NewMask = DAG.getNode(ISD::BUILD_VECTOR, dl,
00814                                     MVT::getVectorVT(IdxVT, Ops.size()),
00815                                     &Ops[0], Ops.size());
00816       SDValue Op0 = Inputs[InputUsed[0]];
00817       // If only one input was used, use an undefined vector for the other.
00818       SDValue Op1 = InputUsed[1] == -1U ?
00819         DAG.getNode(ISD::UNDEF, dl, NewVT) : Inputs[InputUsed[1]];
00820       Output = DAG.getNode(ISD::VECTOR_SHUFFLE, dl, NewVT, Op0, Op1, NewMask);
00821     }
00822 
00823     Ops.clear();
00824   }
00825 }
00826 
00827 void DAGTypeLegalizer::SplitVecRes_VSETCC(SDNode *N, SDValue &Lo,
00828                                           SDValue &Hi) {
00829   MVT LoVT, HiVT;
00830   DebugLoc dl = N->getDebugLoc();
00831   GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
00832 
00833   SDValue LL, LH, RL, RH;
00834   GetSplitVector(N->getOperand(0), LL, LH);
00835   GetSplitVector(N->getOperand(1), RL, RH);
00836 
00837   Lo = DAG.getNode(ISD::VSETCC, dl, LoVT, LL, RL, N->getOperand(2));
00838   Hi = DAG.getNode(ISD::VSETCC, dl, HiVT, LH, RH, N->getOperand(2));
00839 }
00840 
00841 
00842 //===----------------------------------------------------------------------===//
00843 //  Operand Vector Splitting
00844 //===----------------------------------------------------------------------===//
00845 
00846 /// SplitVectorOperand - This method is called when the specified operand of the
00847 /// specified node is found to need vector splitting.  At this point, all of the
00848 /// result types of the node are known to be legal, but other operands of the
00849 /// node may need legalization as well as the specified one.
00850 bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) {
00851   DEBUG(cerr << "Split node operand: "; N->dump(&DAG); cerr << "\n");
00852   SDValue Res = SDValue();
00853 
00854   if (Res.getNode() == 0) {
00855     switch (N->getOpcode()) {
00856     default:
00857 #ifndef NDEBUG
00858       cerr << "SplitVectorOperand Op #" << OpNo << ": ";
00859       N->dump(&DAG); cerr << "\n";
00860 #endif
00861       assert(0 && "Do not know how to split this operator's operand!");
00862       abort();
00863 
00864     case ISD::BIT_CONVERT:       Res = SplitVecOp_BIT_CONVERT(N); break;
00865     case ISD::EXTRACT_SUBVECTOR: Res = SplitVecOp_EXTRACT_SUBVECTOR(N); break;
00866     case ISD::EXTRACT_VECTOR_ELT:Res = SplitVecOp_EXTRACT_VECTOR_ELT(N); break;
00867     case ISD::STORE:             Res = SplitVecOp_STORE(cast<StoreSDNode>(N),
00868                                                         OpNo); break;
00869     case ISD::VECTOR_SHUFFLE:    Res = SplitVecOp_VECTOR_SHUFFLE(N, OpNo);break;
00870 
00871     case ISD::CTTZ:
00872     case ISD::CTLZ:
00873     case ISD::CTPOP:
00874     case ISD::FP_TO_SINT:
00875     case ISD::FP_TO_UINT:
00876     case ISD::SINT_TO_FP:
00877     case ISD::TRUNCATE:
00878     case ISD::UINT_TO_FP: Res = SplitVecOp_UnaryOp(N); break;
00879     }
00880   }
00881 
00882   // If the result is null, the sub-method took care of registering results etc.
00883   if (!Res.getNode()) return false;
00884 
00885   // If the result is N, the sub-method updated N in place.  Tell the legalizer
00886   // core about this.
00887   if (Res.getNode() == N)
00888     return true;
00889 
00890   assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
00891          "Invalid operand expansion");
00892 
00893   ReplaceValueWith(SDValue(N, 0), Res);
00894   return false;
00895 }
00896 
00897 SDValue DAGTypeLegalizer::SplitVecOp_UnaryOp(SDNode *N) {
00898   // The result has a legal vector type, but the input needs splitting.
00899   MVT ResVT = N->getValueType(0);
00900   SDValue Lo, Hi;
00901   DebugLoc dl = N->getDebugLoc();
00902   GetSplitVector(N->getOperand(0), Lo, Hi);
00903   assert(Lo.getValueType() == Hi.getValueType() &&
00904          "Returns legal non-power-of-two vector type?");
00905   MVT InVT = Lo.getValueType();
00906 
00907   MVT OutVT = MVT::getVectorVT(ResVT.getVectorElementType(),
00908                                InVT.getVectorNumElements());
00909 
00910   Lo = DAG.getNode(N->getOpcode(), dl, OutVT, Lo);
00911   Hi = DAG.getNode(N->getOpcode(), dl, OutVT, Hi);
00912 
00913   return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi);
00914 }
00915 
00916 SDValue DAGTypeLegalizer::SplitVecOp_BIT_CONVERT(SDNode *N) {
00917   // For example, i64 = BIT_CONVERT v4i16 on alpha.  Typically the vector will
00918   // end up being split all the way down to individual components.  Convert the
00919   // split pieces into integers and reassemble.
00920   SDValue Lo, Hi;
00921   GetSplitVector(N->getOperand(0), Lo, Hi);
00922   Lo = BitConvertToInteger(Lo);
00923   Hi = BitConvertToInteger(Hi);
00924 
00925   if (TLI.isBigEndian())
00926     std::swap(Lo, Hi);
00927 
00928   return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), N->getValueType(0),
00929                      JoinIntegers(Lo, Hi));
00930 }
00931 
00932 SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N) {
00933   // We know that the extracted result type is legal.  For now, assume the index
00934   // is a constant.
00935   MVT SubVT = N->getValueType(0);
00936   SDValue Idx = N->getOperand(1);
00937   DebugLoc dl = N->getDebugLoc();
00938   SDValue Lo, Hi;
00939   GetSplitVector(N->getOperand(0), Lo, Hi);
00940 
00941   uint64_t LoElts = Lo.getValueType().getVectorNumElements();
00942   uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
00943 
00944   if (IdxVal < LoElts) {
00945     assert(IdxVal + SubVT.getVectorNumElements() <= LoElts &&
00946            "Extracted subvector crosses vector split!");
00947     return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Lo, Idx);
00948   } else {
00949     return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Hi,
00950                        DAG.getConstant(IdxVal - LoElts, Idx.getValueType()));
00951   }
00952 }
00953 
00954 SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
00955   SDValue Vec = N->getOperand(0);
00956   SDValue Idx = N->getOperand(1);
00957   MVT VecVT = Vec.getValueType();
00958 
00959   if (isa<ConstantSDNode>(Idx)) {
00960     uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
00961     assert(IdxVal < VecVT.getVectorNumElements() && "Invalid vector index!");
00962 
00963     SDValue Lo, Hi;
00964     GetSplitVector(Vec, Lo, Hi);
00965 
00966     uint64_t LoElts = Lo.getValueType().getVectorNumElements();
00967 
00968     if (IdxVal < LoElts)
00969       return DAG.UpdateNodeOperands(SDValue(N, 0), Lo, Idx);
00970     else
00971       return DAG.UpdateNodeOperands(SDValue(N, 0), Hi,
00972                                     DAG.getConstant(IdxVal - LoElts,
00973                                                     Idx.getValueType()));
00974   }
00975 
00976   // Store the vector to the stack.
00977   MVT EltVT = VecVT.getVectorElementType();
00978   DebugLoc dl = N->getDebugLoc();
00979   SDValue StackPtr = DAG.CreateStackTemporary(VecVT);
00980   int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
00981   const Value *SV = PseudoSourceValue::getFixedStack(SPFI);
00982   SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, SV, 0);
00983 
00984   // Load back the required element.
00985   StackPtr = GetVectorElementPointer(StackPtr, EltVT, Idx);
00986   return DAG.getLoad(EltVT, dl, Store, StackPtr, SV, 0);
00987 }
00988 
00989 SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
00990   assert(N->isUnindexed() && "Indexed store of vector?");
00991   assert(OpNo == 1 && "Can only split the stored value");
00992   DebugLoc dl = N->getDebugLoc();
00993 
00994   bool isTruncating = N->isTruncatingStore();
00995   SDValue Ch  = N->getChain();
00996   SDValue Ptr = N->getBasePtr();
00997   int SVOffset = N->getSrcValueOffset();
00998   MVT MemoryVT = N->getMemoryVT();
00999   unsigned Alignment = N->getAlignment();
01000   bool isVol = N->isVolatile();
01001   SDValue Lo, Hi;
01002   GetSplitVector(N->getOperand(1), Lo, Hi);
01003 
01004   MVT LoMemVT, HiMemVT;
01005   GetSplitDestVTs(MemoryVT, LoMemVT, HiMemVT);
01006 
01007   unsigned IncrementSize = LoMemVT.getSizeInBits()/8;
01008 
01009   if (isTruncating)
01010     Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
01011                            LoMemVT, isVol, Alignment);
01012   else
01013     Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
01014                       isVol, Alignment);
01015 
01016   // Increment the pointer to the other half.
01017   Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
01018                     DAG.getIntPtrConstant(IncrementSize));
01019 
01020   if (isTruncating)
01021     Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr,
01022                            N->getSrcValue(), SVOffset+IncrementSize,
01023                            HiMemVT,
01024                            isVol, MinAlign(Alignment, IncrementSize));
01025   else
01026     Hi = DAG.getStore(Ch, dl, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
01027                       isVol, MinAlign(Alignment, IncrementSize));
01028 
01029   return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
01030 }
01031 
01032 SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo) {
01033   assert(OpNo == 2 && "Shuffle source type differs from result type?");
01034   SDValue Mask = N->getOperand(2);
01035   DebugLoc dl = N->getDebugLoc();
01036   unsigned MaskLength = Mask.getValueType().getVectorNumElements();
01037   unsigned LargestMaskEntryPlusOne = 2 * MaskLength;
01038   unsigned MinimumBitWidth = Log2_32_Ceil(LargestMaskEntryPlusOne);
01039 
01040   // Look for a legal vector type to place the mask values in.
01041   // Note that there may not be *any* legal vector-of-integer
01042   // type for which the element type is legal!
01043   for (MVT::SimpleValueType EltVT = MVT::FIRST_INTEGER_VALUETYPE;
01044        EltVT <= MVT::LAST_INTEGER_VALUETYPE;
01045        // Integer values types are consecutively numbered.  Exploit this.
01046        EltVT = MVT::SimpleValueType(EltVT + 1)) {
01047 
01048     // Is the element type big enough to hold the values?
01049     if (MVT(EltVT).getSizeInBits() < MinimumBitWidth)
01050       // Nope.
01051       continue;
01052 
01053     // Is the vector type legal?
01054     MVT VecVT = MVT::getVectorVT(EltVT, MaskLength);
01055     if (!isTypeLegal(VecVT))
01056       // Nope.
01057       continue;
01058 
01059     // If the element type is not legal, find a larger legal type to use for
01060     // the BUILD_VECTOR operands.  This is an ugly hack, but seems to work!
01061     // FIXME: The real solution is to change VECTOR_SHUFFLE into a variadic
01062     // node where the shuffle mask is a list of integer operands, #2 .. #2+n.
01063     for (MVT::SimpleValueType OpVT = EltVT; OpVT <= MVT::LAST_INTEGER_VALUETYPE;
01064          // Integer values types are consecutively numbered.  Exploit this.
01065          OpVT = MVT::SimpleValueType(OpVT + 1)) {
01066       if (!isTypeLegal(OpVT))
01067         continue;
01068 
01069       // Success!  Rebuild the vector using the legal types.
01070       SmallVector<SDValue, 16> Ops(MaskLength);
01071       for (unsigned i = 0; i < MaskLength; ++i) {
01072         SDValue Arg = Mask.getOperand(i);
01073         if (Arg.getOpcode() == ISD::UNDEF) {
01074           Ops[i] = DAG.getNode(ISD::UNDEF, dl, OpVT);
01075         } else {
01076           uint64_t Idx = cast<ConstantSDNode>(Arg)->getZExtValue();
01077           Ops[i] = DAG.getConstant(Idx, OpVT);
01078         }
01079       }
01080       return DAG.UpdateNodeOperands(SDValue(N,0),
01081                                     N->getOperand(0), N->getOperand(1),
01082                                     DAG.getNode(ISD::BUILD_VECTOR, dl,
01083                                                 VecVT, &Ops[0], Ops.size()));
01084     }
01085 
01086     // Continuing is pointless - failure is certain.
01087     break;
01088   }
01089   assert(false && "Failed to find an appropriate mask type!");
01090   return SDValue(N, 0);
01091 }
01092 
01093 
01094 //===----------------------------------------------------------------------===//
01095 //  Result Vector Widening
01096 //===----------------------------------------------------------------------===//
01097 
01098 void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
01099   DEBUG(cerr << "Widen node result " << ResNo << ": "; N->dump(&DAG);
01100         cerr << "\n");
01101   SDValue Res = SDValue();
01102 
01103   switch (N->getOpcode()) {
01104   default:
01105 #ifndef NDEBUG
01106     cerr << "WidenVectorResult #" << ResNo << ": ";
01107     N->dump(&DAG); cerr << "\n";
01108 #endif
01109     assert(0 && "Do not know how to widen the result of this operator!");
01110     abort();
01111 
01112   case ISD::BIT_CONVERT:       Res = WidenVecRes_BIT_CONVERT(N); break;
01113   case ISD::BUILD_VECTOR:      Res = WidenVecRes_BUILD_VECTOR(N); break;
01114   case ISD::CONCAT_VECTORS:    Res = WidenVecRes_CONCAT_VECTORS(N); break;
01115   case ISD::CONVERT_RNDSAT:    Res = WidenVecRes_CONVERT_RNDSAT(N); break;
01116   case ISD::EXTRACT_SUBVECTOR: Res = WidenVecRes_EXTRACT_SUBVECTOR(N); break;
01117   case ISD::INSERT_VECTOR_ELT: Res = WidenVecRes_INSERT_VECTOR_ELT(N); break;
01118   case ISD::LOAD:              Res = WidenVecRes_LOAD(N); break;
01119   case ISD::SCALAR_TO_VECTOR:  Res = WidenVecRes_SCALAR_TO_VECTOR(N); break;
01120   case ISD::SELECT:            Res = WidenVecRes_SELECT(N); break;
01121   case ISD::SELECT_CC:         Res = WidenVecRes_SELECT_CC(N); break;
01122   case ISD::UNDEF:             Res = WidenVecRes_UNDEF(N); break;
01123   case ISD::VECTOR_SHUFFLE:    Res = WidenVecRes_VECTOR_SHUFFLE(N); break;
01124   case ISD::VSETCC:            Res = WidenVecRes_VSETCC(N); break;
01125 
01126   case ISD::ADD:
01127   case ISD::AND:
01128   case ISD::BSWAP:
01129   case ISD::FADD:
01130   case ISD::FCOPYSIGN:
01131   case ISD::FDIV:
01132   case ISD::FMUL:
01133   case ISD::FPOW:
01134   case ISD::FPOWI:
01135   case ISD::FREM:
01136   case ISD::FSUB:
01137   case ISD::MUL:
01138   case ISD::MULHS:
01139   case ISD::MULHU:
01140   case ISD::OR:
01141   case ISD::SDIV:
01142   case ISD::SREM:
01143   case ISD::UDIV:
01144   case ISD::UREM:
01145   case ISD::SUB:
01146   case ISD::XOR:               Res = WidenVecRes_Binary(N); break;
01147 
01148   case ISD::SHL:
01149   case ISD::SRA:
01150   case ISD::SRL:               Res = WidenVecRes_Shift(N); break;
01151 
01152   case ISD::ANY_EXTEND:
01153   case ISD::FP_ROUND:
01154   case ISD::FP_TO_SINT:
01155   case ISD::FP_TO_UINT:
01156   case ISD::SIGN_EXTEND:
01157   case ISD::SINT_TO_FP:
01158   case ISD::TRUNCATE:
01159   case ISD::ZERO_EXTEND:
01160   case ISD::UINT_TO_FP:        Res = WidenVecRes_Convert(N); break;
01161 
01162   case ISD::CTLZ:
01163   case ISD::CTPOP:
01164   case ISD::CTTZ:
01165   case ISD::FABS:
01166   case ISD::FCOS:
01167   case ISD::FNEG:
01168   case ISD::FSIN:
01169   case ISD::FSQRT:             Res = WidenVecRes_Unary(N); break;
01170   }
01171 
01172   // If Res is null, the sub-method took care of registering the result.
01173   if (Res.getNode())
01174     SetWidenedVector(SDValue(N, ResNo), Res);
01175 }
01176 
01177 SDValue DAGTypeLegalizer::WidenVecRes_Binary(SDNode *N) {
01178   // Binary op widening.
01179   MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
01180   SDValue InOp1 = GetWidenedVector(N->getOperand(0));
01181   SDValue InOp2 = GetWidenedVector(N->getOperand(1));
01182   return DAG.getNode(N->getOpcode(), N->getDebugLoc(), WidenVT, InOp1, InOp2);
01183 }
01184 
01185 SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
01186   SDValue InOp = N->getOperand(0);
01187   DebugLoc dl = N->getDebugLoc();
01188 
01189   MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
01190   unsigned WidenNumElts = WidenVT.getVectorNumElements();
01191 
01192   MVT InVT = InOp.getValueType();
01193   MVT InEltVT = InVT.getVectorElementType();
01194   MVT InWidenVT = MVT::getVectorVT(InEltVT, WidenNumElts);
01195 
01196   unsigned Opcode = N->getOpcode();
01197   unsigned InVTNumElts = InVT.getVectorNumElements();
01198 
01199   if (getTypeAction(InVT) == WidenVector) {
01200     InOp = GetWidenedVector(N->getOperand(0));
01201     InVT = InOp.getValueType();
01202     InVTNumElts = InVT.getVectorNumElements();
01203     if (InVTNumElts == WidenNumElts)
01204       return DAG.getNode(Opcode, dl, WidenVT, InOp);
01205   }
01206 
01207   if (TLI.isTypeLegal(InWidenVT)) {
01208     // Because the result and the input are different vector types, widening
01209     // the result could create a legal type but widening the input might make
01210     // it an illegal type that might lead to repeatedly splitting the input
01211     // and then widening it. To avoid this, we widen the input only if
01212     // it results in a legal type.
01213     if (WidenNumElts % InVTNumElts == 0) {
01214       // Widen the input and call convert on the widened input vector.
01215       unsigned NumConcat = WidenNumElts/InVTNumElts;
01216       SmallVector<SDValue, 16> Ops(NumConcat);
01217       Ops[0] = InOp;
01218       SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, InVT);
01219       for (unsigned i = 1; i != NumConcat; ++i)
01220         Ops[i] = UndefVal;
01221       return DAG.getNode(Opcode, dl, WidenVT,
01222                          DAG.getNode(ISD::CONCAT_VECTORS, dl, InWidenVT,
01223                          &Ops[0], NumConcat));
01224     }
01225 
01226     if (InVTNumElts % WidenNumElts == 0) {
01227       // Extract the input and convert the shorten input vector.
01228       return DAG.getNode(Opcode, dl, WidenVT,
01229                          DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InWidenVT, 
01230                                      InOp, DAG.getIntPtrConstant(0)));
01231     }
01232   }
01233 
01234   // Otherwise unroll into some nasty scalar code and rebuild the vector.
01235   SmallVector<SDValue, 16> Ops(WidenNumElts);
01236   MVT EltVT = WidenVT.getVectorElementType();
01237   unsigned MinElts = std::min(InVTNumElts, WidenNumElts);
01238   unsigned i;
01239   for (i=0; i < MinElts; ++i)
01240     Ops[i] = DAG.getNode(Opcode, dl, EltVT,
01241                          DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp,
01242                                      DAG.getIntPtrConstant(i)));
01243 
01244   SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, EltVT);
01245   for (; i < WidenNumElts; ++i)
01246     Ops[i] = UndefVal;
01247 
01248   return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts);
01249 }
01250 
01251 SDValue DAGTypeLegalizer::WidenVecRes_Shift(SDNode *N) {
01252   MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
01253   SDValue InOp = GetWidenedVector(N->getOperand(0));
01254   SDValue ShOp = N->getOperand(1);
01255 
01256   MVT ShVT = ShOp.getValueType();
01257   if (getTypeAction(ShVT) == WidenVector) {
01258     ShOp = GetWidenedVector(ShOp);
01259     ShVT = ShOp.getValueType();
01260   }
01261   MVT ShWidenVT = MVT::getVectorVT(ShVT.getVectorElementType(),
01262                                    WidenVT.getVectorNumElements());
01263   if (ShVT != ShWidenVT)
01264     ShOp = ModifyToType(ShOp, ShWidenVT);
01265 
01266   return DAG.getNode(N->getOpcode(), N->getDebugLoc(), WidenVT, InOp, ShOp);
01267 }
01268 
01269 SDValue DAGTypeLegalizer::WidenVecRes_Unary(SDNode *N) {
01270   // Unary op widening.
01271   MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
01272   SDValue InOp = GetWidenedVector(N->getOperand(0));
01273   return DAG.getNode(N->getOpcode(), N->getDebugLoc(), WidenVT, InOp);
01274 }
01275 
01276 SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) {
01277   SDValue InOp = N->getOperand(0);
01278   MVT InVT = InOp.getValueType();
01279   MVT VT = N->getValueType(0);
01280   MVT WidenVT = TLI.getTypeToTransformTo(VT);
01281   DebugLoc dl = N->getDebugLoc();
01282 
01283   switch (getTypeAction(InVT)) {
01284   default:
01285     assert(false && "Unknown type action!");
01286     break;
01287   case Legal:
01288     break;
01289   case PromoteInteger:
01290     // If the InOp is promoted to the same size, convert it.  Otherwise,
01291     // fall out of the switch and widen the promoted input.
01292     InOp = GetPromotedInteger(InOp);
01293     InVT = InOp.getValueType();
01294     if (WidenVT.bitsEq(InVT))
01295       return DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, InOp);
01296     break;
01297   case SoftenFloat:
01298   case ExpandInteger:
01299   case ExpandFloat:
01300   case ScalarizeVector:
01301   case SplitVector:
01302     break;
01303   case WidenVector:
01304     // If the InOp is widened to the same size, convert it.  Otherwise, fall
01305     // out of the switch and widen the widened input.
01306     InOp = GetWidenedVector(InOp);
01307     InVT = InOp.getValueType();
01308     if (WidenVT.bitsEq(InVT))
01309       // The input widens to the same size. Convert to the widen value.
01310       return DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, InOp);
01311     break;
01312   }
01313 
01314   unsigned WidenSize = WidenVT.getSizeInBits();
01315   unsigned InSize = InVT.getSizeInBits();
01316   if (WidenSize % InSize == 0) {
01317     // Determine new input vector type.  The new input vector type will use
01318     // the same element type (if its a vector) or use the input type as a
01319     // vector.  It is the same size as the type to widen to.
01320     MVT NewInVT;
01321     unsigned NewNumElts = WidenSize / InSize;
01322     if (InVT.isVector()) {
01323       MVT InEltVT = InVT.getVectorElementType();
01324       NewInVT= MVT::getVectorVT(InEltVT, WidenSize / InEltVT.getSizeInBits());
01325     } else {
01326       NewInVT = MVT::getVectorVT(InVT, NewNumElts);
01327     }
01328 
01329     if (TLI.isTypeLegal(NewInVT)) {
01330       // Because the result and the input are different vector types, widening
01331       // the result could create a legal type but widening the input might make
01332       // it an illegal type that might lead to repeatedly splitting the input
01333       // and then widening it. To avoid this, we widen the input only if
01334       // it results in a legal type.
01335       SmallVector<SDValue, 16> Ops(NewNumElts);
01336       SDValue UndefVal = DAG.getNode(ISD::UNDEF, InVT);
01337       Ops[0] = InOp;
01338       for (unsigned i = 1; i < NewNumElts; ++i)
01339         Ops[i] = UndefVal;
01340 
01341       SDValue NewVec;
01342       if (InVT.isVector())
01343         NewVec = DAG.getNode(ISD::CONCAT_VECTORS, dl,
01344                              NewInVT, &Ops[0], NewNumElts);
01345       else
01346         NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl,
01347                              NewInVT, &Ops[0], NewNumElts);
01348       return DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, NewVec);
01349     }
01350   }
01351 
01352   // This should occur rarely. Lower the bit-convert to a store/load
01353   // from the stack. Create the stack frame object.  Make sure it is aligned
01354   // for both the source and destination types.
01355   SDValue FIPtr = DAG.CreateStackTemporary(InVT, WidenVT);
01356   int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex();
01357   const Value *SV = PseudoSourceValue::getFixedStack(FI);
01358 
01359   // Emit a store to the stack slot.
01360   SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, SV, 0);
01361 
01362   // Result is a load from the stack slot.
01363   return DAG.getLoad(WidenVT, dl, Store, FIPtr, SV, 0);
01364 }
01365 
01366 SDValue DAGTypeLegalizer::WidenVecRes_BUILD_VECTOR(SDNode *N) {
01367   DebugLoc dl = N->getDebugLoc();
01368   // Build a vector with undefined for the new nodes.
01369   MVT VT = N->getValueType(0);
01370   MVT EltVT = VT.getVectorElementType();
01371   unsigned NumElts = VT.getVectorNumElements();
01372 
01373   MVT WidenVT = TLI.getTypeToTransformTo(VT);
01374   unsigned WidenNumElts = WidenVT.getVectorNumElements();
01375 
01376   SmallVector<SDValue, 16> NewOps(N->op_begin(), N->op_end());
01377   NewOps.reserve(WidenNumElts);
01378   for (unsigned i = NumElts; i < WidenNumElts; ++i)
01379     NewOps.push_back(DAG.getNode(ISD::UNDEF, dl, EltVT));
01380 
01381   return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &NewOps[0], NewOps.size());
01382 }
01383 
01384 SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) {
01385   MVT InVT = N->getOperand(0).getValueType();
01386   MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
01387   DebugLoc dl = N->getDebugLoc();
01388   unsigned WidenNumElts = WidenVT.getVectorNumElements();
01389   unsigned NumOperands = N->getNumOperands();
01390 
01391   bool InputWidened = false; // Indicates we need to widen the input.
01392   if (getTypeAction(InVT) != WidenVector) {
01393     if (WidenVT.getVectorNumElements() % InVT.getVectorNumElements() == 0) {
01394       // Add undef vectors to widen to correct length.
01395       unsigned NumConcat = WidenVT.getVectorNumElements() /
01396                            InVT.getVectorNumElements();
01397       SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, InVT);
01398       SmallVector<SDValue, 16> Ops(NumConcat);
01399       for (unsigned i=0; i < NumOperands; ++i)
01400         Ops[i] = N->getOperand(i);
01401       for (unsigned i = NumOperands; i != NumConcat; ++i)
01402         Ops[i] = UndefVal;
01403       return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &Ops[0], NumConcat);
01404     }
01405   } else {
01406     InputWidened = true;
01407     if (WidenVT == TLI.getTypeToTransformTo(InVT)) {
01408       // The inputs and the result are widen to the same value.
01409       unsigned i;
01410       for (i=1; i < NumOperands; ++i)
01411         if (N->getOperand(i).getOpcode() != ISD::UNDEF)
01412           break;
01413 
01414       if (i > NumOperands)
01415         // Everything but the first operand is an UNDEF so just return the
01416         // widened first operand.
01417         return GetWidenedVector(N->getOperand(0));
01418 
01419       if (NumOperands == 2) {
01420         // Replace concat of two operands with a shuffle.
01421         MVT PtrVT = TLI.getPointerTy();
01422         SmallVector<SDValue, 16> MaskOps(WidenNumElts);
01423         for (unsigned i=0; i < WidenNumElts/2; ++i) {
01424           MaskOps[i] = DAG.getConstant(i, PtrVT);
01425           MaskOps[i+WidenNumElts/2] = DAG.getConstant(i+WidenNumElts, PtrVT);
01426         }
01427         SDValue Mask = DAG.getNode(ISD::BUILD_VECTOR, dl,
01428                                    MVT::getVectorVT(PtrVT, WidenNumElts),
01429                                    &MaskOps[0], WidenNumElts);
01430         return DAG.getNode(ISD::VECTOR_SHUFFLE, dl, WidenVT,
01431                            GetWidenedVector(N->getOperand(0)),
01432                            GetWidenedVector(N->getOperand(1)), Mask);
01433       }
01434     }
01435   }
01436 
01437   // Fall back to use extracts and build vector.
01438   MVT EltVT = WidenVT.getVectorElementType();
01439   unsigned NumInElts = InVT.getVectorNumElements();
01440   SmallVector<SDValue, 16> Ops(WidenNumElts);
01441   unsigned Idx = 0;
01442   for (unsigned i=0; i < NumOperands; ++i) {
01443     SDValue InOp = N->getOperand(i);
01444     if (InputWidened)
01445       InOp = GetWidenedVector(InOp);
01446     for (unsigned j=0; j < NumInElts; ++j)
01447         Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
01448                                  DAG.getIntPtrConstant(j));
01449   }
01450   SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, EltVT);
01451   for (; Idx < WidenNumElts; ++Idx)
01452     Ops[Idx] = UndefVal;
01453   return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts);
01454 }
01455 
01456 SDValue DAGTypeLegalizer::WidenVecRes_CONVERT_RNDSAT(SDNode *N) {
01457   SDValue InOp  = N->getOperand(0);
01458   SDValue RndOp = N->getOperand(3);
01459   SDValue SatOp = N->getOperand(4);
01460 
01461   MVT      WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
01462   unsigned WidenNumElts = WidenVT.getVectorNumElements();
01463 
01464   MVT InVT = InOp.getValueType();
01465   MVT InEltVT = InVT.getVectorElementType();
01466   MVT InWidenVT = MVT::getVectorVT(InEltVT, WidenNumElts);
01467 
01468   SDValue DTyOp = DAG.getValueType(WidenVT);
01469   SDValue STyOp = DAG.getValueType(InWidenVT);
01470   ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode();
01471 
01472   unsigned InVTNumElts = InVT.getVectorNumElements();
01473   if (getTypeAction(InVT) == WidenVector) {
01474     InOp = GetWidenedVector(InOp);
01475     InVT = InOp.getValueType();
01476     InVTNumElts = InVT.getVectorNumElements();
01477     if (InVTNumElts == WidenNumElts)
01478       return DAG.getConvertRndSat(WidenVT, InOp, DTyOp, STyOp, RndOp,
01479                                   SatOp, CvtCode);
01480   }
01481 
01482   if (TLI.isTypeLegal(InWidenVT)) {
01483     // Because the result and the input are different vector types, widening
01484     // the result could create a legal type but widening the input might make
01485     // it an illegal type that might lead to repeatedly splitting the input
01486     // and then widening it. To avoid this, we widen the input only if
01487     // it results in a legal type.
01488     if (WidenNumElts % InVTNumElts == 0) {
01489       // Widen the input and call convert on the widened input vector.
01490       unsigned NumConcat = WidenNumElts/InVTNumElts;
01491       SmallVector<SDValue, 16> Ops(NumConcat);
01492       Ops[0] = InOp;
01493       SDValue UndefVal = DAG.getNode(ISD::UNDEF, InVT);
01494       for (unsigned i = 1; i != NumConcat; ++i) {
01495         Ops[i] = UndefVal;
01496       }
01497       InOp = DAG.getNode(ISD::CONCAT_VECTORS, InWidenVT, &Ops[0], NumConcat);
01498       return DAG.getConvertRndSat(WidenVT, InOp, DTyOp, STyOp, RndOp,
01499                                   SatOp, CvtCode);
01500     }
01501 
01502     if (InVTNumElts % WidenNumElts == 0) {
01503       // Extract the input and convert the shorten input vector.
01504       InOp = DAG.getNode(ISD::EXTRACT_SUBVECTOR, InWidenVT, InOp,
01505                          DAG.getIntPtrConstant(0));
01506       return DAG.getConvertRndSat(WidenVT, InOp, DTyOp, STyOp, RndOp,
01507                                 SatOp, CvtCode);
01508     }
01509   }
01510 
01511   // Otherwise unroll into some nasty scalar code and rebuild the vector.
01512   SmallVector<SDValue, 16> Ops(WidenNumElts);
01513   MVT EltVT = WidenVT.getVectorElementType();
01514   DTyOp = DAG.getValueType(EltVT);
01515   STyOp = DAG.getValueType(InEltVT);
01516 
01517   unsigned MinElts = std::min(InVTNumElts, WidenNumElts);
01518   unsigned i;
01519   for (i=0; i < MinElts; ++i) {
01520     SDValue ExtVal = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, InEltVT, InOp,
01521                                  DAG.getIntPtrConstant(i));
01522     Ops[i] = DAG.getConvertRndSat(WidenVT, ExtVal, DTyOp, STyOp, RndOp,
01523                                         SatOp, CvtCode);
01524   }
01525 
01526   SDValue UndefVal = DAG.getNode(ISD::UNDEF, EltVT);
01527   for (; i < WidenNumElts; ++i)
01528     Ops[i] = UndefVal;
01529 
01530   return DAG.getNode(ISD::BUILD_VECTOR, WidenVT, &Ops[0], WidenNumElts);
01531 }
01532 
01533 SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) {
01534   MVT      VT = N->getValueType(0);
01535   MVT      WidenVT = TLI.getTypeToTransformTo(VT);
01536   unsigned WidenNumElts = WidenVT.getVectorNumElements();
01537   SDValue  InOp = N->getOperand(0);
01538   SDValue  Idx  = N->getOperand(1);
01539   DebugLoc dl = N->getDebugLoc();
01540 
01541   if (getTypeAction(InOp.getValueType()) == WidenVector)
01542     InOp = GetWidenedVector(InOp);
01543 
01544   MVT InVT = InOp.getValueType();
01545 
01546   ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Idx);
01547   if (CIdx) {
01548     unsigned IdxVal = CIdx->getZExtValue();
01549     // Check if we can just return the input vector after widening.
01550     if (IdxVal == 0 && InVT == WidenVT)
01551       return InOp;
01552 
01553     // Check if we can extract from the vector.
01554     unsigned InNumElts = InVT.getVectorNumElements();
01555     if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
01556         return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, WidenVT, InOp, Idx);
01557   }
01558 
01559   // We could try widening the input to the right length but for now, extract
01560   // the original elements, fill the rest with undefs and build a vector.
01561   SmallVector<SDValue, 16> Ops(WidenNumElts);
01562   MVT EltVT = VT.getVectorElementType();
01563   MVT IdxVT = Idx.getValueType();
01564   unsigned NumElts = VT.getVectorNumElements();
01565   unsigned i;
01566   if (CIdx) {
01567     unsigned IdxVal = CIdx->getZExtValue();
01568     for (i=0; i < NumElts; ++i)
01569       Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
01570                            DAG.getConstant(IdxVal+i, IdxVT));
01571   } else {
01572     Ops[0] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, Idx);
01573     for (i=1; i < NumElts; ++i) {
01574       SDValue NewIdx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx,
01575                                    DAG.getConstant(i, IdxVT));
01576       Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, NewIdx);
01577     }
01578   }
01579 
01580   SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, EltVT);
01581   for (; i < WidenNumElts; ++i)
01582     Ops[i] = UndefVal;
01583   return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts);
01584 }
01585 
01586 SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
01587   SDValue InOp = GetWidenedVector(N->getOperand(0));
01588   return DAG.getNode(ISD::INSERT_VECTOR_ELT, N->getDebugLoc(),
01589                      InOp.getValueType(), InOp,
01590                      N->getOperand(1), N->getOperand(2));
01591 }
01592 
01593 SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) {
01594   LoadSDNode *LD = cast<LoadSDNode>(N);
01595   MVT WidenVT = TLI.getTypeToTransformTo(LD->getValueType(0));
01596   MVT LdVT    = LD->getMemoryVT();
01597   DebugLoc dl = N->getDebugLoc();
01598   assert(LdVT.isVector() && WidenVT.isVector());
01599 
01600   // Load information
01601   SDValue   Chain = LD->getChain();
01602   SDValue   BasePtr = LD->getBasePtr();
01603   int       SVOffset = LD->getSrcValueOffset();
01604   unsigned  Align    = LD->getAlignment();
01605   bool      isVolatile = LD->isVolatile();
01606   const Value *SV = LD->getSrcValue();
01607   ISD::LoadExtType ExtType = LD->getExtensionType();
01608 
01609   SDValue Result;
01610   SmallVector<SDValue, 16> LdChain;  // Chain for the series of load
01611   if (ExtType != ISD::NON_EXTLOAD) {
01612     // For extension loads, we can not play the tricks of chopping legal
01613     // vector types and bit cast it to the right type.  Instead, we unroll
01614     // the load and build a vector.
01615     MVT EltVT = WidenVT.getVectorElementType();
01616     MVT LdEltVT = LdVT.getVectorElementType();
01617     unsigned NumElts = LdVT.getVectorNumElements();
01618 
01619     // Load each element and widen
01620     unsigned WidenNumElts = WidenVT.getVectorNumElements();
01621     SmallVector<SDValue, 16> Ops(WidenNumElts);
01622     unsigned Increment = LdEltVT.getSizeInBits() / 8;
01623     Ops[0] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr, SV, SVOffset,
01624                             LdEltVT, isVolatile, Align);
01625     LdChain.push_back(Ops[0].getValue(1));
01626     unsigned i = 0, Offset = Increment;
01627     for (i=1; i < NumElts; ++i, Offset += Increment) {
01628       SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(),
01629                                        BasePtr, DAG.getIntPtrConstant(Offset));
01630       Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr, SV,
01631                               SVOffset + Offset, LdEltVT, isVolatile, Align);
01632       LdChain.push_back(Ops[i].getValue(1));
01633     }
01634 
01635     // Fill the rest with undefs
01636     SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, EltVT);
01637     for (; i != WidenNumElts; ++i)
01638       Ops[i] = UndefVal;
01639 
01640     Result =  DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], Ops.size());
01641   } else {
01642     assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType());
01643     unsigned int LdWidth = LdVT.getSizeInBits();
01644     Result = GenWidenVectorLoads(LdChain, Chain, BasePtr, SV, SVOffset,
01645                                  Align, isVolatile, LdWidth, WidenVT, dl);
01646   }
01647 
01648  // If we generate a single load, we can use that for the chain.  Otherwise,
01649  // build a factor node to remember the multiple loads are independent and
01650  // chain to that.
01651  SDValue NewChain;
01652  if (LdChain.size() == 1)
01653    NewChain = LdChain[0];
01654  else
01655    NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &LdChain[0],
01656                           LdChain.size());
01657 
01658   // Modified the chain - switch anything that used the old chain to use
01659   // the new one.
01660   ReplaceValueWith(SDValue(N, 1), Chain);
01661 
01662   return Result;
01663 }
01664 
01665 SDValue DAGTypeLegalizer::WidenVecRes_SCALAR_TO_VECTOR(SDNode *N) {
01666   MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
01667   return DAG.getNode(ISD::SCALAR_TO_VECTOR, N->getDebugLoc(),
01668                      WidenVT, N->getOperand(0));
01669 }
01670 
01671 SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNode *N) {
01672   MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
01673   unsigned WidenNumElts = WidenVT.getVectorNumElements();
01674 
01675   SDValue Cond1 = N->getOperand(0);
01676   MVT CondVT = Cond1.getValueType();
01677   if (CondVT.isVector()) {
01678     MVT CondEltVT = CondVT.getVectorElementType();
01679     MVT CondWidenVT =  MVT::getVectorVT(CondEltVT, WidenNumElts);
01680     if (getTypeAction(CondVT) == WidenVector)
01681       Cond1 = GetWidenedVector(Cond1);
01682 
01683     if (Cond1.getValueType() != CondWidenVT)
01684        Cond1 = ModifyToType(Cond1, CondWidenVT);
01685   }
01686 
01687   SDValue InOp1 = GetWidenedVector(N->getOperand(1));
01688   SDValue InOp2 = GetWidenedVector(N->getOperand(2));
01689   assert(InOp1.getValueType() == WidenVT && InOp2.getValueType() == WidenVT);
01690   return DAG.getNode(ISD::SELECT, N->getDebugLoc(),
01691                      WidenVT, Cond1, InOp1, InOp2);
01692 }
01693 
01694 SDValue DAGTypeLegalizer::WidenVecRes_SELECT_CC(SDNode *N) {
01695   SDValue InOp1 = GetWidenedVector(N->getOperand(2));
01696   SDValue InOp2 = GetWidenedVector(N->getOperand(3));
01697   return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(),
01698                      InOp1.getValueType(), N->getOperand(0),
01699                      N->getOperand(1), InOp1, InOp2, N->getOperand(4));
01700 }
01701 
01702 SDValue DAGTypeLegalizer::WidenVecRes_UNDEF(SDNode *N) {
01703  MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
01704  return DAG.getNode(ISD::UNDEF, N->getDebugLoc(), WidenVT);
01705 }
01706 
01707 SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(SDNode *N) {
01708   MVT VT = N->getValueType(0);
01709   unsigned NumElts = VT.getVectorNumElements();
01710   DebugLoc dl = N->getDebugLoc();
01711 
01712   MVT WidenVT = TLI.getTypeToTransformTo(VT);
01713   unsigned WidenNumElts = WidenVT.getVectorNumElements();
01714 
01715   SDValue InOp1 = GetWidenedVector(N->getOperand(0));
01716   SDValue InOp2 = GetWidenedVector(N->getOperand(1));
01717 
01718   // Adjust mask based on new input vector length.
01719   SDValue Mask = N->getOperand(2);
01720   SmallVector<SDValue, 16> MaskOps(WidenNumElts);
01721   MVT IdxVT = Mask.getValueType().getVectorElementType();
01722   for (unsigned i = 0; i < NumElts; ++i) {
01723     SDValue Arg = Mask.getOperand(i);
01724     if (Arg.getOpcode() == ISD::UNDEF)
01725       MaskOps[i] = Arg;
01726     else {
01727       unsigned Idx = cast<ConstantSDNode>(Arg)->getZExtValue();
01728       if (Idx < NumElts)
01729         MaskOps[i] = Arg;
01730       else
01731         MaskOps[i] = DAG.getConstant(Idx - NumElts + WidenNumElts, IdxVT);
01732     }
01733   }
01734   for (unsigned i = NumElts; i < WidenNumElts; ++i)
01735     MaskOps[i] = DAG.getNode(ISD::UNDEF, dl, IdxVT);
01736   SDValue NewMask = DAG.getNode(ISD::BUILD_VECTOR, dl,
01737                                 MVT::getVectorVT(IdxVT, WidenNumElts),
01738                                 &MaskOps[0], WidenNumElts);
01739 
01740   return DAG.getNode(ISD::VECTOR_SHUFFLE, dl, WidenVT, InOp1, InOp2, NewMask);
01741 }
01742 
01743 SDValue DAGTypeLegalizer::WidenVecRes_VSETCC(SDNode *N) {
01744   MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0));
01745   unsigned WidenNumElts = WidenVT.getVectorNumElements();
01746 
01747   SDValue InOp1 = N->getOperand(0);
01748   MVT InVT = InOp1.getValueType();
01749   assert(InVT.isVector() && "can not widen non vector type");
01750   MVT WidenInVT = MVT::getVectorVT(InVT.getVectorElementType(), WidenNumElts);
01751   InOp1 = GetWidenedVector(InOp1);
01752   SDValue InOp2 = GetWidenedVector(N->getOperand(1));
01753 
01754   // Assume that the input and output will be widen appropriately.  If not,
01755   // we will have to unroll it at some point.
01756   assert(InOp1.getValueType() == WidenInVT &&
01757          InOp2.getValueType() == WidenInVT &&
01758          "Input not widened to expected type!");
01759   return DAG.getNode(ISD::VSETCC, N->getDebugLoc(),
01760                      WidenVT, InOp1, InOp2, N->getOperand(2));
01761 }
01762 
01763 
01764 //===----------------------------------------------------------------------===//
01765 // Widen Vector Operand
01766 //===----------------------------------------------------------------------===//
01767 bool DAGTypeLegalizer::WidenVectorOperand(SDNode *N, unsigned ResNo) {
01768   DEBUG(cerr << "Widen node operand " << ResNo << ": "; N->dump(&DAG);
01769         cerr << "\n");
01770   SDValue Res = SDValue();
01771 
01772   switch (N->getOpcode()) {
01773   default:
01774 #ifndef NDEBUG
01775     cerr << "WidenVectorOperand op #" << ResNo << ": ";
01776     N->dump(&DAG); cerr << "\n";
01777 #endif
01778     assert(0 && "Do not know how to widen this operator's operand!");
01779     abort();
01780 
01781   case ISD::BIT_CONVERT:        Res = WidenVecOp_BIT_CONVERT(N); break;
01782   case ISD::CONCAT_VECTORS:     Res = WidenVecOp_CONCAT_VECTORS(N); break;
01783   case ISD::EXTRACT_VECTOR_ELT: Res = WidenVecOp_EXTRACT_VECTOR_ELT(N); break;
01784   case ISD::STORE:              Res = WidenVecOp_STORE(N); break;
01785 
01786   case ISD::FP_ROUND:
01787   case ISD::FP_TO_SINT:
01788   case ISD::FP_TO_UINT:
01789   case ISD::SINT_TO_FP:
01790   case ISD::TRUNCATE:
01791   case ISD::UINT_TO_FP:         Res = WidenVecOp_Convert(N); break;
01792   }
01793 
01794   // If Res is null, the sub-method took care of registering the result.
01795   if (!Res.getNode()) return false;
01796 
01797   // If the result is N, the sub-method updated N in place.  Tell the legalizer
01798   // core about this.
01799   if (Res.getNode() == N)
01800     return true;
01801 
01802 
01803   assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
01804          "Invalid operand expansion");
01805 
01806   ReplaceValueWith(SDValue(N, 0), Res);
01807   return false;
01808 }
01809 
01810 SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) {
01811   // Since the result is legal and the input is illegal, it is unlikely
01812   // that we can fix the input to a legal type so unroll the convert
01813   // into some scalar code and create a nasty build vector.
01814   MVT VT = N->getValueType(0);
01815   MVT EltVT = VT.getVectorElementType();
01816   DebugLoc dl = N->getDebugLoc();
01817   unsigned NumElts = VT.getVectorNumElements();
01818   SDValue InOp = N->getOperand(0);
01819   if (getTypeAction(InOp.getValueType()) == WidenVector)
01820     InOp = GetWidenedVector(InOp);
01821   MVT InVT = InOp.getValueType();
01822   MVT InEltVT = InVT.getVectorElementType();
01823 
01824   unsigned Opcode = N->getOpcode();
01825   SmallVector<SDValue, 16> Ops(NumElts);
01826   for (unsigned i=0; i < NumElts; ++i)
01827     Ops[i] = DAG.getNode(Opcode, dl, EltVT,
01828                          DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp,
01829                                      DAG.getIntPtrConstant(i)));
01830 
01831   return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElts);
01832 }
01833 
01834 SDValue DAGTypeLegalizer::WidenVecOp_BIT_CONVERT(SDNode *N) {
01835   MVT VT = N->getValueType(0);
01836   SDValue InOp = GetWidenedVector(N->getOperand(0));
01837   MVT InWidenVT = InOp.getValueType();
01838   DebugLoc dl = N->getDebugLoc();
01839 
01840   // Check if we can convert between two legal vector types and extract.
01841   unsigned InWidenSize = InWidenVT.getSizeInBits();
01842   unsigned Size = VT.getSizeInBits();
01843   if (InWidenSize % Size == 0 && !VT.isVector()) {
01844     unsigned NewNumElts = InWidenSize / Size;
01845     MVT NewVT = MVT::getVectorVT(VT, NewNumElts);
01846     if (TLI.isTypeLegal(NewVT)) {
01847       SDValue BitOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVT, InOp);
01848       return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, BitOp,
01849                          DAG.getIntPtrConstant(0));
01850     }
01851   }
01852 
01853   // Lower the bit-convert to a store/load from the stack. Create the stack
01854   // frame object.  Make sure it is aligned for both the source and destination
01855   // types.
01856   SDValue FIPtr = DAG.CreateStackTemporary(InWidenVT, VT);
01857   int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex();
01858   const Value *SV = PseudoSourceValue::getFixedStack(FI);
01859 
01860   // Emit a store to the stack slot.
01861   SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, SV, 0);
01862 
01863   // Result is a load from the stack slot.
01864   return DAG.getLoad(VT, dl, Store, FIPtr, SV, 0);
01865 }
01866 
01867 SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) {
01868   // If the input vector is not legal, it is likely that we will not find a
01869   // legal vector of the same size. Replace the concatenate vector with a
01870   // nasty build vector.
01871   MVT VT = N->getValueType(0);
01872   MVT EltVT = VT.getVectorElementType();
01873   DebugLoc dl = N->getDebugLoc();
01874   unsigned NumElts = VT.getVectorNumElements();
01875   SmallVector<SDValue, 16> Ops(NumElts);
01876 
01877   MVT InVT = N->getOperand(0).getValueType();
01878   unsigned NumInElts = InVT.getVectorNumElements();
01879 
01880   unsigned Idx = 0;
01881   unsigned NumOperands = N->getNumOperands();
01882   for (unsigned i=0; i < NumOperands; ++i) {
01883     SDValue InOp = N->getOperand(i);
01884     if (getTypeAction(InOp.getValueType()) == WidenVector)
01885       InOp = GetWidenedVector(InOp);
01886     for (unsigned j=0; j < NumInElts; ++j)
01887       Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
01888                                DAG.getIntPtrConstant(j));
01889   }
01890   return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElts);
01891 }
01892 
01893 SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
01894   SDValue InOp = GetWidenedVector(N->getOperand(0));
01895   MVT EltVT = InOp.getValueType().getVectorElementType();
01896   return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, N->getDebugLoc(),
01897                      EltVT, InOp, N->getOperand(1));
01898 }
01899 
01900 SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) {
01901   // We have to widen the value but we want only to store the original
01902   // vector type.
01903   StoreSDNode *ST = cast<StoreSDNode>(N);
01904   SDValue  Chain = ST->getChain();
01905   SDValue  BasePtr = ST->getBasePtr();
01906   const    Value *SV = ST->getSrcValue();
01907   int      SVOffset = ST->getSrcValueOffset();
01908   unsigned Align = ST->getAlignment();
01909   bool     isVolatile = ST->isVolatile();
01910   SDValue  ValOp = GetWidenedVector(ST->getValue());
01911   DebugLoc dl = N->getDebugLoc();
01912 
01913   MVT StVT = ST->getMemoryVT();
01914   MVT ValVT = ValOp.getValueType();
01915   // It must be true that we the widen vector type is bigger than where
01916   // we need to store.
01917   assert(StVT.isVector() && ValOp.getValueType().isVector());
01918   assert(StVT.bitsLT(ValOp.getValueType()));
01919 
01920   SmallVector<SDValue, 16> StChain;
01921   if (ST->isTruncatingStore()) {
01922     // For truncating stores, we can not play the tricks of chopping legal
01923     // vector types and bit cast it to the right type.  Instead, we unroll
01924     // the store.
01925     MVT StEltVT  = StVT.getVectorElementType();
01926     MVT ValEltVT = ValVT.getVectorElementType();
01927     unsigned Increment = ValEltVT.getSizeInBits() / 8;
01928     unsigned NumElts = StVT.getVectorNumElements();
01929     SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp,
01930                               DAG.getIntPtrConstant(0));
01931     StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, BasePtr, SV,
01932                                         SVOffset, StEltVT,
01933                                         isVolatile, Align));
01934     unsigned Offset = Increment;
01935     for (unsigned i=1; i < NumElts; ++i, Offset += Increment) {
01936       SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(),
01937                                        BasePtr, DAG.getIntPtrConstant(Offset));
01938       SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp,
01939                               DAG.getIntPtrConstant(0));
01940       StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, NewBasePtr, SV,
01941                                           SVOffset + Offset, StEltVT,
01942                                           isVolatile, MinAlign(Align, Offset)));
01943     }
01944   }
01945   else {
01946     assert(StVT.getVectorElementType() == ValVT.getVectorElementType());
01947     // Store value
01948     GenWidenVectorStores(StChain, Chain, BasePtr, SV, SVOffset,
01949                          Align, isVolatile, ValOp, StVT.getSizeInBits(), dl);
01950   }
01951   if (StChain.size() == 1)
01952     return StChain[0];
01953   else
01954     return DAG.getNode(ISD::TokenFactor, dl, 
01955                        MVT::Other,&StChain[0],StChain.size());
01956 }
01957 
01958 //===----------------------------------------------------------------------===//
01959 // Vector Widening Utilities
01960 //===----------------------------------------------------------------------===//
01961 
01962 
01963 // Utility function to find a vector type and its associated element
01964 // type from a preferred width and whose vector type must be the same size
01965 // as the VecVT.
01966 //  TLI:   Target lowering used to determine legal types.
01967 //  Width: Preferred width to store.
01968 //  VecVT: Vector value type whose size we must match.
01969 // Returns NewVecVT and NewEltVT - the vector type and its associated
01970 // element type.
01971 static void FindAssocWidenVecType(const TargetLowering &TLI, unsigned Width,
01972                                   MVT VecVT,
01973                                   MVT& NewEltVT, MVT& NewVecVT) {
01974   unsigned EltWidth = Width + 1;
01975   if (TLI.isTypeLegal(VecVT)) {
01976     // We start with the preferred with, making it a power of 2 and find a
01977     // legal vector type of that width.  If not, we reduce it by another of 2.
01978     // For incoming type is legal, this process will end as a vector of the
01979     // smallest loadable type should always be legal.
01980     do {
01981       assert(EltWidth > 0);
01982       EltWidth = 1 << Log2_32(EltWidth - 1);
01983       NewEltVT = MVT::getIntegerVT(EltWidth);
01984       unsigned NumElts = VecVT.getSizeInBits() / EltWidth;
01985       NewVecVT = MVT::getVectorVT(NewEltVT, NumElts);
01986     } while (!TLI.isTypeLegal(NewVecVT) ||
01987              VecVT.getSizeInBits() != NewVecVT.getSizeInBits());
01988   } else {
01989     // The incoming vector type is illegal and is the result of widening
01990     // a vector to a power of 2. In this case, we will use the preferred
01991     // with as long as it is a multiple of the incoming vector length.
01992     // The legalization process will eventually make this into a legal type
01993     // and remove the illegal bit converts (which would turn to stack converts
01994     // if they are allow to exist).
01995      do {
01996       assert(EltWidth > 0);
01997       EltWidth = 1 << Log2_32(EltWidth - 1);
01998       NewEltVT = MVT::getIntegerVT(EltWidth);
01999       unsigned NumElts = VecVT.getSizeInBits() / EltWidth;
02000       NewVecVT = MVT::getVectorVT(NewEltVT, NumElts);
02001     } while (!TLI.isTypeLegal(NewEltVT) ||
02002              VecVT.getSizeInBits() != NewVecVT.getSizeInBits());
02003   }
02004 }
02005 
02006 SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVector<SDValue, 16>& LdChain,
02007                                               SDValue      Chain,
02008                                               SDValue      BasePtr,
02009                                               const Value *SV,
02010                                               int          SVOffset,
02011                                               unsigned     Alignment,
02012                                               bool         isVolatile,
02013                                               unsigned     LdWidth,
02014                                               MVT          ResType,
02015                                               DebugLoc     dl) {
02016   // The strategy assumes that we can efficiently load powers of two widths.
02017   // The routines chops the vector into the largest power of 2 load and
02018   // can be inserted into a legal vector and then cast the result into the
02019   // vector type we want.  This avoids unnecessary stack converts.
02020 
02021   // TODO: If the Ldwidth is legal, alignment is the same as the LdWidth, and
02022   //       the load is nonvolatile, we an use a wider load for the value.
02023 
02024   // Find the vector type that can load from.
02025   MVT NewEltVT, NewVecVT;
02026   unsigned NewEltVTWidth;
02027   FindAssocWidenVecType(TLI, LdWidth, ResType, NewEltVT, NewVecVT);
02028   NewEltVTWidth = NewEltVT.getSizeInBits();
02029 
02030   SDValue LdOp = DAG.getLoad(NewEltVT, dl, Chain, BasePtr, SV, SVOffset,
02031                              isVolatile, Alignment);
02032   SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
02033   LdChain.push_back(LdOp.getValue(1));
02034 
02035   // Check if we can load the element with one instruction
02036   if (LdWidth == NewEltVTWidth) {
02037     return DAG.getNode(ISD::BIT_CONVERT, dl, ResType, VecOp);
02038   }
02039 
02040   unsigned Idx = 1;
02041   LdWidth -= NewEltVTWidth;
02042   unsigned Offset = 0;
02043 
02044   while (LdWidth > 0) {
02045     unsigned Increment = NewEltVTWidth / 8;
02046     Offset += Increment;
02047     BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
02048                           DAG.getIntPtrConstant(Increment));
02049 
02050     if (LdWidth < NewEltVTWidth) {
02051       // Our current type we are using is too large, use a smaller size by
02052       // using a smaller power of 2
02053       unsigned oNewEltVTWidth = NewEltVTWidth;
02054       FindAssocWidenVecType(TLI, LdWidth, ResType, NewEltVT, NewVecVT);
02055       NewEltVTWidth = NewEltVT.getSizeInBits();
02056       // Readjust position and vector position based on new load type
02057       Idx = Idx * (oNewEltVTWidth/NewEltVTWidth);
02058       VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, VecOp);
02059     }
02060 
02061     SDValue LdOp = DAG.getLoad(NewEltVT, dl, Chain, BasePtr, SV,
02062                                  SVOffset+Offset, isVolatile,
02063                                  MinAlign(Alignment, Offset));
02064     LdChain.push_back(LdOp.getValue(1));
02065     VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, VecOp, LdOp,
02066                         DAG.getIntPtrConstant(Idx++));
02067 
02068     LdWidth -= NewEltVTWidth;
02069   }
02070 
02071   return DAG.getNode(ISD::BIT_CONVERT, dl, ResType, VecOp);
02072 }
02073 
02074 void DAGTypeLegalizer::GenWidenVectorStores(SmallVector<SDValue, 16>& StChain,
02075                                             SDValue   Chain,
02076                                             SDValue   BasePtr,
02077                                             const Value *SV,
02078                                             int         SVOffset,
02079                                             unsigned    Alignment,
02080                                             bool        isVolatile,
02081                                             SDValue     ValOp,
02082                                             unsigned    StWidth,
02083                                             DebugLoc    dl) {
02084   // Breaks the stores into a series of power of 2 width stores.  For any
02085   // width, we convert the vector to the vector of element size that we
02086   // want to store.  This avoids requiring a stack convert.
02087 
02088   // Find a width of the element type we can store with
02089   MVT WidenVT = ValOp.getValueType();
02090   MVT NewEltVT, NewVecVT;
02091 
02092   FindAssocWidenVecType(TLI, StWidth, WidenVT, NewEltVT, NewVecVT);
02093   unsigned NewEltVTWidth = NewEltVT.getSizeInBits();
02094 
02095   SDValue VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, ValOp);
02096   SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, VecOp,
02097                             DAG.getIntPtrConstant(0));
02098   SDValue StOp = DAG.getStore(Chain, dl, EOp, BasePtr, SV, SVOffset,
02099                                isVolatile, Alignment);
02100   StChain.push_back(StOp);
02101 
02102   // Check if we are done
02103   if (StWidth == NewEltVTWidth) {
02104     return;
02105   }
02106 
02107   unsigned Idx = 1;
02108   StWidth -= NewEltVTWidth;
02109   unsigned Offset = 0;
02110 
02111   while (StWidth > 0) {
02112     unsigned Increment = NewEltVTWidth / 8;
02113     Offset += Increment;
02114     BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr,
02115                           DAG.getIntPtrConstant(Increment));
02116 
02117     if (StWidth < NewEltVTWidth) {
02118       // Our current type we are using is too large, use a smaller size by
02119       // using a smaller power of 2
02120       unsigned oNewEltVTWidth = NewEltVTWidth;
02121       FindAssocWidenVecType(TLI, StWidth, WidenVT, NewEltVT, NewVecVT);
02122       NewEltVTWidth = NewEltVT.getSizeInBits();
02123       // Readjust position and vector position based on new load type
02124       Idx = Idx * (oNewEltVTWidth/NewEltVTWidth);
02125       VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, VecOp);
02126     }
02127 
02128     EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, VecOp,
02129                       DAG.getIntPtrConstant(Idx++));
02130     StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, SV,
02131                                    SVOffset + Offset, isVolatile,
02132                                    MinAlign(Alignment, Offset)));
02133     StWidth -= NewEltVTWidth;
02134   }
02135 }
02136 
02137 /// Modifies a vector input (widen or narrows) to a vector of NVT.  The
02138 /// input vector must have the same element type as NVT.
02139 SDValue DAGTypeLegalizer::ModifyToType(SDValue InOp, MVT NVT) {
02140   // Note that InOp might have been widened so it might already have
02141   // the right width or it might need be narrowed.
02142   MVT InVT = InOp.getValueType();
02143   assert(InVT.getVectorElementType() == NVT.getVectorElementType() &&
02144          "input and widen element type must match");
02145   DebugLoc dl = InOp.getNode()->getDebugLoc();
02146 
02147   // Check if InOp already has the right width.
02148   if (InVT == NVT)
02149     return InOp;
02150 
02151   unsigned InNumElts = InVT.getVectorNumElements();
02152   unsigned WidenNumElts = NVT.getVectorNumElements();
02153   if (WidenNumElts > InNumElts && WidenNumElts % InNumElts == 0) {
02154     unsigned NumConcat = WidenNumElts / InNumElts;
02155     SmallVector<SDValue, 16> Ops(NumConcat);
02156     SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, InVT);
02157     Ops[0] = InOp;
02158     for (unsigned i = 1; i != NumConcat; ++i)
02159       Ops[i] = UndefVal;
02160 
02161     return DAG.getNode(ISD::CONCAT_VECTORS, dl, NVT, &Ops[0], NumConcat);
02162   }
02163 
02164   if (WidenNumElts < InNumElts && InNumElts % WidenNumElts)
02165     return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NVT, InOp,
02166                        DAG.getIntPtrConstant(0));
02167 
02168   // Fall back to extract and build.
02169   SmallVector<SDValue, 16> Ops(WidenNumElts);
02170   MVT EltVT = NVT.getVectorElementType();
02171   unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
02172   unsigned Idx;
02173   for (Idx = 0; Idx < MinNumElts; ++Idx)
02174     Ops[Idx] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
02175                            DAG.getIntPtrConstant(Idx));
02176 
02177   SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, EltVT);
02178   for ( ; Idx < WidenNumElts; ++Idx)
02179     Ops[Idx] = UndefVal;
02180   return DAG.getNode(ISD::BUILD_VECTOR, dl, NVT, &Ops[0], WidenNumElts);
02181 }