1 //===------- LegalizeVectorTypes.cpp - Legalization of vector types -------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file performs vector type splitting and scalarization for LegalizeTypes. 11 // Scalarization is the act of changing a computation in an illegal one-element 12 // vector type to be a computation in its scalar element type. For example, 13 // implementing <1 x f32> arithmetic in a scalar f32 register. This is needed 14 // as a base case when scalarizing vector arithmetic like <4 x f32>, which 15 // eventually decomposes to scalars if the target doesn't support v4f32 or v2f32 16 // types. 17 // Splitting is the act of changing a computation in an invalid vector type to 18 // be a computation in two vectors of half the size. For example, implementing 19 // <128 x f32> operations in terms of two <64 x f32> operations. 20 // 21 //===----------------------------------------------------------------------===// 22 23 #include "LegalizeTypes.h" 24 #include "llvm/IR/DataLayout.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include "llvm/Support/raw_ostream.h" 27 using namespace llvm; 28 29 #define DEBUG_TYPE "legalize-types" 30 31 //===----------------------------------------------------------------------===// 32 // Result Vector Scalarization: <1 x ty> -> ty. 33 //===----------------------------------------------------------------------===// 34 35 void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) { 36 DEBUG(dbgs() << "Scalarize node result " << ResNo << ": "; 37 N->dump(&DAG); 38 dbgs() << "\n"); 39 SDValue R = SDValue(); 40 41 switch (N->getOpcode()) { 42 default: 43 #ifndef NDEBUG 44 dbgs() << "ScalarizeVectorResult #" << ResNo << ": "; 45 N->dump(&DAG); 46 dbgs() << "\n"; 47 #endif 48 report_fatal_error("Do not know how to scalarize the result of this " 49 "operator!\n"); 50 51 case ISD::MERGE_VALUES: R = ScalarizeVecRes_MERGE_VALUES(N, ResNo);break; 52 case ISD::BITCAST: R = ScalarizeVecRes_BITCAST(N); break; 53 case ISD::BUILD_VECTOR: R = ScalarizeVecRes_BUILD_VECTOR(N); break; 54 case ISD::CONVERT_RNDSAT: R = ScalarizeVecRes_CONVERT_RNDSAT(N); break; 55 case ISD::EXTRACT_SUBVECTOR: R = ScalarizeVecRes_EXTRACT_SUBVECTOR(N); break; 56 case ISD::FP_ROUND: R = ScalarizeVecRes_FP_ROUND(N); break; 57 case ISD::FP_ROUND_INREG: R = ScalarizeVecRes_InregOp(N); break; 58 case ISD::FPOWI: R = ScalarizeVecRes_FPOWI(N); break; 59 case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break; 60 case ISD::LOAD: R = ScalarizeVecRes_LOAD(cast<LoadSDNode>(N));break; 61 case ISD::SCALAR_TO_VECTOR: R = ScalarizeVecRes_SCALAR_TO_VECTOR(N); break; 62 case ISD::SIGN_EXTEND_INREG: R = ScalarizeVecRes_InregOp(N); break; 63 case ISD::VSELECT: R = ScalarizeVecRes_VSELECT(N); break; 64 case ISD::SELECT: R = ScalarizeVecRes_SELECT(N); break; 65 case ISD::SELECT_CC: R = ScalarizeVecRes_SELECT_CC(N); break; 66 case ISD::SETCC: R = ScalarizeVecRes_SETCC(N); break; 67 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(N); break; 68 case ISD::VECTOR_SHUFFLE: R = ScalarizeVecRes_VECTOR_SHUFFLE(N); break; 69 case ISD::ANY_EXTEND: 70 case ISD::BITREVERSE: 71 case ISD::BSWAP: 72 case ISD::CTLZ: 73 case ISD::CTLZ_ZERO_UNDEF: 74 case ISD::CTPOP: 75 case ISD::CTTZ: 76 case ISD::CTTZ_ZERO_UNDEF: 77 case ISD::FABS: 78 case ISD::FCEIL: 79 case ISD::FCOS: 80 case ISD::FEXP: 81 case ISD::FEXP2: 82 case ISD::FFLOOR: 83 case ISD::FLOG: 84 case ISD::FLOG10: 85 case ISD::FLOG2: 86 case ISD::FNEARBYINT: 87 case ISD::FNEG: 88 case ISD::FP_EXTEND: 89 case ISD::FP_TO_SINT: 90 case ISD::FP_TO_UINT: 91 case ISD::FRINT: 92 case ISD::FROUND: 93 case ISD::FSIN: 94 case ISD::FSQRT: 95 case ISD::FTRUNC: 96 case ISD::SIGN_EXTEND: 97 case ISD::SINT_TO_FP: 98 case ISD::TRUNCATE: 99 case ISD::UINT_TO_FP: 100 case ISD::ZERO_EXTEND: 101 R = ScalarizeVecRes_UnaryOp(N); 102 break; 103 104 case ISD::ADD: 105 case ISD::AND: 106 case ISD::FADD: 107 case ISD::FCOPYSIGN: 108 case ISD::FDIV: 109 case ISD::FMUL: 110 case ISD::FMINNUM: 111 case ISD::FMAXNUM: 112 case ISD::FMINNAN: 113 case ISD::FMAXNAN: 114 case ISD::SMIN: 115 case ISD::SMAX: 116 case ISD::UMIN: 117 case ISD::UMAX: 118 119 case ISD::FPOW: 120 case ISD::FREM: 121 case ISD::FSUB: 122 case ISD::MUL: 123 case ISD::OR: 124 case ISD::SDIV: 125 case ISD::SREM: 126 case ISD::SUB: 127 case ISD::UDIV: 128 case ISD::UREM: 129 case ISD::XOR: 130 case ISD::SHL: 131 case ISD::SRA: 132 case ISD::SRL: 133 R = ScalarizeVecRes_BinOp(N); 134 break; 135 case ISD::FMA: 136 R = ScalarizeVecRes_TernaryOp(N); 137 break; 138 } 139 140 // If R is null, the sub-method took care of registering the result. 141 if (R.getNode()) 142 SetScalarizedVector(SDValue(N, ResNo), R); 143 } 144 145 SDValue DAGTypeLegalizer::ScalarizeVecRes_BinOp(SDNode *N) { 146 SDValue LHS = GetScalarizedVector(N->getOperand(0)); 147 SDValue RHS = GetScalarizedVector(N->getOperand(1)); 148 return DAG.getNode(N->getOpcode(), SDLoc(N), 149 LHS.getValueType(), LHS, RHS, N->getFlags()); 150 } 151 152 SDValue DAGTypeLegalizer::ScalarizeVecRes_TernaryOp(SDNode *N) { 153 SDValue Op0 = GetScalarizedVector(N->getOperand(0)); 154 SDValue Op1 = GetScalarizedVector(N->getOperand(1)); 155 SDValue Op2 = GetScalarizedVector(N->getOperand(2)); 156 return DAG.getNode(N->getOpcode(), SDLoc(N), 157 Op0.getValueType(), Op0, Op1, Op2); 158 } 159 160 SDValue DAGTypeLegalizer::ScalarizeVecRes_MERGE_VALUES(SDNode *N, 161 unsigned ResNo) { 162 SDValue Op = DisintegrateMERGE_VALUES(N, ResNo); 163 return GetScalarizedVector(Op); 164 } 165 166 SDValue DAGTypeLegalizer::ScalarizeVecRes_BITCAST(SDNode *N) { 167 EVT NewVT = N->getValueType(0).getVectorElementType(); 168 return DAG.getNode(ISD::BITCAST, SDLoc(N), 169 NewVT, N->getOperand(0)); 170 } 171 172 SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(SDNode *N) { 173 EVT EltVT = N->getValueType(0).getVectorElementType(); 174 SDValue InOp = N->getOperand(0); 175 // The BUILD_VECTOR operands may be of wider element types and 176 // we may need to truncate them back to the requested return type. 177 if (EltVT.isInteger()) 178 return DAG.getNode(ISD::TRUNCATE, SDLoc(N), EltVT, InOp); 179 return InOp; 180 } 181 182 SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_RNDSAT(SDNode *N) { 183 EVT NewVT = N->getValueType(0).getVectorElementType(); 184 SDValue Op0 = GetScalarizedVector(N->getOperand(0)); 185 return DAG.getConvertRndSat(NewVT, SDLoc(N), 186 Op0, DAG.getValueType(NewVT), 187 DAG.getValueType(Op0.getValueType()), 188 N->getOperand(3), 189 N->getOperand(4), 190 cast<CvtRndSatSDNode>(N)->getCvtCode()); 191 } 192 193 SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N) { 194 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), 195 N->getValueType(0).getVectorElementType(), 196 N->getOperand(0), N->getOperand(1)); 197 } 198 199 SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_ROUND(SDNode *N) { 200 EVT NewVT = N->getValueType(0).getVectorElementType(); 201 SDValue Op = GetScalarizedVector(N->getOperand(0)); 202 return DAG.getNode(ISD::FP_ROUND, SDLoc(N), 203 NewVT, Op, N->getOperand(1)); 204 } 205 206 SDValue DAGTypeLegalizer::ScalarizeVecRes_FPOWI(SDNode *N) { 207 SDValue Op = GetScalarizedVector(N->getOperand(0)); 208 return DAG.getNode(ISD::FPOWI, SDLoc(N), 209 Op.getValueType(), Op, N->getOperand(1)); 210 } 211 212 SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N) { 213 // The value to insert may have a wider type than the vector element type, 214 // so be sure to truncate it to the element type if necessary. 215 SDValue Op = N->getOperand(1); 216 EVT EltVT = N->getValueType(0).getVectorElementType(); 217 if (Op.getValueType() != EltVT) 218 // FIXME: Can this happen for floating point types? 219 Op = DAG.getNode(ISD::TRUNCATE, SDLoc(N), EltVT, Op); 220 return Op; 221 } 222 223 SDValue DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) { 224 assert(N->isUnindexed() && "Indexed vector load?"); 225 226 SDValue Result = DAG.getLoad(ISD::UNINDEXED, 227 N->getExtensionType(), 228 N->getValueType(0).getVectorElementType(), 229 SDLoc(N), 230 N->getChain(), N->getBasePtr(), 231 DAG.getUNDEF(N->getBasePtr().getValueType()), 232 N->getPointerInfo(), 233 N->getMemoryVT().getVectorElementType(), 234 N->isVolatile(), N->isNonTemporal(), 235 N->isInvariant(), N->getOriginalAlignment(), 236 N->getAAInfo()); 237 238 // Legalize the chain result - switch anything that used the old chain to 239 // use the new one. 240 ReplaceValueWith(SDValue(N, 1), Result.getValue(1)); 241 return Result; 242 } 243 244 SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(SDNode *N) { 245 // Get the dest type - it doesn't always match the input type, e.g. int_to_fp. 246 EVT DestVT = N->getValueType(0).getVectorElementType(); 247 SDValue Op = N->getOperand(0); 248 EVT OpVT = Op.getValueType(); 249 SDLoc DL(N); 250 // The result needs scalarizing, but it's not a given that the source does. 251 // This is a workaround for targets where it's impossible to scalarize the 252 // result of a conversion, because the source type is legal. 253 // For instance, this happens on AArch64: v1i1 is illegal but v1i{8,16,32} 254 // are widened to v8i8, v4i16, and v2i32, which is legal, because v1i64 is 255 // legal and was not scalarized. 256 // See the similar logic in ScalarizeVecRes_VSETCC 257 if (getTypeAction(OpVT) == TargetLowering::TypeScalarizeVector) { 258 Op = GetScalarizedVector(Op); 259 } else { 260 EVT VT = OpVT.getVectorElementType(); 261 Op = DAG.getNode( 262 ISD::EXTRACT_VECTOR_ELT, DL, VT, Op, 263 DAG.getConstant(0, DL, TLI.getVectorIdxTy(DAG.getDataLayout()))); 264 } 265 return DAG.getNode(N->getOpcode(), SDLoc(N), DestVT, Op); 266 } 267 268 SDValue DAGTypeLegalizer::ScalarizeVecRes_InregOp(SDNode *N) { 269 EVT EltVT = N->getValueType(0).getVectorElementType(); 270 EVT ExtVT = cast<VTSDNode>(N->getOperand(1))->getVT().getVectorElementType(); 271 SDValue LHS = GetScalarizedVector(N->getOperand(0)); 272 return DAG.getNode(N->getOpcode(), SDLoc(N), EltVT, 273 LHS, DAG.getValueType(ExtVT)); 274 } 275 276 SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N) { 277 // If the operand is wider than the vector element type then it is implicitly 278 // truncated. Make that explicit here. 279 EVT EltVT = N->getValueType(0).getVectorElementType(); 280 SDValue InOp = N->getOperand(0); 281 if (InOp.getValueType() != EltVT) 282 return DAG.getNode(ISD::TRUNCATE, SDLoc(N), EltVT, InOp); 283 return InOp; 284 } 285 286 SDValue DAGTypeLegalizer::ScalarizeVecRes_VSELECT(SDNode *N) { 287 SDValue Cond = GetScalarizedVector(N->getOperand(0)); 288 SDValue LHS = GetScalarizedVector(N->getOperand(1)); 289 TargetLowering::BooleanContent ScalarBool = 290 TLI.getBooleanContents(false, false); 291 TargetLowering::BooleanContent VecBool = TLI.getBooleanContents(true, false); 292 293 // If integer and float booleans have different contents then we can't 294 // reliably optimize in all cases. There is a full explanation for this in 295 // DAGCombiner::visitSELECT() where the same issue affects folding 296 // (select C, 0, 1) to (xor C, 1). 297 if (TLI.getBooleanContents(false, false) != 298 TLI.getBooleanContents(false, true)) { 299 // At least try the common case where the boolean is generated by a 300 // comparison. 301 if (Cond->getOpcode() == ISD::SETCC) { 302 EVT OpVT = Cond->getOperand(0)->getValueType(0); 303 ScalarBool = TLI.getBooleanContents(OpVT.getScalarType()); 304 VecBool = TLI.getBooleanContents(OpVT); 305 } else 306 ScalarBool = TargetLowering::UndefinedBooleanContent; 307 } 308 309 if (ScalarBool != VecBool) { 310 EVT CondVT = Cond.getValueType(); 311 switch (ScalarBool) { 312 case TargetLowering::UndefinedBooleanContent: 313 break; 314 case TargetLowering::ZeroOrOneBooleanContent: 315 assert(VecBool == TargetLowering::UndefinedBooleanContent || 316 VecBool == TargetLowering::ZeroOrNegativeOneBooleanContent); 317 // Vector read from all ones, scalar expects a single 1 so mask. 318 Cond = DAG.getNode(ISD::AND, SDLoc(N), CondVT, 319 Cond, DAG.getConstant(1, SDLoc(N), CondVT)); 320 break; 321 case TargetLowering::ZeroOrNegativeOneBooleanContent: 322 assert(VecBool == TargetLowering::UndefinedBooleanContent || 323 VecBool == TargetLowering::ZeroOrOneBooleanContent); 324 // Vector reads from a one, scalar from all ones so sign extend. 325 Cond = DAG.getNode(ISD::SIGN_EXTEND_INREG, SDLoc(N), CondVT, 326 Cond, DAG.getValueType(MVT::i1)); 327 break; 328 } 329 } 330 331 return DAG.getSelect(SDLoc(N), 332 LHS.getValueType(), Cond, LHS, 333 GetScalarizedVector(N->getOperand(2))); 334 } 335 336 SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT(SDNode *N) { 337 SDValue LHS = GetScalarizedVector(N->getOperand(1)); 338 return DAG.getSelect(SDLoc(N), 339 LHS.getValueType(), N->getOperand(0), LHS, 340 GetScalarizedVector(N->getOperand(2))); 341 } 342 343 SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT_CC(SDNode *N) { 344 SDValue LHS = GetScalarizedVector(N->getOperand(2)); 345 return DAG.getNode(ISD::SELECT_CC, SDLoc(N), LHS.getValueType(), 346 N->getOperand(0), N->getOperand(1), 347 LHS, GetScalarizedVector(N->getOperand(3)), 348 N->getOperand(4)); 349 } 350 351 SDValue DAGTypeLegalizer::ScalarizeVecRes_SETCC(SDNode *N) { 352 assert(N->getValueType(0).isVector() == 353 N->getOperand(0).getValueType().isVector() && 354 "Scalar/Vector type mismatch"); 355 356 if (N->getValueType(0).isVector()) return ScalarizeVecRes_VSETCC(N); 357 358 SDValue LHS = GetScalarizedVector(N->getOperand(0)); 359 SDValue RHS = GetScalarizedVector(N->getOperand(1)); 360 SDLoc DL(N); 361 362 // Turn it into a scalar SETCC. 363 return DAG.getNode(ISD::SETCC, DL, MVT::i1, LHS, RHS, N->getOperand(2)); 364 } 365 366 SDValue DAGTypeLegalizer::ScalarizeVecRes_UNDEF(SDNode *N) { 367 return DAG.getUNDEF(N->getValueType(0).getVectorElementType()); 368 } 369 370 SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N) { 371 // Figure out if the scalar is the LHS or RHS and return it. 372 SDValue Arg = N->getOperand(2).getOperand(0); 373 if (Arg.getOpcode() == ISD::UNDEF) 374 return DAG.getUNDEF(N->getValueType(0).getVectorElementType()); 375 unsigned Op = !cast<ConstantSDNode>(Arg)->isNullValue(); 376 return GetScalarizedVector(N->getOperand(Op)); 377 } 378 379 SDValue DAGTypeLegalizer::ScalarizeVecRes_VSETCC(SDNode *N) { 380 assert(N->getValueType(0).isVector() && 381 N->getOperand(0).getValueType().isVector() && 382 "Operand types must be vectors"); 383 SDValue LHS = N->getOperand(0); 384 SDValue RHS = N->getOperand(1); 385 EVT OpVT = LHS.getValueType(); 386 EVT NVT = N->getValueType(0).getVectorElementType(); 387 SDLoc DL(N); 388 389 // The result needs scalarizing, but it's not a given that the source does. 390 if (getTypeAction(OpVT) == TargetLowering::TypeScalarizeVector) { 391 LHS = GetScalarizedVector(LHS); 392 RHS = GetScalarizedVector(RHS); 393 } else { 394 EVT VT = OpVT.getVectorElementType(); 395 LHS = DAG.getNode( 396 ISD::EXTRACT_VECTOR_ELT, DL, VT, LHS, 397 DAG.getConstant(0, DL, TLI.getVectorIdxTy(DAG.getDataLayout()))); 398 RHS = DAG.getNode( 399 ISD::EXTRACT_VECTOR_ELT, DL, VT, RHS, 400 DAG.getConstant(0, DL, TLI.getVectorIdxTy(DAG.getDataLayout()))); 401 } 402 403 // Turn it into a scalar SETCC. 404 SDValue Res = DAG.getNode(ISD::SETCC, DL, MVT::i1, LHS, RHS, 405 N->getOperand(2)); 406 // Vectors may have a different boolean contents to scalars. Promote the 407 // value appropriately. 408 ISD::NodeType ExtendCode = 409 TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT)); 410 return DAG.getNode(ExtendCode, DL, NVT, Res); 411 } 412 413 414 //===----------------------------------------------------------------------===// 415 // Operand Vector Scalarization <1 x ty> -> ty. 416 //===----------------------------------------------------------------------===// 417 418 bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) { 419 DEBUG(dbgs() << "Scalarize node operand " << OpNo << ": "; 420 N->dump(&DAG); 421 dbgs() << "\n"); 422 SDValue Res = SDValue(); 423 424 if (!Res.getNode()) { 425 switch (N->getOpcode()) { 426 default: 427 #ifndef NDEBUG 428 dbgs() << "ScalarizeVectorOperand Op #" << OpNo << ": "; 429 N->dump(&DAG); 430 dbgs() << "\n"; 431 #endif 432 llvm_unreachable("Do not know how to scalarize this operator's operand!"); 433 case ISD::BITCAST: 434 Res = ScalarizeVecOp_BITCAST(N); 435 break; 436 case ISD::ANY_EXTEND: 437 case ISD::ZERO_EXTEND: 438 case ISD::SIGN_EXTEND: 439 case ISD::TRUNCATE: 440 case ISD::FP_TO_SINT: 441 case ISD::FP_TO_UINT: 442 case ISD::SINT_TO_FP: 443 case ISD::UINT_TO_FP: 444 Res = ScalarizeVecOp_UnaryOp(N); 445 break; 446 case ISD::CONCAT_VECTORS: 447 Res = ScalarizeVecOp_CONCAT_VECTORS(N); 448 break; 449 case ISD::EXTRACT_VECTOR_ELT: 450 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(N); 451 break; 452 case ISD::VSELECT: 453 Res = ScalarizeVecOp_VSELECT(N); 454 break; 455 case ISD::STORE: 456 Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(N), OpNo); 457 break; 458 case ISD::FP_ROUND: 459 Res = ScalarizeVecOp_FP_ROUND(N, OpNo); 460 break; 461 } 462 } 463 464 // If the result is null, the sub-method took care of registering results etc. 465 if (!Res.getNode()) return false; 466 467 // If the result is N, the sub-method updated N in place. Tell the legalizer 468 // core about this. 469 if (Res.getNode() == N) 470 return true; 471 472 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 473 "Invalid operand expansion"); 474 475 ReplaceValueWith(SDValue(N, 0), Res); 476 return false; 477 } 478 479 /// ScalarizeVecOp_BITCAST - If the value to convert is a vector that needs 480 /// to be scalarized, it must be <1 x ty>. Convert the element instead. 481 SDValue DAGTypeLegalizer::ScalarizeVecOp_BITCAST(SDNode *N) { 482 SDValue Elt = GetScalarizedVector(N->getOperand(0)); 483 return DAG.getNode(ISD::BITCAST, SDLoc(N), 484 N->getValueType(0), Elt); 485 } 486 487 /// ScalarizeVecOp_UnaryOp - If the input is a vector that needs to be 488 /// scalarized, it must be <1 x ty>. Do the operation on the element instead. 489 SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp(SDNode *N) { 490 assert(N->getValueType(0).getVectorNumElements() == 1 && 491 "Unexpected vector type!"); 492 SDValue Elt = GetScalarizedVector(N->getOperand(0)); 493 SDValue Op = DAG.getNode(N->getOpcode(), SDLoc(N), 494 N->getValueType(0).getScalarType(), Elt); 495 // Revectorize the result so the types line up with what the uses of this 496 // expression expect. 497 return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(N), N->getValueType(0), Op); 498 } 499 500 /// ScalarizeVecOp_CONCAT_VECTORS - The vectors to concatenate have length one - 501 /// use a BUILD_VECTOR instead. 502 SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(SDNode *N) { 503 SmallVector<SDValue, 8> Ops(N->getNumOperands()); 504 for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i) 505 Ops[i] = GetScalarizedVector(N->getOperand(i)); 506 return DAG.getNode(ISD::BUILD_VECTOR, SDLoc(N), N->getValueType(0), Ops); 507 } 508 509 /// ScalarizeVecOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to 510 /// be scalarized, it must be <1 x ty>, so just return the element, ignoring the 511 /// index. 512 SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { 513 SDValue Res = GetScalarizedVector(N->getOperand(0)); 514 if (Res.getValueType() != N->getValueType(0)) 515 Res = DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), N->getValueType(0), 516 Res); 517 return Res; 518 } 519 520 521 /// ScalarizeVecOp_VSELECT - If the input condition is a vector that needs to be 522 /// scalarized, it must be <1 x i1>, so just convert to a normal ISD::SELECT 523 /// (still with vector output type since that was acceptable if we got here). 524 SDValue DAGTypeLegalizer::ScalarizeVecOp_VSELECT(SDNode *N) { 525 SDValue ScalarCond = GetScalarizedVector(N->getOperand(0)); 526 EVT VT = N->getValueType(0); 527 528 return DAG.getNode(ISD::SELECT, SDLoc(N), VT, ScalarCond, N->getOperand(1), 529 N->getOperand(2)); 530 } 531 532 /// ScalarizeVecOp_STORE - If the value to store is a vector that needs to be 533 /// scalarized, it must be <1 x ty>. Just store the element. 534 SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){ 535 assert(N->isUnindexed() && "Indexed store of one-element vector?"); 536 assert(OpNo == 1 && "Do not know how to scalarize this operand!"); 537 SDLoc dl(N); 538 539 if (N->isTruncatingStore()) 540 return DAG.getTruncStore(N->getChain(), dl, 541 GetScalarizedVector(N->getOperand(1)), 542 N->getBasePtr(), N->getPointerInfo(), 543 N->getMemoryVT().getVectorElementType(), 544 N->isVolatile(), N->isNonTemporal(), 545 N->getAlignment(), N->getAAInfo()); 546 547 return DAG.getStore(N->getChain(), dl, GetScalarizedVector(N->getOperand(1)), 548 N->getBasePtr(), N->getPointerInfo(), 549 N->isVolatile(), N->isNonTemporal(), 550 N->getOriginalAlignment(), N->getAAInfo()); 551 } 552 553 /// ScalarizeVecOp_FP_ROUND - If the value to round is a vector that needs 554 /// to be scalarized, it must be <1 x ty>. Convert the element instead. 555 SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(SDNode *N, unsigned OpNo) { 556 SDValue Elt = GetScalarizedVector(N->getOperand(0)); 557 SDValue Res = DAG.getNode(ISD::FP_ROUND, SDLoc(N), 558 N->getValueType(0).getVectorElementType(), Elt, 559 N->getOperand(1)); 560 return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res); 561 } 562 563 //===----------------------------------------------------------------------===// 564 // Result Vector Splitting 565 //===----------------------------------------------------------------------===// 566 567 /// SplitVectorResult - This method is called when the specified result of the 568 /// specified node is found to need vector splitting. At this point, the node 569 /// may also have invalid operands or may have other results that need 570 /// legalization, we just know that (at least) one result needs vector 571 /// splitting. 572 void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) { 573 DEBUG(dbgs() << "Split node result: "; 574 N->dump(&DAG); 575 dbgs() << "\n"); 576 SDValue Lo, Hi; 577 578 // See if the target wants to custom expand this node. 579 if (CustomLowerNode(N, N->getValueType(ResNo), true)) 580 return; 581 582 switch (N->getOpcode()) { 583 default: 584 #ifndef NDEBUG 585 dbgs() << "SplitVectorResult #" << ResNo << ": "; 586 N->dump(&DAG); 587 dbgs() << "\n"; 588 #endif 589 report_fatal_error("Do not know how to split the result of this " 590 "operator!\n"); 591 592 case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, ResNo, Lo, Hi); break; 593 case ISD::VSELECT: 594 case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; 595 case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; 596 case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; 597 case ISD::BITCAST: SplitVecRes_BITCAST(N, Lo, Hi); break; 598 case ISD::BUILD_VECTOR: SplitVecRes_BUILD_VECTOR(N, Lo, Hi); break; 599 case ISD::CONCAT_VECTORS: SplitVecRes_CONCAT_VECTORS(N, Lo, Hi); break; 600 case ISD::EXTRACT_SUBVECTOR: SplitVecRes_EXTRACT_SUBVECTOR(N, Lo, Hi); break; 601 case ISD::INSERT_SUBVECTOR: SplitVecRes_INSERT_SUBVECTOR(N, Lo, Hi); break; 602 case ISD::FP_ROUND_INREG: SplitVecRes_InregOp(N, Lo, Hi); break; 603 case ISD::FPOWI: SplitVecRes_FPOWI(N, Lo, Hi); break; 604 case ISD::FCOPYSIGN: SplitVecRes_FCOPYSIGN(N, Lo, Hi); break; 605 case ISD::INSERT_VECTOR_ELT: SplitVecRes_INSERT_VECTOR_ELT(N, Lo, Hi); break; 606 case ISD::SCALAR_TO_VECTOR: SplitVecRes_SCALAR_TO_VECTOR(N, Lo, Hi); break; 607 case ISD::SIGN_EXTEND_INREG: SplitVecRes_InregOp(N, Lo, Hi); break; 608 case ISD::LOAD: 609 SplitVecRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); 610 break; 611 case ISD::MLOAD: 612 SplitVecRes_MLOAD(cast<MaskedLoadSDNode>(N), Lo, Hi); 613 break; 614 case ISD::MGATHER: 615 SplitVecRes_MGATHER(cast<MaskedGatherSDNode>(N), Lo, Hi); 616 break; 617 case ISD::SETCC: 618 SplitVecRes_SETCC(N, Lo, Hi); 619 break; 620 case ISD::VECTOR_SHUFFLE: 621 SplitVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N), Lo, Hi); 622 break; 623 624 case ISD::BITREVERSE: 625 case ISD::BSWAP: 626 case ISD::CONVERT_RNDSAT: 627 case ISD::CTLZ: 628 case ISD::CTTZ: 629 case ISD::CTLZ_ZERO_UNDEF: 630 case ISD::CTTZ_ZERO_UNDEF: 631 case ISD::CTPOP: 632 case ISD::FABS: 633 case ISD::FCEIL: 634 case ISD::FCOS: 635 case ISD::FEXP: 636 case ISD::FEXP2: 637 case ISD::FFLOOR: 638 case ISD::FLOG: 639 case ISD::FLOG10: 640 case ISD::FLOG2: 641 case ISD::FNEARBYINT: 642 case ISD::FNEG: 643 case ISD::FP_EXTEND: 644 case ISD::FP_ROUND: 645 case ISD::FP_TO_SINT: 646 case ISD::FP_TO_UINT: 647 case ISD::FRINT: 648 case ISD::FROUND: 649 case ISD::FSIN: 650 case ISD::FSQRT: 651 case ISD::FTRUNC: 652 case ISD::SINT_TO_FP: 653 case ISD::TRUNCATE: 654 case ISD::UINT_TO_FP: 655 SplitVecRes_UnaryOp(N, Lo, Hi); 656 break; 657 658 case ISD::ANY_EXTEND: 659 case ISD::SIGN_EXTEND: 660 case ISD::ZERO_EXTEND: 661 SplitVecRes_ExtendOp(N, Lo, Hi); 662 break; 663 664 case ISD::ADD: 665 case ISD::SUB: 666 case ISD::MUL: 667 case ISD::FADD: 668 case ISD::FSUB: 669 case ISD::FMUL: 670 case ISD::FMINNUM: 671 case ISD::FMAXNUM: 672 case ISD::FMINNAN: 673 case ISD::FMAXNAN: 674 case ISD::SDIV: 675 case ISD::UDIV: 676 case ISD::FDIV: 677 case ISD::FPOW: 678 case ISD::AND: 679 case ISD::OR: 680 case ISD::XOR: 681 case ISD::SHL: 682 case ISD::SRA: 683 case ISD::SRL: 684 case ISD::UREM: 685 case ISD::SREM: 686 case ISD::FREM: 687 case ISD::SMIN: 688 case ISD::SMAX: 689 case ISD::UMIN: 690 case ISD::UMAX: 691 SplitVecRes_BinOp(N, Lo, Hi); 692 break; 693 case ISD::FMA: 694 SplitVecRes_TernaryOp(N, Lo, Hi); 695 break; 696 } 697 698 // If Lo/Hi is null, the sub-method took care of registering results etc. 699 if (Lo.getNode()) 700 SetSplitVector(SDValue(N, ResNo), Lo, Hi); 701 } 702 703 void DAGTypeLegalizer::SplitVecRes_BinOp(SDNode *N, SDValue &Lo, 704 SDValue &Hi) { 705 SDValue LHSLo, LHSHi; 706 GetSplitVector(N->getOperand(0), LHSLo, LHSHi); 707 SDValue RHSLo, RHSHi; 708 GetSplitVector(N->getOperand(1), RHSLo, RHSHi); 709 SDLoc dl(N); 710 711 const SDNodeFlags *Flags = N->getFlags(); 712 unsigned Opcode = N->getOpcode(); 713 Lo = DAG.getNode(Opcode, dl, LHSLo.getValueType(), LHSLo, RHSLo, Flags); 714 Hi = DAG.getNode(Opcode, dl, LHSHi.getValueType(), LHSHi, RHSHi, Flags); 715 } 716 717 void DAGTypeLegalizer::SplitVecRes_TernaryOp(SDNode *N, SDValue &Lo, 718 SDValue &Hi) { 719 SDValue Op0Lo, Op0Hi; 720 GetSplitVector(N->getOperand(0), Op0Lo, Op0Hi); 721 SDValue Op1Lo, Op1Hi; 722 GetSplitVector(N->getOperand(1), Op1Lo, Op1Hi); 723 SDValue Op2Lo, Op2Hi; 724 GetSplitVector(N->getOperand(2), Op2Lo, Op2Hi); 725 SDLoc dl(N); 726 727 Lo = DAG.getNode(N->getOpcode(), dl, Op0Lo.getValueType(), 728 Op0Lo, Op1Lo, Op2Lo); 729 Hi = DAG.getNode(N->getOpcode(), dl, Op0Hi.getValueType(), 730 Op0Hi, Op1Hi, Op2Hi); 731 } 732 733 void DAGTypeLegalizer::SplitVecRes_BITCAST(SDNode *N, SDValue &Lo, 734 SDValue &Hi) { 735 // We know the result is a vector. The input may be either a vector or a 736 // scalar value. 737 EVT LoVT, HiVT; 738 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); 739 SDLoc dl(N); 740 741 SDValue InOp = N->getOperand(0); 742 EVT InVT = InOp.getValueType(); 743 744 // Handle some special cases efficiently. 745 switch (getTypeAction(InVT)) { 746 case TargetLowering::TypeLegal: 747 case TargetLowering::TypePromoteInteger: 748 case TargetLowering::TypePromoteFloat: 749 case TargetLowering::TypeSoftenFloat: 750 case TargetLowering::TypeScalarizeVector: 751 case TargetLowering::TypeWidenVector: 752 break; 753 case TargetLowering::TypeExpandInteger: 754 case TargetLowering::TypeExpandFloat: 755 // A scalar to vector conversion, where the scalar needs expansion. 756 // If the vector is being split in two then we can just convert the 757 // expanded pieces. 758 if (LoVT == HiVT) { 759 GetExpandedOp(InOp, Lo, Hi); 760 if (DAG.getDataLayout().isBigEndian()) 761 std::swap(Lo, Hi); 762 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, Lo); 763 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, Hi); 764 return; 765 } 766 break; 767 case TargetLowering::TypeSplitVector: 768 // If the input is a vector that needs to be split, convert each split 769 // piece of the input now. 770 GetSplitVector(InOp, Lo, Hi); 771 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, Lo); 772 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, Hi); 773 return; 774 } 775 776 // In the general case, convert the input to an integer and split it by hand. 777 EVT LoIntVT = EVT::getIntegerVT(*DAG.getContext(), LoVT.getSizeInBits()); 778 EVT HiIntVT = EVT::getIntegerVT(*DAG.getContext(), HiVT.getSizeInBits()); 779 if (DAG.getDataLayout().isBigEndian()) 780 std::swap(LoIntVT, HiIntVT); 781 782 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT, Lo, Hi); 783 784 if (DAG.getDataLayout().isBigEndian()) 785 std::swap(Lo, Hi); 786 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, Lo); 787 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, Hi); 788 } 789 790 void DAGTypeLegalizer::SplitVecRes_BUILD_VECTOR(SDNode *N, SDValue &Lo, 791 SDValue &Hi) { 792 EVT LoVT, HiVT; 793 SDLoc dl(N); 794 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); 795 unsigned LoNumElts = LoVT.getVectorNumElements(); 796 SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+LoNumElts); 797 Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, LoVT, LoOps); 798 799 SmallVector<SDValue, 8> HiOps(N->op_begin()+LoNumElts, N->op_end()); 800 Hi = DAG.getNode(ISD::BUILD_VECTOR, dl, HiVT, HiOps); 801 } 802 803 void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo, 804 SDValue &Hi) { 805 assert(!(N->getNumOperands() & 1) && "Unsupported CONCAT_VECTORS"); 806 SDLoc dl(N); 807 unsigned NumSubvectors = N->getNumOperands() / 2; 808 if (NumSubvectors == 1) { 809 Lo = N->getOperand(0); 810 Hi = N->getOperand(1); 811 return; 812 } 813 814 EVT LoVT, HiVT; 815 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); 816 817 SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+NumSubvectors); 818 Lo = DAG.getNode(ISD::CONCAT_VECTORS, dl, LoVT, LoOps); 819 820 SmallVector<SDValue, 8> HiOps(N->op_begin()+NumSubvectors, N->op_end()); 821 Hi = DAG.getNode(ISD::CONCAT_VECTORS, dl, HiVT, HiOps); 822 } 823 824 void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo, 825 SDValue &Hi) { 826 SDValue Vec = N->getOperand(0); 827 SDValue Idx = N->getOperand(1); 828 SDLoc dl(N); 829 830 EVT LoVT, HiVT; 831 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); 832 833 Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, LoVT, Vec, Idx); 834 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue(); 835 Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HiVT, Vec, 836 DAG.getConstant(IdxVal + LoVT.getVectorNumElements(), dl, 837 TLI.getVectorIdxTy(DAG.getDataLayout()))); 838 } 839 840 void DAGTypeLegalizer::SplitVecRes_INSERT_SUBVECTOR(SDNode *N, SDValue &Lo, 841 SDValue &Hi) { 842 SDValue Vec = N->getOperand(0); 843 SDValue SubVec = N->getOperand(1); 844 SDValue Idx = N->getOperand(2); 845 SDLoc dl(N); 846 GetSplitVector(Vec, Lo, Hi); 847 848 // Spill the vector to the stack. 849 EVT VecVT = Vec.getValueType(); 850 EVT SubVecVT = VecVT.getVectorElementType(); 851 SDValue StackPtr = DAG.CreateStackTemporary(VecVT); 852 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, 853 MachinePointerInfo(), false, false, 0); 854 855 // Store the new subvector into the specified index. 856 SDValue SubVecPtr = GetVectorElementPointer(StackPtr, SubVecVT, Idx); 857 Type *VecType = VecVT.getTypeForEVT(*DAG.getContext()); 858 unsigned Alignment = DAG.getDataLayout().getPrefTypeAlignment(VecType); 859 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr, MachinePointerInfo(), 860 false, false, 0); 861 862 // Load the Lo part from the stack slot. 863 Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, MachinePointerInfo(), 864 false, false, false, 0); 865 866 // Increment the pointer to the other part. 867 unsigned IncrementSize = Lo.getValueType().getSizeInBits() / 8; 868 StackPtr = 869 DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 870 DAG.getConstant(IncrementSize, dl, StackPtr.getValueType())); 871 872 // Load the Hi part from the stack slot. 873 Hi = DAG.getLoad(Hi.getValueType(), dl, Store, StackPtr, MachinePointerInfo(), 874 false, false, false, MinAlign(Alignment, IncrementSize)); 875 } 876 877 void DAGTypeLegalizer::SplitVecRes_FPOWI(SDNode *N, SDValue &Lo, 878 SDValue &Hi) { 879 SDLoc dl(N); 880 GetSplitVector(N->getOperand(0), Lo, Hi); 881 Lo = DAG.getNode(ISD::FPOWI, dl, Lo.getValueType(), Lo, N->getOperand(1)); 882 Hi = DAG.getNode(ISD::FPOWI, dl, Hi.getValueType(), Hi, N->getOperand(1)); 883 } 884 885 void DAGTypeLegalizer::SplitVecRes_FCOPYSIGN(SDNode *N, SDValue &Lo, 886 SDValue &Hi) { 887 SDValue LHSLo, LHSHi; 888 GetSplitVector(N->getOperand(0), LHSLo, LHSHi); 889 SDLoc DL(N); 890 891 SDValue RHSLo, RHSHi; 892 SDValue RHS = N->getOperand(1); 893 EVT RHSVT = RHS.getValueType(); 894 if (getTypeAction(RHSVT) == TargetLowering::TypeSplitVector) 895 GetSplitVector(RHS, RHSLo, RHSHi); 896 else 897 std::tie(RHSLo, RHSHi) = DAG.SplitVector(RHS, SDLoc(RHS)); 898 899 900 Lo = DAG.getNode(ISD::FCOPYSIGN, DL, LHSLo.getValueType(), LHSLo, RHSLo); 901 Hi = DAG.getNode(ISD::FCOPYSIGN, DL, LHSHi.getValueType(), LHSHi, RHSHi); 902 } 903 904 void DAGTypeLegalizer::SplitVecRes_InregOp(SDNode *N, SDValue &Lo, 905 SDValue &Hi) { 906 SDValue LHSLo, LHSHi; 907 GetSplitVector(N->getOperand(0), LHSLo, LHSHi); 908 SDLoc dl(N); 909 910 EVT LoVT, HiVT; 911 std::tie(LoVT, HiVT) = 912 DAG.GetSplitDestVTs(cast<VTSDNode>(N->getOperand(1))->getVT()); 913 914 Lo = DAG.getNode(N->getOpcode(), dl, LHSLo.getValueType(), LHSLo, 915 DAG.getValueType(LoVT)); 916 Hi = DAG.getNode(N->getOpcode(), dl, LHSHi.getValueType(), LHSHi, 917 DAG.getValueType(HiVT)); 918 } 919 920 void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, 921 SDValue &Hi) { 922 SDValue Vec = N->getOperand(0); 923 SDValue Elt = N->getOperand(1); 924 SDValue Idx = N->getOperand(2); 925 SDLoc dl(N); 926 GetSplitVector(Vec, Lo, Hi); 927 928 if (ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Idx)) { 929 unsigned IdxVal = CIdx->getZExtValue(); 930 unsigned LoNumElts = Lo.getValueType().getVectorNumElements(); 931 if (IdxVal < LoNumElts) 932 Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, 933 Lo.getValueType(), Lo, Elt, Idx); 934 else 935 Hi = 936 DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, Hi.getValueType(), Hi, Elt, 937 DAG.getConstant(IdxVal - LoNumElts, dl, 938 TLI.getVectorIdxTy(DAG.getDataLayout()))); 939 return; 940 } 941 942 // See if the target wants to custom expand this node. 943 if (CustomLowerNode(N, N->getValueType(0), true)) 944 return; 945 946 // Spill the vector to the stack. 947 EVT VecVT = Vec.getValueType(); 948 EVT EltVT = VecVT.getVectorElementType(); 949 SDValue StackPtr = DAG.CreateStackTemporary(VecVT); 950 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, 951 MachinePointerInfo(), false, false, 0); 952 953 // Store the new element. This may be larger than the vector element type, 954 // so use a truncating store. 955 SDValue EltPtr = GetVectorElementPointer(StackPtr, EltVT, Idx); 956 Type *VecType = VecVT.getTypeForEVT(*DAG.getContext()); 957 unsigned Alignment = DAG.getDataLayout().getPrefTypeAlignment(VecType); 958 Store = DAG.getTruncStore(Store, dl, Elt, EltPtr, MachinePointerInfo(), EltVT, 959 false, false, 0); 960 961 // Load the Lo part from the stack slot. 962 Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, MachinePointerInfo(), 963 false, false, false, 0); 964 965 // Increment the pointer to the other part. 966 unsigned IncrementSize = Lo.getValueType().getSizeInBits() / 8; 967 StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 968 DAG.getConstant(IncrementSize, dl, 969 StackPtr.getValueType())); 970 971 // Load the Hi part from the stack slot. 972 Hi = DAG.getLoad(Hi.getValueType(), dl, Store, StackPtr, MachinePointerInfo(), 973 false, false, false, MinAlign(Alignment, IncrementSize)); 974 } 975 976 void DAGTypeLegalizer::SplitVecRes_SCALAR_TO_VECTOR(SDNode *N, SDValue &Lo, 977 SDValue &Hi) { 978 EVT LoVT, HiVT; 979 SDLoc dl(N); 980 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); 981 Lo = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, LoVT, N->getOperand(0)); 982 Hi = DAG.getUNDEF(HiVT); 983 } 984 985 void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo, 986 SDValue &Hi) { 987 assert(ISD::isUNINDEXEDLoad(LD) && "Indexed load during type legalization!"); 988 EVT LoVT, HiVT; 989 SDLoc dl(LD); 990 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(LD->getValueType(0)); 991 992 ISD::LoadExtType ExtType = LD->getExtensionType(); 993 SDValue Ch = LD->getChain(); 994 SDValue Ptr = LD->getBasePtr(); 995 SDValue Offset = DAG.getUNDEF(Ptr.getValueType()); 996 EVT MemoryVT = LD->getMemoryVT(); 997 unsigned Alignment = LD->getOriginalAlignment(); 998 bool isVolatile = LD->isVolatile(); 999 bool isNonTemporal = LD->isNonTemporal(); 1000 bool isInvariant = LD->isInvariant(); 1001 AAMDNodes AAInfo = LD->getAAInfo(); 1002 1003 EVT LoMemVT, HiMemVT; 1004 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT); 1005 1006 Lo = DAG.getLoad(ISD::UNINDEXED, ExtType, LoVT, dl, Ch, Ptr, Offset, 1007 LD->getPointerInfo(), LoMemVT, isVolatile, isNonTemporal, 1008 isInvariant, Alignment, AAInfo); 1009 1010 unsigned IncrementSize = LoMemVT.getSizeInBits()/8; 1011 Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 1012 DAG.getConstant(IncrementSize, dl, Ptr.getValueType())); 1013 Hi = DAG.getLoad(ISD::UNINDEXED, ExtType, HiVT, dl, Ch, Ptr, Offset, 1014 LD->getPointerInfo().getWithOffset(IncrementSize), 1015 HiMemVT, isVolatile, isNonTemporal, isInvariant, Alignment, 1016 AAInfo); 1017 1018 // Build a factor node to remember that this load is independent of the 1019 // other one. 1020 Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 1021 Hi.getValue(1)); 1022 1023 // Legalize the chain result - switch anything that used the old chain to 1024 // use the new one. 1025 ReplaceValueWith(SDValue(LD, 1), Ch); 1026 } 1027 1028 void DAGTypeLegalizer::SplitVecRes_MLOAD(MaskedLoadSDNode *MLD, 1029 SDValue &Lo, SDValue &Hi) { 1030 EVT LoVT, HiVT; 1031 SDLoc dl(MLD); 1032 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->getValueType(0)); 1033 1034 SDValue Ch = MLD->getChain(); 1035 SDValue Ptr = MLD->getBasePtr(); 1036 SDValue Mask = MLD->getMask(); 1037 SDValue Src0 = MLD->getSrc0(); 1038 unsigned Alignment = MLD->getOriginalAlignment(); 1039 ISD::LoadExtType ExtType = MLD->getExtensionType(); 1040 1041 // if Alignment is equal to the vector size, 1042 // take the half of it for the second part 1043 unsigned SecondHalfAlignment = 1044 (Alignment == MLD->getValueType(0).getSizeInBits()/8) ? 1045 Alignment/2 : Alignment; 1046 1047 // Split Mask operand 1048 SDValue MaskLo, MaskHi; 1049 if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector) 1050 GetSplitVector(Mask, MaskLo, MaskHi); 1051 else 1052 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl); 1053 1054 EVT MemoryVT = MLD->getMemoryVT(); 1055 EVT LoMemVT, HiMemVT; 1056 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT); 1057 1058 SDValue Src0Lo, Src0Hi; 1059 if (getTypeAction(Src0.getValueType()) == TargetLowering::TypeSplitVector) 1060 GetSplitVector(Src0, Src0Lo, Src0Hi); 1061 else 1062 std::tie(Src0Lo, Src0Hi) = DAG.SplitVector(Src0, dl); 1063 1064 MachineMemOperand *MMO = DAG.getMachineFunction(). 1065 getMachineMemOperand(MLD->getPointerInfo(), 1066 MachineMemOperand::MOLoad, LoMemVT.getStoreSize(), 1067 Alignment, MLD->getAAInfo(), MLD->getRanges()); 1068 1069 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr, MaskLo, Src0Lo, LoMemVT, MMO, 1070 ExtType); 1071 1072 unsigned IncrementSize = LoMemVT.getSizeInBits()/8; 1073 Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 1074 DAG.getConstant(IncrementSize, dl, Ptr.getValueType())); 1075 1076 MMO = DAG.getMachineFunction(). 1077 getMachineMemOperand(MLD->getPointerInfo(), 1078 MachineMemOperand::MOLoad, HiMemVT.getStoreSize(), 1079 SecondHalfAlignment, MLD->getAAInfo(), MLD->getRanges()); 1080 1081 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr, MaskHi, Src0Hi, HiMemVT, MMO, 1082 ExtType); 1083 1084 1085 // Build a factor node to remember that this load is independent of the 1086 // other one. 1087 Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 1088 Hi.getValue(1)); 1089 1090 // Legalize the chain result - switch anything that used the old chain to 1091 // use the new one. 1092 ReplaceValueWith(SDValue(MLD, 1), Ch); 1093 1094 } 1095 1096 void DAGTypeLegalizer::SplitVecRes_MGATHER(MaskedGatherSDNode *MGT, 1097 SDValue &Lo, SDValue &Hi) { 1098 EVT LoVT, HiVT; 1099 SDLoc dl(MGT); 1100 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MGT->getValueType(0)); 1101 1102 SDValue Ch = MGT->getChain(); 1103 SDValue Ptr = MGT->getBasePtr(); 1104 SDValue Mask = MGT->getMask(); 1105 SDValue Src0 = MGT->getValue(); 1106 SDValue Index = MGT->getIndex(); 1107 unsigned Alignment = MGT->getOriginalAlignment(); 1108 1109 // Split Mask operand 1110 SDValue MaskLo, MaskHi; 1111 if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector) 1112 GetSplitVector(Mask, MaskLo, MaskHi); 1113 else 1114 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl); 1115 1116 EVT MemoryVT = MGT->getMemoryVT(); 1117 EVT LoMemVT, HiMemVT; 1118 // Split MemoryVT 1119 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT); 1120 1121 SDValue Src0Lo, Src0Hi; 1122 if (getTypeAction(Src0.getValueType()) == TargetLowering::TypeSplitVector) 1123 GetSplitVector(Src0, Src0Lo, Src0Hi); 1124 else 1125 std::tie(Src0Lo, Src0Hi) = DAG.SplitVector(Src0, dl); 1126 1127 SDValue IndexHi, IndexLo; 1128 if (getTypeAction(Index.getValueType()) == TargetLowering::TypeSplitVector) 1129 GetSplitVector(Index, IndexLo, IndexHi); 1130 else 1131 std::tie(IndexLo, IndexHi) = DAG.SplitVector(Index, dl); 1132 1133 MachineMemOperand *MMO = DAG.getMachineFunction(). 1134 getMachineMemOperand(MGT->getPointerInfo(), 1135 MachineMemOperand::MOLoad, LoMemVT.getStoreSize(), 1136 Alignment, MGT->getAAInfo(), MGT->getRanges()); 1137 1138 SDValue OpsLo[] = {Ch, Src0Lo, MaskLo, Ptr, IndexLo}; 1139 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoVT, dl, OpsLo, 1140 MMO); 1141 1142 SDValue OpsHi[] = {Ch, Src0Hi, MaskHi, Ptr, IndexHi}; 1143 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiVT, dl, OpsHi, 1144 MMO); 1145 1146 // Build a factor node to remember that this load is independent of the 1147 // other one. 1148 Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 1149 Hi.getValue(1)); 1150 1151 // Legalize the chain result - switch anything that used the old chain to 1152 // use the new one. 1153 ReplaceValueWith(SDValue(MGT, 1), Ch); 1154 } 1155 1156 1157 void DAGTypeLegalizer::SplitVecRes_SETCC(SDNode *N, SDValue &Lo, SDValue &Hi) { 1158 assert(N->getValueType(0).isVector() && 1159 N->getOperand(0).getValueType().isVector() && 1160 "Operand types must be vectors"); 1161 1162 EVT LoVT, HiVT; 1163 SDLoc DL(N); 1164 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); 1165 1166 // Split the input. 1167 SDValue LL, LH, RL, RH; 1168 std::tie(LL, LH) = DAG.SplitVectorOperand(N, 0); 1169 std::tie(RL, RH) = DAG.SplitVectorOperand(N, 1); 1170 1171 Lo = DAG.getNode(N->getOpcode(), DL, LoVT, LL, RL, N->getOperand(2)); 1172 Hi = DAG.getNode(N->getOpcode(), DL, HiVT, LH, RH, N->getOperand(2)); 1173 } 1174 1175 void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo, 1176 SDValue &Hi) { 1177 // Get the dest types - they may not match the input types, e.g. int_to_fp. 1178 EVT LoVT, HiVT; 1179 SDLoc dl(N); 1180 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0)); 1181 1182 // If the input also splits, handle it directly for a compile time speedup. 1183 // Otherwise split it by hand. 1184 EVT InVT = N->getOperand(0).getValueType(); 1185 if (getTypeAction(InVT) == TargetLowering::TypeSplitVector) 1186 GetSplitVector(N->getOperand(0), Lo, Hi); 1187 else 1188 std::tie(Lo, Hi) = DAG.SplitVectorOperand(N, 0); 1189 1190 if (N->getOpcode() == ISD::FP_ROUND) { 1191 Lo = DAG.getNode(N->getOpcode(), dl, LoVT, Lo, N->getOperand(1)); 1192 Hi = DAG.getNode(N->getOpcode(), dl, HiVT, Hi, N->getOperand(1)); 1193 } else if (N->getOpcode() == ISD::CONVERT_RNDSAT) { 1194 SDValue DTyOpLo = DAG.getValueType(LoVT); 1195 SDValue DTyOpHi = DAG.getValueType(HiVT); 1196 SDValue STyOpLo = DAG.getValueType(Lo.getValueType()); 1197 SDValue STyOpHi = DAG.getValueType(Hi.getValueType()); 1198 SDValue RndOp = N->getOperand(3); 1199 SDValue SatOp = N->getOperand(4); 1200 ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode(); 1201 Lo = DAG.getConvertRndSat(LoVT, dl, Lo, DTyOpLo, STyOpLo, RndOp, SatOp, 1202 CvtCode); 1203 Hi = DAG.getConvertRndSat(HiVT, dl, Hi, DTyOpHi, STyOpHi, RndOp, SatOp, 1204 CvtCode); 1205 } else { 1206 Lo = DAG.getNode(N->getOpcode(), dl, LoVT, Lo); 1207 Hi = DAG.getNode(N->getOpcode(), dl, HiVT, Hi); 1208 } 1209 } 1210 1211 void DAGTypeLegalizer::SplitVecRes_ExtendOp(SDNode *N, SDValue &Lo, 1212 SDValue &Hi) { 1213 SDLoc dl(N); 1214 EVT SrcVT = N->getOperand(0).getValueType(); 1215 EVT DestVT = N->getValueType(0); 1216 EVT LoVT, HiVT; 1217 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT); 1218 1219 // We can do better than a generic split operation if the extend is doing 1220 // more than just doubling the width of the elements and the following are 1221 // true: 1222 // - The number of vector elements is even, 1223 // - the source type is legal, 1224 // - the type of a split source is illegal, 1225 // - the type of an extended (by doubling element size) source is legal, and 1226 // - the type of that extended source when split is legal. 1227 // 1228 // This won't necessarily completely legalize the operation, but it will 1229 // more effectively move in the right direction and prevent falling down 1230 // to scalarization in many cases due to the input vector being split too 1231 // far. 1232 unsigned NumElements = SrcVT.getVectorNumElements(); 1233 if ((NumElements & 1) == 0 && 1234 SrcVT.getSizeInBits() * 2 < DestVT.getSizeInBits()) { 1235 LLVMContext &Ctx = *DAG.getContext(); 1236 EVT NewSrcVT = EVT::getVectorVT( 1237 Ctx, EVT::getIntegerVT( 1238 Ctx, SrcVT.getVectorElementType().getSizeInBits() * 2), 1239 NumElements); 1240 EVT SplitSrcVT = 1241 EVT::getVectorVT(Ctx, SrcVT.getVectorElementType(), NumElements / 2); 1242 EVT SplitLoVT, SplitHiVT; 1243 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT); 1244 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) && 1245 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) { 1246 DEBUG(dbgs() << "Split vector extend via incremental extend:"; 1247 N->dump(&DAG); dbgs() << "\n"); 1248 // Extend the source vector by one step. 1249 SDValue NewSrc = 1250 DAG.getNode(N->getOpcode(), dl, NewSrcVT, N->getOperand(0)); 1251 // Get the low and high halves of the new, extended one step, vector. 1252 std::tie(Lo, Hi) = DAG.SplitVector(NewSrc, dl); 1253 // Extend those vector halves the rest of the way. 1254 Lo = DAG.getNode(N->getOpcode(), dl, LoVT, Lo); 1255 Hi = DAG.getNode(N->getOpcode(), dl, HiVT, Hi); 1256 return; 1257 } 1258 } 1259 // Fall back to the generic unary operator splitting otherwise. 1260 SplitVecRes_UnaryOp(N, Lo, Hi); 1261 } 1262 1263 void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N, 1264 SDValue &Lo, SDValue &Hi) { 1265 // The low and high parts of the original input give four input vectors. 1266 SDValue Inputs[4]; 1267 SDLoc dl(N); 1268 GetSplitVector(N->getOperand(0), Inputs[0], Inputs[1]); 1269 GetSplitVector(N->getOperand(1), Inputs[2], Inputs[3]); 1270 EVT NewVT = Inputs[0].getValueType(); 1271 unsigned NewElts = NewVT.getVectorNumElements(); 1272 1273 // If Lo or Hi uses elements from at most two of the four input vectors, then 1274 // express it as a vector shuffle of those two inputs. Otherwise extract the 1275 // input elements by hand and construct the Lo/Hi output using a BUILD_VECTOR. 1276 SmallVector<int, 16> Ops; 1277 for (unsigned High = 0; High < 2; ++High) { 1278 SDValue &Output = High ? Hi : Lo; 1279 1280 // Build a shuffle mask for the output, discovering on the fly which 1281 // input vectors to use as shuffle operands (recorded in InputUsed). 1282 // If building a suitable shuffle vector proves too hard, then bail 1283 // out with useBuildVector set. 1284 unsigned InputUsed[2] = { -1U, -1U }; // Not yet discovered. 1285 unsigned FirstMaskIdx = High * NewElts; 1286 bool useBuildVector = false; 1287 for (unsigned MaskOffset = 0; MaskOffset < NewElts; ++MaskOffset) { 1288 // The mask element. This indexes into the input. 1289 int Idx = N->getMaskElt(FirstMaskIdx + MaskOffset); 1290 1291 // The input vector this mask element indexes into. 1292 unsigned Input = (unsigned)Idx / NewElts; 1293 1294 if (Input >= array_lengthof(Inputs)) { 1295 // The mask element does not index into any input vector. 1296 Ops.push_back(-1); 1297 continue; 1298 } 1299 1300 // Turn the index into an offset from the start of the input vector. 1301 Idx -= Input * NewElts; 1302 1303 // Find or create a shuffle vector operand to hold this input. 1304 unsigned OpNo; 1305 for (OpNo = 0; OpNo < array_lengthof(InputUsed); ++OpNo) { 1306 if (InputUsed[OpNo] == Input) { 1307 // This input vector is already an operand. 1308 break; 1309 } else if (InputUsed[OpNo] == -1U) { 1310 // Create a new operand for this input vector. 1311 InputUsed[OpNo] = Input; 1312 break; 1313 } 1314 } 1315 1316 if (OpNo >= array_lengthof(InputUsed)) { 1317 // More than two input vectors used! Give up on trying to create a 1318 // shuffle vector. Insert all elements into a BUILD_VECTOR instead. 1319 useBuildVector = true; 1320 break; 1321 } 1322 1323 // Add the mask index for the new shuffle vector. 1324 Ops.push_back(Idx + OpNo * NewElts); 1325 } 1326 1327 if (useBuildVector) { 1328 EVT EltVT = NewVT.getVectorElementType(); 1329 SmallVector<SDValue, 16> SVOps; 1330 1331 // Extract the input elements by hand. 1332 for (unsigned MaskOffset = 0; MaskOffset < NewElts; ++MaskOffset) { 1333 // The mask element. This indexes into the input. 1334 int Idx = N->getMaskElt(FirstMaskIdx + MaskOffset); 1335 1336 // The input vector this mask element indexes into. 1337 unsigned Input = (unsigned)Idx / NewElts; 1338 1339 if (Input >= array_lengthof(Inputs)) { 1340 // The mask element is "undef" or indexes off the end of the input. 1341 SVOps.push_back(DAG.getUNDEF(EltVT)); 1342 continue; 1343 } 1344 1345 // Turn the index into an offset from the start of the input vector. 1346 Idx -= Input * NewElts; 1347 1348 // Extract the vector element by hand. 1349 SVOps.push_back(DAG.getNode( 1350 ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Inputs[Input], 1351 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout())))); 1352 } 1353 1354 // Construct the Lo/Hi output using a BUILD_VECTOR. 1355 Output = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT, SVOps); 1356 } else if (InputUsed[0] == -1U) { 1357 // No input vectors were used! The result is undefined. 1358 Output = DAG.getUNDEF(NewVT); 1359 } else { 1360 SDValue Op0 = Inputs[InputUsed[0]]; 1361 // If only one input was used, use an undefined vector for the other. 1362 SDValue Op1 = InputUsed[1] == -1U ? 1363 DAG.getUNDEF(NewVT) : Inputs[InputUsed[1]]; 1364 // At least one input vector was used. Create a new shuffle vector. 1365 Output = DAG.getVectorShuffle(NewVT, dl, Op0, Op1, &Ops[0]); 1366 } 1367 1368 Ops.clear(); 1369 } 1370 } 1371 1372 1373 //===----------------------------------------------------------------------===// 1374 // Operand Vector Splitting 1375 //===----------------------------------------------------------------------===// 1376 1377 /// SplitVectorOperand - This method is called when the specified operand of the 1378 /// specified node is found to need vector splitting. At this point, all of the 1379 /// result types of the node are known to be legal, but other operands of the 1380 /// node may need legalization as well as the specified one. 1381 bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) { 1382 DEBUG(dbgs() << "Split node operand: "; 1383 N->dump(&DAG); 1384 dbgs() << "\n"); 1385 SDValue Res = SDValue(); 1386 1387 // See if the target wants to custom split this node. 1388 if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) 1389 return false; 1390 1391 if (!Res.getNode()) { 1392 switch (N->getOpcode()) { 1393 default: 1394 #ifndef NDEBUG 1395 dbgs() << "SplitVectorOperand Op #" << OpNo << ": "; 1396 N->dump(&DAG); 1397 dbgs() << "\n"; 1398 #endif 1399 report_fatal_error("Do not know how to split this operator's " 1400 "operand!\n"); 1401 1402 case ISD::SETCC: Res = SplitVecOp_VSETCC(N); break; 1403 case ISD::BITCAST: Res = SplitVecOp_BITCAST(N); break; 1404 case ISD::EXTRACT_SUBVECTOR: Res = SplitVecOp_EXTRACT_SUBVECTOR(N); break; 1405 case ISD::EXTRACT_VECTOR_ELT:Res = SplitVecOp_EXTRACT_VECTOR_ELT(N); break; 1406 case ISD::CONCAT_VECTORS: Res = SplitVecOp_CONCAT_VECTORS(N); break; 1407 case ISD::TRUNCATE: 1408 Res = SplitVecOp_TruncateHelper(N); 1409 break; 1410 case ISD::FP_ROUND: Res = SplitVecOp_FP_ROUND(N); break; 1411 case ISD::FCOPYSIGN: Res = SplitVecOp_FCOPYSIGN(N); break; 1412 case ISD::STORE: 1413 Res = SplitVecOp_STORE(cast<StoreSDNode>(N), OpNo); 1414 break; 1415 case ISD::MSTORE: 1416 Res = SplitVecOp_MSTORE(cast<MaskedStoreSDNode>(N), OpNo); 1417 break; 1418 case ISD::MSCATTER: 1419 Res = SplitVecOp_MSCATTER(cast<MaskedScatterSDNode>(N), OpNo); 1420 break; 1421 case ISD::MGATHER: 1422 Res = SplitVecOp_MGATHER(cast<MaskedGatherSDNode>(N), OpNo); 1423 break; 1424 case ISD::VSELECT: 1425 Res = SplitVecOp_VSELECT(N, OpNo); 1426 break; 1427 case ISD::FP_TO_SINT: 1428 case ISD::FP_TO_UINT: 1429 if (N->getValueType(0).bitsLT(N->getOperand(0)->getValueType(0))) 1430 Res = SplitVecOp_TruncateHelper(N); 1431 else 1432 Res = SplitVecOp_UnaryOp(N); 1433 break; 1434 case ISD::SINT_TO_FP: 1435 case ISD::UINT_TO_FP: 1436 if (N->getValueType(0).bitsLT(N->getOperand(0)->getValueType(0))) 1437 Res = SplitVecOp_TruncateHelper(N); 1438 else 1439 Res = SplitVecOp_UnaryOp(N); 1440 break; 1441 case ISD::CTTZ: 1442 case ISD::CTLZ: 1443 case ISD::CTPOP: 1444 case ISD::FP_EXTEND: 1445 case ISD::SIGN_EXTEND: 1446 case ISD::ZERO_EXTEND: 1447 case ISD::ANY_EXTEND: 1448 case ISD::FTRUNC: 1449 Res = SplitVecOp_UnaryOp(N); 1450 break; 1451 } 1452 } 1453 1454 // If the result is null, the sub-method took care of registering results etc. 1455 if (!Res.getNode()) return false; 1456 1457 // If the result is N, the sub-method updated N in place. Tell the legalizer 1458 // core about this. 1459 if (Res.getNode() == N) 1460 return true; 1461 1462 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 1463 "Invalid operand expansion"); 1464 1465 ReplaceValueWith(SDValue(N, 0), Res); 1466 return false; 1467 } 1468 1469 SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(SDNode *N, unsigned OpNo) { 1470 // The only possibility for an illegal operand is the mask, since result type 1471 // legalization would have handled this node already otherwise. 1472 assert(OpNo == 0 && "Illegal operand must be mask"); 1473 1474 SDValue Mask = N->getOperand(0); 1475 SDValue Src0 = N->getOperand(1); 1476 SDValue Src1 = N->getOperand(2); 1477 EVT Src0VT = Src0.getValueType(); 1478 SDLoc DL(N); 1479 assert(Mask.getValueType().isVector() && "VSELECT without a vector mask?"); 1480 1481 SDValue Lo, Hi; 1482 GetSplitVector(N->getOperand(0), Lo, Hi); 1483 assert(Lo.getValueType() == Hi.getValueType() && 1484 "Lo and Hi have differing types"); 1485 1486 EVT LoOpVT, HiOpVT; 1487 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT); 1488 assert(LoOpVT == HiOpVT && "Asymmetric vector split?"); 1489 1490 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask; 1491 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0, DL); 1492 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1, DL); 1493 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask, DL); 1494 1495 SDValue LoSelect = 1496 DAG.getNode(ISD::VSELECT, DL, LoOpVT, LoMask, LoOp0, LoOp1); 1497 SDValue HiSelect = 1498 DAG.getNode(ISD::VSELECT, DL, HiOpVT, HiMask, HiOp0, HiOp1); 1499 1500 return DAG.getNode(ISD::CONCAT_VECTORS, DL, Src0VT, LoSelect, HiSelect); 1501 } 1502 1503 SDValue DAGTypeLegalizer::SplitVecOp_UnaryOp(SDNode *N) { 1504 // The result has a legal vector type, but the input needs splitting. 1505 EVT ResVT = N->getValueType(0); 1506 SDValue Lo, Hi; 1507 SDLoc dl(N); 1508 GetSplitVector(N->getOperand(0), Lo, Hi); 1509 EVT InVT = Lo.getValueType(); 1510 1511 EVT OutVT = EVT::getVectorVT(*DAG.getContext(), ResVT.getVectorElementType(), 1512 InVT.getVectorNumElements()); 1513 1514 Lo = DAG.getNode(N->getOpcode(), dl, OutVT, Lo); 1515 Hi = DAG.getNode(N->getOpcode(), dl, OutVT, Hi); 1516 1517 return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi); 1518 } 1519 1520 SDValue DAGTypeLegalizer::SplitVecOp_BITCAST(SDNode *N) { 1521 // For example, i64 = BITCAST v4i16 on alpha. Typically the vector will 1522 // end up being split all the way down to individual components. Convert the 1523 // split pieces into integers and reassemble. 1524 SDValue Lo, Hi; 1525 GetSplitVector(N->getOperand(0), Lo, Hi); 1526 Lo = BitConvertToInteger(Lo); 1527 Hi = BitConvertToInteger(Hi); 1528 1529 if (DAG.getDataLayout().isBigEndian()) 1530 std::swap(Lo, Hi); 1531 1532 return DAG.getNode(ISD::BITCAST, SDLoc(N), N->getValueType(0), 1533 JoinIntegers(Lo, Hi)); 1534 } 1535 1536 SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N) { 1537 // We know that the extracted result type is legal. 1538 EVT SubVT = N->getValueType(0); 1539 SDValue Idx = N->getOperand(1); 1540 SDLoc dl(N); 1541 SDValue Lo, Hi; 1542 GetSplitVector(N->getOperand(0), Lo, Hi); 1543 1544 uint64_t LoElts = Lo.getValueType().getVectorNumElements(); 1545 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue(); 1546 1547 if (IdxVal < LoElts) { 1548 assert(IdxVal + SubVT.getVectorNumElements() <= LoElts && 1549 "Extracted subvector crosses vector split!"); 1550 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Lo, Idx); 1551 } else { 1552 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Hi, 1553 DAG.getConstant(IdxVal - LoElts, dl, 1554 Idx.getValueType())); 1555 } 1556 } 1557 1558 SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { 1559 SDValue Vec = N->getOperand(0); 1560 SDValue Idx = N->getOperand(1); 1561 EVT VecVT = Vec.getValueType(); 1562 1563 if (isa<ConstantSDNode>(Idx)) { 1564 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue(); 1565 assert(IdxVal < VecVT.getVectorNumElements() && "Invalid vector index!"); 1566 1567 SDValue Lo, Hi; 1568 GetSplitVector(Vec, Lo, Hi); 1569 1570 uint64_t LoElts = Lo.getValueType().getVectorNumElements(); 1571 1572 if (IdxVal < LoElts) 1573 return SDValue(DAG.UpdateNodeOperands(N, Lo, Idx), 0); 1574 return SDValue(DAG.UpdateNodeOperands(N, Hi, 1575 DAG.getConstant(IdxVal - LoElts, SDLoc(N), 1576 Idx.getValueType())), 0); 1577 } 1578 1579 // See if the target wants to custom expand this node. 1580 if (CustomLowerNode(N, N->getValueType(0), true)) 1581 return SDValue(); 1582 1583 // Make the vector elements byte-addressable if they aren't already. 1584 SDLoc dl(N); 1585 EVT EltVT = VecVT.getVectorElementType(); 1586 if (EltVT.getSizeInBits() < 8) { 1587 SmallVector<SDValue, 4> ElementOps; 1588 for (unsigned i = 0; i < VecVT.getVectorNumElements(); ++i) { 1589 ElementOps.push_back(DAG.getAnyExtOrTrunc( 1590 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Vec, 1591 DAG.getConstant(i, dl, MVT::i8)), 1592 dl, MVT::i8)); 1593 } 1594 1595 EltVT = MVT::i8; 1596 VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, 1597 VecVT.getVectorNumElements()); 1598 Vec = DAG.getNode(ISD::BUILD_VECTOR, dl, VecVT, ElementOps); 1599 } 1600 1601 // Store the vector to the stack. 1602 SDValue StackPtr = DAG.CreateStackTemporary(VecVT); 1603 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, 1604 MachinePointerInfo(), false, false, 0); 1605 1606 // Load back the required element. 1607 StackPtr = GetVectorElementPointer(StackPtr, EltVT, Idx); 1608 return DAG.getExtLoad(ISD::EXTLOAD, dl, N->getValueType(0), Store, StackPtr, 1609 MachinePointerInfo(), EltVT, false, false, false, 0); 1610 } 1611 1612 SDValue DAGTypeLegalizer::SplitVecOp_MGATHER(MaskedGatherSDNode *MGT, 1613 unsigned OpNo) { 1614 EVT LoVT, HiVT; 1615 SDLoc dl(MGT); 1616 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MGT->getValueType(0)); 1617 1618 SDValue Ch = MGT->getChain(); 1619 SDValue Ptr = MGT->getBasePtr(); 1620 SDValue Index = MGT->getIndex(); 1621 SDValue Mask = MGT->getMask(); 1622 SDValue Src0 = MGT->getValue(); 1623 unsigned Alignment = MGT->getOriginalAlignment(); 1624 1625 SDValue MaskLo, MaskHi; 1626 if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector) 1627 // Split Mask operand 1628 GetSplitVector(Mask, MaskLo, MaskHi); 1629 else 1630 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl); 1631 1632 EVT MemoryVT = MGT->getMemoryVT(); 1633 EVT LoMemVT, HiMemVT; 1634 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT); 1635 1636 SDValue Src0Lo, Src0Hi; 1637 if (getTypeAction(Src0.getValueType()) == TargetLowering::TypeSplitVector) 1638 GetSplitVector(Src0, Src0Lo, Src0Hi); 1639 else 1640 std::tie(Src0Lo, Src0Hi) = DAG.SplitVector(Src0, dl); 1641 1642 SDValue IndexHi, IndexLo; 1643 if (getTypeAction(Index.getValueType()) == TargetLowering::TypeSplitVector) 1644 GetSplitVector(Index, IndexLo, IndexHi); 1645 else 1646 std::tie(IndexLo, IndexHi) = DAG.SplitVector(Index, dl); 1647 1648 MachineMemOperand *MMO = DAG.getMachineFunction(). 1649 getMachineMemOperand(MGT->getPointerInfo(), 1650 MachineMemOperand::MOLoad, LoMemVT.getStoreSize(), 1651 Alignment, MGT->getAAInfo(), MGT->getRanges()); 1652 1653 SDValue OpsLo[] = {Ch, Src0Lo, MaskLo, Ptr, IndexLo}; 1654 SDValue Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoVT, dl, 1655 OpsLo, MMO); 1656 1657 MMO = DAG.getMachineFunction(). 1658 getMachineMemOperand(MGT->getPointerInfo(), 1659 MachineMemOperand::MOLoad, HiMemVT.getStoreSize(), 1660 Alignment, MGT->getAAInfo(), 1661 MGT->getRanges()); 1662 1663 SDValue OpsHi[] = {Ch, Src0Hi, MaskHi, Ptr, IndexHi}; 1664 SDValue Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiVT, dl, 1665 OpsHi, MMO); 1666 1667 // Build a factor node to remember that this load is independent of the 1668 // other one. 1669 Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 1670 Hi.getValue(1)); 1671 1672 // Legalize the chain result - switch anything that used the old chain to 1673 // use the new one. 1674 ReplaceValueWith(SDValue(MGT, 1), Ch); 1675 1676 SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, dl, MGT->getValueType(0), Lo, 1677 Hi); 1678 ReplaceValueWith(SDValue(MGT, 0), Res); 1679 return SDValue(); 1680 } 1681 1682 SDValue DAGTypeLegalizer::SplitVecOp_MSTORE(MaskedStoreSDNode *N, 1683 unsigned OpNo) { 1684 SDValue Ch = N->getChain(); 1685 SDValue Ptr = N->getBasePtr(); 1686 SDValue Mask = N->getMask(); 1687 SDValue Data = N->getValue(); 1688 EVT MemoryVT = N->getMemoryVT(); 1689 unsigned Alignment = N->getOriginalAlignment(); 1690 SDLoc DL(N); 1691 1692 EVT LoMemVT, HiMemVT; 1693 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT); 1694 1695 SDValue DataLo, DataHi; 1696 if (getTypeAction(Data.getValueType()) == TargetLowering::TypeSplitVector) 1697 // Split Data operand 1698 GetSplitVector(Data, DataLo, DataHi); 1699 else 1700 std::tie(DataLo, DataHi) = DAG.SplitVector(Data, DL); 1701 1702 SDValue MaskLo, MaskHi; 1703 if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector) 1704 // Split Mask operand 1705 GetSplitVector(Mask, MaskLo, MaskHi); 1706 else 1707 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, DL); 1708 1709 MaskLo = PromoteTargetBoolean(MaskLo, DataLo.getValueType()); 1710 MaskHi = PromoteTargetBoolean(MaskHi, DataHi.getValueType()); 1711 1712 // if Alignment is equal to the vector size, 1713 // take the half of it for the second part 1714 unsigned SecondHalfAlignment = 1715 (Alignment == Data->getValueType(0).getSizeInBits()/8) ? 1716 Alignment/2 : Alignment; 1717 1718 SDValue Lo, Hi; 1719 MachineMemOperand *MMO = DAG.getMachineFunction(). 1720 getMachineMemOperand(N->getPointerInfo(), 1721 MachineMemOperand::MOStore, LoMemVT.getStoreSize(), 1722 Alignment, N->getAAInfo(), N->getRanges()); 1723 1724 Lo = DAG.getMaskedStore(Ch, DL, DataLo, Ptr, MaskLo, LoMemVT, MMO, 1725 N->isTruncatingStore()); 1726 1727 unsigned IncrementSize = LoMemVT.getSizeInBits()/8; 1728 Ptr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr, 1729 DAG.getConstant(IncrementSize, DL, Ptr.getValueType())); 1730 1731 MMO = DAG.getMachineFunction(). 1732 getMachineMemOperand(N->getPointerInfo(), 1733 MachineMemOperand::MOStore, HiMemVT.getStoreSize(), 1734 SecondHalfAlignment, N->getAAInfo(), N->getRanges()); 1735 1736 Hi = DAG.getMaskedStore(Ch, DL, DataHi, Ptr, MaskHi, HiMemVT, MMO, 1737 N->isTruncatingStore()); 1738 1739 // Build a factor node to remember that this store is independent of the 1740 // other one. 1741 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Lo, Hi); 1742 } 1743 1744 SDValue DAGTypeLegalizer::SplitVecOp_MSCATTER(MaskedScatterSDNode *N, 1745 unsigned OpNo) { 1746 SDValue Ch = N->getChain(); 1747 SDValue Ptr = N->getBasePtr(); 1748 SDValue Mask = N->getMask(); 1749 SDValue Index = N->getIndex(); 1750 SDValue Data = N->getValue(); 1751 EVT MemoryVT = N->getMemoryVT(); 1752 unsigned Alignment = N->getOriginalAlignment(); 1753 SDLoc DL(N); 1754 1755 // Split all operands 1756 EVT LoMemVT, HiMemVT; 1757 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT); 1758 1759 SDValue DataLo, DataHi; 1760 if (getTypeAction(Data.getValueType()) == TargetLowering::TypeSplitVector) 1761 // Split Data operand 1762 GetSplitVector(Data, DataLo, DataHi); 1763 else 1764 std::tie(DataLo, DataHi) = DAG.SplitVector(Data, DL); 1765 1766 SDValue MaskLo, MaskHi; 1767 if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector) 1768 // Split Mask operand 1769 GetSplitVector(Mask, MaskLo, MaskHi); 1770 else 1771 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, DL); 1772 1773 SDValue IndexHi, IndexLo; 1774 if (getTypeAction(Index.getValueType()) == TargetLowering::TypeSplitVector) 1775 GetSplitVector(Index, IndexLo, IndexHi); 1776 else 1777 std::tie(IndexLo, IndexHi) = DAG.SplitVector(Index, DL); 1778 1779 SDValue Lo, Hi; 1780 MachineMemOperand *MMO = DAG.getMachineFunction(). 1781 getMachineMemOperand(N->getPointerInfo(), 1782 MachineMemOperand::MOStore, LoMemVT.getStoreSize(), 1783 Alignment, N->getAAInfo(), N->getRanges()); 1784 1785 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo}; 1786 Lo = DAG.getMaskedScatter(DAG.getVTList(MVT::Other), DataLo.getValueType(), 1787 DL, OpsLo, MMO); 1788 1789 MMO = DAG.getMachineFunction(). 1790 getMachineMemOperand(N->getPointerInfo(), 1791 MachineMemOperand::MOStore, HiMemVT.getStoreSize(), 1792 Alignment, N->getAAInfo(), N->getRanges()); 1793 1794 SDValue OpsHi[] = {Ch, DataHi, MaskHi, Ptr, IndexHi}; 1795 Hi = DAG.getMaskedScatter(DAG.getVTList(MVT::Other), DataHi.getValueType(), 1796 DL, OpsHi, MMO); 1797 1798 // Build a factor node to remember that this store is independent of the 1799 // other one. 1800 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Lo, Hi); 1801 } 1802 1803 SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) { 1804 assert(N->isUnindexed() && "Indexed store of vector?"); 1805 assert(OpNo == 1 && "Can only split the stored value"); 1806 SDLoc DL(N); 1807 1808 bool isTruncating = N->isTruncatingStore(); 1809 SDValue Ch = N->getChain(); 1810 SDValue Ptr = N->getBasePtr(); 1811 EVT MemoryVT = N->getMemoryVT(); 1812 unsigned Alignment = N->getOriginalAlignment(); 1813 bool isVol = N->isVolatile(); 1814 bool isNT = N->isNonTemporal(); 1815 AAMDNodes AAInfo = N->getAAInfo(); 1816 SDValue Lo, Hi; 1817 GetSplitVector(N->getOperand(1), Lo, Hi); 1818 1819 EVT LoMemVT, HiMemVT; 1820 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT); 1821 1822 unsigned IncrementSize = LoMemVT.getSizeInBits()/8; 1823 1824 if (isTruncating) 1825 Lo = DAG.getTruncStore(Ch, DL, Lo, Ptr, N->getPointerInfo(), 1826 LoMemVT, isVol, isNT, Alignment, AAInfo); 1827 else 1828 Lo = DAG.getStore(Ch, DL, Lo, Ptr, N->getPointerInfo(), 1829 isVol, isNT, Alignment, AAInfo); 1830 1831 // Increment the pointer to the other half. 1832 Ptr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr, 1833 DAG.getConstant(IncrementSize, DL, Ptr.getValueType())); 1834 1835 if (isTruncating) 1836 Hi = DAG.getTruncStore(Ch, DL, Hi, Ptr, 1837 N->getPointerInfo().getWithOffset(IncrementSize), 1838 HiMemVT, isVol, isNT, Alignment, AAInfo); 1839 else 1840 Hi = DAG.getStore(Ch, DL, Hi, Ptr, 1841 N->getPointerInfo().getWithOffset(IncrementSize), 1842 isVol, isNT, Alignment, AAInfo); 1843 1844 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Lo, Hi); 1845 } 1846 1847 SDValue DAGTypeLegalizer::SplitVecOp_CONCAT_VECTORS(SDNode *N) { 1848 SDLoc DL(N); 1849 1850 // The input operands all must have the same type, and we know the result 1851 // type is valid. Convert this to a buildvector which extracts all the 1852 // input elements. 1853 // TODO: If the input elements are power-two vectors, we could convert this to 1854 // a new CONCAT_VECTORS node with elements that are half-wide. 1855 SmallVector<SDValue, 32> Elts; 1856 EVT EltVT = N->getValueType(0).getVectorElementType(); 1857 for (const SDValue &Op : N->op_values()) { 1858 for (unsigned i = 0, e = Op.getValueType().getVectorNumElements(); 1859 i != e; ++i) { 1860 Elts.push_back(DAG.getNode( 1861 ISD::EXTRACT_VECTOR_ELT, DL, EltVT, Op, 1862 DAG.getConstant(i, DL, TLI.getVectorIdxTy(DAG.getDataLayout())))); 1863 } 1864 } 1865 1866 return DAG.getNode(ISD::BUILD_VECTOR, DL, N->getValueType(0), Elts); 1867 } 1868 1869 SDValue DAGTypeLegalizer::SplitVecOp_TruncateHelper(SDNode *N) { 1870 // The result type is legal, but the input type is illegal. If splitting 1871 // ends up with the result type of each half still being legal, just 1872 // do that. If, however, that would result in an illegal result type, 1873 // we can try to get more clever with power-two vectors. Specifically, 1874 // split the input type, but also widen the result element size, then 1875 // concatenate the halves and truncate again. For example, consider a target 1876 // where v8i8 is legal and v8i32 is not (ARM, which doesn't have 256-bit 1877 // vectors). To perform a "%res = v8i8 trunc v8i32 %in" we do: 1878 // %inlo = v4i32 extract_subvector %in, 0 1879 // %inhi = v4i32 extract_subvector %in, 4 1880 // %lo16 = v4i16 trunc v4i32 %inlo 1881 // %hi16 = v4i16 trunc v4i32 %inhi 1882 // %in16 = v8i16 concat_vectors v4i16 %lo16, v4i16 %hi16 1883 // %res = v8i8 trunc v8i16 %in16 1884 // 1885 // Without this transform, the original truncate would end up being 1886 // scalarized, which is pretty much always a last resort. 1887 SDValue InVec = N->getOperand(0); 1888 EVT InVT = InVec->getValueType(0); 1889 EVT OutVT = N->getValueType(0); 1890 unsigned NumElements = OutVT.getVectorNumElements(); 1891 bool IsFloat = OutVT.isFloatingPoint(); 1892 1893 // Widening should have already made sure this is a power-two vector 1894 // if we're trying to split it at all. assert() that's true, just in case. 1895 assert(!(NumElements & 1) && "Splitting vector, but not in half!"); 1896 1897 unsigned InElementSize = InVT.getVectorElementType().getSizeInBits(); 1898 unsigned OutElementSize = OutVT.getVectorElementType().getSizeInBits(); 1899 1900 // If the input elements are only 1/2 the width of the result elements, 1901 // just use the normal splitting. Our trick only work if there's room 1902 // to split more than once. 1903 if (InElementSize <= OutElementSize * 2) 1904 return SplitVecOp_UnaryOp(N); 1905 SDLoc DL(N); 1906 1907 // Extract the halves of the input via extract_subvector. 1908 SDValue InLoVec, InHiVec; 1909 std::tie(InLoVec, InHiVec) = DAG.SplitVector(InVec, DL); 1910 // Truncate them to 1/2 the element size. 1911 EVT HalfElementVT = IsFloat ? 1912 EVT::getFloatingPointVT(InElementSize/2) : 1913 EVT::getIntegerVT(*DAG.getContext(), InElementSize/2); 1914 EVT HalfVT = EVT::getVectorVT(*DAG.getContext(), HalfElementVT, 1915 NumElements/2); 1916 SDValue HalfLo = DAG.getNode(N->getOpcode(), DL, HalfVT, InLoVec); 1917 SDValue HalfHi = DAG.getNode(N->getOpcode(), DL, HalfVT, InHiVec); 1918 // Concatenate them to get the full intermediate truncation result. 1919 EVT InterVT = EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements); 1920 SDValue InterVec = DAG.getNode(ISD::CONCAT_VECTORS, DL, InterVT, HalfLo, 1921 HalfHi); 1922 // Now finish up by truncating all the way down to the original result 1923 // type. This should normally be something that ends up being legal directly, 1924 // but in theory if a target has very wide vectors and an annoyingly 1925 // restricted set of legal types, this split can chain to build things up. 1926 return IsFloat 1927 ? DAG.getNode(ISD::FP_ROUND, DL, OutVT, InterVec, 1928 DAG.getTargetConstant( 1929 0, DL, TLI.getPointerTy(DAG.getDataLayout()))) 1930 : DAG.getNode(ISD::TRUNCATE, DL, OutVT, InterVec); 1931 } 1932 1933 SDValue DAGTypeLegalizer::SplitVecOp_VSETCC(SDNode *N) { 1934 assert(N->getValueType(0).isVector() && 1935 N->getOperand(0).getValueType().isVector() && 1936 "Operand types must be vectors"); 1937 // The result has a legal vector type, but the input needs splitting. 1938 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes; 1939 SDLoc DL(N); 1940 GetSplitVector(N->getOperand(0), Lo0, Hi0); 1941 GetSplitVector(N->getOperand(1), Lo1, Hi1); 1942 unsigned PartElements = Lo0.getValueType().getVectorNumElements(); 1943 EVT PartResVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, PartElements); 1944 EVT WideResVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, 2*PartElements); 1945 1946 LoRes = DAG.getNode(ISD::SETCC, DL, PartResVT, Lo0, Lo1, N->getOperand(2)); 1947 HiRes = DAG.getNode(ISD::SETCC, DL, PartResVT, Hi0, Hi1, N->getOperand(2)); 1948 SDValue Con = DAG.getNode(ISD::CONCAT_VECTORS, DL, WideResVT, LoRes, HiRes); 1949 return PromoteTargetBoolean(Con, N->getValueType(0)); 1950 } 1951 1952 1953 SDValue DAGTypeLegalizer::SplitVecOp_FP_ROUND(SDNode *N) { 1954 // The result has a legal vector type, but the input needs splitting. 1955 EVT ResVT = N->getValueType(0); 1956 SDValue Lo, Hi; 1957 SDLoc DL(N); 1958 GetSplitVector(N->getOperand(0), Lo, Hi); 1959 EVT InVT = Lo.getValueType(); 1960 1961 EVT OutVT = EVT::getVectorVT(*DAG.getContext(), ResVT.getVectorElementType(), 1962 InVT.getVectorNumElements()); 1963 1964 Lo = DAG.getNode(ISD::FP_ROUND, DL, OutVT, Lo, N->getOperand(1)); 1965 Hi = DAG.getNode(ISD::FP_ROUND, DL, OutVT, Hi, N->getOperand(1)); 1966 1967 return DAG.getNode(ISD::CONCAT_VECTORS, DL, ResVT, Lo, Hi); 1968 } 1969 1970 SDValue DAGTypeLegalizer::SplitVecOp_FCOPYSIGN(SDNode *N) { 1971 // The result (and the first input) has a legal vector type, but the second 1972 // input needs splitting. 1973 return DAG.UnrollVectorOp(N, N->getValueType(0).getVectorNumElements()); 1974 } 1975 1976 1977 //===----------------------------------------------------------------------===// 1978 // Result Vector Widening 1979 //===----------------------------------------------------------------------===// 1980 1981 void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) { 1982 DEBUG(dbgs() << "Widen node result " << ResNo << ": "; 1983 N->dump(&DAG); 1984 dbgs() << "\n"); 1985 1986 // See if the target wants to custom widen this node. 1987 if (CustomWidenLowerNode(N, N->getValueType(ResNo))) 1988 return; 1989 1990 SDValue Res = SDValue(); 1991 switch (N->getOpcode()) { 1992 default: 1993 #ifndef NDEBUG 1994 dbgs() << "WidenVectorResult #" << ResNo << ": "; 1995 N->dump(&DAG); 1996 dbgs() << "\n"; 1997 #endif 1998 llvm_unreachable("Do not know how to widen the result of this operator!"); 1999 2000 case ISD::MERGE_VALUES: Res = WidenVecRes_MERGE_VALUES(N, ResNo); break; 2001 case ISD::BITCAST: Res = WidenVecRes_BITCAST(N); break; 2002 case ISD::BUILD_VECTOR: Res = WidenVecRes_BUILD_VECTOR(N); break; 2003 case ISD::CONCAT_VECTORS: Res = WidenVecRes_CONCAT_VECTORS(N); break; 2004 case ISD::CONVERT_RNDSAT: Res = WidenVecRes_CONVERT_RNDSAT(N); break; 2005 case ISD::EXTRACT_SUBVECTOR: Res = WidenVecRes_EXTRACT_SUBVECTOR(N); break; 2006 case ISD::FP_ROUND_INREG: Res = WidenVecRes_InregOp(N); break; 2007 case ISD::INSERT_VECTOR_ELT: Res = WidenVecRes_INSERT_VECTOR_ELT(N); break; 2008 case ISD::LOAD: Res = WidenVecRes_LOAD(N); break; 2009 case ISD::SCALAR_TO_VECTOR: Res = WidenVecRes_SCALAR_TO_VECTOR(N); break; 2010 case ISD::SIGN_EXTEND_INREG: Res = WidenVecRes_InregOp(N); break; 2011 case ISD::VSELECT: 2012 case ISD::SELECT: Res = WidenVecRes_SELECT(N); break; 2013 case ISD::SELECT_CC: Res = WidenVecRes_SELECT_CC(N); break; 2014 case ISD::SETCC: Res = WidenVecRes_SETCC(N); break; 2015 case ISD::UNDEF: Res = WidenVecRes_UNDEF(N); break; 2016 case ISD::VECTOR_SHUFFLE: 2017 Res = WidenVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N)); 2018 break; 2019 case ISD::MLOAD: 2020 Res = WidenVecRes_MLOAD(cast<MaskedLoadSDNode>(N)); 2021 break; 2022 case ISD::MGATHER: 2023 Res = WidenVecRes_MGATHER(cast<MaskedGatherSDNode>(N)); 2024 break; 2025 2026 case ISD::ADD: 2027 case ISD::AND: 2028 case ISD::MUL: 2029 case ISD::MULHS: 2030 case ISD::MULHU: 2031 case ISD::OR: 2032 case ISD::SUB: 2033 case ISD::XOR: 2034 case ISD::FMINNUM: 2035 case ISD::FMAXNUM: 2036 case ISD::FMINNAN: 2037 case ISD::FMAXNAN: 2038 case ISD::SMIN: 2039 case ISD::SMAX: 2040 case ISD::UMIN: 2041 case ISD::UMAX: 2042 Res = WidenVecRes_Binary(N); 2043 break; 2044 2045 case ISD::FADD: 2046 case ISD::FMUL: 2047 case ISD::FPOW: 2048 case ISD::FSUB: 2049 case ISD::FDIV: 2050 case ISD::FREM: 2051 case ISD::SDIV: 2052 case ISD::UDIV: 2053 case ISD::SREM: 2054 case ISD::UREM: 2055 Res = WidenVecRes_BinaryCanTrap(N); 2056 break; 2057 2058 case ISD::FCOPYSIGN: 2059 Res = WidenVecRes_FCOPYSIGN(N); 2060 break; 2061 2062 case ISD::FPOWI: 2063 Res = WidenVecRes_POWI(N); 2064 break; 2065 2066 case ISD::SHL: 2067 case ISD::SRA: 2068 case ISD::SRL: 2069 Res = WidenVecRes_Shift(N); 2070 break; 2071 2072 case ISD::ANY_EXTEND: 2073 case ISD::FP_EXTEND: 2074 case ISD::FP_ROUND: 2075 case ISD::FP_TO_SINT: 2076 case ISD::FP_TO_UINT: 2077 case ISD::SIGN_EXTEND: 2078 case ISD::SINT_TO_FP: 2079 case ISD::TRUNCATE: 2080 case ISD::UINT_TO_FP: 2081 case ISD::ZERO_EXTEND: 2082 Res = WidenVecRes_Convert(N); 2083 break; 2084 2085 case ISD::BITREVERSE: 2086 case ISD::BSWAP: 2087 case ISD::CTLZ: 2088 case ISD::CTPOP: 2089 case ISD::CTTZ: 2090 case ISD::FABS: 2091 case ISD::FCEIL: 2092 case ISD::FCOS: 2093 case ISD::FEXP: 2094 case ISD::FEXP2: 2095 case ISD::FFLOOR: 2096 case ISD::FLOG: 2097 case ISD::FLOG10: 2098 case ISD::FLOG2: 2099 case ISD::FNEARBYINT: 2100 case ISD::FNEG: 2101 case ISD::FRINT: 2102 case ISD::FROUND: 2103 case ISD::FSIN: 2104 case ISD::FSQRT: 2105 case ISD::FTRUNC: 2106 Res = WidenVecRes_Unary(N); 2107 break; 2108 case ISD::FMA: 2109 Res = WidenVecRes_Ternary(N); 2110 break; 2111 } 2112 2113 // If Res is null, the sub-method took care of registering the result. 2114 if (Res.getNode()) 2115 SetWidenedVector(SDValue(N, ResNo), Res); 2116 } 2117 2118 SDValue DAGTypeLegalizer::WidenVecRes_Ternary(SDNode *N) { 2119 // Ternary op widening. 2120 SDLoc dl(N); 2121 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2122 SDValue InOp1 = GetWidenedVector(N->getOperand(0)); 2123 SDValue InOp2 = GetWidenedVector(N->getOperand(1)); 2124 SDValue InOp3 = GetWidenedVector(N->getOperand(2)); 2125 return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3); 2126 } 2127 2128 SDValue DAGTypeLegalizer::WidenVecRes_Binary(SDNode *N) { 2129 // Binary op widening. 2130 SDLoc dl(N); 2131 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2132 SDValue InOp1 = GetWidenedVector(N->getOperand(0)); 2133 SDValue InOp2 = GetWidenedVector(N->getOperand(1)); 2134 return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2, N->getFlags()); 2135 } 2136 2137 SDValue DAGTypeLegalizer::WidenVecRes_BinaryCanTrap(SDNode *N) { 2138 // Binary op widening for operations that can trap. 2139 unsigned Opcode = N->getOpcode(); 2140 SDLoc dl(N); 2141 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2142 EVT WidenEltVT = WidenVT.getVectorElementType(); 2143 EVT VT = WidenVT; 2144 unsigned NumElts = VT.getVectorNumElements(); 2145 const SDNodeFlags *Flags = N->getFlags(); 2146 while (!TLI.isTypeLegal(VT) && NumElts != 1) { 2147 NumElts = NumElts / 2; 2148 VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts); 2149 } 2150 2151 if (NumElts != 1 && !TLI.canOpTrap(N->getOpcode(), VT)) { 2152 // Operation doesn't trap so just widen as normal. 2153 SDValue InOp1 = GetWidenedVector(N->getOperand(0)); 2154 SDValue InOp2 = GetWidenedVector(N->getOperand(1)); 2155 return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags); 2156 } 2157 2158 // No legal vector version so unroll the vector operation and then widen. 2159 if (NumElts == 1) 2160 return DAG.UnrollVectorOp(N, WidenVT.getVectorNumElements()); 2161 2162 // Since the operation can trap, apply operation on the original vector. 2163 EVT MaxVT = VT; 2164 SDValue InOp1 = GetWidenedVector(N->getOperand(0)); 2165 SDValue InOp2 = GetWidenedVector(N->getOperand(1)); 2166 unsigned CurNumElts = N->getValueType(0).getVectorNumElements(); 2167 2168 SmallVector<SDValue, 16> ConcatOps(CurNumElts); 2169 unsigned ConcatEnd = 0; // Current ConcatOps index. 2170 int Idx = 0; // Current Idx into input vectors. 2171 2172 // NumElts := greatest legal vector size (at most WidenVT) 2173 // while (orig. vector has unhandled elements) { 2174 // take munches of size NumElts from the beginning and add to ConcatOps 2175 // NumElts := next smaller supported vector size or 1 2176 // } 2177 while (CurNumElts != 0) { 2178 while (CurNumElts >= NumElts) { 2179 SDValue EOp1 = DAG.getNode( 2180 ISD::EXTRACT_SUBVECTOR, dl, VT, InOp1, 2181 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 2182 SDValue EOp2 = DAG.getNode( 2183 ISD::EXTRACT_SUBVECTOR, dl, VT, InOp2, 2184 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 2185 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags); 2186 Idx += NumElts; 2187 CurNumElts -= NumElts; 2188 } 2189 do { 2190 NumElts = NumElts / 2; 2191 VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts); 2192 } while (!TLI.isTypeLegal(VT) && NumElts != 1); 2193 2194 if (NumElts == 1) { 2195 for (unsigned i = 0; i != CurNumElts; ++i, ++Idx) { 2196 SDValue EOp1 = DAG.getNode( 2197 ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT, InOp1, 2198 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 2199 SDValue EOp2 = DAG.getNode( 2200 ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT, InOp2, 2201 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 2202 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, WidenEltVT, 2203 EOp1, EOp2, Flags); 2204 } 2205 CurNumElts = 0; 2206 } 2207 } 2208 2209 // Check to see if we have a single operation with the widen type. 2210 if (ConcatEnd == 1) { 2211 VT = ConcatOps[0].getValueType(); 2212 if (VT == WidenVT) 2213 return ConcatOps[0]; 2214 } 2215 2216 // while (Some element of ConcatOps is not of type MaxVT) { 2217 // From the end of ConcatOps, collect elements of the same type and put 2218 // them into an op of the next larger supported type 2219 // } 2220 while (ConcatOps[ConcatEnd-1].getValueType() != MaxVT) { 2221 Idx = ConcatEnd - 1; 2222 VT = ConcatOps[Idx--].getValueType(); 2223 while (Idx >= 0 && ConcatOps[Idx].getValueType() == VT) 2224 Idx--; 2225 2226 int NextSize = VT.isVector() ? VT.getVectorNumElements() : 1; 2227 EVT NextVT; 2228 do { 2229 NextSize *= 2; 2230 NextVT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NextSize); 2231 } while (!TLI.isTypeLegal(NextVT)); 2232 2233 if (!VT.isVector()) { 2234 // Scalar type, create an INSERT_VECTOR_ELEMENT of type NextVT 2235 SDValue VecOp = DAG.getUNDEF(NextVT); 2236 unsigned NumToInsert = ConcatEnd - Idx - 1; 2237 for (unsigned i = 0, OpIdx = Idx+1; i < NumToInsert; i++, OpIdx++) { 2238 VecOp = DAG.getNode( 2239 ISD::INSERT_VECTOR_ELT, dl, NextVT, VecOp, ConcatOps[OpIdx], 2240 DAG.getConstant(i, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 2241 } 2242 ConcatOps[Idx+1] = VecOp; 2243 ConcatEnd = Idx + 2; 2244 } else { 2245 // Vector type, create a CONCAT_VECTORS of type NextVT 2246 SDValue undefVec = DAG.getUNDEF(VT); 2247 unsigned OpsToConcat = NextSize/VT.getVectorNumElements(); 2248 SmallVector<SDValue, 16> SubConcatOps(OpsToConcat); 2249 unsigned RealVals = ConcatEnd - Idx - 1; 2250 unsigned SubConcatEnd = 0; 2251 unsigned SubConcatIdx = Idx + 1; 2252 while (SubConcatEnd < RealVals) 2253 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx]; 2254 while (SubConcatEnd < OpsToConcat) 2255 SubConcatOps[SubConcatEnd++] = undefVec; 2256 ConcatOps[SubConcatIdx] = DAG.getNode(ISD::CONCAT_VECTORS, dl, 2257 NextVT, SubConcatOps); 2258 ConcatEnd = SubConcatIdx + 1; 2259 } 2260 } 2261 2262 // Check to see if we have a single operation with the widen type. 2263 if (ConcatEnd == 1) { 2264 VT = ConcatOps[0].getValueType(); 2265 if (VT == WidenVT) 2266 return ConcatOps[0]; 2267 } 2268 2269 // add undefs of size MaxVT until ConcatOps grows to length of WidenVT 2270 unsigned NumOps = WidenVT.getVectorNumElements()/MaxVT.getVectorNumElements(); 2271 if (NumOps != ConcatEnd ) { 2272 SDValue UndefVal = DAG.getUNDEF(MaxVT); 2273 for (unsigned j = ConcatEnd; j < NumOps; ++j) 2274 ConcatOps[j] = UndefVal; 2275 } 2276 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, 2277 makeArrayRef(ConcatOps.data(), NumOps)); 2278 } 2279 2280 SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) { 2281 SDValue InOp = N->getOperand(0); 2282 SDLoc DL(N); 2283 2284 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2285 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 2286 2287 EVT InVT = InOp.getValueType(); 2288 EVT InEltVT = InVT.getVectorElementType(); 2289 EVT InWidenVT = EVT::getVectorVT(*DAG.getContext(), InEltVT, WidenNumElts); 2290 2291 unsigned Opcode = N->getOpcode(); 2292 unsigned InVTNumElts = InVT.getVectorNumElements(); 2293 const SDNodeFlags *Flags = N->getFlags(); 2294 if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) { 2295 InOp = GetWidenedVector(N->getOperand(0)); 2296 InVT = InOp.getValueType(); 2297 InVTNumElts = InVT.getVectorNumElements(); 2298 if (InVTNumElts == WidenNumElts) { 2299 if (N->getNumOperands() == 1) 2300 return DAG.getNode(Opcode, DL, WidenVT, InOp); 2301 return DAG.getNode(Opcode, DL, WidenVT, InOp, N->getOperand(1), Flags); 2302 } 2303 } 2304 2305 if (TLI.isTypeLegal(InWidenVT)) { 2306 // Because the result and the input are different vector types, widening 2307 // the result could create a legal type but widening the input might make 2308 // it an illegal type that might lead to repeatedly splitting the input 2309 // and then widening it. To avoid this, we widen the input only if 2310 // it results in a legal type. 2311 if (WidenNumElts % InVTNumElts == 0) { 2312 // Widen the input and call convert on the widened input vector. 2313 unsigned NumConcat = WidenNumElts/InVTNumElts; 2314 SmallVector<SDValue, 16> Ops(NumConcat); 2315 Ops[0] = InOp; 2316 SDValue UndefVal = DAG.getUNDEF(InVT); 2317 for (unsigned i = 1; i != NumConcat; ++i) 2318 Ops[i] = UndefVal; 2319 SDValue InVec = DAG.getNode(ISD::CONCAT_VECTORS, DL, InWidenVT, Ops); 2320 if (N->getNumOperands() == 1) 2321 return DAG.getNode(Opcode, DL, WidenVT, InVec); 2322 return DAG.getNode(Opcode, DL, WidenVT, InVec, N->getOperand(1), Flags); 2323 } 2324 2325 if (InVTNumElts % WidenNumElts == 0) { 2326 SDValue InVal = DAG.getNode( 2327 ISD::EXTRACT_SUBVECTOR, DL, InWidenVT, InOp, 2328 DAG.getConstant(0, DL, TLI.getVectorIdxTy(DAG.getDataLayout()))); 2329 // Extract the input and convert the shorten input vector. 2330 if (N->getNumOperands() == 1) 2331 return DAG.getNode(Opcode, DL, WidenVT, InVal); 2332 return DAG.getNode(Opcode, DL, WidenVT, InVal, N->getOperand(1), Flags); 2333 } 2334 } 2335 2336 // Otherwise unroll into some nasty scalar code and rebuild the vector. 2337 SmallVector<SDValue, 16> Ops(WidenNumElts); 2338 EVT EltVT = WidenVT.getVectorElementType(); 2339 unsigned MinElts = std::min(InVTNumElts, WidenNumElts); 2340 unsigned i; 2341 for (i=0; i < MinElts; ++i) { 2342 SDValue Val = DAG.getNode( 2343 ISD::EXTRACT_VECTOR_ELT, DL, InEltVT, InOp, 2344 DAG.getConstant(i, DL, TLI.getVectorIdxTy(DAG.getDataLayout()))); 2345 if (N->getNumOperands() == 1) 2346 Ops[i] = DAG.getNode(Opcode, DL, EltVT, Val); 2347 else 2348 Ops[i] = DAG.getNode(Opcode, DL, EltVT, Val, N->getOperand(1), Flags); 2349 } 2350 2351 SDValue UndefVal = DAG.getUNDEF(EltVT); 2352 for (; i < WidenNumElts; ++i) 2353 Ops[i] = UndefVal; 2354 2355 return DAG.getNode(ISD::BUILD_VECTOR, DL, WidenVT, Ops); 2356 } 2357 2358 SDValue DAGTypeLegalizer::WidenVecRes_FCOPYSIGN(SDNode *N) { 2359 // If this is an FCOPYSIGN with same input types, we can treat it as a 2360 // normal (can trap) binary op. 2361 if (N->getOperand(0).getValueType() == N->getOperand(1).getValueType()) 2362 return WidenVecRes_BinaryCanTrap(N); 2363 2364 // If the types are different, fall back to unrolling. 2365 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2366 return DAG.UnrollVectorOp(N, WidenVT.getVectorNumElements()); 2367 } 2368 2369 SDValue DAGTypeLegalizer::WidenVecRes_POWI(SDNode *N) { 2370 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2371 SDValue InOp = GetWidenedVector(N->getOperand(0)); 2372 SDValue ShOp = N->getOperand(1); 2373 return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, InOp, ShOp); 2374 } 2375 2376 SDValue DAGTypeLegalizer::WidenVecRes_Shift(SDNode *N) { 2377 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2378 SDValue InOp = GetWidenedVector(N->getOperand(0)); 2379 SDValue ShOp = N->getOperand(1); 2380 2381 EVT ShVT = ShOp.getValueType(); 2382 if (getTypeAction(ShVT) == TargetLowering::TypeWidenVector) { 2383 ShOp = GetWidenedVector(ShOp); 2384 ShVT = ShOp.getValueType(); 2385 } 2386 EVT ShWidenVT = EVT::getVectorVT(*DAG.getContext(), 2387 ShVT.getVectorElementType(), 2388 WidenVT.getVectorNumElements()); 2389 if (ShVT != ShWidenVT) 2390 ShOp = ModifyToType(ShOp, ShWidenVT); 2391 2392 return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, InOp, ShOp); 2393 } 2394 2395 SDValue DAGTypeLegalizer::WidenVecRes_Unary(SDNode *N) { 2396 // Unary op widening. 2397 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2398 SDValue InOp = GetWidenedVector(N->getOperand(0)); 2399 return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, InOp); 2400 } 2401 2402 SDValue DAGTypeLegalizer::WidenVecRes_InregOp(SDNode *N) { 2403 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2404 EVT ExtVT = EVT::getVectorVT(*DAG.getContext(), 2405 cast<VTSDNode>(N->getOperand(1))->getVT() 2406 .getVectorElementType(), 2407 WidenVT.getVectorNumElements()); 2408 SDValue WidenLHS = GetWidenedVector(N->getOperand(0)); 2409 return DAG.getNode(N->getOpcode(), SDLoc(N), 2410 WidenVT, WidenLHS, DAG.getValueType(ExtVT)); 2411 } 2412 2413 SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(SDNode *N, unsigned ResNo) { 2414 SDValue WidenVec = DisintegrateMERGE_VALUES(N, ResNo); 2415 return GetWidenedVector(WidenVec); 2416 } 2417 2418 SDValue DAGTypeLegalizer::WidenVecRes_BITCAST(SDNode *N) { 2419 SDValue InOp = N->getOperand(0); 2420 EVT InVT = InOp.getValueType(); 2421 EVT VT = N->getValueType(0); 2422 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 2423 SDLoc dl(N); 2424 2425 switch (getTypeAction(InVT)) { 2426 case TargetLowering::TypeLegal: 2427 break; 2428 case TargetLowering::TypePromoteInteger: 2429 // If the incoming type is a vector that is being promoted, then 2430 // we know that the elements are arranged differently and that we 2431 // must perform the conversion using a stack slot. 2432 if (InVT.isVector()) 2433 break; 2434 2435 // If the InOp is promoted to the same size, convert it. Otherwise, 2436 // fall out of the switch and widen the promoted input. 2437 InOp = GetPromotedInteger(InOp); 2438 InVT = InOp.getValueType(); 2439 if (WidenVT.bitsEq(InVT)) 2440 return DAG.getNode(ISD::BITCAST, dl, WidenVT, InOp); 2441 break; 2442 case TargetLowering::TypeSoftenFloat: 2443 case TargetLowering::TypePromoteFloat: 2444 case TargetLowering::TypeExpandInteger: 2445 case TargetLowering::TypeExpandFloat: 2446 case TargetLowering::TypeScalarizeVector: 2447 case TargetLowering::TypeSplitVector: 2448 break; 2449 case TargetLowering::TypeWidenVector: 2450 // If the InOp is widened to the same size, convert it. Otherwise, fall 2451 // out of the switch and widen the widened input. 2452 InOp = GetWidenedVector(InOp); 2453 InVT = InOp.getValueType(); 2454 if (WidenVT.bitsEq(InVT)) 2455 // The input widens to the same size. Convert to the widen value. 2456 return DAG.getNode(ISD::BITCAST, dl, WidenVT, InOp); 2457 break; 2458 } 2459 2460 unsigned WidenSize = WidenVT.getSizeInBits(); 2461 unsigned InSize = InVT.getSizeInBits(); 2462 // x86mmx is not an acceptable vector element type, so don't try. 2463 if (WidenSize % InSize == 0 && InVT != MVT::x86mmx) { 2464 // Determine new input vector type. The new input vector type will use 2465 // the same element type (if its a vector) or use the input type as a 2466 // vector. It is the same size as the type to widen to. 2467 EVT NewInVT; 2468 unsigned NewNumElts = WidenSize / InSize; 2469 if (InVT.isVector()) { 2470 EVT InEltVT = InVT.getVectorElementType(); 2471 NewInVT = EVT::getVectorVT(*DAG.getContext(), InEltVT, 2472 WidenSize / InEltVT.getSizeInBits()); 2473 } else { 2474 NewInVT = EVT::getVectorVT(*DAG.getContext(), InVT, NewNumElts); 2475 } 2476 2477 if (TLI.isTypeLegal(NewInVT)) { 2478 // Because the result and the input are different vector types, widening 2479 // the result could create a legal type but widening the input might make 2480 // it an illegal type that might lead to repeatedly splitting the input 2481 // and then widening it. To avoid this, we widen the input only if 2482 // it results in a legal type. 2483 SmallVector<SDValue, 16> Ops(NewNumElts); 2484 SDValue UndefVal = DAG.getUNDEF(InVT); 2485 Ops[0] = InOp; 2486 for (unsigned i = 1; i < NewNumElts; ++i) 2487 Ops[i] = UndefVal; 2488 2489 SDValue NewVec; 2490 if (InVT.isVector()) 2491 NewVec = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewInVT, Ops); 2492 else 2493 NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl, NewInVT, Ops); 2494 return DAG.getNode(ISD::BITCAST, dl, WidenVT, NewVec); 2495 } 2496 } 2497 2498 return CreateStackStoreLoad(InOp, WidenVT); 2499 } 2500 2501 SDValue DAGTypeLegalizer::WidenVecRes_BUILD_VECTOR(SDNode *N) { 2502 SDLoc dl(N); 2503 // Build a vector with undefined for the new nodes. 2504 EVT VT = N->getValueType(0); 2505 2506 // Integer BUILD_VECTOR operands may be larger than the node's vector element 2507 // type. The UNDEFs need to have the same type as the existing operands. 2508 EVT EltVT = N->getOperand(0).getValueType(); 2509 unsigned NumElts = VT.getVectorNumElements(); 2510 2511 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 2512 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 2513 2514 SmallVector<SDValue, 16> NewOps(N->op_begin(), N->op_end()); 2515 assert(WidenNumElts >= NumElts && "Shrinking vector instead of widening!"); 2516 NewOps.append(WidenNumElts - NumElts, DAG.getUNDEF(EltVT)); 2517 2518 return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, NewOps); 2519 } 2520 2521 SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) { 2522 EVT InVT = N->getOperand(0).getValueType(); 2523 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2524 SDLoc dl(N); 2525 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 2526 unsigned NumInElts = InVT.getVectorNumElements(); 2527 unsigned NumOperands = N->getNumOperands(); 2528 2529 bool InputWidened = false; // Indicates we need to widen the input. 2530 if (getTypeAction(InVT) != TargetLowering::TypeWidenVector) { 2531 if (WidenVT.getVectorNumElements() % InVT.getVectorNumElements() == 0) { 2532 // Add undef vectors to widen to correct length. 2533 unsigned NumConcat = WidenVT.getVectorNumElements() / 2534 InVT.getVectorNumElements(); 2535 SDValue UndefVal = DAG.getUNDEF(InVT); 2536 SmallVector<SDValue, 16> Ops(NumConcat); 2537 for (unsigned i=0; i < NumOperands; ++i) 2538 Ops[i] = N->getOperand(i); 2539 for (unsigned i = NumOperands; i != NumConcat; ++i) 2540 Ops[i] = UndefVal; 2541 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, Ops); 2542 } 2543 } else { 2544 InputWidened = true; 2545 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) { 2546 // The inputs and the result are widen to the same value. 2547 unsigned i; 2548 for (i=1; i < NumOperands; ++i) 2549 if (N->getOperand(i).getOpcode() != ISD::UNDEF) 2550 break; 2551 2552 if (i == NumOperands) 2553 // Everything but the first operand is an UNDEF so just return the 2554 // widened first operand. 2555 return GetWidenedVector(N->getOperand(0)); 2556 2557 if (NumOperands == 2) { 2558 // Replace concat of two operands with a shuffle. 2559 SmallVector<int, 16> MaskOps(WidenNumElts, -1); 2560 for (unsigned i = 0; i < NumInElts; ++i) { 2561 MaskOps[i] = i; 2562 MaskOps[i + NumInElts] = i + WidenNumElts; 2563 } 2564 return DAG.getVectorShuffle(WidenVT, dl, 2565 GetWidenedVector(N->getOperand(0)), 2566 GetWidenedVector(N->getOperand(1)), 2567 &MaskOps[0]); 2568 } 2569 } 2570 } 2571 2572 // Fall back to use extracts and build vector. 2573 EVT EltVT = WidenVT.getVectorElementType(); 2574 SmallVector<SDValue, 16> Ops(WidenNumElts); 2575 unsigned Idx = 0; 2576 for (unsigned i=0; i < NumOperands; ++i) { 2577 SDValue InOp = N->getOperand(i); 2578 if (InputWidened) 2579 InOp = GetWidenedVector(InOp); 2580 for (unsigned j=0; j < NumInElts; ++j) 2581 Ops[Idx++] = DAG.getNode( 2582 ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, 2583 DAG.getConstant(j, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 2584 } 2585 SDValue UndefVal = DAG.getUNDEF(EltVT); 2586 for (; Idx < WidenNumElts; ++Idx) 2587 Ops[Idx] = UndefVal; 2588 return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, Ops); 2589 } 2590 2591 SDValue DAGTypeLegalizer::WidenVecRes_CONVERT_RNDSAT(SDNode *N) { 2592 SDLoc dl(N); 2593 SDValue InOp = N->getOperand(0); 2594 SDValue RndOp = N->getOperand(3); 2595 SDValue SatOp = N->getOperand(4); 2596 2597 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2598 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 2599 2600 EVT InVT = InOp.getValueType(); 2601 EVT InEltVT = InVT.getVectorElementType(); 2602 EVT InWidenVT = EVT::getVectorVT(*DAG.getContext(), InEltVT, WidenNumElts); 2603 2604 SDValue DTyOp = DAG.getValueType(WidenVT); 2605 SDValue STyOp = DAG.getValueType(InWidenVT); 2606 ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode(); 2607 2608 unsigned InVTNumElts = InVT.getVectorNumElements(); 2609 if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) { 2610 InOp = GetWidenedVector(InOp); 2611 InVT = InOp.getValueType(); 2612 InVTNumElts = InVT.getVectorNumElements(); 2613 if (InVTNumElts == WidenNumElts) 2614 return DAG.getConvertRndSat(WidenVT, dl, InOp, DTyOp, STyOp, RndOp, 2615 SatOp, CvtCode); 2616 } 2617 2618 if (TLI.isTypeLegal(InWidenVT)) { 2619 // Because the result and the input are different vector types, widening 2620 // the result could create a legal type but widening the input might make 2621 // it an illegal type that might lead to repeatedly splitting the input 2622 // and then widening it. To avoid this, we widen the input only if 2623 // it results in a legal type. 2624 if (WidenNumElts % InVTNumElts == 0) { 2625 // Widen the input and call convert on the widened input vector. 2626 unsigned NumConcat = WidenNumElts/InVTNumElts; 2627 SmallVector<SDValue, 16> Ops(NumConcat); 2628 Ops[0] = InOp; 2629 SDValue UndefVal = DAG.getUNDEF(InVT); 2630 for (unsigned i = 1; i != NumConcat; ++i) 2631 Ops[i] = UndefVal; 2632 2633 InOp = DAG.getNode(ISD::CONCAT_VECTORS, dl, InWidenVT, Ops); 2634 return DAG.getConvertRndSat(WidenVT, dl, InOp, DTyOp, STyOp, RndOp, 2635 SatOp, CvtCode); 2636 } 2637 2638 if (InVTNumElts % WidenNumElts == 0) { 2639 // Extract the input and convert the shorten input vector. 2640 InOp = DAG.getNode( 2641 ISD::EXTRACT_SUBVECTOR, dl, InWidenVT, InOp, 2642 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 2643 return DAG.getConvertRndSat(WidenVT, dl, InOp, DTyOp, STyOp, RndOp, 2644 SatOp, CvtCode); 2645 } 2646 } 2647 2648 // Otherwise unroll into some nasty scalar code and rebuild the vector. 2649 SmallVector<SDValue, 16> Ops(WidenNumElts); 2650 EVT EltVT = WidenVT.getVectorElementType(); 2651 DTyOp = DAG.getValueType(EltVT); 2652 STyOp = DAG.getValueType(InEltVT); 2653 2654 unsigned MinElts = std::min(InVTNumElts, WidenNumElts); 2655 unsigned i; 2656 for (i=0; i < MinElts; ++i) { 2657 SDValue ExtVal = DAG.getNode( 2658 ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp, 2659 DAG.getConstant(i, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 2660 Ops[i] = DAG.getConvertRndSat(WidenVT, dl, ExtVal, DTyOp, STyOp, RndOp, 2661 SatOp, CvtCode); 2662 } 2663 2664 SDValue UndefVal = DAG.getUNDEF(EltVT); 2665 for (; i < WidenNumElts; ++i) 2666 Ops[i] = UndefVal; 2667 2668 return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, Ops); 2669 } 2670 2671 SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) { 2672 EVT VT = N->getValueType(0); 2673 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 2674 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 2675 SDValue InOp = N->getOperand(0); 2676 SDValue Idx = N->getOperand(1); 2677 SDLoc dl(N); 2678 2679 if (getTypeAction(InOp.getValueType()) == TargetLowering::TypeWidenVector) 2680 InOp = GetWidenedVector(InOp); 2681 2682 EVT InVT = InOp.getValueType(); 2683 2684 // Check if we can just return the input vector after widening. 2685 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue(); 2686 if (IdxVal == 0 && InVT == WidenVT) 2687 return InOp; 2688 2689 // Check if we can extract from the vector. 2690 unsigned InNumElts = InVT.getVectorNumElements(); 2691 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts) 2692 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, WidenVT, InOp, Idx); 2693 2694 // We could try widening the input to the right length but for now, extract 2695 // the original elements, fill the rest with undefs and build a vector. 2696 SmallVector<SDValue, 16> Ops(WidenNumElts); 2697 EVT EltVT = VT.getVectorElementType(); 2698 unsigned NumElts = VT.getVectorNumElements(); 2699 unsigned i; 2700 for (i=0; i < NumElts; ++i) 2701 Ops[i] = 2702 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, 2703 DAG.getConstant(IdxVal + i, dl, 2704 TLI.getVectorIdxTy(DAG.getDataLayout()))); 2705 2706 SDValue UndefVal = DAG.getUNDEF(EltVT); 2707 for (; i < WidenNumElts; ++i) 2708 Ops[i] = UndefVal; 2709 return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, Ops); 2710 } 2711 2712 SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) { 2713 SDValue InOp = GetWidenedVector(N->getOperand(0)); 2714 return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(N), 2715 InOp.getValueType(), InOp, 2716 N->getOperand(1), N->getOperand(2)); 2717 } 2718 2719 SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) { 2720 LoadSDNode *LD = cast<LoadSDNode>(N); 2721 ISD::LoadExtType ExtType = LD->getExtensionType(); 2722 2723 SDValue Result; 2724 SmallVector<SDValue, 16> LdChain; // Chain for the series of load 2725 if (ExtType != ISD::NON_EXTLOAD) 2726 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType); 2727 else 2728 Result = GenWidenVectorLoads(LdChain, LD); 2729 2730 // If we generate a single load, we can use that for the chain. Otherwise, 2731 // build a factor node to remember the multiple loads are independent and 2732 // chain to that. 2733 SDValue NewChain; 2734 if (LdChain.size() == 1) 2735 NewChain = LdChain[0]; 2736 else 2737 NewChain = DAG.getNode(ISD::TokenFactor, SDLoc(LD), MVT::Other, LdChain); 2738 2739 // Modified the chain - switch anything that used the old chain to use 2740 // the new one. 2741 ReplaceValueWith(SDValue(N, 1), NewChain); 2742 2743 return Result; 2744 } 2745 2746 SDValue DAGTypeLegalizer::WidenVecRes_MLOAD(MaskedLoadSDNode *N) { 2747 2748 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),N->getValueType(0)); 2749 SDValue Mask = N->getMask(); 2750 EVT MaskVT = Mask.getValueType(); 2751 SDValue Src0 = GetWidenedVector(N->getSrc0()); 2752 ISD::LoadExtType ExtType = N->getExtensionType(); 2753 SDLoc dl(N); 2754 2755 if (getTypeAction(MaskVT) == TargetLowering::TypeWidenVector) 2756 Mask = GetWidenedVector(Mask); 2757 else { 2758 EVT BoolVT = getSetCCResultType(WidenVT); 2759 2760 // We can't use ModifyToType() because we should fill the mask with 2761 // zeroes 2762 unsigned WidenNumElts = BoolVT.getVectorNumElements(); 2763 unsigned MaskNumElts = MaskVT.getVectorNumElements(); 2764 2765 unsigned NumConcat = WidenNumElts / MaskNumElts; 2766 SmallVector<SDValue, 16> Ops(NumConcat); 2767 SDValue ZeroVal = DAG.getConstant(0, dl, MaskVT); 2768 Ops[0] = Mask; 2769 for (unsigned i = 1; i != NumConcat; ++i) 2770 Ops[i] = ZeroVal; 2771 2772 Mask = DAG.getNode(ISD::CONCAT_VECTORS, dl, BoolVT, Ops); 2773 } 2774 2775 SDValue Res = DAG.getMaskedLoad(WidenVT, dl, N->getChain(), N->getBasePtr(), 2776 Mask, Src0, N->getMemoryVT(), 2777 N->getMemOperand(), ExtType); 2778 // Legalize the chain result - switch anything that used the old chain to 2779 // use the new one. 2780 ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); 2781 return Res; 2782 } 2783 2784 SDValue DAGTypeLegalizer::WidenVecRes_MGATHER(MaskedGatherSDNode *N) { 2785 2786 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2787 SDValue Mask = N->getMask(); 2788 SDValue Src0 = GetWidenedVector(N->getValue()); 2789 unsigned NumElts = WideVT.getVectorNumElements(); 2790 SDLoc dl(N); 2791 2792 // The mask should be widened as well 2793 Mask = WidenTargetBoolean(Mask, WideVT, true); 2794 2795 // Widen the Index operand 2796 SDValue Index = N->getIndex(); 2797 EVT WideIndexVT = EVT::getVectorVT(*DAG.getContext(), 2798 Index.getValueType().getScalarType(), 2799 NumElts); 2800 Index = ModifyToType(Index, WideIndexVT); 2801 SDValue Ops[] = { N->getChain(), Src0, Mask, N->getBasePtr(), Index }; 2802 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other), 2803 N->getMemoryVT(), dl, Ops, 2804 N->getMemOperand()); 2805 2806 // Legalize the chain result - switch anything that used the old chain to 2807 // use the new one. 2808 ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); 2809 return Res; 2810 } 2811 2812 SDValue DAGTypeLegalizer::WidenVecRes_SCALAR_TO_VECTOR(SDNode *N) { 2813 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2814 return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), 2815 WidenVT, N->getOperand(0)); 2816 } 2817 2818 SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNode *N) { 2819 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2820 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 2821 2822 SDValue Cond1 = N->getOperand(0); 2823 EVT CondVT = Cond1.getValueType(); 2824 if (CondVT.isVector()) { 2825 EVT CondEltVT = CondVT.getVectorElementType(); 2826 EVT CondWidenVT = EVT::getVectorVT(*DAG.getContext(), 2827 CondEltVT, WidenNumElts); 2828 if (getTypeAction(CondVT) == TargetLowering::TypeWidenVector) 2829 Cond1 = GetWidenedVector(Cond1); 2830 2831 // If we have to split the condition there is no point in widening the 2832 // select. This would result in an cycle of widening the select -> 2833 // widening the condition operand -> splitting the condition operand -> 2834 // splitting the select -> widening the select. Instead split this select 2835 // further and widen the resulting type. 2836 if (getTypeAction(CondVT) == TargetLowering::TypeSplitVector) { 2837 SDValue SplitSelect = SplitVecOp_VSELECT(N, 0); 2838 SDValue Res = ModifyToType(SplitSelect, WidenVT); 2839 return Res; 2840 } 2841 2842 if (Cond1.getValueType() != CondWidenVT) 2843 Cond1 = ModifyToType(Cond1, CondWidenVT); 2844 } 2845 2846 SDValue InOp1 = GetWidenedVector(N->getOperand(1)); 2847 SDValue InOp2 = GetWidenedVector(N->getOperand(2)); 2848 assert(InOp1.getValueType() == WidenVT && InOp2.getValueType() == WidenVT); 2849 return DAG.getNode(N->getOpcode(), SDLoc(N), 2850 WidenVT, Cond1, InOp1, InOp2); 2851 } 2852 2853 SDValue DAGTypeLegalizer::WidenVecRes_SELECT_CC(SDNode *N) { 2854 SDValue InOp1 = GetWidenedVector(N->getOperand(2)); 2855 SDValue InOp2 = GetWidenedVector(N->getOperand(3)); 2856 return DAG.getNode(ISD::SELECT_CC, SDLoc(N), 2857 InOp1.getValueType(), N->getOperand(0), 2858 N->getOperand(1), InOp1, InOp2, N->getOperand(4)); 2859 } 2860 2861 SDValue DAGTypeLegalizer::WidenVecRes_SETCC(SDNode *N) { 2862 assert(N->getValueType(0).isVector() == 2863 N->getOperand(0).getValueType().isVector() && 2864 "Scalar/Vector type mismatch"); 2865 if (N->getValueType(0).isVector()) return WidenVecRes_VSETCC(N); 2866 2867 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2868 SDValue InOp1 = GetWidenedVector(N->getOperand(0)); 2869 SDValue InOp2 = GetWidenedVector(N->getOperand(1)); 2870 return DAG.getNode(ISD::SETCC, SDLoc(N), WidenVT, 2871 InOp1, InOp2, N->getOperand(2)); 2872 } 2873 2874 SDValue DAGTypeLegalizer::WidenVecRes_UNDEF(SDNode *N) { 2875 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2876 return DAG.getUNDEF(WidenVT); 2877 } 2878 2879 SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N) { 2880 EVT VT = N->getValueType(0); 2881 SDLoc dl(N); 2882 2883 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 2884 unsigned NumElts = VT.getVectorNumElements(); 2885 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 2886 2887 SDValue InOp1 = GetWidenedVector(N->getOperand(0)); 2888 SDValue InOp2 = GetWidenedVector(N->getOperand(1)); 2889 2890 // Adjust mask based on new input vector length. 2891 SmallVector<int, 16> NewMask; 2892 for (unsigned i = 0; i != NumElts; ++i) { 2893 int Idx = N->getMaskElt(i); 2894 if (Idx < (int)NumElts) 2895 NewMask.push_back(Idx); 2896 else 2897 NewMask.push_back(Idx - NumElts + WidenNumElts); 2898 } 2899 for (unsigned i = NumElts; i != WidenNumElts; ++i) 2900 NewMask.push_back(-1); 2901 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, &NewMask[0]); 2902 } 2903 2904 SDValue DAGTypeLegalizer::WidenVecRes_VSETCC(SDNode *N) { 2905 assert(N->getValueType(0).isVector() && 2906 N->getOperand(0).getValueType().isVector() && 2907 "Operands must be vectors"); 2908 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2909 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 2910 2911 SDValue InOp1 = N->getOperand(0); 2912 EVT InVT = InOp1.getValueType(); 2913 assert(InVT.isVector() && "can not widen non-vector type"); 2914 EVT WidenInVT = EVT::getVectorVT(*DAG.getContext(), 2915 InVT.getVectorElementType(), WidenNumElts); 2916 2917 // The input and output types often differ here, and it could be that while 2918 // we'd prefer to widen the result type, the input operands have been split. 2919 // In this case, we also need to split the result of this node as well. 2920 if (getTypeAction(InVT) == TargetLowering::TypeSplitVector) { 2921 SDValue SplitVSetCC = SplitVecOp_VSETCC(N); 2922 SDValue Res = ModifyToType(SplitVSetCC, WidenVT); 2923 return Res; 2924 } 2925 2926 InOp1 = GetWidenedVector(InOp1); 2927 SDValue InOp2 = GetWidenedVector(N->getOperand(1)); 2928 2929 // Assume that the input and output will be widen appropriately. If not, 2930 // we will have to unroll it at some point. 2931 assert(InOp1.getValueType() == WidenInVT && 2932 InOp2.getValueType() == WidenInVT && 2933 "Input not widened to expected type!"); 2934 (void)WidenInVT; 2935 return DAG.getNode(ISD::SETCC, SDLoc(N), 2936 WidenVT, InOp1, InOp2, N->getOperand(2)); 2937 } 2938 2939 2940 //===----------------------------------------------------------------------===// 2941 // Widen Vector Operand 2942 //===----------------------------------------------------------------------===// 2943 bool DAGTypeLegalizer::WidenVectorOperand(SDNode *N, unsigned OpNo) { 2944 DEBUG(dbgs() << "Widen node operand " << OpNo << ": "; 2945 N->dump(&DAG); 2946 dbgs() << "\n"); 2947 SDValue Res = SDValue(); 2948 2949 // See if the target wants to custom widen this node. 2950 if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) 2951 return false; 2952 2953 switch (N->getOpcode()) { 2954 default: 2955 #ifndef NDEBUG 2956 dbgs() << "WidenVectorOperand op #" << OpNo << ": "; 2957 N->dump(&DAG); 2958 dbgs() << "\n"; 2959 #endif 2960 llvm_unreachable("Do not know how to widen this operator's operand!"); 2961 2962 case ISD::BITCAST: Res = WidenVecOp_BITCAST(N); break; 2963 case ISD::CONCAT_VECTORS: Res = WidenVecOp_CONCAT_VECTORS(N); break; 2964 case ISD::EXTRACT_SUBVECTOR: Res = WidenVecOp_EXTRACT_SUBVECTOR(N); break; 2965 case ISD::EXTRACT_VECTOR_ELT: Res = WidenVecOp_EXTRACT_VECTOR_ELT(N); break; 2966 case ISD::STORE: Res = WidenVecOp_STORE(N); break; 2967 case ISD::MSTORE: Res = WidenVecOp_MSTORE(N, OpNo); break; 2968 case ISD::MSCATTER: Res = WidenVecOp_MSCATTER(N, OpNo); break; 2969 case ISD::SETCC: Res = WidenVecOp_SETCC(N); break; 2970 case ISD::FCOPYSIGN: Res = WidenVecOp_FCOPYSIGN(N); break; 2971 2972 case ISD::ANY_EXTEND: 2973 case ISD::SIGN_EXTEND: 2974 case ISD::ZERO_EXTEND: 2975 Res = WidenVecOp_EXTEND(N); 2976 break; 2977 2978 case ISD::FP_EXTEND: 2979 case ISD::FP_TO_SINT: 2980 case ISD::FP_TO_UINT: 2981 case ISD::SINT_TO_FP: 2982 case ISD::UINT_TO_FP: 2983 case ISD::TRUNCATE: 2984 Res = WidenVecOp_Convert(N); 2985 break; 2986 } 2987 2988 // If Res is null, the sub-method took care of registering the result. 2989 if (!Res.getNode()) return false; 2990 2991 // If the result is N, the sub-method updated N in place. Tell the legalizer 2992 // core about this. 2993 if (Res.getNode() == N) 2994 return true; 2995 2996 2997 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 2998 "Invalid operand expansion"); 2999 3000 ReplaceValueWith(SDValue(N, 0), Res); 3001 return false; 3002 } 3003 3004 SDValue DAGTypeLegalizer::WidenVecOp_EXTEND(SDNode *N) { 3005 SDLoc DL(N); 3006 EVT VT = N->getValueType(0); 3007 3008 SDValue InOp = N->getOperand(0); 3009 // If some legalization strategy other than widening is used on the operand, 3010 // we can't safely assume that just extending the low lanes is the correct 3011 // transformation. 3012 if (getTypeAction(InOp.getValueType()) != TargetLowering::TypeWidenVector) 3013 return WidenVecOp_Convert(N); 3014 InOp = GetWidenedVector(InOp); 3015 assert(VT.getVectorNumElements() < 3016 InOp.getValueType().getVectorNumElements() && 3017 "Input wasn't widened!"); 3018 3019 // We may need to further widen the operand until it has the same total 3020 // vector size as the result. 3021 EVT InVT = InOp.getValueType(); 3022 if (InVT.getSizeInBits() != VT.getSizeInBits()) { 3023 EVT InEltVT = InVT.getVectorElementType(); 3024 for (int i = MVT::FIRST_VECTOR_VALUETYPE, e = MVT::LAST_VECTOR_VALUETYPE; i < e; ++i) { 3025 EVT FixedVT = (MVT::SimpleValueType)i; 3026 EVT FixedEltVT = FixedVT.getVectorElementType(); 3027 if (TLI.isTypeLegal(FixedVT) && 3028 FixedVT.getSizeInBits() == VT.getSizeInBits() && 3029 FixedEltVT == InEltVT) { 3030 assert(FixedVT.getVectorNumElements() >= VT.getVectorNumElements() && 3031 "Not enough elements in the fixed type for the operand!"); 3032 assert(FixedVT.getVectorNumElements() != InVT.getVectorNumElements() && 3033 "We can't have the same type as we started with!"); 3034 if (FixedVT.getVectorNumElements() > InVT.getVectorNumElements()) 3035 InOp = DAG.getNode( 3036 ISD::INSERT_SUBVECTOR, DL, FixedVT, DAG.getUNDEF(FixedVT), InOp, 3037 DAG.getConstant(0, DL, TLI.getVectorIdxTy(DAG.getDataLayout()))); 3038 else 3039 InOp = DAG.getNode( 3040 ISD::EXTRACT_SUBVECTOR, DL, FixedVT, InOp, 3041 DAG.getConstant(0, DL, TLI.getVectorIdxTy(DAG.getDataLayout()))); 3042 break; 3043 } 3044 } 3045 InVT = InOp.getValueType(); 3046 if (InVT.getSizeInBits() != VT.getSizeInBits()) 3047 // We couldn't find a legal vector type that was a widening of the input 3048 // and could be extended in-register to the result type, so we have to 3049 // scalarize. 3050 return WidenVecOp_Convert(N); 3051 } 3052 3053 // Use special DAG nodes to represent the operation of extending the 3054 // low lanes. 3055 switch (N->getOpcode()) { 3056 default: 3057 llvm_unreachable("Extend legalization on on extend operation!"); 3058 case ISD::ANY_EXTEND: 3059 return DAG.getAnyExtendVectorInReg(InOp, DL, VT); 3060 case ISD::SIGN_EXTEND: 3061 return DAG.getSignExtendVectorInReg(InOp, DL, VT); 3062 case ISD::ZERO_EXTEND: 3063 return DAG.getZeroExtendVectorInReg(InOp, DL, VT); 3064 } 3065 } 3066 3067 SDValue DAGTypeLegalizer::WidenVecOp_FCOPYSIGN(SDNode *N) { 3068 // The result (and first input) is legal, but the second input is illegal. 3069 // We can't do much to fix that, so just unroll and let the extracts off of 3070 // the second input be widened as needed later. 3071 return DAG.UnrollVectorOp(N); 3072 } 3073 3074 SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) { 3075 // Since the result is legal and the input is illegal, it is unlikely 3076 // that we can fix the input to a legal type so unroll the convert 3077 // into some scalar code and create a nasty build vector. 3078 EVT VT = N->getValueType(0); 3079 EVT EltVT = VT.getVectorElementType(); 3080 SDLoc dl(N); 3081 unsigned NumElts = VT.getVectorNumElements(); 3082 SDValue InOp = N->getOperand(0); 3083 if (getTypeAction(InOp.getValueType()) == TargetLowering::TypeWidenVector) 3084 InOp = GetWidenedVector(InOp); 3085 EVT InVT = InOp.getValueType(); 3086 EVT InEltVT = InVT.getVectorElementType(); 3087 3088 unsigned Opcode = N->getOpcode(); 3089 SmallVector<SDValue, 16> Ops(NumElts); 3090 for (unsigned i=0; i < NumElts; ++i) 3091 Ops[i] = DAG.getNode( 3092 Opcode, dl, EltVT, 3093 DAG.getNode( 3094 ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp, 3095 DAG.getConstant(i, dl, TLI.getVectorIdxTy(DAG.getDataLayout())))); 3096 3097 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops); 3098 } 3099 3100 SDValue DAGTypeLegalizer::WidenVecOp_BITCAST(SDNode *N) { 3101 EVT VT = N->getValueType(0); 3102 SDValue InOp = GetWidenedVector(N->getOperand(0)); 3103 EVT InWidenVT = InOp.getValueType(); 3104 SDLoc dl(N); 3105 3106 // Check if we can convert between two legal vector types and extract. 3107 unsigned InWidenSize = InWidenVT.getSizeInBits(); 3108 unsigned Size = VT.getSizeInBits(); 3109 // x86mmx is not an acceptable vector element type, so don't try. 3110 if (InWidenSize % Size == 0 && !VT.isVector() && VT != MVT::x86mmx) { 3111 unsigned NewNumElts = InWidenSize / Size; 3112 EVT NewVT = EVT::getVectorVT(*DAG.getContext(), VT, NewNumElts); 3113 if (TLI.isTypeLegal(NewVT)) { 3114 SDValue BitOp = DAG.getNode(ISD::BITCAST, dl, NewVT, InOp); 3115 return DAG.getNode( 3116 ISD::EXTRACT_VECTOR_ELT, dl, VT, BitOp, 3117 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 3118 } 3119 } 3120 3121 return CreateStackStoreLoad(InOp, VT); 3122 } 3123 3124 SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) { 3125 // If the input vector is not legal, it is likely that we will not find a 3126 // legal vector of the same size. Replace the concatenate vector with a 3127 // nasty build vector. 3128 EVT VT = N->getValueType(0); 3129 EVT EltVT = VT.getVectorElementType(); 3130 SDLoc dl(N); 3131 unsigned NumElts = VT.getVectorNumElements(); 3132 SmallVector<SDValue, 16> Ops(NumElts); 3133 3134 EVT InVT = N->getOperand(0).getValueType(); 3135 unsigned NumInElts = InVT.getVectorNumElements(); 3136 3137 unsigned Idx = 0; 3138 unsigned NumOperands = N->getNumOperands(); 3139 for (unsigned i=0; i < NumOperands; ++i) { 3140 SDValue InOp = N->getOperand(i); 3141 if (getTypeAction(InOp.getValueType()) == TargetLowering::TypeWidenVector) 3142 InOp = GetWidenedVector(InOp); 3143 for (unsigned j=0; j < NumInElts; ++j) 3144 Ops[Idx++] = DAG.getNode( 3145 ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, 3146 DAG.getConstant(j, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 3147 } 3148 return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops); 3149 } 3150 3151 SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(SDNode *N) { 3152 SDValue InOp = GetWidenedVector(N->getOperand(0)); 3153 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(N), 3154 N->getValueType(0), InOp, N->getOperand(1)); 3155 } 3156 3157 SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { 3158 SDValue InOp = GetWidenedVector(N->getOperand(0)); 3159 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), 3160 N->getValueType(0), InOp, N->getOperand(1)); 3161 } 3162 3163 SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) { 3164 // We have to widen the value but we want only to store the original 3165 // vector type. 3166 StoreSDNode *ST = cast<StoreSDNode>(N); 3167 3168 SmallVector<SDValue, 16> StChain; 3169 if (ST->isTruncatingStore()) 3170 GenWidenVectorTruncStores(StChain, ST); 3171 else 3172 GenWidenVectorStores(StChain, ST); 3173 3174 if (StChain.size() == 1) 3175 return StChain[0]; 3176 else 3177 return DAG.getNode(ISD::TokenFactor, SDLoc(ST), MVT::Other, StChain); 3178 } 3179 3180 SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(SDNode *N, unsigned OpNo) { 3181 MaskedStoreSDNode *MST = cast<MaskedStoreSDNode>(N); 3182 SDValue Mask = MST->getMask(); 3183 EVT MaskVT = Mask.getValueType(); 3184 SDValue StVal = MST->getValue(); 3185 // Widen the value 3186 SDValue WideVal = GetWidenedVector(StVal); 3187 SDLoc dl(N); 3188 3189 if (OpNo == 2 || getTypeAction(MaskVT) == TargetLowering::TypeWidenVector) 3190 Mask = GetWidenedVector(Mask); 3191 else { 3192 // The mask should be widened as well 3193 EVT BoolVT = getSetCCResultType(WideVal.getValueType()); 3194 // We can't use ModifyToType() because we should fill the mask with 3195 // zeroes 3196 unsigned WidenNumElts = BoolVT.getVectorNumElements(); 3197 unsigned MaskNumElts = MaskVT.getVectorNumElements(); 3198 3199 unsigned NumConcat = WidenNumElts / MaskNumElts; 3200 SmallVector<SDValue, 16> Ops(NumConcat); 3201 SDValue ZeroVal = DAG.getConstant(0, dl, MaskVT); 3202 Ops[0] = Mask; 3203 for (unsigned i = 1; i != NumConcat; ++i) 3204 Ops[i] = ZeroVal; 3205 3206 Mask = DAG.getNode(ISD::CONCAT_VECTORS, dl, BoolVT, Ops); 3207 } 3208 assert(Mask.getValueType().getVectorNumElements() == 3209 WideVal.getValueType().getVectorNumElements() && 3210 "Mask and data vectors should have the same number of elements"); 3211 return DAG.getMaskedStore(MST->getChain(), dl, WideVal, MST->getBasePtr(), 3212 Mask, MST->getMemoryVT(), MST->getMemOperand(), 3213 false); 3214 } 3215 3216 SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(SDNode *N, unsigned OpNo) { 3217 assert(OpNo == 1 && "Can widen only data operand of mscatter"); 3218 MaskedScatterSDNode *MSC = cast<MaskedScatterSDNode>(N); 3219 SDValue DataOp = MSC->getValue(); 3220 SDValue Mask = MSC->getMask(); 3221 3222 // Widen the value 3223 SDValue WideVal = GetWidenedVector(DataOp); 3224 EVT WideVT = WideVal.getValueType(); 3225 unsigned NumElts = WideVal.getValueType().getVectorNumElements(); 3226 SDLoc dl(N); 3227 3228 // The mask should be widened as well 3229 Mask = WidenTargetBoolean(Mask, WideVT, true); 3230 3231 // Widen index 3232 SDValue Index = MSC->getIndex(); 3233 EVT WideIndexVT = EVT::getVectorVT(*DAG.getContext(), 3234 Index.getValueType().getScalarType(), 3235 NumElts); 3236 Index = ModifyToType(Index, WideIndexVT); 3237 3238 SDValue Ops[] = {MSC->getChain(), WideVal, Mask, MSC->getBasePtr(), Index}; 3239 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), 3240 MSC->getMemoryVT(), dl, Ops, 3241 MSC->getMemOperand()); 3242 } 3243 3244 SDValue DAGTypeLegalizer::WidenVecOp_SETCC(SDNode *N) { 3245 SDValue InOp0 = GetWidenedVector(N->getOperand(0)); 3246 SDValue InOp1 = GetWidenedVector(N->getOperand(1)); 3247 SDLoc dl(N); 3248 3249 // WARNING: In this code we widen the compare instruction with garbage. 3250 // This garbage may contain denormal floats which may be slow. Is this a real 3251 // concern ? Should we zero the unused lanes if this is a float compare ? 3252 3253 // Get a new SETCC node to compare the newly widened operands. 3254 // Only some of the compared elements are legal. 3255 EVT SVT = TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), 3256 InOp0.getValueType()); 3257 SDValue WideSETCC = DAG.getNode(ISD::SETCC, SDLoc(N), 3258 SVT, InOp0, InOp1, N->getOperand(2)); 3259 3260 // Extract the needed results from the result vector. 3261 EVT ResVT = EVT::getVectorVT(*DAG.getContext(), 3262 SVT.getVectorElementType(), 3263 N->getValueType(0).getVectorNumElements()); 3264 SDValue CC = DAG.getNode( 3265 ISD::EXTRACT_SUBVECTOR, dl, ResVT, WideSETCC, 3266 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 3267 3268 return PromoteTargetBoolean(CC, N->getValueType(0)); 3269 } 3270 3271 3272 //===----------------------------------------------------------------------===// 3273 // Vector Widening Utilities 3274 //===----------------------------------------------------------------------===// 3275 3276 // Utility function to find the type to chop up a widen vector for load/store 3277 // TLI: Target lowering used to determine legal types. 3278 // Width: Width left need to load/store. 3279 // WidenVT: The widen vector type to load to/store from 3280 // Align: If 0, don't allow use of a wider type 3281 // WidenEx: If Align is not 0, the amount additional we can load/store from. 3282 3283 static EVT FindMemType(SelectionDAG& DAG, const TargetLowering &TLI, 3284 unsigned Width, EVT WidenVT, 3285 unsigned Align = 0, unsigned WidenEx = 0) { 3286 EVT WidenEltVT = WidenVT.getVectorElementType(); 3287 unsigned WidenWidth = WidenVT.getSizeInBits(); 3288 unsigned WidenEltWidth = WidenEltVT.getSizeInBits(); 3289 unsigned AlignInBits = Align*8; 3290 3291 // If we have one element to load/store, return it. 3292 EVT RetVT = WidenEltVT; 3293 if (Width == WidenEltWidth) 3294 return RetVT; 3295 3296 // See if there is larger legal integer than the element type to load/store 3297 unsigned VT; 3298 for (VT = (unsigned)MVT::LAST_INTEGER_VALUETYPE; 3299 VT >= (unsigned)MVT::FIRST_INTEGER_VALUETYPE; --VT) { 3300 EVT MemVT((MVT::SimpleValueType) VT); 3301 unsigned MemVTWidth = MemVT.getSizeInBits(); 3302 if (MemVT.getSizeInBits() <= WidenEltWidth) 3303 break; 3304 auto Action = TLI.getTypeAction(*DAG.getContext(), MemVT); 3305 if ((Action == TargetLowering::TypeLegal || 3306 Action == TargetLowering::TypePromoteInteger) && 3307 (WidenWidth % MemVTWidth) == 0 && 3308 isPowerOf2_32(WidenWidth / MemVTWidth) && 3309 (MemVTWidth <= Width || 3310 (Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) { 3311 RetVT = MemVT; 3312 break; 3313 } 3314 } 3315 3316 // See if there is a larger vector type to load/store that has the same vector 3317 // element type and is evenly divisible with the WidenVT. 3318 for (VT = (unsigned)MVT::LAST_VECTOR_VALUETYPE; 3319 VT >= (unsigned)MVT::FIRST_VECTOR_VALUETYPE; --VT) { 3320 EVT MemVT = (MVT::SimpleValueType) VT; 3321 unsigned MemVTWidth = MemVT.getSizeInBits(); 3322 if (TLI.isTypeLegal(MemVT) && WidenEltVT == MemVT.getVectorElementType() && 3323 (WidenWidth % MemVTWidth) == 0 && 3324 isPowerOf2_32(WidenWidth / MemVTWidth) && 3325 (MemVTWidth <= Width || 3326 (Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) { 3327 if (RetVT.getSizeInBits() < MemVTWidth || MemVT == WidenVT) 3328 return MemVT; 3329 } 3330 } 3331 3332 return RetVT; 3333 } 3334 3335 // Builds a vector type from scalar loads 3336 // VecTy: Resulting Vector type 3337 // LDOps: Load operators to build a vector type 3338 // [Start,End) the list of loads to use. 3339 static SDValue BuildVectorFromScalar(SelectionDAG& DAG, EVT VecTy, 3340 SmallVectorImpl<SDValue> &LdOps, 3341 unsigned Start, unsigned End) { 3342 const TargetLowering &TLI = DAG.getTargetLoweringInfo(); 3343 SDLoc dl(LdOps[Start]); 3344 EVT LdTy = LdOps[Start].getValueType(); 3345 unsigned Width = VecTy.getSizeInBits(); 3346 unsigned NumElts = Width / LdTy.getSizeInBits(); 3347 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), LdTy, NumElts); 3348 3349 unsigned Idx = 1; 3350 SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT,LdOps[Start]); 3351 3352 for (unsigned i = Start + 1; i != End; ++i) { 3353 EVT NewLdTy = LdOps[i].getValueType(); 3354 if (NewLdTy != LdTy) { 3355 NumElts = Width / NewLdTy.getSizeInBits(); 3356 NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewLdTy, NumElts); 3357 VecOp = DAG.getNode(ISD::BITCAST, dl, NewVecVT, VecOp); 3358 // Readjust position and vector position based on new load type 3359 Idx = Idx * LdTy.getSizeInBits() / NewLdTy.getSizeInBits(); 3360 LdTy = NewLdTy; 3361 } 3362 VecOp = DAG.getNode( 3363 ISD::INSERT_VECTOR_ELT, dl, NewVecVT, VecOp, LdOps[i], 3364 DAG.getConstant(Idx++, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 3365 } 3366 return DAG.getNode(ISD::BITCAST, dl, VecTy, VecOp); 3367 } 3368 3369 SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain, 3370 LoadSDNode *LD) { 3371 // The strategy assumes that we can efficiently load powers of two widths. 3372 // The routines chops the vector into the largest vector loads with the same 3373 // element type or scalar loads and then recombines it to the widen vector 3374 // type. 3375 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),LD->getValueType(0)); 3376 unsigned WidenWidth = WidenVT.getSizeInBits(); 3377 EVT LdVT = LD->getMemoryVT(); 3378 SDLoc dl(LD); 3379 assert(LdVT.isVector() && WidenVT.isVector()); 3380 assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType()); 3381 3382 // Load information 3383 SDValue Chain = LD->getChain(); 3384 SDValue BasePtr = LD->getBasePtr(); 3385 unsigned Align = LD->getAlignment(); 3386 bool isVolatile = LD->isVolatile(); 3387 bool isNonTemporal = LD->isNonTemporal(); 3388 bool isInvariant = LD->isInvariant(); 3389 AAMDNodes AAInfo = LD->getAAInfo(); 3390 3391 int LdWidth = LdVT.getSizeInBits(); 3392 int WidthDiff = WidenWidth - LdWidth; // Difference 3393 unsigned LdAlign = (isVolatile) ? 0 : Align; // Allow wider loads 3394 3395 // Find the vector type that can load from. 3396 EVT NewVT = FindMemType(DAG, TLI, LdWidth, WidenVT, LdAlign, WidthDiff); 3397 int NewVTWidth = NewVT.getSizeInBits(); 3398 SDValue LdOp = DAG.getLoad(NewVT, dl, Chain, BasePtr, LD->getPointerInfo(), 3399 isVolatile, isNonTemporal, isInvariant, Align, 3400 AAInfo); 3401 LdChain.push_back(LdOp.getValue(1)); 3402 3403 // Check if we can load the element with one instruction 3404 if (LdWidth <= NewVTWidth) { 3405 if (!NewVT.isVector()) { 3406 unsigned NumElts = WidenWidth / NewVTWidth; 3407 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NumElts); 3408 SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp); 3409 return DAG.getNode(ISD::BITCAST, dl, WidenVT, VecOp); 3410 } 3411 if (NewVT == WidenVT) 3412 return LdOp; 3413 3414 assert(WidenWidth % NewVTWidth == 0); 3415 unsigned NumConcat = WidenWidth / NewVTWidth; 3416 SmallVector<SDValue, 16> ConcatOps(NumConcat); 3417 SDValue UndefVal = DAG.getUNDEF(NewVT); 3418 ConcatOps[0] = LdOp; 3419 for (unsigned i = 1; i != NumConcat; ++i) 3420 ConcatOps[i] = UndefVal; 3421 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, ConcatOps); 3422 } 3423 3424 // Load vector by using multiple loads from largest vector to scalar 3425 SmallVector<SDValue, 16> LdOps; 3426 LdOps.push_back(LdOp); 3427 3428 LdWidth -= NewVTWidth; 3429 unsigned Offset = 0; 3430 3431 while (LdWidth > 0) { 3432 unsigned Increment = NewVTWidth / 8; 3433 Offset += Increment; 3434 BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, 3435 DAG.getConstant(Increment, dl, BasePtr.getValueType())); 3436 3437 SDValue L; 3438 if (LdWidth < NewVTWidth) { 3439 // Our current type we are using is too large, find a better size 3440 NewVT = FindMemType(DAG, TLI, LdWidth, WidenVT, LdAlign, WidthDiff); 3441 NewVTWidth = NewVT.getSizeInBits(); 3442 L = DAG.getLoad(NewVT, dl, Chain, BasePtr, 3443 LD->getPointerInfo().getWithOffset(Offset), isVolatile, 3444 isNonTemporal, isInvariant, MinAlign(Align, Increment), 3445 AAInfo); 3446 LdChain.push_back(L.getValue(1)); 3447 if (L->getValueType(0).isVector()) { 3448 SmallVector<SDValue, 16> Loads; 3449 Loads.push_back(L); 3450 unsigned size = L->getValueSizeInBits(0); 3451 while (size < LdOp->getValueSizeInBits(0)) { 3452 Loads.push_back(DAG.getUNDEF(L->getValueType(0))); 3453 size += L->getValueSizeInBits(0); 3454 } 3455 L = DAG.getNode(ISD::CONCAT_VECTORS, dl, LdOp->getValueType(0), Loads); 3456 } 3457 } else { 3458 L = DAG.getLoad(NewVT, dl, Chain, BasePtr, 3459 LD->getPointerInfo().getWithOffset(Offset), isVolatile, 3460 isNonTemporal, isInvariant, MinAlign(Align, Increment), 3461 AAInfo); 3462 LdChain.push_back(L.getValue(1)); 3463 } 3464 3465 LdOps.push_back(L); 3466 3467 3468 LdWidth -= NewVTWidth; 3469 } 3470 3471 // Build the vector from the loads operations 3472 unsigned End = LdOps.size(); 3473 if (!LdOps[0].getValueType().isVector()) 3474 // All the loads are scalar loads. 3475 return BuildVectorFromScalar(DAG, WidenVT, LdOps, 0, End); 3476 3477 // If the load contains vectors, build the vector using concat vector. 3478 // All of the vectors used to loads are power of 2 and the scalars load 3479 // can be combined to make a power of 2 vector. 3480 SmallVector<SDValue, 16> ConcatOps(End); 3481 int i = End - 1; 3482 int Idx = End; 3483 EVT LdTy = LdOps[i].getValueType(); 3484 // First combine the scalar loads to a vector 3485 if (!LdTy.isVector()) { 3486 for (--i; i >= 0; --i) { 3487 LdTy = LdOps[i].getValueType(); 3488 if (LdTy.isVector()) 3489 break; 3490 } 3491 ConcatOps[--Idx] = BuildVectorFromScalar(DAG, LdTy, LdOps, i+1, End); 3492 } 3493 ConcatOps[--Idx] = LdOps[i]; 3494 for (--i; i >= 0; --i) { 3495 EVT NewLdTy = LdOps[i].getValueType(); 3496 if (NewLdTy != LdTy) { 3497 // Create a larger vector 3498 ConcatOps[End-1] = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewLdTy, 3499 makeArrayRef(&ConcatOps[Idx], End - Idx)); 3500 Idx = End - 1; 3501 LdTy = NewLdTy; 3502 } 3503 ConcatOps[--Idx] = LdOps[i]; 3504 } 3505 3506 if (WidenWidth == LdTy.getSizeInBits()*(End - Idx)) 3507 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, 3508 makeArrayRef(&ConcatOps[Idx], End - Idx)); 3509 3510 // We need to fill the rest with undefs to build the vector 3511 unsigned NumOps = WidenWidth / LdTy.getSizeInBits(); 3512 SmallVector<SDValue, 16> WidenOps(NumOps); 3513 SDValue UndefVal = DAG.getUNDEF(LdTy); 3514 { 3515 unsigned i = 0; 3516 for (; i != End-Idx; ++i) 3517 WidenOps[i] = ConcatOps[Idx+i]; 3518 for (; i != NumOps; ++i) 3519 WidenOps[i] = UndefVal; 3520 } 3521 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, WidenOps); 3522 } 3523 3524 SDValue 3525 DAGTypeLegalizer::GenWidenVectorExtLoads(SmallVectorImpl<SDValue> &LdChain, 3526 LoadSDNode *LD, 3527 ISD::LoadExtType ExtType) { 3528 // For extension loads, it may not be more efficient to chop up the vector 3529 // and then extended it. Instead, we unroll the load and build a new vector. 3530 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),LD->getValueType(0)); 3531 EVT LdVT = LD->getMemoryVT(); 3532 SDLoc dl(LD); 3533 assert(LdVT.isVector() && WidenVT.isVector()); 3534 3535 // Load information 3536 SDValue Chain = LD->getChain(); 3537 SDValue BasePtr = LD->getBasePtr(); 3538 unsigned Align = LD->getAlignment(); 3539 bool isVolatile = LD->isVolatile(); 3540 bool isNonTemporal = LD->isNonTemporal(); 3541 bool isInvariant = LD->isInvariant(); 3542 AAMDNodes AAInfo = LD->getAAInfo(); 3543 3544 EVT EltVT = WidenVT.getVectorElementType(); 3545 EVT LdEltVT = LdVT.getVectorElementType(); 3546 unsigned NumElts = LdVT.getVectorNumElements(); 3547 3548 // Load each element and widen 3549 unsigned WidenNumElts = WidenVT.getVectorNumElements(); 3550 SmallVector<SDValue, 16> Ops(WidenNumElts); 3551 unsigned Increment = LdEltVT.getSizeInBits() / 8; 3552 Ops[0] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr, 3553 LD->getPointerInfo(), 3554 LdEltVT, isVolatile, isNonTemporal, isInvariant, 3555 Align, AAInfo); 3556 LdChain.push_back(Ops[0].getValue(1)); 3557 unsigned i = 0, Offset = Increment; 3558 for (i=1; i < NumElts; ++i, Offset += Increment) { 3559 SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), 3560 BasePtr, 3561 DAG.getConstant(Offset, dl, 3562 BasePtr.getValueType())); 3563 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr, 3564 LD->getPointerInfo().getWithOffset(Offset), LdEltVT, 3565 isVolatile, isNonTemporal, isInvariant, Align, 3566 AAInfo); 3567 LdChain.push_back(Ops[i].getValue(1)); 3568 } 3569 3570 // Fill the rest with undefs 3571 SDValue UndefVal = DAG.getUNDEF(EltVT); 3572 for (; i != WidenNumElts; ++i) 3573 Ops[i] = UndefVal; 3574 3575 return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, Ops); 3576 } 3577 3578 3579 void DAGTypeLegalizer::GenWidenVectorStores(SmallVectorImpl<SDValue> &StChain, 3580 StoreSDNode *ST) { 3581 // The strategy assumes that we can efficiently store powers of two widths. 3582 // The routines chops the vector into the largest vector stores with the same 3583 // element type or scalar stores. 3584 SDValue Chain = ST->getChain(); 3585 SDValue BasePtr = ST->getBasePtr(); 3586 unsigned Align = ST->getAlignment(); 3587 bool isVolatile = ST->isVolatile(); 3588 bool isNonTemporal = ST->isNonTemporal(); 3589 AAMDNodes AAInfo = ST->getAAInfo(); 3590 SDValue ValOp = GetWidenedVector(ST->getValue()); 3591 SDLoc dl(ST); 3592 3593 EVT StVT = ST->getMemoryVT(); 3594 unsigned StWidth = StVT.getSizeInBits(); 3595 EVT ValVT = ValOp.getValueType(); 3596 unsigned ValWidth = ValVT.getSizeInBits(); 3597 EVT ValEltVT = ValVT.getVectorElementType(); 3598 unsigned ValEltWidth = ValEltVT.getSizeInBits(); 3599 assert(StVT.getVectorElementType() == ValEltVT); 3600 3601 int Idx = 0; // current index to store 3602 unsigned Offset = 0; // offset from base to store 3603 while (StWidth != 0) { 3604 // Find the largest vector type we can store with 3605 EVT NewVT = FindMemType(DAG, TLI, StWidth, ValVT); 3606 unsigned NewVTWidth = NewVT.getSizeInBits(); 3607 unsigned Increment = NewVTWidth / 8; 3608 if (NewVT.isVector()) { 3609 unsigned NumVTElts = NewVT.getVectorNumElements(); 3610 do { 3611 SDValue EOp = DAG.getNode( 3612 ISD::EXTRACT_SUBVECTOR, dl, NewVT, ValOp, 3613 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 3614 StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, 3615 ST->getPointerInfo().getWithOffset(Offset), 3616 isVolatile, isNonTemporal, 3617 MinAlign(Align, Offset), AAInfo)); 3618 StWidth -= NewVTWidth; 3619 Offset += Increment; 3620 Idx += NumVTElts; 3621 BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, 3622 DAG.getConstant(Increment, dl, 3623 BasePtr.getValueType())); 3624 } while (StWidth != 0 && StWidth >= NewVTWidth); 3625 } else { 3626 // Cast the vector to the scalar type we can store 3627 unsigned NumElts = ValWidth / NewVTWidth; 3628 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NumElts); 3629 SDValue VecOp = DAG.getNode(ISD::BITCAST, dl, NewVecVT, ValOp); 3630 // Readjust index position based on new vector type 3631 Idx = Idx * ValEltWidth / NewVTWidth; 3632 do { 3633 SDValue EOp = DAG.getNode( 3634 ISD::EXTRACT_VECTOR_ELT, dl, NewVT, VecOp, 3635 DAG.getConstant(Idx++, dl, 3636 TLI.getVectorIdxTy(DAG.getDataLayout()))); 3637 StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, 3638 ST->getPointerInfo().getWithOffset(Offset), 3639 isVolatile, isNonTemporal, 3640 MinAlign(Align, Offset), AAInfo)); 3641 StWidth -= NewVTWidth; 3642 Offset += Increment; 3643 BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, 3644 DAG.getConstant(Increment, dl, 3645 BasePtr.getValueType())); 3646 } while (StWidth != 0 && StWidth >= NewVTWidth); 3647 // Restore index back to be relative to the original widen element type 3648 Idx = Idx * NewVTWidth / ValEltWidth; 3649 } 3650 } 3651 } 3652 3653 void 3654 DAGTypeLegalizer::GenWidenVectorTruncStores(SmallVectorImpl<SDValue> &StChain, 3655 StoreSDNode *ST) { 3656 // For extension loads, it may not be more efficient to truncate the vector 3657 // and then store it. Instead, we extract each element and then store it. 3658 SDValue Chain = ST->getChain(); 3659 SDValue BasePtr = ST->getBasePtr(); 3660 unsigned Align = ST->getAlignment(); 3661 bool isVolatile = ST->isVolatile(); 3662 bool isNonTemporal = ST->isNonTemporal(); 3663 AAMDNodes AAInfo = ST->getAAInfo(); 3664 SDValue ValOp = GetWidenedVector(ST->getValue()); 3665 SDLoc dl(ST); 3666 3667 EVT StVT = ST->getMemoryVT(); 3668 EVT ValVT = ValOp.getValueType(); 3669 3670 // It must be true that we the widen vector type is bigger than where 3671 // we need to store. 3672 assert(StVT.isVector() && ValOp.getValueType().isVector()); 3673 assert(StVT.bitsLT(ValOp.getValueType())); 3674 3675 // For truncating stores, we can not play the tricks of chopping legal 3676 // vector types and bit cast it to the right type. Instead, we unroll 3677 // the store. 3678 EVT StEltVT = StVT.getVectorElementType(); 3679 EVT ValEltVT = ValVT.getVectorElementType(); 3680 unsigned Increment = ValEltVT.getSizeInBits() / 8; 3681 unsigned NumElts = StVT.getVectorNumElements(); 3682 SDValue EOp = DAG.getNode( 3683 ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp, 3684 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 3685 StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, BasePtr, 3686 ST->getPointerInfo(), StEltVT, 3687 isVolatile, isNonTemporal, Align, 3688 AAInfo)); 3689 unsigned Offset = Increment; 3690 for (unsigned i=1; i < NumElts; ++i, Offset += Increment) { 3691 SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), 3692 BasePtr, 3693 DAG.getConstant(Offset, dl, 3694 BasePtr.getValueType())); 3695 SDValue EOp = DAG.getNode( 3696 ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp, 3697 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 3698 StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, NewBasePtr, 3699 ST->getPointerInfo().getWithOffset(Offset), 3700 StEltVT, isVolatile, isNonTemporal, 3701 MinAlign(Align, Offset), AAInfo)); 3702 } 3703 } 3704 3705 /// Modifies a vector input (widen or narrows) to a vector of NVT. The 3706 /// input vector must have the same element type as NVT. 3707 /// FillWithZeroes specifies that the vector should be widened with zeroes. 3708 SDValue DAGTypeLegalizer::ModifyToType(SDValue InOp, EVT NVT, 3709 bool FillWithZeroes) { 3710 // Note that InOp might have been widened so it might already have 3711 // the right width or it might need be narrowed. 3712 EVT InVT = InOp.getValueType(); 3713 assert(InVT.getVectorElementType() == NVT.getVectorElementType() && 3714 "input and widen element type must match"); 3715 SDLoc dl(InOp); 3716 3717 // Check if InOp already has the right width. 3718 if (InVT == NVT) 3719 return InOp; 3720 3721 unsigned InNumElts = InVT.getVectorNumElements(); 3722 unsigned WidenNumElts = NVT.getVectorNumElements(); 3723 if (WidenNumElts > InNumElts && WidenNumElts % InNumElts == 0) { 3724 unsigned NumConcat = WidenNumElts / InNumElts; 3725 SmallVector<SDValue, 16> Ops(NumConcat); 3726 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, InVT) : 3727 DAG.getUNDEF(InVT); 3728 Ops[0] = InOp; 3729 for (unsigned i = 1; i != NumConcat; ++i) 3730 Ops[i] = FillVal; 3731 3732 return DAG.getNode(ISD::CONCAT_VECTORS, dl, NVT, Ops); 3733 } 3734 3735 if (WidenNumElts < InNumElts && InNumElts % WidenNumElts) 3736 return DAG.getNode( 3737 ISD::EXTRACT_SUBVECTOR, dl, NVT, InOp, 3738 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 3739 3740 // Fall back to extract and build. 3741 SmallVector<SDValue, 16> Ops(WidenNumElts); 3742 EVT EltVT = NVT.getVectorElementType(); 3743 unsigned MinNumElts = std::min(WidenNumElts, InNumElts); 3744 unsigned Idx; 3745 for (Idx = 0; Idx < MinNumElts; ++Idx) 3746 Ops[Idx] = DAG.getNode( 3747 ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, 3748 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))); 3749 3750 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, EltVT) : 3751 DAG.getUNDEF(EltVT); 3752 for ( ; Idx < WidenNumElts; ++Idx) 3753 Ops[Idx] = FillVal; 3754 return DAG.getNode(ISD::BUILD_VECTOR, dl, NVT, Ops); 3755 } 3756