LLVM API Documentation
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 two vectors of half the size. For example, implementing 00019 // <128 x f32> operations in terms of two <64 x f32> operations. 00020 // 00021 //===----------------------------------------------------------------------===// 00022 00023 #include "LegalizeTypes.h" 00024 #include "llvm/IR/DataLayout.h" 00025 #include "llvm/Support/ErrorHandling.h" 00026 #include "llvm/Support/raw_ostream.h" 00027 using namespace llvm; 00028 00029 #define DEBUG_TYPE "legalize-types" 00030 00031 //===----------------------------------------------------------------------===// 00032 // Result Vector Scalarization: <1 x ty> -> ty. 00033 //===----------------------------------------------------------------------===// 00034 00035 void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) { 00036 DEBUG(dbgs() << "Scalarize node result " << ResNo << ": "; 00037 N->dump(&DAG); 00038 dbgs() << "\n"); 00039 SDValue R = SDValue(); 00040 00041 switch (N->getOpcode()) { 00042 default: 00043 #ifndef NDEBUG 00044 dbgs() << "ScalarizeVectorResult #" << ResNo << ": "; 00045 N->dump(&DAG); 00046 dbgs() << "\n"; 00047 #endif 00048 report_fatal_error("Do not know how to scalarize the result of this " 00049 "operator!\n"); 00050 00051 case ISD::MERGE_VALUES: R = ScalarizeVecRes_MERGE_VALUES(N, ResNo);break; 00052 case ISD::BITCAST: R = ScalarizeVecRes_BITCAST(N); break; 00053 case ISD::BUILD_VECTOR: R = ScalarizeVecRes_BUILD_VECTOR(N); break; 00054 case ISD::CONVERT_RNDSAT: R = ScalarizeVecRes_CONVERT_RNDSAT(N); break; 00055 case ISD::EXTRACT_SUBVECTOR: R = ScalarizeVecRes_EXTRACT_SUBVECTOR(N); break; 00056 case ISD::FP_ROUND: R = ScalarizeVecRes_FP_ROUND(N); break; 00057 case ISD::FP_ROUND_INREG: R = ScalarizeVecRes_InregOp(N); break; 00058 case ISD::FPOWI: R = ScalarizeVecRes_FPOWI(N); break; 00059 case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break; 00060 case ISD::LOAD: R = ScalarizeVecRes_LOAD(cast<LoadSDNode>(N));break; 00061 case ISD::SCALAR_TO_VECTOR: R = ScalarizeVecRes_SCALAR_TO_VECTOR(N); break; 00062 case ISD::SIGN_EXTEND_INREG: R = ScalarizeVecRes_InregOp(N); break; 00063 case ISD::VSELECT: R = ScalarizeVecRes_VSELECT(N); break; 00064 case ISD::SELECT: R = ScalarizeVecRes_SELECT(N); break; 00065 case ISD::SELECT_CC: R = ScalarizeVecRes_SELECT_CC(N); break; 00066 case ISD::SETCC: R = ScalarizeVecRes_SETCC(N); break; 00067 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(N); break; 00068 case ISD::VECTOR_SHUFFLE: R = ScalarizeVecRes_VECTOR_SHUFFLE(N); break; 00069 case ISD::ANY_EXTEND: 00070 case ISD::BSWAP: 00071 case ISD::CTLZ: 00072 case ISD::CTLZ_ZERO_UNDEF: 00073 case ISD::CTPOP: 00074 case ISD::CTTZ: 00075 case ISD::CTTZ_ZERO_UNDEF: 00076 case ISD::FABS: 00077 case ISD::FCEIL: 00078 case ISD::FCOS: 00079 case ISD::FEXP: 00080 case ISD::FEXP2: 00081 case ISD::FFLOOR: 00082 case ISD::FLOG: 00083 case ISD::FLOG10: 00084 case ISD::FLOG2: 00085 case ISD::FNEARBYINT: 00086 case ISD::FNEG: 00087 case ISD::FP_EXTEND: 00088 case ISD::FP_TO_SINT: 00089 case ISD::FP_TO_UINT: 00090 case ISD::FRINT: 00091 case ISD::FROUND: 00092 case ISD::FSIN: 00093 case ISD::FSQRT: 00094 case ISD::FTRUNC: 00095 case ISD::SIGN_EXTEND: 00096 case ISD::SINT_TO_FP: 00097 case ISD::TRUNCATE: 00098 case ISD::UINT_TO_FP: 00099 case ISD::ZERO_EXTEND: 00100 R = ScalarizeVecRes_UnaryOp(N); 00101 break; 00102 00103 case ISD::ADD: 00104 case ISD::AND: 00105 case ISD::FADD: 00106 case ISD::FCOPYSIGN: 00107 case ISD::FDIV: 00108 case ISD::FMUL: 00109 case ISD::FPOW: 00110 case ISD::FREM: 00111 case ISD::FSUB: 00112 case ISD::MUL: 00113 case ISD::OR: 00114 case ISD::SDIV: 00115 case ISD::SREM: 00116 case ISD::SUB: 00117 case ISD::UDIV: 00118 case ISD::UREM: 00119 case ISD::XOR: 00120 case ISD::SHL: 00121 case ISD::SRA: 00122 case ISD::SRL: 00123 R = ScalarizeVecRes_BinOp(N); 00124 break; 00125 case ISD::FMA: 00126 R = ScalarizeVecRes_TernaryOp(N); 00127 break; 00128 } 00129 00130 // If R is null, the sub-method took care of registering the result. 00131 if (R.getNode()) 00132 SetScalarizedVector(SDValue(N, ResNo), R); 00133 } 00134 00135 SDValue DAGTypeLegalizer::ScalarizeVecRes_BinOp(SDNode *N) { 00136 SDValue LHS = GetScalarizedVector(N->getOperand(0)); 00137 SDValue RHS = GetScalarizedVector(N->getOperand(1)); 00138 return DAG.getNode(N->getOpcode(), SDLoc(N), 00139 LHS.getValueType(), LHS, RHS); 00140 } 00141 00142 SDValue DAGTypeLegalizer::ScalarizeVecRes_TernaryOp(SDNode *N) { 00143 SDValue Op0 = GetScalarizedVector(N->getOperand(0)); 00144 SDValue Op1 = GetScalarizedVector(N->getOperand(1)); 00145 SDValue Op2 = GetScalarizedVector(N->getOperand(2)); 00146 return DAG.getNode(N->getOpcode(), SDLoc(N), 00147 Op0.getValueType(), Op0, Op1, Op2); 00148 } 00149 00150 SDValue DAGTypeLegalizer::ScalarizeVecRes_MERGE_VALUES(SDNode *N, 00151 unsigned ResNo) { 00152 SDValue Op = DisintegrateMERGE_VALUES(N, ResNo); 00153 return GetScalarizedVector(Op); 00154 } 00155 00156 SDValue DAGTypeLegalizer::ScalarizeVecRes_BITCAST(SDNode *N) { 00157 EVT NewVT = N->getValueType(0).getVectorElementType(); 00158 return DAG.getNode(ISD::BITCAST, SDLoc(N), 00159 NewVT, N->getOperand(0)); 00160 } 00161 00162 SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(SDNode *N) { 00163 EVT EltVT = N->getValueType(0).getVectorElementType(); 00164 SDValue InOp = N->getOperand(0); 00165 // The BUILD_VECTOR operands may be of wider element types and 00166 // we may need to truncate them back to the requested return type. 00167 if (EltVT.isInteger()) 00168 return DAG.getNode(ISD::TRUNCATE, SDLoc(N), EltVT, InOp); 00169 return InOp; 00170 } 00171 00172 SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_RNDSAT(SDNode *N) { 00173 EVT NewVT = N->getValueType(0).getVectorElementType(); 00174 SDValue Op0 = GetScalarizedVector(N->getOperand(0)); 00175 return DAG.getConvertRndSat(NewVT, SDLoc(N), 00176 Op0, DAG.getValueType(NewVT), 00177 DAG.getValueType(Op0.getValueType()), 00178 N->getOperand(3), 00179 N->getOperand(4), 00180 cast<CvtRndSatSDNode>(N)->getCvtCode()); 00181 } 00182 00183 SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N) { 00184 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), 00185 N->getValueType(0).getVectorElementType(), 00186 N->getOperand(0), N->getOperand(1)); 00187 } 00188 00189 SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_ROUND(SDNode *N) { 00190 EVT NewVT = N->getValueType(0).getVectorElementType(); 00191 SDValue Op = GetScalarizedVector(N->getOperand(0)); 00192 return DAG.getNode(ISD::FP_ROUND, SDLoc(N), 00193 NewVT, Op, N->getOperand(1)); 00194 } 00195 00196 SDValue DAGTypeLegalizer::ScalarizeVecRes_FPOWI(SDNode *N) { 00197 SDValue Op = GetScalarizedVector(N->getOperand(0)); 00198 return DAG.getNode(ISD::FPOWI, SDLoc(N), 00199 Op.getValueType(), Op, N->getOperand(1)); 00200 } 00201 00202 SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N) { 00203 // The value to insert may have a wider type than the vector element type, 00204 // so be sure to truncate it to the element type if necessary. 00205 SDValue Op = N->getOperand(1); 00206 EVT EltVT = N->getValueType(0).getVectorElementType(); 00207 if (Op.getValueType() != EltVT) 00208 // FIXME: Can this happen for floating point types? 00209 Op = DAG.getNode(ISD::TRUNCATE, SDLoc(N), EltVT, Op); 00210 return Op; 00211 } 00212 00213 SDValue DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) { 00214 assert(N->isUnindexed() && "Indexed vector load?"); 00215 00216 SDValue Result = DAG.getLoad(ISD::UNINDEXED, 00217 N->getExtensionType(), 00218 N->getValueType(0).getVectorElementType(), 00219 SDLoc(N), 00220 N->getChain(), N->getBasePtr(), 00221 DAG.getUNDEF(N->getBasePtr().getValueType()), 00222 N->getPointerInfo(), 00223 N->getMemoryVT().getVectorElementType(), 00224 N->isVolatile(), N->isNonTemporal(), 00225 N->isInvariant(), N->getOriginalAlignment(), 00226 N->getAAInfo()); 00227 00228 // Legalized the chain result - switch anything that used the old chain to 00229 // use the new one. 00230 ReplaceValueWith(SDValue(N, 1), Result.getValue(1)); 00231 return Result; 00232 } 00233 00234 SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(SDNode *N) { 00235 // Get the dest type - it doesn't always match the input type, e.g. int_to_fp. 00236 EVT DestVT = N->getValueType(0).getVectorElementType(); 00237 SDValue Op = GetScalarizedVector(N->getOperand(0)); 00238 return DAG.getNode(N->getOpcode(), SDLoc(N), DestVT, Op); 00239 } 00240 00241 SDValue DAGTypeLegalizer::ScalarizeVecRes_InregOp(SDNode *N) { 00242 EVT EltVT = N->getValueType(0).getVectorElementType(); 00243 EVT ExtVT = cast<VTSDNode>(N->getOperand(1))->getVT().getVectorElementType(); 00244 SDValue LHS = GetScalarizedVector(N->getOperand(0)); 00245 return DAG.getNode(N->getOpcode(), SDLoc(N), EltVT, 00246 LHS, DAG.getValueType(ExtVT)); 00247 } 00248 00249 SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N) { 00250 // If the operand is wider than the vector element type then it is implicitly 00251 // truncated. Make that explicit here. 00252 EVT EltVT = N->getValueType(0).getVectorElementType(); 00253 SDValue InOp = N->getOperand(0); 00254 if (InOp.getValueType() != EltVT) 00255 return DAG.getNode(ISD::TRUNCATE, SDLoc(N), EltVT, InOp); 00256 return InOp; 00257 } 00258 00259 SDValue DAGTypeLegalizer::ScalarizeVecRes_VSELECT(SDNode *N) { 00260 SDValue Cond = GetScalarizedVector(N->getOperand(0)); 00261 SDValue LHS = GetScalarizedVector(N->getOperand(1)); 00262 TargetLowering::BooleanContent ScalarBool = 00263 TLI.getBooleanContents(false, false); 00264 TargetLowering::BooleanContent VecBool = TLI.getBooleanContents(true, false); 00265 00266 // If integer and float booleans have different contents then we can't 00267 // reliably optimize in all cases. There is a full explanation for this in 00268 // DAGCombiner::visitSELECT() where the same issue affects folding 00269 // (select C, 0, 1) to (xor C, 1). 00270 if (TLI.getBooleanContents(false, false) != 00271 TLI.getBooleanContents(false, true)) { 00272 // At least try the common case where the boolean is generated by a 00273 // comparison. 00274 if (Cond->getOpcode() == ISD::SETCC) { 00275 EVT OpVT = Cond->getOperand(0)->getValueType(0); 00276 ScalarBool = TLI.getBooleanContents(OpVT.getScalarType()); 00277 VecBool = TLI.getBooleanContents(OpVT); 00278 } else 00279 ScalarBool = TargetLowering::UndefinedBooleanContent; 00280 } 00281 00282 if (ScalarBool != VecBool) { 00283 EVT CondVT = Cond.getValueType(); 00284 switch (ScalarBool) { 00285 case TargetLowering::UndefinedBooleanContent: 00286 break; 00287 case TargetLowering::ZeroOrOneBooleanContent: 00288 assert(VecBool == TargetLowering::UndefinedBooleanContent || 00289 VecBool == TargetLowering::ZeroOrNegativeOneBooleanContent); 00290 // Vector read from all ones, scalar expects a single 1 so mask. 00291 Cond = DAG.getNode(ISD::AND, SDLoc(N), CondVT, 00292 Cond, DAG.getConstant(1, CondVT)); 00293 break; 00294 case TargetLowering::ZeroOrNegativeOneBooleanContent: 00295 assert(VecBool == TargetLowering::UndefinedBooleanContent || 00296 VecBool == TargetLowering::ZeroOrOneBooleanContent); 00297 // Vector reads from a one, scalar from all ones so sign extend. 00298 Cond = DAG.getNode(ISD::SIGN_EXTEND_INREG, SDLoc(N), CondVT, 00299 Cond, DAG.getValueType(MVT::i1)); 00300 break; 00301 } 00302 } 00303 00304 return DAG.getSelect(SDLoc(N), 00305 LHS.getValueType(), Cond, LHS, 00306 GetScalarizedVector(N->getOperand(2))); 00307 } 00308 00309 SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT(SDNode *N) { 00310 SDValue LHS = GetScalarizedVector(N->getOperand(1)); 00311 return DAG.getSelect(SDLoc(N), 00312 LHS.getValueType(), N->getOperand(0), LHS, 00313 GetScalarizedVector(N->getOperand(2))); 00314 } 00315 00316 SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT_CC(SDNode *N) { 00317 SDValue LHS = GetScalarizedVector(N->getOperand(2)); 00318 return DAG.getNode(ISD::SELECT_CC, SDLoc(N), LHS.getValueType(), 00319 N->getOperand(0), N->getOperand(1), 00320 LHS, GetScalarizedVector(N->getOperand(3)), 00321 N->getOperand(4)); 00322 } 00323 00324 SDValue DAGTypeLegalizer::ScalarizeVecRes_SETCC(SDNode *N) { 00325 assert(N->getValueType(0).isVector() == 00326 N->getOperand(0).getValueType().isVector() && 00327 "Scalar/Vector type mismatch"); 00328 00329 if (N->getValueType(0).isVector()) return ScalarizeVecRes_VSETCC(N); 00330 00331 SDValue LHS = GetScalarizedVector(N->getOperand(0)); 00332 SDValue RHS = GetScalarizedVector(N->getOperand(1)); 00333 SDLoc DL(N); 00334 00335 // Turn it into a scalar SETCC. 00336 return DAG.getNode(ISD::SETCC, DL, MVT::i1, LHS, RHS, N->getOperand(2)); 00337 } 00338 00339 SDValue DAGTypeLegalizer::ScalarizeVecRes_UNDEF(SDNode *N) { 00340 return DAG.getUNDEF(N->getValueType(0).getVectorElementType()); 00341 } 00342 00343 SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N) { 00344 // Figure out if the scalar is the LHS or RHS and return it. 00345 SDValue Arg = N->getOperand(2).getOperand(0); 00346 if (Arg.getOpcode() == ISD::UNDEF) 00347 return DAG.getUNDEF(N->getValueType(0).getVectorElementType()); 00348 unsigned Op = !cast<ConstantSDNode>(Arg)->isNullValue(); 00349 return GetScalarizedVector(N->getOperand(Op)); 00350 } 00351 00352 SDValue DAGTypeLegalizer::ScalarizeVecRes_VSETCC(SDNode *N) { 00353 assert(N->getValueType(0).isVector() && 00354 N->getOperand(0).getValueType().isVector() && 00355 "Operand types must be vectors"); 00356 SDValue LHS = N->getOperand(0); 00357 SDValue RHS = N->getOperand(1); 00358 EVT OpVT = LHS.getValueType(); 00359 EVT NVT = N->getValueType(0).getVectorElementType(); 00360 SDLoc DL(N); 00361 00362 // The result needs scalarizing, but it's not a given that the source does. 00363 if (getTypeAction(OpVT) == TargetLowering::TypeScalarizeVector) { 00364 LHS = GetScalarizedVector(LHS); 00365 RHS = GetScalarizedVector(RHS); 00366 } else { 00367 EVT VT = OpVT.getVectorElementType(); 00368 LHS = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, LHS, 00369 DAG.getConstant(0, TLI.getVectorIdxTy())); 00370 RHS = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, RHS, 00371 DAG.getConstant(0, TLI.getVectorIdxTy())); 00372 } 00373 00374 // Turn it into a scalar SETCC. 00375 SDValue Res = DAG.getNode(ISD::SETCC, DL, MVT::i1, LHS, RHS, 00376 N->getOperand(2)); 00377 // Vectors may have a different boolean contents to scalars. Promote the 00378 // value appropriately. 00379 ISD::NodeType ExtendCode = 00380 TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT)); 00381 return DAG.getNode(ExtendCode, DL, NVT, Res); 00382 } 00383 00384 00385 //===----------------------------------------------------------------------===// 00386 // Operand Vector Scalarization <1 x ty> -> ty. 00387 //===----------------------------------------------------------------------===// 00388 00389 bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) { 00390 DEBUG(dbgs() << "Scalarize node operand " << OpNo << ": "; 00391 N->dump(&DAG); 00392 dbgs() << "\n"); 00393 SDValue Res = SDValue(); 00394 00395 if (!Res.getNode()) { 00396 switch (N->getOpcode()) { 00397 default: 00398 #ifndef NDEBUG 00399 dbgs() << "ScalarizeVectorOperand Op #" << OpNo << ": "; 00400 N->dump(&DAG); 00401 dbgs() << "\n"; 00402 #endif 00403 llvm_unreachable("Do not know how to scalarize this operator's operand!"); 00404 case ISD::BITCAST: 00405 Res = ScalarizeVecOp_BITCAST(N); 00406 break; 00407 case ISD::ANY_EXTEND: 00408 case ISD::ZERO_EXTEND: 00409 case ISD::SIGN_EXTEND: 00410 case ISD::TRUNCATE: 00411 Res = ScalarizeVecOp_UnaryOp(N); 00412 break; 00413 case ISD::CONCAT_VECTORS: 00414 Res = ScalarizeVecOp_CONCAT_VECTORS(N); 00415 break; 00416 case ISD::EXTRACT_VECTOR_ELT: 00417 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(N); 00418 break; 00419 case ISD::VSELECT: 00420 Res = ScalarizeVecOp_VSELECT(N); 00421 break; 00422 case ISD::STORE: 00423 Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(N), OpNo); 00424 break; 00425 case ISD::FP_ROUND: 00426 Res = ScalarizeVecOp_FP_ROUND(N, OpNo); 00427 break; 00428 } 00429 } 00430 00431 // If the result is null, the sub-method took care of registering results etc. 00432 if (!Res.getNode()) return false; 00433 00434 // If the result is N, the sub-method updated N in place. Tell the legalizer 00435 // core about this. 00436 if (Res.getNode() == N) 00437 return true; 00438 00439 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 00440 "Invalid operand expansion"); 00441 00442 ReplaceValueWith(SDValue(N, 0), Res); 00443 return false; 00444 } 00445 00446 /// ScalarizeVecOp_BITCAST - If the value to convert is a vector that needs 00447 /// to be scalarized, it must be <1 x ty>. Convert the element instead. 00448 SDValue DAGTypeLegalizer::ScalarizeVecOp_BITCAST(SDNode *N) { 00449 SDValue Elt = GetScalarizedVector(N->getOperand(0)); 00450 return DAG.getNode(ISD::BITCAST, SDLoc(N), 00451 N->getValueType(0), Elt); 00452 } 00453 00454 /// ScalarizeVecOp_EXTEND - If the value to extend is a vector that needs 00455 /// to be scalarized, it must be <1 x ty>. Extend the element instead. 00456 SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp(SDNode *N) { 00457 assert(N->getValueType(0).getVectorNumElements() == 1 && 00458 "Unexected vector type!"); 00459 SDValue Elt = GetScalarizedVector(N->getOperand(0)); 00460 SDValue Op = DAG.getNode(N->getOpcode(), SDLoc(N), 00461 N->getValueType(0).getScalarType(), Elt); 00462 // Revectorize the result so the types line up with what the uses of this 00463 // expression expect. 00464 return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(N), N->getValueType(0), Op); 00465 } 00466 00467 /// ScalarizeVecOp_CONCAT_VECTORS - The vectors to concatenate have length one - 00468 /// use a BUILD_VECTOR instead. 00469 SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(SDNode *N) { 00470 SmallVector<SDValue, 8> Ops(N->getNumOperands()); 00471 for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i) 00472 Ops[i] = GetScalarizedVector(N->getOperand(i)); 00473 return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(N), N->getValueType(0), Ops); 00474 } 00475 00476 /// ScalarizeVecOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to 00477 /// be scalarized, it must be <1 x ty>, so just return the element, ignoring the 00478 /// index. 00479 SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { 00480 SDValue Res = GetScalarizedVector(N->getOperand(0)); 00481 if (Res.getValueType() != N->getValueType(0)) 00482 Res = DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), N->getValueType(0), 00483 Res); 00484 return Res; 00485 } 00486 00487 00488 /// ScalarizeVecOp_VSELECT - If the input condition is a vector that needs to be 00489 /// scalarized, it must be <1 x i1>, so just convert to a normal ISD::SELECT 00490 /// (still with vector output type since that was acceptable if we got here). 00491 SDValue DAGTypeLegalizer::ScalarizeVecOp_VSELECT(SDNode *N) { 00492 SDValue ScalarCond = GetScalarizedVector(N->getOperand(0)); 00493 EVT VT = N->getValueType(0); 00494 00495 return DAG.getNode(ISD::SELECT, SDLoc(N), VT, ScalarCond, N->getOperand(1), 00496 N->getOperand(2)); 00497 } 00498 00499 /// ScalarizeVecOp_STORE - If the value to store is a vector that needs to be 00500 /// scalarized, it must be <1 x ty>. Just store the element. 00501 SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){ 00502 assert(N->isUnindexed() && "Indexed store of one-element vector?"); 00503 assert(OpNo == 1 && "Do not know how to scalarize this operand!"); 00504 SDLoc dl(N); 00505 00506 if (N->isTruncatingStore()) 00507 return DAG.getTruncStore(N->getChain(), dl, 00508 GetScalarizedVector(N->getOperand(1)), 00509 N->getBasePtr(), N->getPointerInfo(), 00510 N->getMemoryVT().getVectorElementType(), 00511 N->isVolatile(), N->isNonTemporal(), 00512 N->getAlignment(), N->getAAInfo()); 00513 00514 return DAG.getStore(N->getChain(), dl, GetScalarizedVector(N->getOperand(1)), 00515 N->getBasePtr(), N->getPointerInfo(), 00516 N->isVolatile(), N->isNonTemporal(), 00517 N->getOriginalAlignment(), N->getAAInfo()); 00518 } 00519 00520 /// ScalarizeVecOp_FP_ROUND - If the value to round is a vector that needs 00521 /// to be scalarized, it must be <1 x ty>. Convert the element instead. 00522 SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(SDNode *N, unsigned OpNo) { 00523 SDValue Elt = GetScalarizedVector(N->getOperand(0)); 00524 SDValue Res = DAG.getNode(ISD::FP_ROUND, SDLoc(N), 00525 N->getValueType(0).getVectorElementType(), Elt, 00526 N->getOperand(1)); 00527 return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res); 00528 } 00529 00530 //===----------------------------------------------------------------------===// 00531 // Result Vector Splitting 00532 //===----------------------------------------------------------------------===// 00533 00534 /// SplitVectorResult - This method is called when the specified result of the 00535 /// specified node is found to need vector splitting. At this point, the node 00536 /// may also have invalid operands or may have other results that need 00537 /// legalization, we just know that (at least) one result needs vector 00538 /// splitting. 00539 void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) { 00540 DEBUG(dbgs() << "Split node result: "; 00541 N->dump(&DAG); 00542 dbgs() << "\n"); 00543 SDValue Lo, Hi; 00544 00545 // See if the target wants to custom expand this node. 00546 if (CustomLowerNode(N, N->getValueType(ResNo), true)) 00547 return; 00548 00549 switch (N->getOpcode()) { 00550 default: 00551 #ifndef NDEBUG 00552 dbgs() << "SplitVectorResult #" << ResNo << ": "; 00553 N->dump(&DAG); 00554 dbgs() << "\n"; 00555 #endif 00556 report_fatal_error("Do not know how to split the result of this " 00557 "operator!\n"); 00558 00559 case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, ResNo, Lo, Hi); break; 00560 case ISD::VSELECT: 00561 case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; 00562 case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; 00563 case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; 00564 case ISD::BITCAST: SplitVecRes_BITCAST(N, Lo, Hi); break; 00565 case ISD::BUILD_VECTOR: SplitVecRes_BUILD_VECTOR(N, Lo, Hi); break; 00566 case ISD::CONCAT_VECTORS: SplitVecRes_CONCAT_VECTORS(N, Lo, Hi); break; 00567 case ISD::EXTRACT_SUBVECTOR: SplitVecRes_EXTRACT_SUBVECTOR(N, Lo, Hi); break; 00568 case ISD::INSERT_SUBVECTOR: SplitVecRes_INSERT_SUBVECTOR(N, Lo, Hi); break; 00569 case ISD::FP_ROUND_INREG: SplitVecRes_InregOp(N, Lo, Hi); break; 00570 case ISD::FPOWI: SplitVecRes_FPOWI(N, Lo, Hi); break; 00571 case ISD::INSERT_VECTOR_ELT: SplitVecRes_INSERT_VECTOR_ELT(N, Lo, Hi); break; 00572 case ISD::SCALAR_TO_VECTOR: SplitVecRes_SCALAR_TO_VECTOR(N, Lo, Hi); break; 00573 case ISD::SIGN_EXTEND_INREG: SplitVecRes_InregOp(N, Lo, Hi); break; 00574 case ISD::LOAD: 00575 SplitVecRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); 00576 break; 00577 case ISD::SETCC: 00578 SplitVecRes_SETCC(N, Lo, Hi); 00579 break; 00580 case ISD::VECTOR_SHUFFLE: 00581 SplitVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N), Lo, Hi); 00582 break; 00583 00584 case ISD::BSWAP: 00585 case ISD::CONVERT_RNDSAT: 00586 case ISD::CTLZ: 00587 case ISD::CTTZ: 00588 case ISD::CTLZ_ZERO_UNDEF: 00589 case ISD::CTTZ_ZERO_UNDEF: 00590 case ISD::CTPOP: 00591 case ISD::FABS: 00592 case ISD::FCEIL: 00593 case ISD::FCOS: 00594 case ISD::FEXP: 00595 case ISD::FEXP2: 00596 case ISD::FFLOOR: 00597 case ISD::FLOG: 00598 case ISD::FLOG10: 00599 case ISD::FLOG2: 00600 case ISD::FNEARBYINT: 00601 case ISD::FNEG: 00602 case ISD::FP_EXTEND: 00603 case ISD::FP_ROUND: 00604 case ISD::FP_TO_SINT: 00605 case ISD::FP_TO_UINT: 00606 case ISD::FRINT: 00607 case ISD::FROUND: 00608 case ISD::FSIN: 00609 case ISD::FSQRT: 00610 case ISD::FTRUNC: 00611 case ISD::SINT_TO_FP: 00612 case ISD::TRUNCATE: 00613 case ISD::UINT_TO_FP: 00614 SplitVecRes_UnaryOp(N, Lo, Hi); 00615 break; 00616 00617 case ISD::ANY_EXTEND: 00618 case ISD::SIGN_EXTEND: 00619 case ISD::ZERO_EXTEND: 00620 SplitVecRes_ExtendOp(N, Lo, Hi); 00621 break; 00622 00623 case ISD::ADD: 00624 case ISD::SUB: 00625 case ISD::MUL: 00626 case ISD::FADD: 00627 case ISD::FCOPYSIGN: 00628 case ISD::FSUB: 00629 case ISD::FMUL: 00630 case ISD::SDIV: 00631 case ISD::UDIV: 00632 case ISD::FDIV: 00633 case ISD::FPOW: 00634 case ISD::AND: 00635 case ISD::OR: 00636 case ISD::XOR: 00637 case ISD::SHL: 00638 case ISD::SRA: 00639 case ISD::SRL: 00640 case ISD::UREM: 00641 case ISD::SREM: 00642 case ISD::FREM: 00643 SplitVecRes_BinOp(N, Lo, Hi); 00644 break; 00645 case ISD::FMA: 00646 SplitVecRes_TernaryOp(N, Lo, Hi); 00647 break; 00648 } 00649 00650 // If Lo/Hi is null, the sub-method took care of registering results etc. 00651 if (Lo.getNode()) 00652 SetSplitVector(SDValue(N, ResNo), Lo, Hi); 00653 } 00654 00655 void DAGTypeLegalizer::SplitVecRes_BinOp(SDNode *N, SDValue &Lo, 00656 SDValue &Hi) { 00657 SDValue LHSLo, LHSHi; 00658 GetSplitVector(N->getOperand(0), LHSLo, LHSHi); 00659 SDValue RHSLo, RHSHi; 00660 GetSplitVector(N->getOperand(1), RHSLo, RHSHi); 00661 SDLoc dl(N); 00662 00663 Lo = DAG.getNode(N->getOpcode(), dl, LHSLo.getValueType(), LHSLo, RHSLo); 00664 Hi = DAG.getNode(N->getOpcode(), dl, LHSHi.getValueType(), LHSHi, RHSHi); 00665 } 00666 00667 void DAGTypeLegalizer::SplitVecRes_TernaryOp(SDNode *N, SDValue &Lo, 00668 SDValue &Hi) { 00669 SDValue Op0Lo, Op0Hi; 00670 GetSplitVector(N->getOperand(0), Op0Lo, Op0Hi); 00671 SDValue Op1Lo, Op1Hi; 00672 GetSplitVector(N->getOperand(1), Op1Lo, Op1Hi); 00673 SDValue Op2Lo, Op2Hi; 00674 GetSplitVector(N->getOperand(2), Op2Lo, Op2Hi); 00675 SDLoc dl(N); 00676 00677 Lo = DAG.getNode(N->getOpcode(), dl, Op0Lo.getValueType(), 00678 Op0Lo, Op1Lo, Op2Lo); 00679 Hi = DAG.getNode(N->getOpcode(), dl, Op0Hi.getValueType(), 00680 Op0Hi, Op1Hi, Op2Hi); 00681 } 00682 00683 void DAGTypeLegalizer::SplitVecRes_BITCAST(SDNode *N, SDValue &Lo, 00684 SDValue &Hi) { 00685 // We know the result is a vector. The input may be either a vector or a 00686 // scalar value. 00687 EVT LoVT, HiVT; 00688 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); 00689 SDLoc dl(N); 00690 00691 SDValue InOp = N->getOperand(0); 00692 EVT InVT = InOp.getValueType(); 00693 00694 // Handle some special cases efficiently. 00695 switch (getTypeAction(InVT)) { 00696 case TargetLowering::TypeLegal: 00697 case TargetLowering::TypePromoteInteger: 00698 case TargetLowering::TypeSoftenFloat: 00699 case TargetLowering::TypeScalarizeVector: 00700 case TargetLowering::TypeWidenVector: 00701 break; 00702 case TargetLowering::TypeExpandInteger: 00703 case TargetLowering::TypeExpandFloat: 00704 // A scalar to vector conversion, where the scalar needs expansion. 00705 // If the vector is being split in two then we can just convert the 00706 // expanded pieces. 00707 if (LoVT == HiVT) { 00708 GetExpandedOp(InOp, Lo, Hi); 00709 if (TLI.isBigEndian()) 00710 std::swap(Lo, Hi); 00711 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, Lo); 00712 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, Hi); 00713 return; 00714 } 00715 break; 00716 case TargetLowering::TypeSplitVector: 00717 // If the input is a vector that needs to be split, convert each split 00718 // piece of the input now. 00719 GetSplitVector(InOp, Lo, Hi); 00720 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, Lo); 00721 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, Hi); 00722 return; 00723 } 00724 00725 // In the general case, convert the input to an integer and split it by hand. 00726 EVT LoIntVT = EVT::getIntegerVT(*DAG.getContext(), LoVT.getSizeInBits()); 00727 EVT HiIntVT = EVT::getIntegerVT(*DAG.getContext(), HiVT.getSizeInBits()); 00728 if (TLI.isBigEndian()) 00729 std::swap(LoIntVT, HiIntVT); 00730 00731 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT, Lo, Hi); 00732 00733 if (TLI.isBigEndian()) 00734 std::swap(Lo, Hi); 00735 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, Lo); 00736 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, Hi); 00737 } 00738 00739 void DAGTypeLegalizer::SplitVecRes_BUILD_VECTOR(SDNode *N, SDValue &Lo, 00740 SDValue &Hi) { 00741 EVT LoVT, HiVT; 00742 SDLoc dl(N); 00743 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); 00744 unsigned LoNumElts = LoVT.getVectorNumElements(); 00745 SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+LoNumElts); 00746 Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, LoVT, LoOps); 00747 00748 SmallVector<SDValue, 8> HiOps(N->op_begin()+LoNumElts, N->op_end()); 00749 Hi = DAG.getNode(ISD::BUILD_VECTOR, dl, HiVT, HiOps); 00750 } 00751 00752 void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo, 00753 SDValue &Hi) { 00754 assert(!(N->getNumOperands() & 1) && "Unsupported CONCAT_VECTORS"); 00755 SDLoc dl(N); 00756 unsigned NumSubvectors = N->getNumOperands() / 2; 00757 if (NumSubvectors == 1) { 00758 Lo = N->getOperand(0); 00759 Hi = N->getOperand(1); 00760 return; 00761 } 00762 00763 EVT LoVT, HiVT; 00764 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); 00765 00766 SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+NumSubvectors); 00767 Lo = DAG.getNode(ISD::CONCAT_VECTORS, dl, LoVT, LoOps); 00768 00769 SmallVector<SDValue, 8> HiOps(N->op_begin()+NumSubvectors, N->op_end()); 00770 Hi = DAG.getNode(ISD::CONCAT_VECTORS, dl, HiVT, HiOps); 00771 } 00772 00773 void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo, 00774 SDValue &Hi) { 00775 SDValue Vec = N->getOperand(0); 00776 SDValue Idx = N->getOperand(1); 00777 SDLoc dl(N); 00778 00779 EVT LoVT, HiVT; 00780 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); 00781 00782 Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, LoVT, Vec, Idx); 00783 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue(); 00784 Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HiVT, Vec, 00785 DAG.getConstant(IdxVal + LoVT.getVectorNumElements(), 00786 TLI.getVectorIdxTy())); 00787 } 00788 00789 void DAGTypeLegalizer::SplitVecRes_INSERT_SUBVECTOR(SDNode *N, SDValue &Lo, 00790 SDValue &Hi) { 00791 SDValue Vec = N->getOperand(0); 00792 SDValue SubVec = N->getOperand(1); 00793 SDValue Idx = N->getOperand(2); 00794 SDLoc dl(N); 00795 GetSplitVector(Vec, Lo, Hi); 00796 00797 // Spill the vector to the stack. 00798 EVT VecVT = Vec.getValueType(); 00799 EVT SubVecVT = VecVT.getVectorElementType(); 00800 SDValue StackPtr = DAG.CreateStackTemporary(VecVT); 00801 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, 00802 MachinePointerInfo(), false, false, 0); 00803 00804 // Store the new subvector into the specified index. 00805 SDValue SubVecPtr = GetVectorElementPointer(StackPtr, SubVecVT, Idx); 00806 Type *VecType = VecVT.getTypeForEVT(*DAG.getContext()); 00807 unsigned Alignment = TLI.getDataLayout()->getPrefTypeAlignment(VecType); 00808 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr, MachinePointerInfo(), 00809 false, false, 0); 00810 00811 // Load the Lo part from the stack slot. 00812 Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, MachinePointerInfo(), 00813 false, false, false, 0); 00814 00815 // Increment the pointer to the other part. 00816 unsigned IncrementSize = Lo.getValueType().getSizeInBits() / 8; 00817 StackPtr = 00818 DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 00819 DAG.getConstant(IncrementSize, StackPtr.getValueType())); 00820 00821 // Load the Hi part from the stack slot. 00822 Hi = DAG.getLoad(Hi.getValueType(), dl, Store, StackPtr, MachinePointerInfo(), 00823 false, false, false, MinAlign(Alignment, IncrementSize)); 00824 } 00825 00826 void DAGTypeLegalizer::SplitVecRes_FPOWI(SDNode *N, SDValue &Lo, 00827 SDValue &Hi) { 00828 SDLoc dl(N); 00829 GetSplitVector(N->getOperand(0), Lo, Hi); 00830 Lo = DAG.getNode(ISD::FPOWI, dl, Lo.getValueType(), Lo, N->getOperand(1)); 00831 Hi = DAG.getNode(ISD::FPOWI, dl, Hi.getValueType(), Hi, N->getOperand(1)); 00832 } 00833 00834 void DAGTypeLegalizer::SplitVecRes_InregOp(SDNode *N, SDValue &Lo, 00835 SDValue &Hi) { 00836 SDValue LHSLo, LHSHi; 00837 GetSplitVector(N->getOperand(0), LHSLo, LHSHi); 00838 SDLoc dl(N); 00839 00840 EVT LoVT, HiVT; 00841 std::tie(LoVT, HiVT) = 00842 DAG.GetSplitDestVTs(cast<VTSDNode>(N->getOperand(1))->getVT()); 00843 00844 Lo = DAG.getNode(N->getOpcode(), dl, LHSLo.getValueType(), LHSLo, 00845 DAG.getValueType(LoVT)); 00846 Hi = DAG.getNode(N->getOpcode(), dl, LHSHi.getValueType(), LHSHi, 00847 DAG.getValueType(HiVT)); 00848 } 00849 00850 void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, 00851 SDValue &Hi) { 00852 SDValue Vec = N->getOperand(0); 00853 SDValue Elt = N->getOperand(1); 00854 SDValue Idx = N->getOperand(2); 00855 SDLoc dl(N); 00856 GetSplitVector(Vec, Lo, Hi); 00857 00858 if (ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Idx)) { 00859 unsigned IdxVal = CIdx->getZExtValue(); 00860 unsigned LoNumElts = Lo.getValueType().getVectorNumElements(); 00861 if (IdxVal < LoNumElts) 00862 Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, 00863 Lo.getValueType(), Lo, Elt, Idx); 00864 else 00865 Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, Hi.getValueType(), Hi, Elt, 00866 DAG.getConstant(IdxVal - LoNumElts, 00867 TLI.getVectorIdxTy())); 00868 return; 00869 } 00870 00871 // See if the target wants to custom expand this node. 00872 if (CustomLowerNode(N, N->getValueType(0), true)) 00873 return; 00874 00875 // Spill the vector to the stack. 00876 EVT VecVT = Vec.getValueType(); 00877 EVT EltVT = VecVT.getVectorElementType(); 00878 SDValue StackPtr = DAG.CreateStackTemporary(VecVT); 00879 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, 00880 MachinePointerInfo(), false, false, 0); 00881 00882 // Store the new element. This may be larger than the vector element type, 00883 // so use a truncating store. 00884 SDValue EltPtr = GetVectorElementPointer(StackPtr, EltVT, Idx); 00885 Type *VecType = VecVT.getTypeForEVT(*DAG.getContext()); 00886 unsigned Alignment = 00887 TLI.getDataLayout()->getPrefTypeAlignment(VecType); 00888 Store = DAG.getTruncStore(Store, dl, Elt, EltPtr, MachinePointerInfo(), EltVT, 00889 false, false, 0); 00890 00891 // Load the Lo part from the stack slot. 00892 Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, MachinePointerInfo(), 00893 false, false, false, 0); 00894 00895 // Increment the pointer to the other part. 00896 unsigned IncrementSize = Lo.getValueType().getSizeInBits() / 8; 00897 StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 00898 DAG.getConstant(IncrementSize, StackPtr.getValueType())); 00899 00900 // Load the Hi part from the stack slot. 00901 Hi = DAG.getLoad(Hi.getValueType(), dl, Store, StackPtr, MachinePointerInfo(), 00902 false, false, false, MinAlign(Alignment, IncrementSize)); 00903 } 00904 00905 void DAGTypeLegalizer::SplitVecRes_SCALAR_TO_VECTOR(SDNode *N, SDValue &Lo, 00906 SDValue &Hi) { 00907 EVT LoVT, HiVT; 00908 SDLoc dl(N); 00909 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); 00910 Lo = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, LoVT, N->getOperand(0)); 00911 Hi = DAG.getUNDEF(HiVT); 00912 } 00913 00914 void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo, 00915 SDValue &Hi) { 00916 assert(ISD::isUNINDEXEDLoad(LD) && "Indexed load during type legalization!"); 00917 EVT LoVT, HiVT; 00918 SDLoc dl(LD); 00919 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(LD->getValueType(0)); 00920 00921 ISD::LoadExtType ExtType = LD->getExtensionType(); 00922 SDValue Ch = LD->getChain(); 00923 SDValue Ptr = LD->getBasePtr(); 00924 SDValue Offset = DAG.getUNDEF(Ptr.getValueType()); 00925 EVT MemoryVT = LD->getMemoryVT(); 00926 unsigned Alignment = LD->getOriginalAlignment(); 00927 bool isVolatile = LD->isVolatile(); 00928 bool isNonTemporal = LD->isNonTemporal(); 00929 bool isInvariant = LD->isInvariant(); 00930 AAMDNodes AAInfo = LD->getAAInfo(); 00931 00932 EVT LoMemVT, HiMemVT; 00933 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT); 00934 00935 Lo = DAG.getLoad(ISD::UNINDEXED, ExtType, LoVT, dl, Ch, Ptr, Offset, 00936 LD->getPointerInfo(), LoMemVT, isVolatile, isNonTemporal, 00937 isInvariant, Alignment, AAInfo); 00938 00939 unsigned IncrementSize = LoMemVT.getSizeInBits()/8; 00940 Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 00941 DAG.getConstant(IncrementSize, Ptr.getValueType())); 00942 Hi = DAG.getLoad(ISD::UNINDEXED, ExtType, HiVT, dl, Ch, Ptr, Offset, 00943 LD->getPointerInfo().getWithOffset(IncrementSize), 00944 HiMemVT, isVolatile, isNonTemporal, isInvariant, Alignment, 00945 AAInfo); 00946 00947 // Build a factor node to remember that this load is independent of the 00948 // other one. 00949 Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 00950 Hi.getValue(1)); 00951 00952 // Legalized the chain result - switch anything that used the old chain to 00953 // use the new one. 00954 ReplaceValueWith(SDValue(LD, 1), Ch); 00955 } 00956 00957 void DAGTypeLegalizer::SplitVecRes_SETCC(SDNode *N, SDValue &Lo, SDValue &Hi) { 00958 assert(N->getValueType(0).isVector() && 00959 N->getOperand(0).getValueType().isVector() && 00960 "Operand types must be vectors"); 00961 00962 EVT LoVT, HiVT; 00963 SDLoc DL(N); 00964 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); 00965 00966 // Split the input. 00967 SDValue LL, LH, RL, RH; 00968 std::tie(LL, LH) = DAG.SplitVectorOperand(N, 0); 00969 std::tie(RL, RH) = DAG.SplitVectorOperand(N, 1); 00970 00971 Lo = DAG.getNode(N->getOpcode(), DL, LoVT, LL, RL, N->getOperand(2)); 00972 Hi = DAG.getNode(N->getOpcode(), DL, HiVT, LH, RH, N->getOperand(2)); 00973 } 00974 00975 void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo, 00976 SDValue &Hi) { 00977 // Get the dest types - they may not match the input types, e.g. int_to_fp. 00978 EVT LoVT, HiVT; 00979 SDLoc dl(N); 00980 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); 00981 00982 // If the input also splits, handle it directly for a compile time speedup. 00983 // Otherwise split it by hand. 00984 EVT InVT = N->getOperand(0).getValueType(); 00985 if (getTypeAction(InVT) == TargetLowering::TypeSplitVector) 00986 GetSplitVector(N->getOperand(0), Lo, Hi); 00987 else 00988 std::tie(Lo, Hi) = DAG.SplitVectorOperand(N, 0); 00989 00990 if (N->getOpcode() == ISD::FP_ROUND) { 00991 Lo = DAG.getNode(N->getOpcode(), dl, LoVT, Lo, N->getOperand(1)); 00992 Hi = DAG.getNode(N->getOpcode(), dl, HiVT, Hi, N->getOperand(1)); 00993 } else if (N->getOpcode() == ISD::CONVERT_RNDSAT) { 00994 SDValue DTyOpLo = DAG.getValueType(LoVT); 00995 SDValue DTyOpHi = DAG.getValueType(HiVT); 00996 SDValue STyOpLo = DAG.getValueType(Lo.getValueType()); 00997 SDValue STyOpHi = DAG.getValueType(Hi.getValueType()); 00998 SDValue RndOp = N->getOperand(3); 00999 SDValue SatOp = N->getOperand(4); 01000 ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode(); 01001 Lo = DAG.getConvertRndSat(LoVT, dl, Lo, DTyOpLo, STyOpLo, RndOp, SatOp, 01002 CvtCode); 01003 Hi = DAG.getConvertRndSat(HiVT, dl, Hi, DTyOpHi, STyOpHi, RndOp, SatOp, 01004 CvtCode); 01005 } else { 01006 Lo = DAG.getNode(N->getOpcode(), dl, LoVT, Lo); 01007 Hi = DAG.getNode(N->getOpcode(), dl, HiVT, Hi); 01008 } 01009 } 01010 01011 void DAGTypeLegalizer::SplitVecRes_ExtendOp(SDNode *N, SDValue &Lo, 01012 SDValue &Hi) { 01013 SDLoc dl(N); 01014 EVT SrcVT = N->getOperand(0).getValueType(); 01015 EVT DestVT = N->getValueType(0); 01016 EVT LoVT, HiVT; 01017 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT); 01018 01019 // We can do better than a generic split operation if the extend is doing 01020 // more than just doubling the width of the elements and the following are 01021 // true: 01022 // - The number of vector elements is even, 01023 // - the source type is legal, 01024 // - the type of a split source is illegal, 01025 // - the type of an extended (by doubling element size) source is legal, and 01026 // - the type of that extended source when split is legal. 01027 // 01028 // This won't necessarily completely legalize the operation, but it will 01029 // more effectively move in the right direction and prevent falling down 01030 // to scalarization in many cases due to the input vector being split too 01031 // far. 01032 unsigned NumElements = SrcVT.getVectorNumElements(); 01033 if ((NumElements & 1) == 0 && 01034 SrcVT.getSizeInBits() * 2 < DestVT.getSizeInBits()) { 01035 LLVMContext &Ctx = *DAG.getContext(); 01036 EVT NewSrcVT = EVT::getVectorVT( 01037 Ctx, EVT::getIntegerVT( 01038 Ctx, SrcVT.getVectorElementType().getSizeInBits() * 2), 01039 NumElements); 01040 EVT SplitSrcVT = 01041 EVT::getVectorVT(Ctx, SrcVT.getVectorElementType(), NumElements / 2); 01042 EVT SplitLoVT, SplitHiVT; 01043 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT); 01044 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) && 01045 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) { 01046 DEBUG(dbgs() << "Split vector extend via incremental extend:"; 01047 N->dump(&DAG); dbgs() << "\n"); 01048 // Extend the source vector by one step. 01049 SDValue NewSrc = 01050 DAG.getNode(N->getOpcode(), dl, NewSrcVT, N->getOperand(0)); 01051 // Get the low and high halves of the new, extended one step, vector. 01052 std::tie(Lo, Hi) = DAG.SplitVector(NewSrc, dl); 01053 // Extend those vector halves the rest of the way. 01054 Lo = DAG.getNode(N->getOpcode(), dl, LoVT, Lo); 01055 Hi = DAG.getNode(N->getOpcode(), dl, HiVT, Hi); 01056 return; 01057 } 01058 } 01059 // Fall back to the generic unary operator splitting otherwise. 01060 SplitVecRes_UnaryOp(N, Lo, Hi); 01061 } 01062 01063 void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N, 01064 SDValue &Lo, SDValue &Hi) { 01065 // The low and high parts of the original input give four input vectors. 01066 SDValue Inputs[4]; 01067 SDLoc dl(N); 01068 GetSplitVector(N->getOperand(0), Inputs[0], Inputs[1]); 01069 GetSplitVector(N->getOperand(1), Inputs[2], Inputs[3]); 01070 EVT NewVT = Inputs[0].getValueType(); 01071 unsigned NewElts = NewVT.getVectorNumElements(); 01072 01073 // If Lo or Hi uses elements from at most two of the four input vectors, then 01074 // express it as a vector shuffle of those two inputs. Otherwise extract the 01075 // input elements by hand and construct the Lo/Hi output using a BUILD_VECTOR. 01076 SmallVector<int, 16> Ops; 01077 for (unsigned High = 0; High < 2; ++High) { 01078 SDValue &Output = High ? Hi : Lo; 01079 01080 // Build a shuffle mask for the output, discovering on the fly which 01081 // input vectors to use as shuffle operands (recorded in InputUsed). 01082 // If building a suitable shuffle vector proves too hard, then bail 01083 // out with useBuildVector set. 01084 unsigned InputUsed[2] = { -1U, -1U }; // Not yet discovered. 01085 unsigned FirstMaskIdx = High * NewElts; 01086 bool useBuildVector = false; 01087 for (unsigned MaskOffset = 0; MaskOffset < NewElts; ++MaskOffset) { 01088 // The mask element. This indexes into the input. 01089 int Idx = N->getMaskElt(FirstMaskIdx + MaskOffset); 01090 01091 // The input vector this mask element indexes into. 01092 unsigned Input = (unsigned)Idx / NewElts; 01093 01094 if (Input >= array_lengthof(Inputs)) { 01095 // The mask element does not index into any input vector. 01096 Ops.push_back(-1); 01097 continue; 01098 } 01099 01100 // Turn the index into an offset from the start of the input vector. 01101 Idx -= Input * NewElts; 01102 01103 // Find or create a shuffle vector operand to hold this input. 01104 unsigned OpNo; 01105 for (OpNo = 0; OpNo < array_lengthof(InputUsed); ++OpNo) { 01106 if (InputUsed[OpNo] == Input) { 01107 // This input vector is already an operand. 01108 break; 01109 } else if (InputUsed[OpNo] == -1U) { 01110 // Create a new operand for this input vector. 01111 InputUsed[OpNo] = Input; 01112 break; 01113 } 01114 } 01115 01116 if (OpNo >= array_lengthof(InputUsed)) { 01117 // More than two input vectors used! Give up on trying to create a 01118 // shuffle vector. Insert all elements into a BUILD_VECTOR instead. 01119 useBuildVector = true; 01120 break; 01121 } 01122 01123 // Add the mask index for the new shuffle vector. 01124 Ops.push_back(Idx + OpNo * NewElts); 01125 } 01126 01127 if (useBuildVector) { 01128 EVT EltVT = NewVT.getVectorElementType(); 01129 SmallVector<SDValue, 16> SVOps; 01130 01131 // Extract the input elements by hand. 01132 for (unsigned MaskOffset = 0; MaskOffset < NewElts; ++MaskOffset) { 01133 // The mask element. This indexes into the input. 01134 int Idx = N->getMaskElt(FirstMaskIdx + MaskOffset); 01135 01136 // The input vector this mask element indexes into. 01137 unsigned Input = (unsigned)Idx / NewElts; 01138 01139 if (Input >= array_lengthof(Inputs)) { 01140 // The mask element is "undef" or indexes off the end of the input. 01141 SVOps.push_back(DAG.getUNDEF(EltVT)); 01142 continue; 01143 } 01144 01145 // Turn the index into an offset from the start of the input vector. 01146 Idx -= Input * NewElts; 01147 01148 // Extract the vector element by hand. 01149 SVOps.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, 01150 Inputs[Input], DAG.getConstant(Idx, 01151 TLI.getVectorIdxTy()))); 01152 } 01153 01154 // Construct the Lo/Hi output using a BUILD_VECTOR. 01155 Output = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT, SVOps); 01156 } else if (InputUsed[0] == -1U) { 01157 // No input vectors were used! The result is undefined. 01158 Output = DAG.getUNDEF(NewVT); 01159 } else { 01160 SDValue Op0 = Inputs[InputUsed[0]]; 01161 // If only one input was used, use an undefined vector for the other. 01162 SDValue Op1 = InputUsed[1] == -1U ? 01163 DAG.getUNDEF(NewVT) : Inputs[InputUsed[1]]; 01164 // At least one input vector was used. Create a new shuffle vector. 01165 Output = DAG.getVectorShuffle(NewVT, dl, Op0, Op1, &Ops[0]); 01166 } 01167 01168 Ops.clear(); 01169 } 01170 } 01171 01172 01173 //===----------------------------------------------------------------------===// 01174 // Operand Vector Splitting 01175 //===----------------------------------------------------------------------===// 01176 01177 /// SplitVectorOperand - This method is called when the specified operand of the 01178 /// specified node is found to need vector splitting. At this point, all of the 01179 /// result types of the node are known to be legal, but other operands of the 01180 /// node may need legalization as well as the specified one. 01181 bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) { 01182 DEBUG(dbgs() << "Split node operand: "; 01183 N->dump(&DAG); 01184 dbgs() << "\n"); 01185 SDValue Res = SDValue(); 01186 01187 // See if the target wants to custom split this node. 01188 if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) 01189 return false; 01190 01191 if (!Res.getNode()) { 01192 switch (N->getOpcode()) { 01193 default: 01194 #ifndef NDEBUG 01195 dbgs() << "SplitVectorOperand Op #" << OpNo << ": "; 01196 N->dump(&DAG); 01197 dbgs() << "\n"; 01198 #endif 01199 report_fatal_error("Do not know how to split this operator's " 01200 "operand!\n"); 01201 01202 case ISD::SETCC: Res = SplitVecOp_VSETCC(N); break; 01203 case ISD::BITCAST: Res = SplitVecOp_BITCAST(N); break; 01204 case ISD::EXTRACT_SUBVECTOR: Res = SplitVecOp_EXTRACT_SUBVECTOR(N); break; 01205 case ISD::EXTRACT_VECTOR_ELT:Res = SplitVecOp_EXTRACT_VECTOR_ELT(N); break; 01206 case ISD::CONCAT_VECTORS: Res = SplitVecOp_CONCAT_VECTORS(N); break; 01207 case ISD::TRUNCATE: Res = SplitVecOp_TRUNCATE(N); break; 01208 case ISD::FP_ROUND: Res = SplitVecOp_FP_ROUND(N); break; 01209 case ISD::STORE: 01210 Res = SplitVecOp_STORE(cast<StoreSDNode>(N), OpNo); 01211 break; 01212 case ISD::VSELECT: 01213 Res = SplitVecOp_VSELECT(N, OpNo); 01214 break; 01215 case ISD::CTTZ: 01216 case ISD::CTLZ: 01217 case ISD::CTPOP: 01218 case ISD::FP_EXTEND: 01219 case ISD::FP_TO_SINT: 01220 case ISD::FP_TO_UINT: 01221 case ISD::SINT_TO_FP: 01222 case ISD::UINT_TO_FP: 01223 case ISD::FTRUNC: 01224 case ISD::SIGN_EXTEND: 01225 case ISD::ZERO_EXTEND: 01226 case ISD::ANY_EXTEND: 01227 Res = SplitVecOp_UnaryOp(N); 01228 break; 01229 } 01230 } 01231 01232 // If the result is null, the sub-method took care of registering results etc. 01233 if (!Res.getNode()) return false; 01234 01235 // If the result is N, the sub-method updated N in place. Tell the legalizer 01236 // core about this. 01237 if (Res.getNode() == N) 01238 return true; 01239 01240 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 01241 "Invalid operand expansion"); 01242 01243 ReplaceValueWith(SDValue(N, 0), Res); 01244 return false; 01245 } 01246 01247 SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(SDNode *N, unsigned OpNo) { 01248 // The only possibility for an illegal operand is the mask, since result type 01249 // legalization would have handled this node already otherwise. 01250 assert(OpNo == 0 && "Illegal operand must be mask"); 01251 01252 SDValue Mask = N->getOperand(0); 01253 SDValue Src0 = N->getOperand(1); 01254 SDValue Src1 = N->getOperand(2); 01255 EVT Src0VT = Src0.getValueType(); 01256 SDLoc DL(N); 01257 assert(Mask.getValueType().isVector() && "VSELECT without a vector mask?"); 01258 01259 SDValue Lo, Hi; 01260 GetSplitVector(N->getOperand(0), Lo, Hi); 01261 assert(Lo.getValueType() == Hi.getValueType() && 01262 "Lo and Hi have differing types"); 01263 01264 EVT LoOpVT, HiOpVT; 01265 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT); 01266 assert(LoOpVT == HiOpVT && "Asymmetric vector split?"); 01267 01268 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask; 01269 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0, DL); 01270 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1, DL); 01271 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask, DL); 01272 01273 SDValue LoSelect = 01274 DAG.getNode(ISD::VSELECT, DL, LoOpVT, LoMask, LoOp0, LoOp1); 01275 SDValue HiSelect = 01276 DAG.getNode(ISD::VSELECT, DL, HiOpVT, HiMask, HiOp0, HiOp1); 01277 01278 return DAG.getNode(ISD::CONCAT_VECTORS, DL, Src0VT, LoSelect, HiSelect); 01279 } 01280 01281 SDValue DAGTypeLegalizer::SplitVecOp_UnaryOp(SDNode *N) { 01282 // The result has a legal vector type, but the input needs splitting. 01283 EVT ResVT = N->getValueType(0); 01284 SDValue Lo, Hi; 01285 SDLoc dl(N); 01286 GetSplitVector(N->getOperand(0), Lo, Hi); 01287 EVT InVT = Lo.getValueType(); 01288 01289 EVT OutVT = EVT::getVectorVT(*DAG.getContext(), ResVT.getVectorElementType(), 01290 InVT.getVectorNumElements()); 01291 01292 Lo = DAG.getNode(N->getOpcode(), dl, OutVT, Lo); 01293 Hi = DAG.getNode(N->getOpcode(), dl, OutVT, Hi); 01294 01295 return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi); 01296 } 01297 01298 SDValue DAGTypeLegalizer::SplitVecOp_BITCAST(SDNode *N) { 01299 // For example, i64 = BITCAST v4i16 on alpha. Typically the vector will 01300 // end up being split all the way down to individual components. Convert the 01301 // split pieces into integers and reassemble. 01302 SDValue Lo, Hi; 01303 GetSplitVector(N->getOperand(0), Lo, Hi); 01304 Lo = BitConvertToInteger(Lo); 01305 Hi = BitConvertToInteger(Hi); 01306 01307 if (TLI.isBigEndian()) 01308 std::swap(Lo, Hi); 01309 01310 return DAG.getNode(ISD::BITCAST, SDLoc(N), N->getValueType(0), 01311 JoinIntegers(Lo, Hi)); 01312 } 01313 01314 SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N) { 01315 // We know that the extracted result type is legal. 01316 EVT SubVT = N->getValueType(0); 01317 SDValue Idx = N->getOperand(1); 01318 SDLoc dl(N); 01319 SDValue Lo, Hi; 01320 GetSplitVector(N->getOperand(0), Lo, Hi); 01321 01322 uint64_t LoElts = Lo.getValueType().getVectorNumElements(); 01323 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue(); 01324 01325 if (IdxVal < LoElts) { 01326 assert(IdxVal + SubVT.getVectorNumElements() <= LoElts && 01327 "Extracted subvector crosses vector split!"); 01328 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Lo, Idx); 01329 } else { 01330 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Hi, 01331 DAG.getConstant(IdxVal - LoElts, Idx.getValueType())); 01332 } 01333 } 01334 01335 SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { 01336 SDValue Vec = N->getOperand(0); 01337 SDValue Idx = N->getOperand(1); 01338 EVT VecVT = Vec.getValueType(); 01339 01340 if (isa<ConstantSDNode>(Idx)) { 01341 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue(); 01342 assert(IdxVal < VecVT.getVectorNumElements() && "Invalid vector index!"); 01343 01344 SDValue Lo, Hi; 01345 GetSplitVector(Vec, Lo, Hi); 01346 01347 uint64_t LoElts = Lo.getValueType().getVectorNumElements(); 01348 01349 if (IdxVal < LoElts) 01350 return SDValue(DAG.UpdateNodeOperands(N, Lo, Idx), 0); 01351 return SDValue(DAG.UpdateNodeOperands(N, Hi, 01352 DAG.getConstant(IdxVal - LoElts, 01353 Idx.getValueType())), 0); 01354 } 01355 01356 // See if the target wants to custom expand this node. 01357 if (CustomLowerNode(N, N->getValueType(0), true)) 01358 return SDValue(); 01359 01360 // Store the vector to the stack. 01361 EVT EltVT = VecVT.getVectorElementType(); 01362 SDLoc dl(N); 01363 SDValue StackPtr = DAG.CreateStackTemporary(VecVT); 01364 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, 01365 MachinePointerInfo(), false, false, 0); 01366 01367 // Load back the required element. 01368 StackPtr = GetVectorElementPointer(StackPtr, EltVT, Idx); 01369 return DAG.getExtLoad(ISD::EXTLOAD, dl, N->getValueType(0), Store, StackPtr, 01370 MachinePointerInfo(), EltVT, false, false, false, 0); 01371 } 01372 01373 SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) { 01374 assert(N->isUnindexed() && "Indexed store of vector?"); 01375 assert(OpNo == 1 && "Can only split the stored value"); 01376 SDLoc DL(N); 01377 01378 bool isTruncating = N->isTruncatingStore(); 01379 SDValue Ch = N->getChain(); 01380 SDValue Ptr = N->getBasePtr(); 01381 EVT MemoryVT = N->getMemoryVT(); 01382 unsigned Alignment = N->getOriginalAlignment(); 01383 bool isVol = N->isVolatile(); 01384 bool isNT = N->isNonTemporal(); 01385 AAMDNodes AAInfo = N->getAAInfo(); 01386 SDValue Lo, Hi; 01387 GetSplitVector(N->getOperand(1), Lo, Hi); 01388 01389 EVT LoMemVT, HiMemVT; 01390 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT); 01391 01392 unsigned IncrementSize = LoMemVT.getSizeInBits()/8; 01393 01394 if (isTruncating) 01395 Lo = DAG.getTruncStore(Ch, DL, Lo, Ptr, N->getPointerInfo(), 01396 LoMemVT, isVol, isNT, Alignment, AAInfo); 01397 else 01398 Lo = DAG.getStore(Ch, DL, Lo, Ptr, N->getPointerInfo(), 01399 isVol, isNT, Alignment, AAInfo); 01400 01401 // Increment the pointer to the other half. 01402 Ptr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr, 01403 DAG.getConstant(IncrementSize, Ptr.getValueType())); 01404 01405 if (isTruncating) 01406 Hi = DAG.getTruncStore(Ch, DL, Hi, Ptr, 01407 N->getPointerInfo().getWithOffset(IncrementSize), 01408 HiMemVT, isVol, isNT, Alignment, AAInfo); 01409 else 01410 Hi = DAG.getStore(Ch, DL, Hi, Ptr, 01411 N->getPointerInfo().getWithOffset(IncrementSize), 01412 isVol, isNT, Alignment, AAInfo); 01413 01414 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Lo, Hi); 01415 } 01416 01417 SDValue DAGTypeLegalizer::SplitVecOp_CONCAT_VECTORS(SDNode *N) { 01418 SDLoc DL(N); 01419 01420 // The input operands all must have the same type, and we know the result 01421 // type is valid. Convert this to a buildvector which extracts all the 01422 // input elements. 01423 // TODO: If the input elements are power-two vectors, we could convert this to 01424 // a new CONCAT_VECTORS node with elements that are half-wide. 01425 SmallVector<SDValue, 32> Elts; 01426 EVT EltVT = N->getValueType(0).getVectorElementType(); 01427 for (unsigned op = 0, e = N->getNumOperands(); op != e; ++op) { 01428 SDValue Op = N->getOperand(op); 01429 for (unsigned i = 0, e = Op.getValueType().getVectorNumElements(); 01430 i != e; ++i) { 01431 Elts.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, 01432 Op, DAG.getConstant(i, TLI.getVectorIdxTy()))); 01433 01434 } 01435 } 01436 01437 return DAG.getNode(ISD::BUILD_VECTOR, DL, N->getValueType(0), Elts); 01438 } 01439 01440 SDValue DAGTypeLegalizer::SplitVecOp_TRUNCATE(SDNode *N) { 01441 // The result type is legal, but the input type is illegal. If splitting 01442 // ends up with the result type of each half still being legal, just 01443 // do that. If, however, that would result in an illegal result type, 01444 // we can try to get more clever with power-two vectors. Specifically, 01445 // split the input type, but also widen the result element size, then 01446 // concatenate the halves and truncate again. For example, consider a target 01447 // where v8i8 is legal and v8i32 is not (ARM, which doesn't have 256-bit 01448 // vectors). To perform a "%res = v8i8 trunc v8i32 %in" we do: 01449 // %inlo = v4i32 extract_subvector %in, 0 01450 // %inhi = v4i32 extract_subvector %in, 4 01451 // %lo16 = v4i16 trunc v4i32 %inlo 01452 // %hi16 = v4i16 trunc v4i32 %inhi 01453 // %in16 = v8i16 concat_vectors v4i16 %lo16, v4i16 %hi16 01454 // %res = v8i8 trunc v8i16 %in16 01455 // 01456 // Without this transform, the original truncate would end up being 01457 // scalarized, which is pretty much always a last resort. 01458 SDValue InVec = N->getOperand(0); 01459 EVT InVT = InVec->getValueType(0); 01460 EVT OutVT = N->getValueType(0); 01461 unsigned NumElements = OutVT.getVectorNumElements(); 01462 // Widening should have already made sure this is a power-two vector 01463 // if we're trying to split it at all. assert() that's true, just in case. 01464 assert(!(NumElements & 1) && "Splitting vector, but not in half!"); 01465 01466 unsigned InElementSize = InVT.getVectorElementType().getSizeInBits(); 01467 unsigned OutElementSize = OutVT.getVectorElementType().getSizeInBits(); 01468 01469 // If the input elements are only 1/2 the width of the result elements, 01470 // just use the normal splitting. Our trick only work if there's room 01471 // to split more than once. 01472 if (InElementSize <= OutElementSize * 2) 01473 return SplitVecOp_UnaryOp(N); 01474 SDLoc DL(N); 01475 01476 // Extract the halves of the input via extract_subvector. 01477 SDValue InLoVec, InHiVec; 01478 std::tie(InLoVec, InHiVec) = DAG.SplitVector(InVec, DL); 01479 // Truncate them to 1/2 the element size. 01480 EVT HalfElementVT = EVT::getIntegerVT(*DAG.getContext(), InElementSize/2); 01481 EVT HalfVT = EVT::getVectorVT(*DAG.getContext(), HalfElementVT, 01482 NumElements/2); 01483 SDValue HalfLo = DAG.getNode(ISD::TRUNCATE, DL, HalfVT, InLoVec); 01484 SDValue HalfHi = DAG.getNode(ISD::TRUNCATE, DL, HalfVT, InHiVec); 01485 // Concatenate them to get the full intermediate truncation result. 01486 EVT InterVT = EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements); 01487 SDValue InterVec = DAG.getNode(ISD::CONCAT_VECTORS, DL, InterVT, HalfLo, 01488 HalfHi); 01489 // Now finish up by truncating all the way down to the original result 01490 // type. This should normally be something that ends up being legal directly, 01491 // but in theory if a target has very wide vectors and an annoyingly 01492 // restricted set of legal types, this split can chain to build things up. 01493 return DAG.getNode(ISD::TRUNCATE, DL, OutVT, InterVec); 01494 } 01495 01496 SDValue DAGTypeLegalizer::SplitVecOp_VSETCC(SDNode *N) { 01497 assert(N->getValueType(0).isVector() && 01498 N->getOperand(0).getValueType().isVector() && 01499 "Operand types must be vectors"); 01500 // The result has a legal vector type, but the input needs splitting. 01501 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes; 01502 SDLoc DL(N); 01503 GetSplitVector(N->getOperand(0), Lo0, Hi0); 01504 GetSplitVector(N->getOperand(1), Lo1, Hi1); 01505 unsigned PartElements = Lo0.getValueType().getVectorNumElements(); 01506 EVT PartResVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, PartElements); 01507 EVT WideResVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, 2*PartElements); 01508 01509 LoRes = DAG.getNode(ISD::SETCC, DL, PartResVT, Lo0, Lo1, N->getOperand(2)); 01510 HiRes = DAG.getNode(ISD::SETCC, DL, PartResVT, Hi0, Hi1, N->getOperand(2)); 01511 SDValue Con = DAG.getNode(ISD::CONCAT_VECTORS, DL, WideResVT, LoRes, HiRes); 01512 return PromoteTargetBoolean(Con, N->getValueType(0)); 01513 } 01514 01515 01516 SDValue DAGTypeLegalizer::SplitVecOp_FP_ROUND(SDNode *N) { 01517 // The result has a legal vector type, but the input needs splitting. 01518 EVT ResVT = N->getValueType(0); 01519 SDValue Lo, Hi; 01520 SDLoc DL(N); 01521 GetSplitVector(N->getOperand(0), Lo, Hi); 01522 EVT InVT = Lo.getValueType(); 01523 01524 EVT OutVT = EVT::getVectorVT(*DAG.getContext(), ResVT.getVectorElementType(), 01525 InVT.getVectorNumElements()); 01526 01527 Lo = DAG.getNode(ISD::FP_ROUND, DL, OutVT, Lo, N->getOperand(1)); 01528 Hi = DAG.getNode(ISD::FP_ROUND, DL, OutVT, Hi, N->getOperand(1)); 01529 01530 return DAG.getNode(ISD::CONCAT_VECTORS, DL, ResVT, Lo, Hi); 01531 } 01532 01533 01534 01535 //===----------------------------------------------------------------------===// 01536 // Result Vector Widening 01537 //===----------------------------------------------------------------------===// 01538 01539 void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) { 01540 DEBUG(dbgs() << "Widen node result " << ResNo << ": "; 01541 N->dump(&DAG); 01542 dbgs() << "\n"); 01543 01544 // See if the target wants to custom widen this node. 01545 if (CustomWidenLowerNode(N, N->getValueType(ResNo))) 01546 return; 01547 01548 SDValue Res = SDValue(); 01549 switch (N->getOpcode()) { 01550 default: 01551 #ifndef NDEBUG 01552 dbgs() << "WidenVectorResult #" << ResNo << ": "; 01553 N->dump(&DAG); 01554 dbgs() << "\n"; 01555 #endif 01556 llvm_unreachable("Do not know how to widen the result of this operator!"); 01557 01558 case ISD::MERGE_VALUES: Res = WidenVecRes_MERGE_VALUES(N, ResNo); break; 01559 case ISD::BITCAST: Res = WidenVecRes_BITCAST(N); break; 01560 case ISD::BUILD_VECTOR: Res = WidenVecRes_BUILD_VECTOR(N); break; 01561 case ISD::CONCAT_VECTORS: Res = WidenVecRes_CONCAT_VECTORS(N); break; 01562 case ISD::CONVERT_RNDSAT: Res = WidenVecRes_CONVERT_RNDSAT(N); break; 01563 case ISD::EXTRACT_SUBVECTOR: Res = WidenVecRes_EXTRACT_SUBVECTOR(N); break; 01564 case ISD::FP_ROUND_INREG: Res = WidenVecRes_InregOp(N); break; 01565 case ISD::INSERT_VECTOR_ELT: Res = WidenVecRes_INSERT_VECTOR_ELT(N); break; 01566 case ISD::LOAD: Res = WidenVecRes_LOAD(N); break; 01567 case ISD::SCALAR_TO_VECTOR: Res = WidenVecRes_SCALAR_TO_VECTOR(N); break; 01568 case ISD::SIGN_EXTEND_INREG: Res = WidenVecRes_InregOp(N); break; 01569 case ISD::VSELECT: 01570 case ISD::SELECT: Res = WidenVecRes_SELECT(N); break; 01571 case ISD::SELECT_CC: Res = WidenVecRes_SELECT_CC(N); break; 01572 case ISD::SETCC: Res = WidenVecRes_SETCC(N); break; 01573 case ISD::UNDEF: Res = WidenVecRes_UNDEF(N); break; 01574 case ISD::VECTOR_SHUFFLE: 01575 Res = WidenVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N)); 01576 break; 01577 01578 case ISD::ADD: 01579 case ISD::AND: 01580 case ISD::MUL: 01581 case ISD::MULHS: 01582 case ISD::MULHU: 01583 case ISD::OR: 01584 case ISD::SUB: 01585 case ISD::XOR: 01586 Res = WidenVecRes_Binary(N); 01587 break; 01588 01589 case ISD::FADD: 01590 case ISD::FCOPYSIGN: 01591 case ISD::FMUL: 01592 case ISD::FPOW: 01593 case ISD::FSUB: 01594 case ISD::FDIV: 01595 case ISD::FREM: 01596 case ISD::SDIV: 01597 case ISD::UDIV: 01598 case ISD::SREM: 01599 case ISD::UREM: 01600 Res = WidenVecRes_BinaryCanTrap(N); 01601 break; 01602 01603 case ISD::FPOWI: 01604 Res = WidenVecRes_POWI(N); 01605 break; 01606 01607 case ISD::SHL: 01608 case ISD::SRA: 01609 case ISD::SRL: 01610 Res = WidenVecRes_Shift(N); 01611 break; 01612 01613 case ISD::ANY_EXTEND: 01614 case ISD::FP_EXTEND: 01615 case ISD::FP_ROUND: 01616 case ISD::FP_TO_SINT: 01617 case ISD::FP_TO_UINT: 01618 case ISD::SIGN_EXTEND: 01619 case ISD::SINT_TO_FP: 01620 case ISD::TRUNCATE: 01621 case ISD::UINT_TO_FP: 01622 case ISD::ZERO_EXTEND: 01623 Res = WidenVecRes_Convert(N); 01624 break; 01625 01626 case ISD::BSWAP: 01627 case ISD::CTLZ: 01628 case ISD::CTPOP: 01629 case ISD::CTTZ: 01630 case ISD::FABS: 01631 case ISD::FCEIL: 01632 case ISD::FCOS: 01633 case ISD::FEXP: 01634 case ISD::FEXP2: 01635 case ISD::FFLOOR: 01636 case ISD::FLOG: 01637 case ISD::FLOG10: 01638 case ISD::FLOG2: 01639 case ISD::FNEARBYINT: 01640 case ISD::FNEG: 01641 case ISD::FRINT: 01642 case ISD::FROUND: 01643 case ISD::FSIN: 01644 case ISD::FSQRT: 01645 case ISD::FTRUNC: 01646 Res = WidenVecRes_Unary(N); 01647 break; 01648 case ISD::FMA: 01649 Res = WidenVecRes_Ternary(N); 01650 break; 01651 } 01652 01653 // If Res is null, the sub-method took care of registering the result. 01654 if (Res.getNode()) 01655 SetWidenedVector(SDValue(N, ResNo), Res); 01656 } 01657 01658 SDValue DAGTypeLegalizer::WidenVecRes_Ternary(SDNode *N) { 01659 // Ternary op widening. 01660 SDLoc dl(N); 01661 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 01662 SDValue InOp1 = GetWidenedVector(N->getOperand(0)); 01663 SDValue InOp2 = GetWidenedVector(N->getOperand(1)); 01664 SDValue InOp3 = GetWidenedVector(N->getOperand(2)); 01665 return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3); 01666 } 01667 01668 SDValue DAGTypeLegalizer::WidenVecRes_Binary(SDNode *N) { 01669 // Binary op widening. 01670 SDLoc dl(N); 01671 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 01672 SDValue InOp1 = GetWidenedVector(N->getOperand(0)); 01673 SDValue InOp2 = GetWidenedVector(N->getOperand(1)); 01674 return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2); 01675 } 01676 01677 SDValue DAGTypeLegalizer::WidenVecRes_BinaryCanTrap(SDNode *N) { 01678 // Binary op widening for operations that can trap. 01679 unsigned Opcode = N->getOpcode(); 01680 SDLoc dl(N); 01681 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 01682 EVT WidenEltVT = WidenVT.getVectorElementType(); 01683 EVT VT = WidenVT; 01684 unsigned NumElts = VT.getVectorNumElements(); 01685 while (!TLI.isTypeLegal(VT) && NumElts != 1) { 01686 NumElts = NumElts / 2; 01687 VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts); 01688 } 01689 01690 if (NumElts != 1 && !TLI.canOpTrap(N->getOpcode(), VT)) { 01691 // Operation doesn't trap so just widen as normal. 01692 SDValue InOp1 = GetWidenedVector(N->getOperand(0)); 01693 SDValue InOp2 = GetWidenedVector(N->getOperand(1)); 01694 return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2); 01695 } 01696 01697 // No legal vector version so unroll the vector operation and then widen. 01698 if (NumElts == 1) 01699 return DAG.UnrollVectorOp(N, WidenVT.getVectorNumElements()); 01700 01701 // Since the operation can trap, apply operation on the original vector. 01702 EVT MaxVT = VT; 01703 SDValue InOp1 = GetWidenedVector(N->getOperand(0)); 01704 SDValue InOp2 = GetWidenedVector(N->getOperand(1)); 01705 unsigned CurNumElts = N->getValueType(0).getVectorNumElements(); 01706 01707 SmallVector<SDValue, 16> ConcatOps(CurNumElts); 01708 unsigned ConcatEnd = 0; // Current ConcatOps index. 01709 int Idx = 0; // Current Idx into input vectors. 01710 01711 // NumElts := greatest legal vector size (at most WidenVT) 01712 // while (orig. vector has unhandled elements) { 01713 // take munches of size NumElts from the beginning and add to ConcatOps 01714 // NumElts := next smaller supported vector size or 1 01715 // } 01716 while (CurNumElts != 0) { 01717 while (CurNumElts >= NumElts) { 01718 SDValue EOp1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, InOp1, 01719 DAG.getConstant(Idx, TLI.getVectorIdxTy())); 01720 SDValue EOp2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, InOp2, 01721 DAG.getConstant(Idx, TLI.getVectorIdxTy())); 01722 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2); 01723 Idx += NumElts; 01724 CurNumElts -= NumElts; 01725 } 01726 do { 01727 NumElts = NumElts / 2; 01728 VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts); 01729 } while (!TLI.isTypeLegal(VT) && NumElts != 1); 01730 01731 if (NumElts == 1) { 01732 for (unsigned i = 0; i != CurNumElts; ++i, ++Idx) { 01733 SDValue EOp1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT, 01734 InOp1, DAG.getConstant(Idx, 01735 TLI.getVectorIdxTy())); 01736 SDValue EOp2 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT, 01737 InOp2, DAG.getConstant(Idx, 01738 TLI.getVectorIdxTy())); 01739 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, WidenEltVT, 01740 EOp1, EOp2); 01741 } 01742 CurNumElts = 0; 01743 } 01744 } 01745 01746 // Check to see if we have a single operation with the widen type. 01747 if (ConcatEnd == 1) { 01748 VT = ConcatOps[0].getValueType(); 01749 if (VT == WidenVT) 01750 return ConcatOps[0]; 01751 } 01752 01753 // while (Some element of ConcatOps is not of type MaxVT) { 01754 // From the end of ConcatOps, collect elements of the same type and put 01755 // them into an op of the next larger supported type 01756 // } 01757 while (ConcatOps[ConcatEnd-1].getValueType() != MaxVT) { 01758 Idx = ConcatEnd - 1; 01759 VT = ConcatOps[Idx--].getValueType(); 01760 while (Idx >= 0 && ConcatOps[Idx].getValueType() == VT) 01761 Idx--; 01762 01763 int NextSize = VT.isVector() ? VT.getVectorNumElements() : 1; 01764 EVT NextVT; 01765 do { 01766 NextSize *= 2; 01767 NextVT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NextSize); 01768 } while (!TLI.isTypeLegal(NextVT)); 01769 01770 if (!VT.isVector()) { 01771 // Scalar type, create an INSERT_VECTOR_ELEMENT of type NextVT 01772 SDValue VecOp = DAG.getUNDEF(NextVT); 01773 unsigned NumToInsert = ConcatEnd - Idx - 1; 01774 for (unsigned i = 0, OpIdx = Idx+1; i < NumToInsert; i++, OpIdx++) { 01775 VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NextVT, VecOp, 01776 ConcatOps[OpIdx], DAG.getConstant(i, 01777 TLI.getVectorIdxTy())); 01778 } 01779 ConcatOps[Idx+1] = VecOp; 01780 ConcatEnd = Idx + 2; 01781 } else { 01782 // Vector type, create a CONCAT_VECTORS of type NextVT 01783 SDValue undefVec = DAG.getUNDEF(VT); 01784 unsigned OpsToConcat = NextSize/VT.getVectorNumElements(); 01785 SmallVector<SDValue, 16> SubConcatOps(OpsToConcat); 01786 unsigned RealVals = ConcatEnd - Idx - 1; 01787 unsigned SubConcatEnd = 0; 01788 unsigned SubConcatIdx = Idx + 1; 01789 while (SubConcatEnd < RealVals) 01790 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx]; 01791 while (SubConcatEnd < OpsToConcat) 01792 SubConcatOps[SubConcatEnd++] = undefVec; 01793 ConcatOps[SubConcatIdx] = DAG.getNode(ISD::CONCAT_VECTORS, dl, 01794 NextVT, SubConcatOps); 01795 ConcatEnd = SubConcatIdx + 1; 01796 } 01797 } 01798 01799 // Check to see if we have a single operation with the widen type. 01800 if (ConcatEnd == 1) { 01801 VT = ConcatOps[0].getValueType(); 01802 if (VT == WidenVT) 01803 return ConcatOps[0]; 01804 } 01805 01806 // add undefs of size MaxVT until ConcatOps grows to length of WidenVT 01807 unsigned NumOps = WidenVT.getVectorNumElements()/MaxVT.getVectorNumElements(); 01808 if (NumOps != ConcatEnd ) { 01809 SDValue UndefVal = DAG.getUNDEF(MaxVT); 01810 for (unsigned j = ConcatEnd; j < NumOps; ++j) 01811 ConcatOps[j] = UndefVal; 01812 } 01813 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, 01814 makeArrayRef(ConcatOps.data(), NumOps)); 01815 } 01816 01817 SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) { 01818 SDValue InOp = N->getOperand(0); 01819 SDLoc DL(N); 01820 01821 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 01822 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 01823 01824 EVT InVT = InOp.getValueType(); 01825 EVT InEltVT = InVT.getVectorElementType(); 01826 EVT InWidenVT = EVT::getVectorVT(*DAG.getContext(), InEltVT, WidenNumElts); 01827 01828 unsigned Opcode = N->getOpcode(); 01829 unsigned InVTNumElts = InVT.getVectorNumElements(); 01830 01831 if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) { 01832 InOp = GetWidenedVector(N->getOperand(0)); 01833 InVT = InOp.getValueType(); 01834 InVTNumElts = InVT.getVectorNumElements(); 01835 if (InVTNumElts == WidenNumElts) { 01836 if (N->getNumOperands() == 1) 01837 return DAG.getNode(Opcode, DL, WidenVT, InOp); 01838 return DAG.getNode(Opcode, DL, WidenVT, InOp, N->getOperand(1)); 01839 } 01840 } 01841 01842 if (TLI.isTypeLegal(InWidenVT)) { 01843 // Because the result and the input are different vector types, widening 01844 // the result could create a legal type but widening the input might make 01845 // it an illegal type that might lead to repeatedly splitting the input 01846 // and then widening it. To avoid this, we widen the input only if 01847 // it results in a legal type. 01848 if (WidenNumElts % InVTNumElts == 0) { 01849 // Widen the input and call convert on the widened input vector. 01850 unsigned NumConcat = WidenNumElts/InVTNumElts; 01851 SmallVector<SDValue, 16> Ops(NumConcat); 01852 Ops[0] = InOp; 01853 SDValue UndefVal = DAG.getUNDEF(InVT); 01854 for (unsigned i = 1; i != NumConcat; ++i) 01855 Ops[i] = UndefVal; 01856 SDValue InVec = DAG.getNode(ISD::CONCAT_VECTORS, DL, InWidenVT, Ops); 01857 if (N->getNumOperands() == 1) 01858 return DAG.getNode(Opcode, DL, WidenVT, InVec); 01859 return DAG.getNode(Opcode, DL, WidenVT, InVec, N->getOperand(1)); 01860 } 01861 01862 if (InVTNumElts % WidenNumElts == 0) { 01863 SDValue InVal = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, InWidenVT, 01864 InOp, DAG.getConstant(0, 01865 TLI.getVectorIdxTy())); 01866 // Extract the input and convert the shorten input vector. 01867 if (N->getNumOperands() == 1) 01868 return DAG.getNode(Opcode, DL, WidenVT, InVal); 01869 return DAG.getNode(Opcode, DL, WidenVT, InVal, N->getOperand(1)); 01870 } 01871 } 01872 01873 // Otherwise unroll into some nasty scalar code and rebuild the vector. 01874 SmallVector<SDValue, 16> Ops(WidenNumElts); 01875 EVT EltVT = WidenVT.getVectorElementType(); 01876 unsigned MinElts = std::min(InVTNumElts, WidenNumElts); 01877 unsigned i; 01878 for (i=0; i < MinElts; ++i) { 01879 SDValue Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, InEltVT, InOp, 01880 DAG.getConstant(i, TLI.getVectorIdxTy())); 01881 if (N->getNumOperands() == 1) 01882 Ops[i] = DAG.getNode(Opcode, DL, EltVT, Val); 01883 else 01884 Ops[i] = DAG.getNode(Opcode, DL, EltVT, Val, N->getOperand(1)); 01885 } 01886 01887 SDValue UndefVal = DAG.getUNDEF(EltVT); 01888 for (; i < WidenNumElts; ++i) 01889 Ops[i] = UndefVal; 01890 01891 return DAG.getNode(ISD::BUILD_VECTOR, DL, WidenVT, Ops); 01892 } 01893 01894 SDValue DAGTypeLegalizer::WidenVecRes_POWI(SDNode *N) { 01895 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 01896 SDValue InOp = GetWidenedVector(N->getOperand(0)); 01897 SDValue ShOp = N->getOperand(1); 01898 return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, InOp, ShOp); 01899 } 01900 01901 SDValue DAGTypeLegalizer::WidenVecRes_Shift(SDNode *N) { 01902 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 01903 SDValue InOp = GetWidenedVector(N->getOperand(0)); 01904 SDValue ShOp = N->getOperand(1); 01905 01906 EVT ShVT = ShOp.getValueType(); 01907 if (getTypeAction(ShVT) == TargetLowering::TypeWidenVector) { 01908 ShOp = GetWidenedVector(ShOp); 01909 ShVT = ShOp.getValueType(); 01910 } 01911 EVT ShWidenVT = EVT::getVectorVT(*DAG.getContext(), 01912 ShVT.getVectorElementType(), 01913 WidenVT.getVectorNumElements()); 01914 if (ShVT != ShWidenVT) 01915 ShOp = ModifyToType(ShOp, ShWidenVT); 01916 01917 return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, InOp, ShOp); 01918 } 01919 01920 SDValue DAGTypeLegalizer::WidenVecRes_Unary(SDNode *N) { 01921 // Unary op widening. 01922 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 01923 SDValue InOp = GetWidenedVector(N->getOperand(0)); 01924 return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, InOp); 01925 } 01926 01927 SDValue DAGTypeLegalizer::WidenVecRes_InregOp(SDNode *N) { 01928 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 01929 EVT ExtVT = EVT::getVectorVT(*DAG.getContext(), 01930 cast<VTSDNode>(N->getOperand(1))->getVT() 01931 .getVectorElementType(), 01932 WidenVT.getVectorNumElements()); 01933 SDValue WidenLHS = GetWidenedVector(N->getOperand(0)); 01934 return DAG.getNode(N->getOpcode(), SDLoc(N), 01935 WidenVT, WidenLHS, DAG.getValueType(ExtVT)); 01936 } 01937 01938 SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(SDNode *N, unsigned ResNo) { 01939 SDValue WidenVec = DisintegrateMERGE_VALUES(N, ResNo); 01940 return GetWidenedVector(WidenVec); 01941 } 01942 01943 SDValue DAGTypeLegalizer::WidenVecRes_BITCAST(SDNode *N) { 01944 SDValue InOp = N->getOperand(0); 01945 EVT InVT = InOp.getValueType(); 01946 EVT VT = N->getValueType(0); 01947 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 01948 SDLoc dl(N); 01949 01950 switch (getTypeAction(InVT)) { 01951 case TargetLowering::TypeLegal: 01952 break; 01953 case TargetLowering::TypePromoteInteger: 01954 // If the incoming type is a vector that is being promoted, then 01955 // we know that the elements are arranged differently and that we 01956 // must perform the conversion using a stack slot. 01957 if (InVT.isVector()) 01958 break; 01959 01960 // If the InOp is promoted to the same size, convert it. Otherwise, 01961 // fall out of the switch and widen the promoted input. 01962 InOp = GetPromotedInteger(InOp); 01963 InVT = InOp.getValueType(); 01964 if (WidenVT.bitsEq(InVT)) 01965 return DAG.getNode(ISD::BITCAST, dl, WidenVT, InOp); 01966 break; 01967 case TargetLowering::TypeSoftenFloat: 01968 case TargetLowering::TypeExpandInteger: 01969 case TargetLowering::TypeExpandFloat: 01970 case TargetLowering::TypeScalarizeVector: 01971 case TargetLowering::TypeSplitVector: 01972 break; 01973 case TargetLowering::TypeWidenVector: 01974 // If the InOp is widened to the same size, convert it. Otherwise, fall 01975 // out of the switch and widen the widened input. 01976 InOp = GetWidenedVector(InOp); 01977 InVT = InOp.getValueType(); 01978 if (WidenVT.bitsEq(InVT)) 01979 // The input widens to the same size. Convert to the widen value. 01980 return DAG.getNode(ISD::BITCAST, dl, WidenVT, InOp); 01981 break; 01982 } 01983 01984 unsigned WidenSize = WidenVT.getSizeInBits(); 01985 unsigned InSize = InVT.getSizeInBits(); 01986 // x86mmx is not an acceptable vector element type, so don't try. 01987 if (WidenSize % InSize == 0 && InVT != MVT::x86mmx) { 01988 // Determine new input vector type. The new input vector type will use 01989 // the same element type (if its a vector) or use the input type as a 01990 // vector. It is the same size as the type to widen to. 01991 EVT NewInVT; 01992 unsigned NewNumElts = WidenSize / InSize; 01993 if (InVT.isVector()) { 01994 EVT InEltVT = InVT.getVectorElementType(); 01995 NewInVT = EVT::getVectorVT(*DAG.getContext(), InEltVT, 01996 WidenSize / InEltVT.getSizeInBits()); 01997 } else { 01998 NewInVT = EVT::getVectorVT(*DAG.getContext(), InVT, NewNumElts); 01999 } 02000 02001 if (TLI.isTypeLegal(NewInVT)) { 02002 // Because the result and the input are different vector types, widening 02003 // the result could create a legal type but widening the input might make 02004 // it an illegal type that might lead to repeatedly splitting the input 02005 // and then widening it. To avoid this, we widen the input only if 02006 // it results in a legal type. 02007 SmallVector<SDValue, 16> Ops(NewNumElts); 02008 SDValue UndefVal = DAG.getUNDEF(InVT); 02009 Ops[0] = InOp; 02010 for (unsigned i = 1; i < NewNumElts; ++i) 02011 Ops[i] = UndefVal; 02012 02013 SDValue NewVec; 02014 if (InVT.isVector()) 02015 NewVec = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewInVT, Ops); 02016 else 02017 NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl, NewInVT, Ops); 02018 return DAG.getNode(ISD::BITCAST, dl, WidenVT, NewVec); 02019 } 02020 } 02021 02022 return CreateStackStoreLoad(InOp, WidenVT); 02023 } 02024 02025 SDValue DAGTypeLegalizer::WidenVecRes_BUILD_VECTOR(SDNode *N) { 02026 SDLoc dl(N); 02027 // Build a vector with undefined for the new nodes. 02028 EVT VT = N->getValueType(0); 02029 02030 // Integer BUILD_VECTOR operands may be larger than the node's vector element 02031 // type. The UNDEFs need to have the same type as the existing operands. 02032 EVT EltVT = N->getOperand(0).getValueType(); 02033 unsigned NumElts = VT.getVectorNumElements(); 02034 02035 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 02036 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 02037 02038 SmallVector<SDValue, 16> NewOps(N->op_begin(), N->op_end()); 02039 assert(WidenNumElts >= NumElts && "Shrinking vector instead of widening!"); 02040 NewOps.append(WidenNumElts - NumElts, DAG.getUNDEF(EltVT)); 02041 02042 return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, NewOps); 02043 } 02044 02045 SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) { 02046 EVT InVT = N->getOperand(0).getValueType(); 02047 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 02048 SDLoc dl(N); 02049 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 02050 unsigned NumInElts = InVT.getVectorNumElements(); 02051 unsigned NumOperands = N->getNumOperands(); 02052 02053 bool InputWidened = false; // Indicates we need to widen the input. 02054 if (getTypeAction(InVT) != TargetLowering::TypeWidenVector) { 02055 if (WidenVT.getVectorNumElements() % InVT.getVectorNumElements() == 0) { 02056 // Add undef vectors to widen to correct length. 02057 unsigned NumConcat = WidenVT.getVectorNumElements() / 02058 InVT.getVectorNumElements(); 02059 SDValue UndefVal = DAG.getUNDEF(InVT); 02060 SmallVector<SDValue, 16> Ops(NumConcat); 02061 for (unsigned i=0; i < NumOperands; ++i) 02062 Ops[i] = N->getOperand(i); 02063 for (unsigned i = NumOperands; i != NumConcat; ++i) 02064 Ops[i] = UndefVal; 02065 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, Ops); 02066 } 02067 } else { 02068 InputWidened = true; 02069 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) { 02070 // The inputs and the result are widen to the same value. 02071 unsigned i; 02072 for (i=1; i < NumOperands; ++i) 02073 if (N->getOperand(i).getOpcode() != ISD::UNDEF) 02074 break; 02075 02076 if (i == NumOperands) 02077 // Everything but the first operand is an UNDEF so just return the 02078 // widened first operand. 02079 return GetWidenedVector(N->getOperand(0)); 02080 02081 if (NumOperands == 2) { 02082 // Replace concat of two operands with a shuffle. 02083 SmallVector<int, 16> MaskOps(WidenNumElts, -1); 02084 for (unsigned i = 0; i < NumInElts; ++i) { 02085 MaskOps[i] = i; 02086 MaskOps[i + NumInElts] = i + WidenNumElts; 02087 } 02088 return DAG.getVectorShuffle(WidenVT, dl, 02089 GetWidenedVector(N->getOperand(0)), 02090 GetWidenedVector(N->getOperand(1)), 02091 &MaskOps[0]); 02092 } 02093 } 02094 } 02095 02096 // Fall back to use extracts and build vector. 02097 EVT EltVT = WidenVT.getVectorElementType(); 02098 SmallVector<SDValue, 16> Ops(WidenNumElts); 02099 unsigned Idx = 0; 02100 for (unsigned i=0; i < NumOperands; ++i) { 02101 SDValue InOp = N->getOperand(i); 02102 if (InputWidened) 02103 InOp = GetWidenedVector(InOp); 02104 for (unsigned j=0; j < NumInElts; ++j) 02105 Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, 02106 DAG.getConstant(j, TLI.getVectorIdxTy())); 02107 } 02108 SDValue UndefVal = DAG.getUNDEF(EltVT); 02109 for (; Idx < WidenNumElts; ++Idx) 02110 Ops[Idx] = UndefVal; 02111 return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, Ops); 02112 } 02113 02114 SDValue DAGTypeLegalizer::WidenVecRes_CONVERT_RNDSAT(SDNode *N) { 02115 SDLoc dl(N); 02116 SDValue InOp = N->getOperand(0); 02117 SDValue RndOp = N->getOperand(3); 02118 SDValue SatOp = N->getOperand(4); 02119 02120 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 02121 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 02122 02123 EVT InVT = InOp.getValueType(); 02124 EVT InEltVT = InVT.getVectorElementType(); 02125 EVT InWidenVT = EVT::getVectorVT(*DAG.getContext(), InEltVT, WidenNumElts); 02126 02127 SDValue DTyOp = DAG.getValueType(WidenVT); 02128 SDValue STyOp = DAG.getValueType(InWidenVT); 02129 ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode(); 02130 02131 unsigned InVTNumElts = InVT.getVectorNumElements(); 02132 if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) { 02133 InOp = GetWidenedVector(InOp); 02134 InVT = InOp.getValueType(); 02135 InVTNumElts = InVT.getVectorNumElements(); 02136 if (InVTNumElts == WidenNumElts) 02137 return DAG.getConvertRndSat(WidenVT, dl, InOp, DTyOp, STyOp, RndOp, 02138 SatOp, CvtCode); 02139 } 02140 02141 if (TLI.isTypeLegal(InWidenVT)) { 02142 // Because the result and the input are different vector types, widening 02143 // the result could create a legal type but widening the input might make 02144 // it an illegal type that might lead to repeatedly splitting the input 02145 // and then widening it. To avoid this, we widen the input only if 02146 // it results in a legal type. 02147 if (WidenNumElts % InVTNumElts == 0) { 02148 // Widen the input and call convert on the widened input vector. 02149 unsigned NumConcat = WidenNumElts/InVTNumElts; 02150 SmallVector<SDValue, 16> Ops(NumConcat); 02151 Ops[0] = InOp; 02152 SDValue UndefVal = DAG.getUNDEF(InVT); 02153 for (unsigned i = 1; i != NumConcat; ++i) 02154 Ops[i] = UndefVal; 02155 02156 InOp = DAG.getNode(ISD::CONCAT_VECTORS, dl, InWidenVT, Ops); 02157 return DAG.getConvertRndSat(WidenVT, dl, InOp, DTyOp, STyOp, RndOp, 02158 SatOp, CvtCode); 02159 } 02160 02161 if (InVTNumElts % WidenNumElts == 0) { 02162 // Extract the input and convert the shorten input vector. 02163 InOp = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InWidenVT, InOp, 02164 DAG.getConstant(0, TLI.getVectorIdxTy())); 02165 return DAG.getConvertRndSat(WidenVT, dl, InOp, DTyOp, STyOp, RndOp, 02166 SatOp, CvtCode); 02167 } 02168 } 02169 02170 // Otherwise unroll into some nasty scalar code and rebuild the vector. 02171 SmallVector<SDValue, 16> Ops(WidenNumElts); 02172 EVT EltVT = WidenVT.getVectorElementType(); 02173 DTyOp = DAG.getValueType(EltVT); 02174 STyOp = DAG.getValueType(InEltVT); 02175 02176 unsigned MinElts = std::min(InVTNumElts, WidenNumElts); 02177 unsigned i; 02178 for (i=0; i < MinElts; ++i) { 02179 SDValue ExtVal = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp, 02180 DAG.getConstant(i, TLI.getVectorIdxTy())); 02181 Ops[i] = DAG.getConvertRndSat(WidenVT, dl, ExtVal, DTyOp, STyOp, RndOp, 02182 SatOp, CvtCode); 02183 } 02184 02185 SDValue UndefVal = DAG.getUNDEF(EltVT); 02186 for (; i < WidenNumElts; ++i) 02187 Ops[i] = UndefVal; 02188 02189 return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, Ops); 02190 } 02191 02192 SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) { 02193 EVT VT = N->getValueType(0); 02194 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 02195 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 02196 SDValue InOp = N->getOperand(0); 02197 SDValue Idx = N->getOperand(1); 02198 SDLoc dl(N); 02199 02200 if (getTypeAction(InOp.getValueType()) == TargetLowering::TypeWidenVector) 02201 InOp = GetWidenedVector(InOp); 02202 02203 EVT InVT = InOp.getValueType(); 02204 02205 // Check if we can just return the input vector after widening. 02206 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue(); 02207 if (IdxVal == 0 && InVT == WidenVT) 02208 return InOp; 02209 02210 // Check if we can extract from the vector. 02211 unsigned InNumElts = InVT.getVectorNumElements(); 02212 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts) 02213 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, WidenVT, InOp, Idx); 02214 02215 // We could try widening the input to the right length but for now, extract 02216 // the original elements, fill the rest with undefs and build a vector. 02217 SmallVector<SDValue, 16> Ops(WidenNumElts); 02218 EVT EltVT = VT.getVectorElementType(); 02219 unsigned NumElts = VT.getVectorNumElements(); 02220 unsigned i; 02221 for (i=0; i < NumElts; ++i) 02222 Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, 02223 DAG.getConstant(IdxVal+i, TLI.getVectorIdxTy())); 02224 02225 SDValue UndefVal = DAG.getUNDEF(EltVT); 02226 for (; i < WidenNumElts; ++i) 02227 Ops[i] = UndefVal; 02228 return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, Ops); 02229 } 02230 02231 SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) { 02232 SDValue InOp = GetWidenedVector(N->getOperand(0)); 02233 return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(N), 02234 InOp.getValueType(), InOp, 02235 N->getOperand(1), N->getOperand(2)); 02236 } 02237 02238 SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) { 02239 LoadSDNode *LD = cast<LoadSDNode>(N); 02240 ISD::LoadExtType ExtType = LD->getExtensionType(); 02241 02242 SDValue Result; 02243 SmallVector<SDValue, 16> LdChain; // Chain for the series of load 02244 if (ExtType != ISD::NON_EXTLOAD) 02245 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType); 02246 else 02247 Result = GenWidenVectorLoads(LdChain, LD); 02248 02249 // If we generate a single load, we can use that for the chain. Otherwise, 02250 // build a factor node to remember the multiple loads are independent and 02251 // chain to that. 02252 SDValue NewChain; 02253 if (LdChain.size() == 1) 02254 NewChain = LdChain[0]; 02255 else 02256 NewChain = DAG.getNode(ISD::TokenFactor, SDLoc(LD), MVT::Other, LdChain); 02257 02258 // Modified the chain - switch anything that used the old chain to use 02259 // the new one. 02260 ReplaceValueWith(SDValue(N, 1), NewChain); 02261 02262 return Result; 02263 } 02264 02265 SDValue DAGTypeLegalizer::WidenVecRes_SCALAR_TO_VECTOR(SDNode *N) { 02266 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 02267 return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), 02268 WidenVT, N->getOperand(0)); 02269 } 02270 02271 SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNode *N) { 02272 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 02273 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 02274 02275 SDValue Cond1 = N->getOperand(0); 02276 EVT CondVT = Cond1.getValueType(); 02277 if (CondVT.isVector()) { 02278 EVT CondEltVT = CondVT.getVectorElementType(); 02279 EVT CondWidenVT = EVT::getVectorVT(*DAG.getContext(), 02280 CondEltVT, WidenNumElts); 02281 if (getTypeAction(CondVT) == TargetLowering::TypeWidenVector) 02282 Cond1 = GetWidenedVector(Cond1); 02283 02284 // If we have to split the condition there is no point in widening the 02285 // select. This would result in an cycle of widening the select -> 02286 // widening the condition operand -> splitting the condition operand -> 02287 // splitting the select -> widening the select. Instead split this select 02288 // further and widen the resulting type. 02289 if (getTypeAction(CondVT) == TargetLowering::TypeSplitVector) { 02290 SDValue SplitSelect = SplitVecOp_VSELECT(N, 0); 02291 SDValue Res = ModifyToType(SplitSelect, WidenVT); 02292 return Res; 02293 } 02294 02295 if (Cond1.getValueType() != CondWidenVT) 02296 Cond1 = ModifyToType(Cond1, CondWidenVT); 02297 } 02298 02299 SDValue InOp1 = GetWidenedVector(N->getOperand(1)); 02300 SDValue InOp2 = GetWidenedVector(N->getOperand(2)); 02301 assert(InOp1.getValueType() == WidenVT && InOp2.getValueType() == WidenVT); 02302 return DAG.getNode(N->getOpcode(), SDLoc(N), 02303 WidenVT, Cond1, InOp1, InOp2); 02304 } 02305 02306 SDValue DAGTypeLegalizer::WidenVecRes_SELECT_CC(SDNode *N) { 02307 SDValue InOp1 = GetWidenedVector(N->getOperand(2)); 02308 SDValue InOp2 = GetWidenedVector(N->getOperand(3)); 02309 return DAG.getNode(ISD::SELECT_CC, SDLoc(N), 02310 InOp1.getValueType(), N->getOperand(0), 02311 N->getOperand(1), InOp1, InOp2, N->getOperand(4)); 02312 } 02313 02314 SDValue DAGTypeLegalizer::WidenVecRes_SETCC(SDNode *N) { 02315 assert(N->getValueType(0).isVector() == 02316 N->getOperand(0).getValueType().isVector() && 02317 "Scalar/Vector type mismatch"); 02318 if (N->getValueType(0).isVector()) return WidenVecRes_VSETCC(N); 02319 02320 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 02321 SDValue InOp1 = GetWidenedVector(N->getOperand(0)); 02322 SDValue InOp2 = GetWidenedVector(N->getOperand(1)); 02323 return DAG.getNode(ISD::SETCC, SDLoc(N), WidenVT, 02324 InOp1, InOp2, N->getOperand(2)); 02325 } 02326 02327 SDValue DAGTypeLegalizer::WidenVecRes_UNDEF(SDNode *N) { 02328 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 02329 return DAG.getUNDEF(WidenVT); 02330 } 02331 02332 SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N) { 02333 EVT VT = N->getValueType(0); 02334 SDLoc dl(N); 02335 02336 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 02337 unsigned NumElts = VT.getVectorNumElements(); 02338 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 02339 02340 SDValue InOp1 = GetWidenedVector(N->getOperand(0)); 02341 SDValue InOp2 = GetWidenedVector(N->getOperand(1)); 02342 02343 // Adjust mask based on new input vector length. 02344 SmallVector<int, 16> NewMask; 02345 for (unsigned i = 0; i != NumElts; ++i) { 02346 int Idx = N->getMaskElt(i); 02347 if (Idx < (int)NumElts) 02348 NewMask.push_back(Idx); 02349 else 02350 NewMask.push_back(Idx - NumElts + WidenNumElts); 02351 } 02352 for (unsigned i = NumElts; i != WidenNumElts; ++i) 02353 NewMask.push_back(-1); 02354 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, &NewMask[0]); 02355 } 02356 02357 SDValue DAGTypeLegalizer::WidenVecRes_VSETCC(SDNode *N) { 02358 assert(N->getValueType(0).isVector() && 02359 N->getOperand(0).getValueType().isVector() && 02360 "Operands must be vectors"); 02361 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 02362 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 02363 02364 SDValue InOp1 = N->getOperand(0); 02365 EVT InVT = InOp1.getValueType(); 02366 assert(InVT.isVector() && "can not widen non-vector type"); 02367 EVT WidenInVT = EVT::getVectorVT(*DAG.getContext(), 02368 InVT.getVectorElementType(), WidenNumElts); 02369 InOp1 = GetWidenedVector(InOp1); 02370 SDValue InOp2 = GetWidenedVector(N->getOperand(1)); 02371 02372 // Assume that the input and output will be widen appropriately. If not, 02373 // we will have to unroll it at some point. 02374 assert(InOp1.getValueType() == WidenInVT && 02375 InOp2.getValueType() == WidenInVT && 02376 "Input not widened to expected type!"); 02377 (void)WidenInVT; 02378 return DAG.getNode(ISD::SETCC, SDLoc(N), 02379 WidenVT, InOp1, InOp2, N->getOperand(2)); 02380 } 02381 02382 02383 //===----------------------------------------------------------------------===// 02384 // Widen Vector Operand 02385 //===----------------------------------------------------------------------===// 02386 bool DAGTypeLegalizer::WidenVectorOperand(SDNode *N, unsigned OpNo) { 02387 DEBUG(dbgs() << "Widen node operand " << OpNo << ": "; 02388 N->dump(&DAG); 02389 dbgs() << "\n"); 02390 SDValue Res = SDValue(); 02391 02392 // See if the target wants to custom widen this node. 02393 if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) 02394 return false; 02395 02396 switch (N->getOpcode()) { 02397 default: 02398 #ifndef NDEBUG 02399 dbgs() << "WidenVectorOperand op #" << OpNo << ": "; 02400 N->dump(&DAG); 02401 dbgs() << "\n"; 02402 #endif 02403 llvm_unreachable("Do not know how to widen this operator's operand!"); 02404 02405 case ISD::BITCAST: Res = WidenVecOp_BITCAST(N); break; 02406 case ISD::CONCAT_VECTORS: Res = WidenVecOp_CONCAT_VECTORS(N); break; 02407 case ISD::EXTRACT_SUBVECTOR: Res = WidenVecOp_EXTRACT_SUBVECTOR(N); break; 02408 case ISD::EXTRACT_VECTOR_ELT: Res = WidenVecOp_EXTRACT_VECTOR_ELT(N); break; 02409 case ISD::STORE: Res = WidenVecOp_STORE(N); break; 02410 case ISD::SETCC: Res = WidenVecOp_SETCC(N); break; 02411 02412 case ISD::ANY_EXTEND: 02413 case ISD::SIGN_EXTEND: 02414 case ISD::ZERO_EXTEND: 02415 Res = WidenVecOp_EXTEND(N); 02416 break; 02417 02418 case ISD::FP_EXTEND: 02419 case ISD::FP_TO_SINT: 02420 case ISD::FP_TO_UINT: 02421 case ISD::SINT_TO_FP: 02422 case ISD::UINT_TO_FP: 02423 case ISD::TRUNCATE: 02424 Res = WidenVecOp_Convert(N); 02425 break; 02426 } 02427 02428 // If Res is null, the sub-method took care of registering the result. 02429 if (!Res.getNode()) return false; 02430 02431 // If the result is N, the sub-method updated N in place. Tell the legalizer 02432 // core about this. 02433 if (Res.getNode() == N) 02434 return true; 02435 02436 02437 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 02438 "Invalid operand expansion"); 02439 02440 ReplaceValueWith(SDValue(N, 0), Res); 02441 return false; 02442 } 02443 02444 SDValue DAGTypeLegalizer::WidenVecOp_EXTEND(SDNode *N) { 02445 SDLoc DL(N); 02446 EVT VT = N->getValueType(0); 02447 02448 SDValue InOp = N->getOperand(0); 02449 // If some legalization strategy other than widening is used on the operand, 02450 // we can't safely assume that just extending the low lanes is the correct 02451 // transformation. 02452 if (getTypeAction(InOp.getValueType()) != TargetLowering::TypeWidenVector) 02453 return WidenVecOp_Convert(N); 02454 InOp = GetWidenedVector(InOp); 02455 assert(VT.getVectorNumElements() < 02456 InOp.getValueType().getVectorNumElements() && 02457 "Input wasn't widened!"); 02458 02459 // We may need to further widen the operand until it has the same total 02460 // vector size as the result. 02461 EVT InVT = InOp.getValueType(); 02462 if (InVT.getSizeInBits() != VT.getSizeInBits()) { 02463 EVT InEltVT = InVT.getVectorElementType(); 02464 for (int i = MVT::FIRST_VECTOR_VALUETYPE, e = MVT::LAST_VECTOR_VALUETYPE; i < e; ++i) { 02465 EVT FixedVT = (MVT::SimpleValueType)i; 02466 EVT FixedEltVT = FixedVT.getVectorElementType(); 02467 if (TLI.isTypeLegal(FixedVT) && 02468 FixedVT.getSizeInBits() == VT.getSizeInBits() && 02469 FixedEltVT == InEltVT) { 02470 assert(FixedVT.getVectorNumElements() >= VT.getVectorNumElements() && 02471 "Not enough elements in the fixed type for the operand!"); 02472 assert(FixedVT.getVectorNumElements() != InVT.getVectorNumElements() && 02473 "We can't have the same type as we started with!"); 02474 if (FixedVT.getVectorNumElements() > InVT.getVectorNumElements()) 02475 InOp = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, FixedVT, 02476 DAG.getUNDEF(FixedVT), InOp, 02477 DAG.getConstant(0, TLI.getVectorIdxTy())); 02478 else 02479 InOp = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, FixedVT, InOp, 02480 DAG.getConstant(0, TLI.getVectorIdxTy())); 02481 break; 02482 } 02483 } 02484 InVT = InOp.getValueType(); 02485 if (InVT.getSizeInBits() != VT.getSizeInBits()) 02486 // We couldn't find a legal vector type that was a widening of the input 02487 // and could be extended in-register to the result type, so we have to 02488 // scalarize. 02489 return WidenVecOp_Convert(N); 02490 } 02491 02492 // Use special DAG nodes to represent the operation of extending the 02493 // low lanes. 02494 switch (N->getOpcode()) { 02495 default: 02496 llvm_unreachable("Extend legalization on on extend operation!"); 02497 case ISD::ANY_EXTEND: 02498 return DAG.getAnyExtendVectorInReg(InOp, DL, VT); 02499 case ISD::SIGN_EXTEND: 02500 return DAG.getSignExtendVectorInReg(InOp, DL, VT); 02501 case ISD::ZERO_EXTEND: 02502 return DAG.getZeroExtendVectorInReg(InOp, DL, VT); 02503 } 02504 } 02505 02506 SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) { 02507 // Since the result is legal and the input is illegal, it is unlikely 02508 // that we can fix the input to a legal type so unroll the convert 02509 // into some scalar code and create a nasty build vector. 02510 EVT VT = N->getValueType(0); 02511 EVT EltVT = VT.getVectorElementType(); 02512 SDLoc dl(N); 02513 unsigned NumElts = VT.getVectorNumElements(); 02514 SDValue InOp = N->getOperand(0); 02515 if (getTypeAction(InOp.getValueType()) == TargetLowering::TypeWidenVector) 02516 InOp = GetWidenedVector(InOp); 02517 EVT InVT = InOp.getValueType(); 02518 EVT InEltVT = InVT.getVectorElementType(); 02519 02520 unsigned Opcode = N->getOpcode(); 02521 SmallVector<SDValue, 16> Ops(NumElts); 02522 for (unsigned i=0; i < NumElts; ++i) 02523 Ops[i] = DAG.getNode(Opcode, dl, EltVT, 02524 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp, 02525 DAG.getConstant(i, TLI.getVectorIdxTy()))); 02526 02527 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops); 02528 } 02529 02530 SDValue DAGTypeLegalizer::WidenVecOp_BITCAST(SDNode *N) { 02531 EVT VT = N->getValueType(0); 02532 SDValue InOp = GetWidenedVector(N->getOperand(0)); 02533 EVT InWidenVT = InOp.getValueType(); 02534 SDLoc dl(N); 02535 02536 // Check if we can convert between two legal vector types and extract. 02537 unsigned InWidenSize = InWidenVT.getSizeInBits(); 02538 unsigned Size = VT.getSizeInBits(); 02539 // x86mmx is not an acceptable vector element type, so don't try. 02540 if (InWidenSize % Size == 0 && !VT.isVector() && VT != MVT::x86mmx) { 02541 unsigned NewNumElts = InWidenSize / Size; 02542 EVT NewVT = EVT::getVectorVT(*DAG.getContext(), VT, NewNumElts); 02543 if (TLI.isTypeLegal(NewVT)) { 02544 SDValue BitOp = DAG.getNode(ISD::BITCAST, dl, NewVT, InOp); 02545 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, BitOp, 02546 DAG.getConstant(0, TLI.getVectorIdxTy())); 02547 } 02548 } 02549 02550 return CreateStackStoreLoad(InOp, VT); 02551 } 02552 02553 SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) { 02554 // If the input vector is not legal, it is likely that we will not find a 02555 // legal vector of the same size. Replace the concatenate vector with a 02556 // nasty build vector. 02557 EVT VT = N->getValueType(0); 02558 EVT EltVT = VT.getVectorElementType(); 02559 SDLoc dl(N); 02560 unsigned NumElts = VT.getVectorNumElements(); 02561 SmallVector<SDValue, 16> Ops(NumElts); 02562 02563 EVT InVT = N->getOperand(0).getValueType(); 02564 unsigned NumInElts = InVT.getVectorNumElements(); 02565 02566 unsigned Idx = 0; 02567 unsigned NumOperands = N->getNumOperands(); 02568 for (unsigned i=0; i < NumOperands; ++i) { 02569 SDValue InOp = N->getOperand(i); 02570 if (getTypeAction(InOp.getValueType()) == TargetLowering::TypeWidenVector) 02571 InOp = GetWidenedVector(InOp); 02572 for (unsigned j=0; j < NumInElts; ++j) 02573 Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, 02574 DAG.getConstant(j, TLI.getVectorIdxTy())); 02575 } 02576 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops); 02577 } 02578 02579 SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(SDNode *N) { 02580 SDValue InOp = GetWidenedVector(N->getOperand(0)); 02581 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(N), 02582 N->getValueType(0), InOp, N->getOperand(1)); 02583 } 02584 02585 SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { 02586 SDValue InOp = GetWidenedVector(N->getOperand(0)); 02587 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), 02588 N->getValueType(0), InOp, N->getOperand(1)); 02589 } 02590 02591 SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) { 02592 // We have to widen the value but we want only to store the original 02593 // vector type. 02594 StoreSDNode *ST = cast<StoreSDNode>(N); 02595 02596 SmallVector<SDValue, 16> StChain; 02597 if (ST->isTruncatingStore()) 02598 GenWidenVectorTruncStores(StChain, ST); 02599 else 02600 GenWidenVectorStores(StChain, ST); 02601 02602 if (StChain.size() == 1) 02603 return StChain[0]; 02604 else 02605 return DAG.getNode(ISD::TokenFactor, SDLoc(ST), MVT::Other, StChain); 02606 } 02607 02608 SDValue DAGTypeLegalizer::WidenVecOp_SETCC(SDNode *N) { 02609 SDValue InOp0 = GetWidenedVector(N->getOperand(0)); 02610 SDValue InOp1 = GetWidenedVector(N->getOperand(1)); 02611 SDLoc dl(N); 02612 02613 // WARNING: In this code we widen the compare instruction with garbage. 02614 // This garbage may contain denormal floats which may be slow. Is this a real 02615 // concern ? Should we zero the unused lanes if this is a float compare ? 02616 02617 // Get a new SETCC node to compare the newly widened operands. 02618 // Only some of the compared elements are legal. 02619 EVT SVT = TLI.getSetCCResultType(*DAG.getContext(), InOp0.getValueType()); 02620 SDValue WideSETCC = DAG.getNode(ISD::SETCC, SDLoc(N), 02621 SVT, InOp0, InOp1, N->getOperand(2)); 02622 02623 // Extract the needed results from the result vector. 02624 EVT ResVT = EVT::getVectorVT(*DAG.getContext(), 02625 SVT.getVectorElementType(), 02626 N->getValueType(0).getVectorNumElements()); 02627 SDValue CC = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, 02628 ResVT, WideSETCC, DAG.getConstant(0, 02629 TLI.getVectorIdxTy())); 02630 02631 return PromoteTargetBoolean(CC, N->getValueType(0)); 02632 } 02633 02634 02635 //===----------------------------------------------------------------------===// 02636 // Vector Widening Utilities 02637 //===----------------------------------------------------------------------===// 02638 02639 // Utility function to find the type to chop up a widen vector for load/store 02640 // TLI: Target lowering used to determine legal types. 02641 // Width: Width left need to load/store. 02642 // WidenVT: The widen vector type to load to/store from 02643 // Align: If 0, don't allow use of a wider type 02644 // WidenEx: If Align is not 0, the amount additional we can load/store from. 02645 02646 static EVT FindMemType(SelectionDAG& DAG, const TargetLowering &TLI, 02647 unsigned Width, EVT WidenVT, 02648 unsigned Align = 0, unsigned WidenEx = 0) { 02649 EVT WidenEltVT = WidenVT.getVectorElementType(); 02650 unsigned WidenWidth = WidenVT.getSizeInBits(); 02651 unsigned WidenEltWidth = WidenEltVT.getSizeInBits(); 02652 unsigned AlignInBits = Align*8; 02653 02654 // If we have one element to load/store, return it. 02655 EVT RetVT = WidenEltVT; 02656 if (Width == WidenEltWidth) 02657 return RetVT; 02658 02659 // See if there is larger legal integer than the element type to load/store 02660 unsigned VT; 02661 for (VT = (unsigned)MVT::LAST_INTEGER_VALUETYPE; 02662 VT >= (unsigned)MVT::FIRST_INTEGER_VALUETYPE; --VT) { 02663 EVT MemVT((MVT::SimpleValueType) VT); 02664 unsigned MemVTWidth = MemVT.getSizeInBits(); 02665 if (MemVT.getSizeInBits() <= WidenEltWidth) 02666 break; 02667 if (TLI.isTypeLegal(MemVT) && (WidenWidth % MemVTWidth) == 0 && 02668 isPowerOf2_32(WidenWidth / MemVTWidth) && 02669 (MemVTWidth <= Width || 02670 (Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) { 02671 RetVT = MemVT; 02672 break; 02673 } 02674 } 02675 02676 // See if there is a larger vector type to load/store that has the same vector 02677 // element type and is evenly divisible with the WidenVT. 02678 for (VT = (unsigned)MVT::LAST_VECTOR_VALUETYPE; 02679 VT >= (unsigned)MVT::FIRST_VECTOR_VALUETYPE; --VT) { 02680 EVT MemVT = (MVT::SimpleValueType) VT; 02681 unsigned MemVTWidth = MemVT.getSizeInBits(); 02682 if (TLI.isTypeLegal(MemVT) && WidenEltVT == MemVT.getVectorElementType() && 02683 (WidenWidth % MemVTWidth) == 0 && 02684 isPowerOf2_32(WidenWidth / MemVTWidth) && 02685 (MemVTWidth <= Width || 02686 (Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) { 02687 if (RetVT.getSizeInBits() < MemVTWidth || MemVT == WidenVT) 02688 return MemVT; 02689 } 02690 } 02691 02692 return RetVT; 02693 } 02694 02695 // Builds a vector type from scalar loads 02696 // VecTy: Resulting Vector type 02697 // LDOps: Load operators to build a vector type 02698 // [Start,End) the list of loads to use. 02699 static SDValue BuildVectorFromScalar(SelectionDAG& DAG, EVT VecTy, 02700 SmallVectorImpl<SDValue> &LdOps, 02701 unsigned Start, unsigned End) { 02702 const TargetLowering &TLI = DAG.getTargetLoweringInfo(); 02703 SDLoc dl(LdOps[Start]); 02704 EVT LdTy = LdOps[Start].getValueType(); 02705 unsigned Width = VecTy.getSizeInBits(); 02706 unsigned NumElts = Width / LdTy.getSizeInBits(); 02707 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), LdTy, NumElts); 02708 02709 unsigned Idx = 1; 02710 SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT,LdOps[Start]); 02711 02712 for (unsigned i = Start + 1; i != End; ++i) { 02713 EVT NewLdTy = LdOps[i].getValueType(); 02714 if (NewLdTy != LdTy) { 02715 NumElts = Width / NewLdTy.getSizeInBits(); 02716 NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewLdTy, NumElts); 02717 VecOp = DAG.getNode(ISD::BITCAST, dl, NewVecVT, VecOp); 02718 // Readjust position and vector position based on new load type 02719 Idx = Idx * LdTy.getSizeInBits() / NewLdTy.getSizeInBits(); 02720 LdTy = NewLdTy; 02721 } 02722 VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, VecOp, LdOps[i], 02723 DAG.getConstant(Idx++, TLI.getVectorIdxTy())); 02724 } 02725 return DAG.getNode(ISD::BITCAST, dl, VecTy, VecOp); 02726 } 02727 02728 SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain, 02729 LoadSDNode *LD) { 02730 // The strategy assumes that we can efficiently load powers of two widths. 02731 // The routines chops the vector into the largest vector loads with the same 02732 // element type or scalar loads and then recombines it to the widen vector 02733 // type. 02734 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),LD->getValueType(0)); 02735 unsigned WidenWidth = WidenVT.getSizeInBits(); 02736 EVT LdVT = LD->getMemoryVT(); 02737 SDLoc dl(LD); 02738 assert(LdVT.isVector() && WidenVT.isVector()); 02739 assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType()); 02740 02741 // Load information 02742 SDValue Chain = LD->getChain(); 02743 SDValue BasePtr = LD->getBasePtr(); 02744 unsigned Align = LD->getAlignment(); 02745 bool isVolatile = LD->isVolatile(); 02746 bool isNonTemporal = LD->isNonTemporal(); 02747 bool isInvariant = LD->isInvariant(); 02748 AAMDNodes AAInfo = LD->getAAInfo(); 02749 02750 int LdWidth = LdVT.getSizeInBits(); 02751 int WidthDiff = WidenWidth - LdWidth; // Difference 02752 unsigned LdAlign = (isVolatile) ? 0 : Align; // Allow wider loads 02753 02754 // Find the vector type that can load from. 02755 EVT NewVT = FindMemType(DAG, TLI, LdWidth, WidenVT, LdAlign, WidthDiff); 02756 int NewVTWidth = NewVT.getSizeInBits(); 02757 SDValue LdOp = DAG.getLoad(NewVT, dl, Chain, BasePtr, LD->getPointerInfo(), 02758 isVolatile, isNonTemporal, isInvariant, Align, 02759 AAInfo); 02760 LdChain.push_back(LdOp.getValue(1)); 02761 02762 // Check if we can load the element with one instruction 02763 if (LdWidth <= NewVTWidth) { 02764 if (!NewVT.isVector()) { 02765 unsigned NumElts = WidenWidth / NewVTWidth; 02766 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NumElts); 02767 SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp); 02768 return DAG.getNode(ISD::BITCAST, dl, WidenVT, VecOp); 02769 } 02770 if (NewVT == WidenVT) 02771 return LdOp; 02772 02773 assert(WidenWidth % NewVTWidth == 0); 02774 unsigned NumConcat = WidenWidth / NewVTWidth; 02775 SmallVector<SDValue, 16> ConcatOps(NumConcat); 02776 SDValue UndefVal = DAG.getUNDEF(NewVT); 02777 ConcatOps[0] = LdOp; 02778 for (unsigned i = 1; i != NumConcat; ++i) 02779 ConcatOps[i] = UndefVal; 02780 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, ConcatOps); 02781 } 02782 02783 // Load vector by using multiple loads from largest vector to scalar 02784 SmallVector<SDValue, 16> LdOps; 02785 LdOps.push_back(LdOp); 02786 02787 LdWidth -= NewVTWidth; 02788 unsigned Offset = 0; 02789 02790 while (LdWidth > 0) { 02791 unsigned Increment = NewVTWidth / 8; 02792 Offset += Increment; 02793 BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, 02794 DAG.getConstant(Increment, BasePtr.getValueType())); 02795 02796 SDValue L; 02797 if (LdWidth < NewVTWidth) { 02798 // Our current type we are using is too large, find a better size 02799 NewVT = FindMemType(DAG, TLI, LdWidth, WidenVT, LdAlign, WidthDiff); 02800 NewVTWidth = NewVT.getSizeInBits(); 02801 L = DAG.getLoad(NewVT, dl, Chain, BasePtr, 02802 LD->getPointerInfo().getWithOffset(Offset), isVolatile, 02803 isNonTemporal, isInvariant, MinAlign(Align, Increment), 02804 AAInfo); 02805 LdChain.push_back(L.getValue(1)); 02806 if (L->getValueType(0).isVector()) { 02807 SmallVector<SDValue, 16> Loads; 02808 Loads.push_back(L); 02809 unsigned size = L->getValueSizeInBits(0); 02810 while (size < LdOp->getValueSizeInBits(0)) { 02811 Loads.push_back(DAG.getUNDEF(L->getValueType(0))); 02812 size += L->getValueSizeInBits(0); 02813 } 02814 L = DAG.getNode(ISD::CONCAT_VECTORS, dl, LdOp->getValueType(0), Loads); 02815 } 02816 } else { 02817 L = DAG.getLoad(NewVT, dl, Chain, BasePtr, 02818 LD->getPointerInfo().getWithOffset(Offset), isVolatile, 02819 isNonTemporal, isInvariant, MinAlign(Align, Increment), 02820 AAInfo); 02821 LdChain.push_back(L.getValue(1)); 02822 } 02823 02824 LdOps.push_back(L); 02825 02826 02827 LdWidth -= NewVTWidth; 02828 } 02829 02830 // Build the vector from the loads operations 02831 unsigned End = LdOps.size(); 02832 if (!LdOps[0].getValueType().isVector()) 02833 // All the loads are scalar loads. 02834 return BuildVectorFromScalar(DAG, WidenVT, LdOps, 0, End); 02835 02836 // If the load contains vectors, build the vector using concat vector. 02837 // All of the vectors used to loads are power of 2 and the scalars load 02838 // can be combined to make a power of 2 vector. 02839 SmallVector<SDValue, 16> ConcatOps(End); 02840 int i = End - 1; 02841 int Idx = End; 02842 EVT LdTy = LdOps[i].getValueType(); 02843 // First combine the scalar loads to a vector 02844 if (!LdTy.isVector()) { 02845 for (--i; i >= 0; --i) { 02846 LdTy = LdOps[i].getValueType(); 02847 if (LdTy.isVector()) 02848 break; 02849 } 02850 ConcatOps[--Idx] = BuildVectorFromScalar(DAG, LdTy, LdOps, i+1, End); 02851 } 02852 ConcatOps[--Idx] = LdOps[i]; 02853 for (--i; i >= 0; --i) { 02854 EVT NewLdTy = LdOps[i].getValueType(); 02855 if (NewLdTy != LdTy) { 02856 // Create a larger vector 02857 ConcatOps[End-1] = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewLdTy, 02858 makeArrayRef(&ConcatOps[Idx], End - Idx)); 02859 Idx = End - 1; 02860 LdTy = NewLdTy; 02861 } 02862 ConcatOps[--Idx] = LdOps[i]; 02863 } 02864 02865 if (WidenWidth == LdTy.getSizeInBits()*(End - Idx)) 02866 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, 02867 makeArrayRef(&ConcatOps[Idx], End - Idx)); 02868 02869 // We need to fill the rest with undefs to build the vector 02870 unsigned NumOps = WidenWidth / LdTy.getSizeInBits(); 02871 SmallVector<SDValue, 16> WidenOps(NumOps); 02872 SDValue UndefVal = DAG.getUNDEF(LdTy); 02873 { 02874 unsigned i = 0; 02875 for (; i != End-Idx; ++i) 02876 WidenOps[i] = ConcatOps[Idx+i]; 02877 for (; i != NumOps; ++i) 02878 WidenOps[i] = UndefVal; 02879 } 02880 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, WidenOps); 02881 } 02882 02883 SDValue 02884 DAGTypeLegalizer::GenWidenVectorExtLoads(SmallVectorImpl<SDValue> &LdChain, 02885 LoadSDNode *LD, 02886 ISD::LoadExtType ExtType) { 02887 // For extension loads, it may not be more efficient to chop up the vector 02888 // and then extended it. Instead, we unroll the load and build a new vector. 02889 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),LD->getValueType(0)); 02890 EVT LdVT = LD->getMemoryVT(); 02891 SDLoc dl(LD); 02892 assert(LdVT.isVector() && WidenVT.isVector()); 02893 02894 // Load information 02895 SDValue Chain = LD->getChain(); 02896 SDValue BasePtr = LD->getBasePtr(); 02897 unsigned Align = LD->getAlignment(); 02898 bool isVolatile = LD->isVolatile(); 02899 bool isNonTemporal = LD->isNonTemporal(); 02900 bool isInvariant = LD->isInvariant(); 02901 AAMDNodes AAInfo = LD->getAAInfo(); 02902 02903 EVT EltVT = WidenVT.getVectorElementType(); 02904 EVT LdEltVT = LdVT.getVectorElementType(); 02905 unsigned NumElts = LdVT.getVectorNumElements(); 02906 02907 // Load each element and widen 02908 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 02909 SmallVector<SDValue, 16> Ops(WidenNumElts); 02910 unsigned Increment = LdEltVT.getSizeInBits() / 8; 02911 Ops[0] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr, 02912 LD->getPointerInfo(), 02913 LdEltVT, isVolatile, isNonTemporal, isInvariant, 02914 Align, AAInfo); 02915 LdChain.push_back(Ops[0].getValue(1)); 02916 unsigned i = 0, Offset = Increment; 02917 for (i=1; i < NumElts; ++i, Offset += Increment) { 02918 SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), 02919 BasePtr, 02920 DAG.getConstant(Offset, 02921 BasePtr.getValueType())); 02922 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr, 02923 LD->getPointerInfo().getWithOffset(Offset), LdEltVT, 02924 isVolatile, isNonTemporal, isInvariant, Align, 02925 AAInfo); 02926 LdChain.push_back(Ops[i].getValue(1)); 02927 } 02928 02929 // Fill the rest with undefs 02930 SDValue UndefVal = DAG.getUNDEF(EltVT); 02931 for (; i != WidenNumElts; ++i) 02932 Ops[i] = UndefVal; 02933 02934 return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, Ops); 02935 } 02936 02937 02938 void DAGTypeLegalizer::GenWidenVectorStores(SmallVectorImpl<SDValue> &StChain, 02939 StoreSDNode *ST) { 02940 // The strategy assumes that we can efficiently store powers of two widths. 02941 // The routines chops the vector into the largest vector stores with the same 02942 // element type or scalar stores. 02943 SDValue Chain = ST->getChain(); 02944 SDValue BasePtr = ST->getBasePtr(); 02945 unsigned Align = ST->getAlignment(); 02946 bool isVolatile = ST->isVolatile(); 02947 bool isNonTemporal = ST->isNonTemporal(); 02948 AAMDNodes AAInfo = ST->getAAInfo(); 02949 SDValue ValOp = GetWidenedVector(ST->getValue()); 02950 SDLoc dl(ST); 02951 02952 EVT StVT = ST->getMemoryVT(); 02953 unsigned StWidth = StVT.getSizeInBits(); 02954 EVT ValVT = ValOp.getValueType(); 02955 unsigned ValWidth = ValVT.getSizeInBits(); 02956 EVT ValEltVT = ValVT.getVectorElementType(); 02957 unsigned ValEltWidth = ValEltVT.getSizeInBits(); 02958 assert(StVT.getVectorElementType() == ValEltVT); 02959 02960 int Idx = 0; // current index to store 02961 unsigned Offset = 0; // offset from base to store 02962 while (StWidth != 0) { 02963 // Find the largest vector type we can store with 02964 EVT NewVT = FindMemType(DAG, TLI, StWidth, ValVT); 02965 unsigned NewVTWidth = NewVT.getSizeInBits(); 02966 unsigned Increment = NewVTWidth / 8; 02967 if (NewVT.isVector()) { 02968 unsigned NumVTElts = NewVT.getVectorNumElements(); 02969 do { 02970 SDValue EOp = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NewVT, ValOp, 02971 DAG.getConstant(Idx, TLI.getVectorIdxTy())); 02972 StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, 02973 ST->getPointerInfo().getWithOffset(Offset), 02974 isVolatile, isNonTemporal, 02975 MinAlign(Align, Offset), AAInfo)); 02976 StWidth -= NewVTWidth; 02977 Offset += Increment; 02978 Idx += NumVTElts; 02979 BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, 02980 DAG.getConstant(Increment, BasePtr.getValueType())); 02981 } while (StWidth != 0 && StWidth >= NewVTWidth); 02982 } else { 02983 // Cast the vector to the scalar type we can store 02984 unsigned NumElts = ValWidth / NewVTWidth; 02985 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NumElts); 02986 SDValue VecOp = DAG.getNode(ISD::BITCAST, dl, NewVecVT, ValOp); 02987 // Readjust index position based on new vector type 02988 Idx = Idx * ValEltWidth / NewVTWidth; 02989 do { 02990 SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, VecOp, 02991 DAG.getConstant(Idx++, TLI.getVectorIdxTy())); 02992 StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, 02993 ST->getPointerInfo().getWithOffset(Offset), 02994 isVolatile, isNonTemporal, 02995 MinAlign(Align, Offset), AAInfo)); 02996 StWidth -= NewVTWidth; 02997 Offset += Increment; 02998 BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, 02999 DAG.getConstant(Increment, BasePtr.getValueType())); 03000 } while (StWidth != 0 && StWidth >= NewVTWidth); 03001 // Restore index back to be relative to the original widen element type 03002 Idx = Idx * NewVTWidth / ValEltWidth; 03003 } 03004 } 03005 } 03006 03007 void 03008 DAGTypeLegalizer::GenWidenVectorTruncStores(SmallVectorImpl<SDValue> &StChain, 03009 StoreSDNode *ST) { 03010 // For extension loads, it may not be more efficient to truncate the vector 03011 // and then store it. Instead, we extract each element and then store it. 03012 SDValue Chain = ST->getChain(); 03013 SDValue BasePtr = ST->getBasePtr(); 03014 unsigned Align = ST->getAlignment(); 03015 bool isVolatile = ST->isVolatile(); 03016 bool isNonTemporal = ST->isNonTemporal(); 03017 AAMDNodes AAInfo = ST->getAAInfo(); 03018 SDValue ValOp = GetWidenedVector(ST->getValue()); 03019 SDLoc dl(ST); 03020 03021 EVT StVT = ST->getMemoryVT(); 03022 EVT ValVT = ValOp.getValueType(); 03023 03024 // It must be true that we the widen vector type is bigger than where 03025 // we need to store. 03026 assert(StVT.isVector() && ValOp.getValueType().isVector()); 03027 assert(StVT.bitsLT(ValOp.getValueType())); 03028 03029 // For truncating stores, we can not play the tricks of chopping legal 03030 // vector types and bit cast it to the right type. Instead, we unroll 03031 // the store. 03032 EVT StEltVT = StVT.getVectorElementType(); 03033 EVT ValEltVT = ValVT.getVectorElementType(); 03034 unsigned Increment = ValEltVT.getSizeInBits() / 8; 03035 unsigned NumElts = StVT.getVectorNumElements(); 03036 SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp, 03037 DAG.getConstant(0, TLI.getVectorIdxTy())); 03038 StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, BasePtr, 03039 ST->getPointerInfo(), StEltVT, 03040 isVolatile, isNonTemporal, Align, 03041 AAInfo)); 03042 unsigned Offset = Increment; 03043 for (unsigned i=1; i < NumElts; ++i, Offset += Increment) { 03044 SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), 03045 BasePtr, DAG.getConstant(Offset, 03046 BasePtr.getValueType())); 03047 SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp, 03048 DAG.getConstant(0, TLI.getVectorIdxTy())); 03049 StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, NewBasePtr, 03050 ST->getPointerInfo().getWithOffset(Offset), 03051 StEltVT, isVolatile, isNonTemporal, 03052 MinAlign(Align, Offset), AAInfo)); 03053 } 03054 } 03055 03056 /// Modifies a vector input (widen or narrows) to a vector of NVT. The 03057 /// input vector must have the same element type as NVT. 03058 SDValue DAGTypeLegalizer::ModifyToType(SDValue InOp, EVT NVT) { 03059 // Note that InOp might have been widened so it might already have 03060 // the right width or it might need be narrowed. 03061 EVT InVT = InOp.getValueType(); 03062 assert(InVT.getVectorElementType() == NVT.getVectorElementType() && 03063 "input and widen element type must match"); 03064 SDLoc dl(InOp); 03065 03066 // Check if InOp already has the right width. 03067 if (InVT == NVT) 03068 return InOp; 03069 03070 unsigned InNumElts = InVT.getVectorNumElements(); 03071 unsigned WidenNumElts = NVT.getVectorNumElements(); 03072 if (WidenNumElts > InNumElts && WidenNumElts % InNumElts == 0) { 03073 unsigned NumConcat = WidenNumElts / InNumElts; 03074 SmallVector<SDValue, 16> Ops(NumConcat); 03075 SDValue UndefVal = DAG.getUNDEF(InVT); 03076 Ops[0] = InOp; 03077 for (unsigned i = 1; i != NumConcat; ++i) 03078 Ops[i] = UndefVal; 03079 03080 return DAG.getNode(ISD::CONCAT_VECTORS, dl, NVT, Ops); 03081 } 03082 03083 if (WidenNumElts < InNumElts && InNumElts % WidenNumElts) 03084 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NVT, InOp, 03085 DAG.getConstant(0, TLI.getVectorIdxTy())); 03086 03087 // Fall back to extract and build. 03088 SmallVector<SDValue, 16> Ops(WidenNumElts); 03089 EVT EltVT = NVT.getVectorElementType(); 03090 unsigned MinNumElts = std::min(WidenNumElts, InNumElts); 03091 unsigned Idx; 03092 for (Idx = 0; Idx < MinNumElts; ++Idx) 03093 Ops[Idx] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, 03094 DAG.getConstant(Idx, TLI.getVectorIdxTy())); 03095 03096 SDValue UndefVal = DAG.getUNDEF(EltVT); 03097 for ( ; Idx < WidenNumElts; ++Idx) 03098 Ops[Idx] = UndefVal; 03099 return DAG.getNode(ISD::BUILD_VECTOR, dl, NVT, Ops); 03100 }