[InstCombine] Signed saturation patterns
[llvm-complete.git] / lib / CodeGen / SelectionDAG / LegalizeVectorTypes.cpp
blob3763e886cef29c182a3125ecf2090ec360fcd8a3
1 //===------- LegalizeVectorTypes.cpp - Legalization of vector types -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file performs vector type splitting and scalarization for LegalizeTypes.
10 // Scalarization is the act of changing a computation in an illegal one-element
11 // vector type to be a computation in its scalar element type. For example,
12 // implementing <1 x f32> arithmetic in a scalar f32 register. This is needed
13 // as a base case when scalarizing vector arithmetic like <4 x f32>, which
14 // eventually decomposes to scalars if the target doesn't support v4f32 or v2f32
15 // types.
16 // Splitting is the act of changing a computation in an invalid vector type to
17 // be a computation in two vectors of half the size. For example, implementing
18 // <128 x f32> operations in terms of two <64 x f32> operations.
20 //===----------------------------------------------------------------------===//
22 #include "LegalizeTypes.h"
23 #include "llvm/IR/DataLayout.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/raw_ostream.h"
26 using namespace llvm;
28 #define DEBUG_TYPE "legalize-types"
30 //===----------------------------------------------------------------------===//
31 // Result Vector Scalarization: <1 x ty> -> ty.
32 //===----------------------------------------------------------------------===//
34 void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
35 LLVM_DEBUG(dbgs() << "Scalarize node result " << ResNo << ": "; N->dump(&DAG);
36 dbgs() << "\n");
37 SDValue R = SDValue();
39 switch (N->getOpcode()) {
40 default:
41 #ifndef NDEBUG
42 dbgs() << "ScalarizeVectorResult #" << ResNo << ": ";
43 N->dump(&DAG);
44 dbgs() << "\n";
45 #endif
46 report_fatal_error("Do not know how to scalarize the result of this "
47 "operator!\n");
49 case ISD::MERGE_VALUES: R = ScalarizeVecRes_MERGE_VALUES(N, ResNo);break;
50 case ISD::BITCAST: R = ScalarizeVecRes_BITCAST(N); break;
51 case ISD::BUILD_VECTOR: R = ScalarizeVecRes_BUILD_VECTOR(N); break;
52 case ISD::EXTRACT_SUBVECTOR: R = ScalarizeVecRes_EXTRACT_SUBVECTOR(N); break;
53 case ISD::STRICT_FP_ROUND: R = ScalarizeVecRes_STRICT_FP_ROUND(N); break;
54 case ISD::FP_ROUND: R = ScalarizeVecRes_FP_ROUND(N); break;
55 case ISD::FPOWI: R = ScalarizeVecRes_FPOWI(N); break;
56 case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break;
57 case ISD::LOAD: R = ScalarizeVecRes_LOAD(cast<LoadSDNode>(N));break;
58 case ISD::SCALAR_TO_VECTOR: R = ScalarizeVecRes_SCALAR_TO_VECTOR(N); break;
59 case ISD::SIGN_EXTEND_INREG: R = ScalarizeVecRes_InregOp(N); break;
60 case ISD::VSELECT: R = ScalarizeVecRes_VSELECT(N); break;
61 case ISD::SELECT: R = ScalarizeVecRes_SELECT(N); break;
62 case ISD::SELECT_CC: R = ScalarizeVecRes_SELECT_CC(N); break;
63 case ISD::SETCC: R = ScalarizeVecRes_SETCC(N); break;
64 case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(N); break;
65 case ISD::VECTOR_SHUFFLE: R = ScalarizeVecRes_VECTOR_SHUFFLE(N); break;
66 case ISD::ANY_EXTEND_VECTOR_INREG:
67 case ISD::SIGN_EXTEND_VECTOR_INREG:
68 case ISD::ZERO_EXTEND_VECTOR_INREG:
69 R = ScalarizeVecRes_VecInregOp(N);
70 break;
71 case ISD::ABS:
72 case ISD::ANY_EXTEND:
73 case ISD::BITREVERSE:
74 case ISD::BSWAP:
75 case ISD::CTLZ:
76 case ISD::CTLZ_ZERO_UNDEF:
77 case ISD::CTPOP:
78 case ISD::CTTZ:
79 case ISD::CTTZ_ZERO_UNDEF:
80 case ISD::FABS:
81 case ISD::FCEIL:
82 case ISD::FCOS:
83 case ISD::FEXP:
84 case ISD::FEXP2:
85 case ISD::FFLOOR:
86 case ISD::FLOG:
87 case ISD::FLOG10:
88 case ISD::FLOG2:
89 case ISD::FNEARBYINT:
90 case ISD::FNEG:
91 case ISD::FP_EXTEND:
92 case ISD::FP_TO_SINT:
93 case ISD::FP_TO_UINT:
94 case ISD::FRINT:
95 case ISD::FROUND:
96 case ISD::FSIN:
97 case ISD::FSQRT:
98 case ISD::FTRUNC:
99 case ISD::SIGN_EXTEND:
100 case ISD::SINT_TO_FP:
101 case ISD::TRUNCATE:
102 case ISD::UINT_TO_FP:
103 case ISD::ZERO_EXTEND:
104 case ISD::FCANONICALIZE:
105 R = ScalarizeVecRes_UnaryOp(N);
106 break;
108 case ISD::ADD:
109 case ISD::AND:
110 case ISD::FADD:
111 case ISD::FCOPYSIGN:
112 case ISD::FDIV:
113 case ISD::FMUL:
114 case ISD::FMINNUM:
115 case ISD::FMAXNUM:
116 case ISD::FMINNUM_IEEE:
117 case ISD::FMAXNUM_IEEE:
118 case ISD::FMINIMUM:
119 case ISD::FMAXIMUM:
120 case ISD::SMIN:
121 case ISD::SMAX:
122 case ISD::UMIN:
123 case ISD::UMAX:
125 case ISD::SADDSAT:
126 case ISD::UADDSAT:
127 case ISD::SSUBSAT:
128 case ISD::USUBSAT:
130 case ISD::FPOW:
131 case ISD::FREM:
132 case ISD::FSUB:
133 case ISD::MUL:
134 case ISD::OR:
135 case ISD::SDIV:
136 case ISD::SREM:
137 case ISD::SUB:
138 case ISD::UDIV:
139 case ISD::UREM:
140 case ISD::XOR:
141 case ISD::SHL:
142 case ISD::SRA:
143 case ISD::SRL:
144 R = ScalarizeVecRes_BinOp(N);
145 break;
146 case ISD::FMA:
147 R = ScalarizeVecRes_TernaryOp(N);
148 break;
149 case ISD::STRICT_FADD:
150 case ISD::STRICT_FSUB:
151 case ISD::STRICT_FMUL:
152 case ISD::STRICT_FDIV:
153 case ISD::STRICT_FREM:
154 case ISD::STRICT_FSQRT:
155 case ISD::STRICT_FMA:
156 case ISD::STRICT_FPOW:
157 case ISD::STRICT_FPOWI:
158 case ISD::STRICT_FSIN:
159 case ISD::STRICT_FCOS:
160 case ISD::STRICT_FEXP:
161 case ISD::STRICT_FEXP2:
162 case ISD::STRICT_FLOG:
163 case ISD::STRICT_FLOG10:
164 case ISD::STRICT_FLOG2:
165 case ISD::STRICT_FRINT:
166 case ISD::STRICT_FNEARBYINT:
167 case ISD::STRICT_FMAXNUM:
168 case ISD::STRICT_FMINNUM:
169 case ISD::STRICT_FCEIL:
170 case ISD::STRICT_FFLOOR:
171 case ISD::STRICT_FROUND:
172 case ISD::STRICT_FTRUNC:
173 case ISD::STRICT_FP_TO_SINT:
174 case ISD::STRICT_FP_TO_UINT:
175 case ISD::STRICT_FP_EXTEND:
176 R = ScalarizeVecRes_StrictFPOp(N);
177 break;
178 case ISD::UADDO:
179 case ISD::SADDO:
180 case ISD::USUBO:
181 case ISD::SSUBO:
182 case ISD::UMULO:
183 case ISD::SMULO:
184 R = ScalarizeVecRes_OverflowOp(N, ResNo);
185 break;
186 case ISD::SMULFIX:
187 case ISD::SMULFIXSAT:
188 case ISD::UMULFIX:
189 case ISD::UMULFIXSAT:
190 R = ScalarizeVecRes_MULFIX(N);
191 break;
194 // If R is null, the sub-method took care of registering the result.
195 if (R.getNode())
196 SetScalarizedVector(SDValue(N, ResNo), R);
199 SDValue DAGTypeLegalizer::ScalarizeVecRes_BinOp(SDNode *N) {
200 SDValue LHS = GetScalarizedVector(N->getOperand(0));
201 SDValue RHS = GetScalarizedVector(N->getOperand(1));
202 return DAG.getNode(N->getOpcode(), SDLoc(N),
203 LHS.getValueType(), LHS, RHS, N->getFlags());
206 SDValue DAGTypeLegalizer::ScalarizeVecRes_TernaryOp(SDNode *N) {
207 SDValue Op0 = GetScalarizedVector(N->getOperand(0));
208 SDValue Op1 = GetScalarizedVector(N->getOperand(1));
209 SDValue Op2 = GetScalarizedVector(N->getOperand(2));
210 return DAG.getNode(N->getOpcode(), SDLoc(N),
211 Op0.getValueType(), Op0, Op1, Op2);
214 SDValue DAGTypeLegalizer::ScalarizeVecRes_MULFIX(SDNode *N) {
215 SDValue Op0 = GetScalarizedVector(N->getOperand(0));
216 SDValue Op1 = GetScalarizedVector(N->getOperand(1));
217 SDValue Op2 = N->getOperand(2);
218 return DAG.getNode(N->getOpcode(), SDLoc(N), Op0.getValueType(), Op0, Op1,
219 Op2);
222 SDValue DAGTypeLegalizer::ScalarizeVecRes_StrictFPOp(SDNode *N) {
223 EVT VT = N->getValueType(0).getVectorElementType();
224 unsigned NumOpers = N->getNumOperands();
225 SDValue Chain = N->getOperand(0);
226 EVT ValueVTs[] = {VT, MVT::Other};
227 SDLoc dl(N);
229 SmallVector<SDValue, 4> Opers;
231 // The Chain is the first operand.
232 Opers.push_back(Chain);
234 // Now process the remaining operands.
235 for (unsigned i = 1; i < NumOpers; ++i) {
236 SDValue Oper = N->getOperand(i);
238 if (Oper.getValueType().isVector())
239 Oper = GetScalarizedVector(Oper);
241 Opers.push_back(Oper);
244 SDValue Result = DAG.getNode(N->getOpcode(), dl, ValueVTs, Opers);
246 // Legalize the chain result - switch anything that used the old chain to
247 // use the new one.
248 ReplaceValueWith(SDValue(N, 1), Result.getValue(1));
249 return Result;
252 SDValue DAGTypeLegalizer::ScalarizeVecRes_OverflowOp(SDNode *N,
253 unsigned ResNo) {
254 SDLoc DL(N);
255 EVT ResVT = N->getValueType(0);
256 EVT OvVT = N->getValueType(1);
258 SDValue ScalarLHS, ScalarRHS;
259 if (getTypeAction(ResVT) == TargetLowering::TypeScalarizeVector) {
260 ScalarLHS = GetScalarizedVector(N->getOperand(0));
261 ScalarRHS = GetScalarizedVector(N->getOperand(1));
262 } else {
263 SmallVector<SDValue, 1> ElemsLHS, ElemsRHS;
264 DAG.ExtractVectorElements(N->getOperand(0), ElemsLHS);
265 DAG.ExtractVectorElements(N->getOperand(1), ElemsRHS);
266 ScalarLHS = ElemsLHS[0];
267 ScalarRHS = ElemsRHS[0];
270 SDVTList ScalarVTs = DAG.getVTList(
271 ResVT.getVectorElementType(), OvVT.getVectorElementType());
272 SDNode *ScalarNode = DAG.getNode(
273 N->getOpcode(), DL, ScalarVTs, ScalarLHS, ScalarRHS).getNode();
275 // Replace the other vector result not being explicitly scalarized here.
276 unsigned OtherNo = 1 - ResNo;
277 EVT OtherVT = N->getValueType(OtherNo);
278 if (getTypeAction(OtherVT) == TargetLowering::TypeScalarizeVector) {
279 SetScalarizedVector(SDValue(N, OtherNo), SDValue(ScalarNode, OtherNo));
280 } else {
281 SDValue OtherVal = DAG.getNode(
282 ISD::SCALAR_TO_VECTOR, DL, OtherVT, SDValue(ScalarNode, OtherNo));
283 ReplaceValueWith(SDValue(N, OtherNo), OtherVal);
286 return SDValue(ScalarNode, ResNo);
289 SDValue DAGTypeLegalizer::ScalarizeVecRes_MERGE_VALUES(SDNode *N,
290 unsigned ResNo) {
291 SDValue Op = DisintegrateMERGE_VALUES(N, ResNo);
292 return GetScalarizedVector(Op);
295 SDValue DAGTypeLegalizer::ScalarizeVecRes_BITCAST(SDNode *N) {
296 SDValue Op = N->getOperand(0);
297 if (Op.getValueType().isVector()
298 && Op.getValueType().getVectorNumElements() == 1
299 && !isSimpleLegalType(Op.getValueType()))
300 Op = GetScalarizedVector(Op);
301 EVT NewVT = N->getValueType(0).getVectorElementType();
302 return DAG.getNode(ISD::BITCAST, SDLoc(N),
303 NewVT, Op);
306 SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(SDNode *N) {
307 EVT EltVT = N->getValueType(0).getVectorElementType();
308 SDValue InOp = N->getOperand(0);
309 // The BUILD_VECTOR operands may be of wider element types and
310 // we may need to truncate them back to the requested return type.
311 if (EltVT.isInteger())
312 return DAG.getNode(ISD::TRUNCATE, SDLoc(N), EltVT, InOp);
313 return InOp;
316 SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N) {
317 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N),
318 N->getValueType(0).getVectorElementType(),
319 N->getOperand(0), N->getOperand(1));
322 SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_ROUND(SDNode *N) {
323 EVT NewVT = N->getValueType(0).getVectorElementType();
324 SDValue Op = GetScalarizedVector(N->getOperand(0));
325 return DAG.getNode(ISD::FP_ROUND, SDLoc(N),
326 NewVT, Op, N->getOperand(1));
329 SDValue DAGTypeLegalizer::ScalarizeVecRes_STRICT_FP_ROUND(SDNode *N) {
330 EVT NewVT = N->getValueType(0).getVectorElementType();
331 SDValue Op = GetScalarizedVector(N->getOperand(1));
332 SDValue Res = DAG.getNode(ISD::STRICT_FP_ROUND, SDLoc(N),
333 { NewVT, MVT::Other },
334 { N->getOperand(0), Op, N->getOperand(2) });
335 // Legalize the chain result - switch anything that used the old chain to
336 // use the new one.
337 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
338 return Res;
341 SDValue DAGTypeLegalizer::ScalarizeVecRes_FPOWI(SDNode *N) {
342 SDValue Op = GetScalarizedVector(N->getOperand(0));
343 return DAG.getNode(ISD::FPOWI, SDLoc(N),
344 Op.getValueType(), Op, N->getOperand(1));
347 SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N) {
348 // The value to insert may have a wider type than the vector element type,
349 // so be sure to truncate it to the element type if necessary.
350 SDValue Op = N->getOperand(1);
351 EVT EltVT = N->getValueType(0).getVectorElementType();
352 if (Op.getValueType() != EltVT)
353 // FIXME: Can this happen for floating point types?
354 Op = DAG.getNode(ISD::TRUNCATE, SDLoc(N), EltVT, Op);
355 return Op;
358 SDValue DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) {
359 assert(N->isUnindexed() && "Indexed vector load?");
361 SDValue Result = DAG.getLoad(
362 ISD::UNINDEXED, N->getExtensionType(),
363 N->getValueType(0).getVectorElementType(), SDLoc(N), N->getChain(),
364 N->getBasePtr(), DAG.getUNDEF(N->getBasePtr().getValueType()),
365 N->getPointerInfo(), N->getMemoryVT().getVectorElementType(),
366 N->getOriginalAlignment(), N->getMemOperand()->getFlags(),
367 N->getAAInfo());
369 // Legalize the chain result - switch anything that used the old chain to
370 // use the new one.
371 ReplaceValueWith(SDValue(N, 1), Result.getValue(1));
372 return Result;
375 SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(SDNode *N) {
376 // Get the dest type - it doesn't always match the input type, e.g. int_to_fp.
377 EVT DestVT = N->getValueType(0).getVectorElementType();
378 SDValue Op = N->getOperand(0);
379 EVT OpVT = Op.getValueType();
380 SDLoc DL(N);
381 // The result needs scalarizing, but it's not a given that the source does.
382 // This is a workaround for targets where it's impossible to scalarize the
383 // result of a conversion, because the source type is legal.
384 // For instance, this happens on AArch64: v1i1 is illegal but v1i{8,16,32}
385 // are widened to v8i8, v4i16, and v2i32, which is legal, because v1i64 is
386 // legal and was not scalarized.
387 // See the similar logic in ScalarizeVecRes_SETCC
388 if (getTypeAction(OpVT) == TargetLowering::TypeScalarizeVector) {
389 Op = GetScalarizedVector(Op);
390 } else {
391 EVT VT = OpVT.getVectorElementType();
392 Op = DAG.getNode(
393 ISD::EXTRACT_VECTOR_ELT, DL, VT, Op,
394 DAG.getConstant(0, DL, TLI.getVectorIdxTy(DAG.getDataLayout())));
396 return DAG.getNode(N->getOpcode(), SDLoc(N), DestVT, Op);
399 SDValue DAGTypeLegalizer::ScalarizeVecRes_InregOp(SDNode *N) {
400 EVT EltVT = N->getValueType(0).getVectorElementType();
401 EVT ExtVT = cast<VTSDNode>(N->getOperand(1))->getVT().getVectorElementType();
402 SDValue LHS = GetScalarizedVector(N->getOperand(0));
403 return DAG.getNode(N->getOpcode(), SDLoc(N), EltVT,
404 LHS, DAG.getValueType(ExtVT));
407 SDValue DAGTypeLegalizer::ScalarizeVecRes_VecInregOp(SDNode *N) {
408 SDLoc DL(N);
409 SDValue Op = N->getOperand(0);
411 EVT OpVT = Op.getValueType();
412 EVT OpEltVT = OpVT.getVectorElementType();
413 EVT EltVT = N->getValueType(0).getVectorElementType();
415 if (getTypeAction(OpVT) == TargetLowering::TypeScalarizeVector) {
416 Op = GetScalarizedVector(Op);
417 } else {
418 Op = DAG.getNode(
419 ISD::EXTRACT_VECTOR_ELT, DL, OpEltVT, Op,
420 DAG.getConstant(0, DL, TLI.getVectorIdxTy(DAG.getDataLayout())));
423 switch (N->getOpcode()) {
424 case ISD::ANY_EXTEND_VECTOR_INREG:
425 return DAG.getNode(ISD::ANY_EXTEND, DL, EltVT, Op);
426 case ISD::SIGN_EXTEND_VECTOR_INREG:
427 return DAG.getNode(ISD::SIGN_EXTEND, DL, EltVT, Op);
428 case ISD::ZERO_EXTEND_VECTOR_INREG:
429 return DAG.getNode(ISD::ZERO_EXTEND, DL, EltVT, Op);
432 llvm_unreachable("Illegal extend_vector_inreg opcode");
435 SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N) {
436 // If the operand is wider than the vector element type then it is implicitly
437 // truncated. Make that explicit here.
438 EVT EltVT = N->getValueType(0).getVectorElementType();
439 SDValue InOp = N->getOperand(0);
440 if (InOp.getValueType() != EltVT)
441 return DAG.getNode(ISD::TRUNCATE, SDLoc(N), EltVT, InOp);
442 return InOp;
445 SDValue DAGTypeLegalizer::ScalarizeVecRes_VSELECT(SDNode *N) {
446 SDValue Cond = N->getOperand(0);
447 EVT OpVT = Cond.getValueType();
448 SDLoc DL(N);
449 // The vselect result and true/value operands needs scalarizing, but it's
450 // not a given that the Cond does. For instance, in AVX512 v1i1 is legal.
451 // See the similar logic in ScalarizeVecRes_SETCC
452 if (getTypeAction(OpVT) == TargetLowering::TypeScalarizeVector) {
453 Cond = GetScalarizedVector(Cond);
454 } else {
455 EVT VT = OpVT.getVectorElementType();
456 Cond = DAG.getNode(
457 ISD::EXTRACT_VECTOR_ELT, DL, VT, Cond,
458 DAG.getConstant(0, DL, TLI.getVectorIdxTy(DAG.getDataLayout())));
461 SDValue LHS = GetScalarizedVector(N->getOperand(1));
462 TargetLowering::BooleanContent ScalarBool =
463 TLI.getBooleanContents(false, false);
464 TargetLowering::BooleanContent VecBool = TLI.getBooleanContents(true, false);
466 // If integer and float booleans have different contents then we can't
467 // reliably optimize in all cases. There is a full explanation for this in
468 // DAGCombiner::visitSELECT() where the same issue affects folding
469 // (select C, 0, 1) to (xor C, 1).
470 if (TLI.getBooleanContents(false, false) !=
471 TLI.getBooleanContents(false, true)) {
472 // At least try the common case where the boolean is generated by a
473 // comparison.
474 if (Cond->getOpcode() == ISD::SETCC) {
475 EVT OpVT = Cond->getOperand(0).getValueType();
476 ScalarBool = TLI.getBooleanContents(OpVT.getScalarType());
477 VecBool = TLI.getBooleanContents(OpVT);
478 } else
479 ScalarBool = TargetLowering::UndefinedBooleanContent;
482 EVT CondVT = Cond.getValueType();
483 if (ScalarBool != VecBool) {
484 switch (ScalarBool) {
485 case TargetLowering::UndefinedBooleanContent:
486 break;
487 case TargetLowering::ZeroOrOneBooleanContent:
488 assert(VecBool == TargetLowering::UndefinedBooleanContent ||
489 VecBool == TargetLowering::ZeroOrNegativeOneBooleanContent);
490 // Vector read from all ones, scalar expects a single 1 so mask.
491 Cond = DAG.getNode(ISD::AND, SDLoc(N), CondVT,
492 Cond, DAG.getConstant(1, SDLoc(N), CondVT));
493 break;
494 case TargetLowering::ZeroOrNegativeOneBooleanContent:
495 assert(VecBool == TargetLowering::UndefinedBooleanContent ||
496 VecBool == TargetLowering::ZeroOrOneBooleanContent);
497 // Vector reads from a one, scalar from all ones so sign extend.
498 Cond = DAG.getNode(ISD::SIGN_EXTEND_INREG, SDLoc(N), CondVT,
499 Cond, DAG.getValueType(MVT::i1));
500 break;
504 // Truncate the condition if needed
505 auto BoolVT = getSetCCResultType(CondVT);
506 if (BoolVT.bitsLT(CondVT))
507 Cond = DAG.getNode(ISD::TRUNCATE, SDLoc(N), BoolVT, Cond);
509 return DAG.getSelect(SDLoc(N),
510 LHS.getValueType(), Cond, LHS,
511 GetScalarizedVector(N->getOperand(2)));
514 SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT(SDNode *N) {
515 SDValue LHS = GetScalarizedVector(N->getOperand(1));
516 return DAG.getSelect(SDLoc(N),
517 LHS.getValueType(), N->getOperand(0), LHS,
518 GetScalarizedVector(N->getOperand(2)));
521 SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT_CC(SDNode *N) {
522 SDValue LHS = GetScalarizedVector(N->getOperand(2));
523 return DAG.getNode(ISD::SELECT_CC, SDLoc(N), LHS.getValueType(),
524 N->getOperand(0), N->getOperand(1),
525 LHS, GetScalarizedVector(N->getOperand(3)),
526 N->getOperand(4));
529 SDValue DAGTypeLegalizer::ScalarizeVecRes_UNDEF(SDNode *N) {
530 return DAG.getUNDEF(N->getValueType(0).getVectorElementType());
533 SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N) {
534 // Figure out if the scalar is the LHS or RHS and return it.
535 SDValue Arg = N->getOperand(2).getOperand(0);
536 if (Arg.isUndef())
537 return DAG.getUNDEF(N->getValueType(0).getVectorElementType());
538 unsigned Op = !cast<ConstantSDNode>(Arg)->isNullValue();
539 return GetScalarizedVector(N->getOperand(Op));
542 SDValue DAGTypeLegalizer::ScalarizeVecRes_SETCC(SDNode *N) {
543 assert(N->getValueType(0).isVector() &&
544 N->getOperand(0).getValueType().isVector() &&
545 "Operand types must be vectors");
546 SDValue LHS = N->getOperand(0);
547 SDValue RHS = N->getOperand(1);
548 EVT OpVT = LHS.getValueType();
549 EVT NVT = N->getValueType(0).getVectorElementType();
550 SDLoc DL(N);
552 // The result needs scalarizing, but it's not a given that the source does.
553 if (getTypeAction(OpVT) == TargetLowering::TypeScalarizeVector) {
554 LHS = GetScalarizedVector(LHS);
555 RHS = GetScalarizedVector(RHS);
556 } else {
557 EVT VT = OpVT.getVectorElementType();
558 LHS = DAG.getNode(
559 ISD::EXTRACT_VECTOR_ELT, DL, VT, LHS,
560 DAG.getConstant(0, DL, TLI.getVectorIdxTy(DAG.getDataLayout())));
561 RHS = DAG.getNode(
562 ISD::EXTRACT_VECTOR_ELT, DL, VT, RHS,
563 DAG.getConstant(0, DL, TLI.getVectorIdxTy(DAG.getDataLayout())));
566 // Turn it into a scalar SETCC.
567 SDValue Res = DAG.getNode(ISD::SETCC, DL, MVT::i1, LHS, RHS,
568 N->getOperand(2));
569 // Vectors may have a different boolean contents to scalars. Promote the
570 // value appropriately.
571 ISD::NodeType ExtendCode =
572 TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT));
573 return DAG.getNode(ExtendCode, DL, NVT, Res);
577 //===----------------------------------------------------------------------===//
578 // Operand Vector Scalarization <1 x ty> -> ty.
579 //===----------------------------------------------------------------------===//
581 bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) {
582 LLVM_DEBUG(dbgs() << "Scalarize node operand " << OpNo << ": "; N->dump(&DAG);
583 dbgs() << "\n");
584 SDValue Res = SDValue();
586 if (!Res.getNode()) {
587 switch (N->getOpcode()) {
588 default:
589 #ifndef NDEBUG
590 dbgs() << "ScalarizeVectorOperand Op #" << OpNo << ": ";
591 N->dump(&DAG);
592 dbgs() << "\n";
593 #endif
594 report_fatal_error("Do not know how to scalarize this operator's "
595 "operand!\n");
596 case ISD::BITCAST:
597 Res = ScalarizeVecOp_BITCAST(N);
598 break;
599 case ISD::ANY_EXTEND:
600 case ISD::ZERO_EXTEND:
601 case ISD::SIGN_EXTEND:
602 case ISD::TRUNCATE:
603 case ISD::FP_TO_SINT:
604 case ISD::FP_TO_UINT:
605 case ISD::SINT_TO_FP:
606 case ISD::UINT_TO_FP:
607 Res = ScalarizeVecOp_UnaryOp(N);
608 break;
609 case ISD::STRICT_FP_TO_SINT:
610 case ISD::STRICT_FP_TO_UINT:
611 Res = ScalarizeVecOp_UnaryOp_StrictFP(N);
612 break;
613 case ISD::CONCAT_VECTORS:
614 Res = ScalarizeVecOp_CONCAT_VECTORS(N);
615 break;
616 case ISD::EXTRACT_VECTOR_ELT:
617 Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(N);
618 break;
619 case ISD::VSELECT:
620 Res = ScalarizeVecOp_VSELECT(N);
621 break;
622 case ISD::SETCC:
623 Res = ScalarizeVecOp_VSETCC(N);
624 break;
625 case ISD::STORE:
626 Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(N), OpNo);
627 break;
628 case ISD::STRICT_FP_ROUND:
629 Res = ScalarizeVecOp_STRICT_FP_ROUND(N, OpNo);
630 break;
631 case ISD::FP_ROUND:
632 Res = ScalarizeVecOp_FP_ROUND(N, OpNo);
633 break;
634 case ISD::VECREDUCE_FADD:
635 case ISD::VECREDUCE_FMUL:
636 case ISD::VECREDUCE_ADD:
637 case ISD::VECREDUCE_MUL:
638 case ISD::VECREDUCE_AND:
639 case ISD::VECREDUCE_OR:
640 case ISD::VECREDUCE_XOR:
641 case ISD::VECREDUCE_SMAX:
642 case ISD::VECREDUCE_SMIN:
643 case ISD::VECREDUCE_UMAX:
644 case ISD::VECREDUCE_UMIN:
645 case ISD::VECREDUCE_FMAX:
646 case ISD::VECREDUCE_FMIN:
647 Res = ScalarizeVecOp_VECREDUCE(N);
648 break;
652 // If the result is null, the sub-method took care of registering results etc.
653 if (!Res.getNode()) return false;
655 // If the result is N, the sub-method updated N in place. Tell the legalizer
656 // core about this.
657 if (Res.getNode() == N)
658 return true;
660 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
661 "Invalid operand expansion");
663 ReplaceValueWith(SDValue(N, 0), Res);
664 return false;
667 /// If the value to convert is a vector that needs to be scalarized, it must be
668 /// <1 x ty>. Convert the element instead.
669 SDValue DAGTypeLegalizer::ScalarizeVecOp_BITCAST(SDNode *N) {
670 SDValue Elt = GetScalarizedVector(N->getOperand(0));
671 return DAG.getNode(ISD::BITCAST, SDLoc(N),
672 N->getValueType(0), Elt);
675 /// If the input is a vector that needs to be scalarized, it must be <1 x ty>.
676 /// Do the operation on the element instead.
677 SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp(SDNode *N) {
678 assert(N->getValueType(0).getVectorNumElements() == 1 &&
679 "Unexpected vector type!");
680 SDValue Elt = GetScalarizedVector(N->getOperand(0));
681 SDValue Op = DAG.getNode(N->getOpcode(), SDLoc(N),
682 N->getValueType(0).getScalarType(), Elt);
683 // Revectorize the result so the types line up with what the uses of this
684 // expression expect.
685 return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Op);
688 /// If the input is a vector that needs to be scalarized, it must be <1 x ty>.
689 /// Do the strict FP operation on the element instead.
690 SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(SDNode *N) {
691 assert(N->getValueType(0).getVectorNumElements() == 1 &&
692 "Unexpected vector type!");
693 SDValue Elt = GetScalarizedVector(N->getOperand(1));
694 SDValue Res = DAG.getNode(N->getOpcode(), SDLoc(N),
695 { N->getValueType(0).getScalarType(), MVT::Other },
696 { N->getOperand(0), Elt });
697 // Legalize the chain result - switch anything that used the old chain to
698 // use the new one.
699 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
700 // Revectorize the result so the types line up with what the uses of this
701 // expression expect.
702 return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res);
705 /// The vectors to concatenate have length one - use a BUILD_VECTOR instead.
706 SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(SDNode *N) {
707 SmallVector<SDValue, 8> Ops(N->getNumOperands());
708 for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i)
709 Ops[i] = GetScalarizedVector(N->getOperand(i));
710 return DAG.getBuildVector(N->getValueType(0), SDLoc(N), Ops);
713 /// If the input is a vector that needs to be scalarized, it must be <1 x ty>,
714 /// so just return the element, ignoring the index.
715 SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
716 EVT VT = N->getValueType(0);
717 SDValue Res = GetScalarizedVector(N->getOperand(0));
718 if (Res.getValueType() != VT)
719 Res = VT.isFloatingPoint()
720 ? DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT, Res)
721 : DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), VT, Res);
722 return Res;
725 /// If the input condition is a vector that needs to be scalarized, it must be
726 /// <1 x i1>, so just convert to a normal ISD::SELECT
727 /// (still with vector output type since that was acceptable if we got here).
728 SDValue DAGTypeLegalizer::ScalarizeVecOp_VSELECT(SDNode *N) {
729 SDValue ScalarCond = GetScalarizedVector(N->getOperand(0));
730 EVT VT = N->getValueType(0);
732 return DAG.getNode(ISD::SELECT, SDLoc(N), VT, ScalarCond, N->getOperand(1),
733 N->getOperand(2));
736 /// If the operand is a vector that needs to be scalarized then the
737 /// result must be v1i1, so just convert to a scalar SETCC and wrap
738 /// with a scalar_to_vector since the res type is legal if we got here
739 SDValue DAGTypeLegalizer::ScalarizeVecOp_VSETCC(SDNode *N) {
740 assert(N->getValueType(0).isVector() &&
741 N->getOperand(0).getValueType().isVector() &&
742 "Operand types must be vectors");
743 assert(N->getValueType(0) == MVT::v1i1 && "Expected v1i1 type");
745 EVT VT = N->getValueType(0);
746 SDValue LHS = GetScalarizedVector(N->getOperand(0));
747 SDValue RHS = GetScalarizedVector(N->getOperand(1));
749 EVT OpVT = N->getOperand(0).getValueType();
750 EVT NVT = VT.getVectorElementType();
751 SDLoc DL(N);
752 // Turn it into a scalar SETCC.
753 SDValue Res = DAG.getNode(ISD::SETCC, DL, MVT::i1, LHS, RHS,
754 N->getOperand(2));
756 // Vectors may have a different boolean contents to scalars. Promote the
757 // value appropriately.
758 ISD::NodeType ExtendCode =
759 TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT));
761 Res = DAG.getNode(ExtendCode, DL, NVT, Res);
763 return DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VT, Res);
766 /// If the value to store is a vector that needs to be scalarized, it must be
767 /// <1 x ty>. Just store the element.
768 SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){
769 assert(N->isUnindexed() && "Indexed store of one-element vector?");
770 assert(OpNo == 1 && "Do not know how to scalarize this operand!");
771 SDLoc dl(N);
773 if (N->isTruncatingStore())
774 return DAG.getTruncStore(
775 N->getChain(), dl, GetScalarizedVector(N->getOperand(1)),
776 N->getBasePtr(), N->getPointerInfo(),
777 N->getMemoryVT().getVectorElementType(), N->getAlignment(),
778 N->getMemOperand()->getFlags(), N->getAAInfo());
780 return DAG.getStore(N->getChain(), dl, GetScalarizedVector(N->getOperand(1)),
781 N->getBasePtr(), N->getPointerInfo(),
782 N->getOriginalAlignment(), N->getMemOperand()->getFlags(),
783 N->getAAInfo());
786 /// If the value to round is a vector that needs to be scalarized, it must be
787 /// <1 x ty>. Convert the element instead.
788 SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(SDNode *N, unsigned OpNo) {
789 SDValue Elt = GetScalarizedVector(N->getOperand(0));
790 SDValue Res = DAG.getNode(ISD::FP_ROUND, SDLoc(N),
791 N->getValueType(0).getVectorElementType(), Elt,
792 N->getOperand(1));
793 return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res);
796 SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(SDNode *N,
797 unsigned OpNo) {
798 assert(OpNo == 1 && "Wrong operand for scalarization!");
799 SDValue Elt = GetScalarizedVector(N->getOperand(1));
800 SDValue Res = DAG.getNode(ISD::STRICT_FP_ROUND, SDLoc(N),
801 { N->getValueType(0).getVectorElementType(),
802 MVT::Other },
803 { N->getOperand(0), Elt, N->getOperand(2) });
804 // Legalize the chain result - switch anything that used the old chain to
805 // use the new one.
806 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
807 return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res);
810 SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE(SDNode *N) {
811 SDValue Res = GetScalarizedVector(N->getOperand(0));
812 // Result type may be wider than element type.
813 if (Res.getValueType() != N->getValueType(0))
814 Res = DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), N->getValueType(0), Res);
815 return Res;
818 //===----------------------------------------------------------------------===//
819 // Result Vector Splitting
820 //===----------------------------------------------------------------------===//
822 /// This method is called when the specified result of the specified node is
823 /// found to need vector splitting. At this point, the node may also have
824 /// invalid operands or may have other results that need legalization, we just
825 /// know that (at least) one result needs vector splitting.
826 void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
827 LLVM_DEBUG(dbgs() << "Split node result: "; N->dump(&DAG); dbgs() << "\n");
828 SDValue Lo, Hi;
830 // See if the target wants to custom expand this node.
831 if (CustomLowerNode(N, N->getValueType(ResNo), true))
832 return;
834 switch (N->getOpcode()) {
835 default:
836 #ifndef NDEBUG
837 dbgs() << "SplitVectorResult #" << ResNo << ": ";
838 N->dump(&DAG);
839 dbgs() << "\n";
840 #endif
841 report_fatal_error("Do not know how to split the result of this "
842 "operator!\n");
844 case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, ResNo, Lo, Hi); break;
845 case ISD::VSELECT:
846 case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break;
847 case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break;
848 case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
849 case ISD::BITCAST: SplitVecRes_BITCAST(N, Lo, Hi); break;
850 case ISD::BUILD_VECTOR: SplitVecRes_BUILD_VECTOR(N, Lo, Hi); break;
851 case ISD::CONCAT_VECTORS: SplitVecRes_CONCAT_VECTORS(N, Lo, Hi); break;
852 case ISD::EXTRACT_SUBVECTOR: SplitVecRes_EXTRACT_SUBVECTOR(N, Lo, Hi); break;
853 case ISD::INSERT_SUBVECTOR: SplitVecRes_INSERT_SUBVECTOR(N, Lo, Hi); break;
854 case ISD::FPOWI: SplitVecRes_FPOWI(N, Lo, Hi); break;
855 case ISD::FCOPYSIGN: SplitVecRes_FCOPYSIGN(N, Lo, Hi); break;
856 case ISD::INSERT_VECTOR_ELT: SplitVecRes_INSERT_VECTOR_ELT(N, Lo, Hi); break;
857 case ISD::SCALAR_TO_VECTOR: SplitVecRes_SCALAR_TO_VECTOR(N, Lo, Hi); break;
858 case ISD::SIGN_EXTEND_INREG: SplitVecRes_InregOp(N, Lo, Hi); break;
859 case ISD::LOAD:
860 SplitVecRes_LOAD(cast<LoadSDNode>(N), Lo, Hi);
861 break;
862 case ISD::MLOAD:
863 SplitVecRes_MLOAD(cast<MaskedLoadSDNode>(N), Lo, Hi);
864 break;
865 case ISD::MGATHER:
866 SplitVecRes_MGATHER(cast<MaskedGatherSDNode>(N), Lo, Hi);
867 break;
868 case ISD::SETCC:
869 SplitVecRes_SETCC(N, Lo, Hi);
870 break;
871 case ISD::VECTOR_SHUFFLE:
872 SplitVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N), Lo, Hi);
873 break;
874 case ISD::VAARG:
875 SplitVecRes_VAARG(N, Lo, Hi);
876 break;
878 case ISD::ANY_EXTEND_VECTOR_INREG:
879 case ISD::SIGN_EXTEND_VECTOR_INREG:
880 case ISD::ZERO_EXTEND_VECTOR_INREG:
881 SplitVecRes_ExtVecInRegOp(N, Lo, Hi);
882 break;
884 case ISD::ABS:
885 case ISD::BITREVERSE:
886 case ISD::BSWAP:
887 case ISD::CTLZ:
888 case ISD::CTTZ:
889 case ISD::CTLZ_ZERO_UNDEF:
890 case ISD::CTTZ_ZERO_UNDEF:
891 case ISD::CTPOP:
892 case ISD::FABS:
893 case ISD::FCEIL:
894 case ISD::FCOS:
895 case ISD::FEXP:
896 case ISD::FEXP2:
897 case ISD::FFLOOR:
898 case ISD::FLOG:
899 case ISD::FLOG10:
900 case ISD::FLOG2:
901 case ISD::FNEARBYINT:
902 case ISD::FNEG:
903 case ISD::FP_EXTEND:
904 case ISD::STRICT_FP_EXTEND:
905 case ISD::FP_ROUND:
906 case ISD::STRICT_FP_ROUND:
907 case ISD::FP_TO_SINT:
908 case ISD::STRICT_FP_TO_SINT:
909 case ISD::FP_TO_UINT:
910 case ISD::STRICT_FP_TO_UINT:
911 case ISD::FRINT:
912 case ISD::FROUND:
913 case ISD::FSIN:
914 case ISD::FSQRT:
915 case ISD::FTRUNC:
916 case ISD::SINT_TO_FP:
917 case ISD::TRUNCATE:
918 case ISD::UINT_TO_FP:
919 case ISD::FCANONICALIZE:
920 SplitVecRes_UnaryOp(N, Lo, Hi);
921 break;
923 case ISD::ANY_EXTEND:
924 case ISD::SIGN_EXTEND:
925 case ISD::ZERO_EXTEND:
926 SplitVecRes_ExtendOp(N, Lo, Hi);
927 break;
929 case ISD::ADD:
930 case ISD::SUB:
931 case ISD::MUL:
932 case ISD::MULHS:
933 case ISD::MULHU:
934 case ISD::FADD:
935 case ISD::FSUB:
936 case ISD::FMUL:
937 case ISD::FMINNUM:
938 case ISD::FMAXNUM:
939 case ISD::FMINIMUM:
940 case ISD::FMAXIMUM:
941 case ISD::SDIV:
942 case ISD::UDIV:
943 case ISD::FDIV:
944 case ISD::FPOW:
945 case ISD::AND:
946 case ISD::OR:
947 case ISD::XOR:
948 case ISD::SHL:
949 case ISD::SRA:
950 case ISD::SRL:
951 case ISD::UREM:
952 case ISD::SREM:
953 case ISD::FREM:
954 case ISD::SMIN:
955 case ISD::SMAX:
956 case ISD::UMIN:
957 case ISD::UMAX:
958 case ISD::SADDSAT:
959 case ISD::UADDSAT:
960 case ISD::SSUBSAT:
961 case ISD::USUBSAT:
962 SplitVecRes_BinOp(N, Lo, Hi);
963 break;
964 case ISD::FMA:
965 SplitVecRes_TernaryOp(N, Lo, Hi);
966 break;
967 case ISD::STRICT_FADD:
968 case ISD::STRICT_FSUB:
969 case ISD::STRICT_FMUL:
970 case ISD::STRICT_FDIV:
971 case ISD::STRICT_FREM:
972 case ISD::STRICT_FSQRT:
973 case ISD::STRICT_FMA:
974 case ISD::STRICT_FPOW:
975 case ISD::STRICT_FPOWI:
976 case ISD::STRICT_FSIN:
977 case ISD::STRICT_FCOS:
978 case ISD::STRICT_FEXP:
979 case ISD::STRICT_FEXP2:
980 case ISD::STRICT_FLOG:
981 case ISD::STRICT_FLOG10:
982 case ISD::STRICT_FLOG2:
983 case ISD::STRICT_FRINT:
984 case ISD::STRICT_FNEARBYINT:
985 case ISD::STRICT_FMAXNUM:
986 case ISD::STRICT_FMINNUM:
987 case ISD::STRICT_FCEIL:
988 case ISD::STRICT_FFLOOR:
989 case ISD::STRICT_FROUND:
990 case ISD::STRICT_FTRUNC:
991 SplitVecRes_StrictFPOp(N, Lo, Hi);
992 break;
993 case ISD::UADDO:
994 case ISD::SADDO:
995 case ISD::USUBO:
996 case ISD::SSUBO:
997 case ISD::UMULO:
998 case ISD::SMULO:
999 SplitVecRes_OverflowOp(N, ResNo, Lo, Hi);
1000 break;
1001 case ISD::SMULFIX:
1002 case ISD::SMULFIXSAT:
1003 case ISD::UMULFIX:
1004 case ISD::UMULFIXSAT:
1005 SplitVecRes_MULFIX(N, Lo, Hi);
1006 break;
1009 // If Lo/Hi is null, the sub-method took care of registering results etc.
1010 if (Lo.getNode())
1011 SetSplitVector(SDValue(N, ResNo), Lo, Hi);
1014 void DAGTypeLegalizer::SplitVecRes_BinOp(SDNode *N, SDValue &Lo,
1015 SDValue &Hi) {
1016 SDValue LHSLo, LHSHi;
1017 GetSplitVector(N->getOperand(0), LHSLo, LHSHi);
1018 SDValue RHSLo, RHSHi;
1019 GetSplitVector(N->getOperand(1), RHSLo, RHSHi);
1020 SDLoc dl(N);
1022 const SDNodeFlags Flags = N->getFlags();
1023 unsigned Opcode = N->getOpcode();
1024 Lo = DAG.getNode(Opcode, dl, LHSLo.getValueType(), LHSLo, RHSLo, Flags);
1025 Hi = DAG.getNode(Opcode, dl, LHSHi.getValueType(), LHSHi, RHSHi, Flags);
1028 void DAGTypeLegalizer::SplitVecRes_TernaryOp(SDNode *N, SDValue &Lo,
1029 SDValue &Hi) {
1030 SDValue Op0Lo, Op0Hi;
1031 GetSplitVector(N->getOperand(0), Op0Lo, Op0Hi);
1032 SDValue Op1Lo, Op1Hi;
1033 GetSplitVector(N->getOperand(1), Op1Lo, Op1Hi);
1034 SDValue Op2Lo, Op2Hi;
1035 GetSplitVector(N->getOperand(2), Op2Lo, Op2Hi);
1036 SDLoc dl(N);
1038 Lo = DAG.getNode(N->getOpcode(), dl, Op0Lo.getValueType(),
1039 Op0Lo, Op1Lo, Op2Lo);
1040 Hi = DAG.getNode(N->getOpcode(), dl, Op0Hi.getValueType(),
1041 Op0Hi, Op1Hi, Op2Hi);
1044 void DAGTypeLegalizer::SplitVecRes_MULFIX(SDNode *N, SDValue &Lo, SDValue &Hi) {
1045 SDValue LHSLo, LHSHi;
1046 GetSplitVector(N->getOperand(0), LHSLo, LHSHi);
1047 SDValue RHSLo, RHSHi;
1048 GetSplitVector(N->getOperand(1), RHSLo, RHSHi);
1049 SDLoc dl(N);
1050 SDValue Op2 = N->getOperand(2);
1052 unsigned Opcode = N->getOpcode();
1053 Lo = DAG.getNode(Opcode, dl, LHSLo.getValueType(), LHSLo, RHSLo, Op2);
1054 Hi = DAG.getNode(Opcode, dl, LHSHi.getValueType(), LHSHi, RHSHi, Op2);
1057 void DAGTypeLegalizer::SplitVecRes_BITCAST(SDNode *N, SDValue &Lo,
1058 SDValue &Hi) {
1059 // We know the result is a vector. The input may be either a vector or a
1060 // scalar value.
1061 EVT LoVT, HiVT;
1062 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1063 SDLoc dl(N);
1065 SDValue InOp = N->getOperand(0);
1066 EVT InVT = InOp.getValueType();
1068 // Handle some special cases efficiently.
1069 switch (getTypeAction(InVT)) {
1070 case TargetLowering::TypeLegal:
1071 case TargetLowering::TypePromoteInteger:
1072 case TargetLowering::TypePromoteFloat:
1073 case TargetLowering::TypeSoftenFloat:
1074 case TargetLowering::TypeScalarizeVector:
1075 case TargetLowering::TypeWidenVector:
1076 break;
1077 case TargetLowering::TypeExpandInteger:
1078 case TargetLowering::TypeExpandFloat:
1079 // A scalar to vector conversion, where the scalar needs expansion.
1080 // If the vector is being split in two then we can just convert the
1081 // expanded pieces.
1082 if (LoVT == HiVT) {
1083 GetExpandedOp(InOp, Lo, Hi);
1084 if (DAG.getDataLayout().isBigEndian())
1085 std::swap(Lo, Hi);
1086 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, Lo);
1087 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, Hi);
1088 return;
1090 break;
1091 case TargetLowering::TypeSplitVector:
1092 // If the input is a vector that needs to be split, convert each split
1093 // piece of the input now.
1094 GetSplitVector(InOp, Lo, Hi);
1095 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, Lo);
1096 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, Hi);
1097 return;
1100 // In the general case, convert the input to an integer and split it by hand.
1101 EVT LoIntVT = EVT::getIntegerVT(*DAG.getContext(), LoVT.getSizeInBits());
1102 EVT HiIntVT = EVT::getIntegerVT(*DAG.getContext(), HiVT.getSizeInBits());
1103 if (DAG.getDataLayout().isBigEndian())
1104 std::swap(LoIntVT, HiIntVT);
1106 SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT, Lo, Hi);
1108 if (DAG.getDataLayout().isBigEndian())
1109 std::swap(Lo, Hi);
1110 Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, Lo);
1111 Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, Hi);
1114 void DAGTypeLegalizer::SplitVecRes_BUILD_VECTOR(SDNode *N, SDValue &Lo,
1115 SDValue &Hi) {
1116 EVT LoVT, HiVT;
1117 SDLoc dl(N);
1118 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1119 unsigned LoNumElts = LoVT.getVectorNumElements();
1120 SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+LoNumElts);
1121 Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1123 SmallVector<SDValue, 8> HiOps(N->op_begin()+LoNumElts, N->op_end());
1124 Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1127 void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo,
1128 SDValue &Hi) {
1129 assert(!(N->getNumOperands() & 1) && "Unsupported CONCAT_VECTORS");
1130 SDLoc dl(N);
1131 unsigned NumSubvectors = N->getNumOperands() / 2;
1132 if (NumSubvectors == 1) {
1133 Lo = N->getOperand(0);
1134 Hi = N->getOperand(1);
1135 return;
1138 EVT LoVT, HiVT;
1139 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1141 SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+NumSubvectors);
1142 Lo = DAG.getNode(ISD::CONCAT_VECTORS, dl, LoVT, LoOps);
1144 SmallVector<SDValue, 8> HiOps(N->op_begin()+NumSubvectors, N->op_end());
1145 Hi = DAG.getNode(ISD::CONCAT_VECTORS, dl, HiVT, HiOps);
1148 void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo,
1149 SDValue &Hi) {
1150 SDValue Vec = N->getOperand(0);
1151 SDValue Idx = N->getOperand(1);
1152 SDLoc dl(N);
1154 EVT LoVT, HiVT;
1155 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1157 Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, LoVT, Vec, Idx);
1158 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
1159 Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HiVT, Vec,
1160 DAG.getConstant(IdxVal + LoVT.getVectorNumElements(), dl,
1161 TLI.getVectorIdxTy(DAG.getDataLayout())));
1164 void DAGTypeLegalizer::SplitVecRes_INSERT_SUBVECTOR(SDNode *N, SDValue &Lo,
1165 SDValue &Hi) {
1166 SDValue Vec = N->getOperand(0);
1167 SDValue SubVec = N->getOperand(1);
1168 SDValue Idx = N->getOperand(2);
1169 SDLoc dl(N);
1170 GetSplitVector(Vec, Lo, Hi);
1172 EVT VecVT = Vec.getValueType();
1173 unsigned VecElems = VecVT.getVectorNumElements();
1174 unsigned SubElems = SubVec.getValueType().getVectorNumElements();
1176 // If we know the index is 0, and we know the subvector doesn't cross the
1177 // boundary between the halves, we can avoid spilling the vector, and insert
1178 // into the lower half of the split vector directly.
1179 // TODO: The IdxVal == 0 constraint is artificial, we could do this whenever
1180 // the index is constant and there is no boundary crossing. But those cases
1181 // don't seem to get hit in practice.
1182 if (ConstantSDNode *ConstIdx = dyn_cast<ConstantSDNode>(Idx)) {
1183 unsigned IdxVal = ConstIdx->getZExtValue();
1184 if ((IdxVal == 0) && (IdxVal + SubElems <= VecElems / 2)) {
1185 EVT LoVT, HiVT;
1186 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1187 Lo = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, LoVT, Lo, SubVec, Idx);
1188 return;
1192 // Spill the vector to the stack.
1193 SDValue StackPtr = DAG.CreateStackTemporary(VecVT);
1194 SDValue Store =
1195 DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, MachinePointerInfo());
1197 // Store the new subvector into the specified index.
1198 SDValue SubVecPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
1199 Type *VecType = VecVT.getTypeForEVT(*DAG.getContext());
1200 unsigned Alignment = DAG.getDataLayout().getPrefTypeAlignment(VecType);
1201 Store = DAG.getStore(Store, dl, SubVec, SubVecPtr, MachinePointerInfo());
1203 // Load the Lo part from the stack slot.
1204 Lo =
1205 DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, MachinePointerInfo());
1207 // Increment the pointer to the other part.
1208 unsigned IncrementSize = Lo.getValueSizeInBits() / 8;
1209 StackPtr =
1210 DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
1211 DAG.getConstant(IncrementSize, dl, StackPtr.getValueType()));
1213 // Load the Hi part from the stack slot.
1214 Hi = DAG.getLoad(Hi.getValueType(), dl, Store, StackPtr, MachinePointerInfo(),
1215 MinAlign(Alignment, IncrementSize));
1218 void DAGTypeLegalizer::SplitVecRes_FPOWI(SDNode *N, SDValue &Lo,
1219 SDValue &Hi) {
1220 SDLoc dl(N);
1221 GetSplitVector(N->getOperand(0), Lo, Hi);
1222 Lo = DAG.getNode(ISD::FPOWI, dl, Lo.getValueType(), Lo, N->getOperand(1));
1223 Hi = DAG.getNode(ISD::FPOWI, dl, Hi.getValueType(), Hi, N->getOperand(1));
1226 void DAGTypeLegalizer::SplitVecRes_FCOPYSIGN(SDNode *N, SDValue &Lo,
1227 SDValue &Hi) {
1228 SDValue LHSLo, LHSHi;
1229 GetSplitVector(N->getOperand(0), LHSLo, LHSHi);
1230 SDLoc DL(N);
1232 SDValue RHSLo, RHSHi;
1233 SDValue RHS = N->getOperand(1);
1234 EVT RHSVT = RHS.getValueType();
1235 if (getTypeAction(RHSVT) == TargetLowering::TypeSplitVector)
1236 GetSplitVector(RHS, RHSLo, RHSHi);
1237 else
1238 std::tie(RHSLo, RHSHi) = DAG.SplitVector(RHS, SDLoc(RHS));
1241 Lo = DAG.getNode(ISD::FCOPYSIGN, DL, LHSLo.getValueType(), LHSLo, RHSLo);
1242 Hi = DAG.getNode(ISD::FCOPYSIGN, DL, LHSHi.getValueType(), LHSHi, RHSHi);
1245 void DAGTypeLegalizer::SplitVecRes_InregOp(SDNode *N, SDValue &Lo,
1246 SDValue &Hi) {
1247 SDValue LHSLo, LHSHi;
1248 GetSplitVector(N->getOperand(0), LHSLo, LHSHi);
1249 SDLoc dl(N);
1251 EVT LoVT, HiVT;
1252 std::tie(LoVT, HiVT) =
1253 DAG.GetSplitDestVTs(cast<VTSDNode>(N->getOperand(1))->getVT());
1255 Lo = DAG.getNode(N->getOpcode(), dl, LHSLo.getValueType(), LHSLo,
1256 DAG.getValueType(LoVT));
1257 Hi = DAG.getNode(N->getOpcode(), dl, LHSHi.getValueType(), LHSHi,
1258 DAG.getValueType(HiVT));
1261 void DAGTypeLegalizer::SplitVecRes_ExtVecInRegOp(SDNode *N, SDValue &Lo,
1262 SDValue &Hi) {
1263 unsigned Opcode = N->getOpcode();
1264 SDValue N0 = N->getOperand(0);
1266 SDLoc dl(N);
1267 SDValue InLo, InHi;
1269 if (getTypeAction(N0.getValueType()) == TargetLowering::TypeSplitVector)
1270 GetSplitVector(N0, InLo, InHi);
1271 else
1272 std::tie(InLo, InHi) = DAG.SplitVectorOperand(N, 0);
1274 EVT InLoVT = InLo.getValueType();
1275 unsigned InNumElements = InLoVT.getVectorNumElements();
1277 EVT OutLoVT, OutHiVT;
1278 std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1279 unsigned OutNumElements = OutLoVT.getVectorNumElements();
1280 assert((2 * OutNumElements) <= InNumElements &&
1281 "Illegal extend vector in reg split");
1283 // *_EXTEND_VECTOR_INREG instructions extend the lowest elements of the
1284 // input vector (i.e. we only use InLo):
1285 // OutLo will extend the first OutNumElements from InLo.
1286 // OutHi will extend the next OutNumElements from InLo.
1288 // Shuffle the elements from InLo for OutHi into the bottom elements to
1289 // create a 'fake' InHi.
1290 SmallVector<int, 8> SplitHi(InNumElements, -1);
1291 for (unsigned i = 0; i != OutNumElements; ++i)
1292 SplitHi[i] = i + OutNumElements;
1293 InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getUNDEF(InLoVT), SplitHi);
1295 Lo = DAG.getNode(Opcode, dl, OutLoVT, InLo);
1296 Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
1299 void DAGTypeLegalizer::SplitVecRes_StrictFPOp(SDNode *N, SDValue &Lo,
1300 SDValue &Hi) {
1301 unsigned NumOps = N->getNumOperands();
1302 SDValue Chain = N->getOperand(0);
1303 EVT LoVT, HiVT;
1304 SDLoc dl(N);
1305 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1307 SmallVector<SDValue, 4> OpsLo;
1308 SmallVector<SDValue, 4> OpsHi;
1310 // The Chain is the first operand.
1311 OpsLo.push_back(Chain);
1312 OpsHi.push_back(Chain);
1314 // Now process the remaining operands.
1315 for (unsigned i = 1; i < NumOps; ++i) {
1316 SDValue Op = N->getOperand(i);
1317 SDValue OpLo = Op;
1318 SDValue OpHi = Op;
1320 EVT InVT = Op.getValueType();
1321 if (InVT.isVector()) {
1322 // If the input also splits, handle it directly for a
1323 // compile time speedup. Otherwise split it by hand.
1324 if (getTypeAction(InVT) == TargetLowering::TypeSplitVector)
1325 GetSplitVector(Op, OpLo, OpHi);
1326 else
1327 std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(N, i);
1330 OpsLo.push_back(OpLo);
1331 OpsHi.push_back(OpHi);
1334 EVT LoValueVTs[] = {LoVT, MVT::Other};
1335 EVT HiValueVTs[] = {HiVT, MVT::Other};
1336 Lo = DAG.getNode(N->getOpcode(), dl, LoValueVTs, OpsLo);
1337 Hi = DAG.getNode(N->getOpcode(), dl, HiValueVTs, OpsHi);
1339 // Build a factor node to remember that this Op is independent of the
1340 // other one.
1341 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
1342 Lo.getValue(1), Hi.getValue(1));
1344 // Legalize the chain result - switch anything that used the old chain to
1345 // use the new one.
1346 ReplaceValueWith(SDValue(N, 1), Chain);
1349 SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(SDNode *N, unsigned ResNE) {
1350 SDValue Chain = N->getOperand(0);
1351 EVT VT = N->getValueType(0);
1352 unsigned NE = VT.getVectorNumElements();
1353 EVT EltVT = VT.getVectorElementType();
1354 SDLoc dl(N);
1356 SmallVector<SDValue, 8> Scalars;
1357 SmallVector<SDValue, 4> Operands(N->getNumOperands());
1359 // If ResNE is 0, fully unroll the vector op.
1360 if (ResNE == 0)
1361 ResNE = NE;
1362 else if (NE > ResNE)
1363 NE = ResNE;
1365 //The results of each unrolled operation, including the chain.
1366 EVT ChainVTs[] = {EltVT, MVT::Other};
1367 SmallVector<SDValue, 8> Chains;
1369 unsigned i;
1370 for (i = 0; i != NE; ++i) {
1371 Operands[0] = Chain;
1372 for (unsigned j = 1, e = N->getNumOperands(); j != e; ++j) {
1373 SDValue Operand = N->getOperand(j);
1374 EVT OperandVT = Operand.getValueType();
1375 if (OperandVT.isVector()) {
1376 EVT OperandEltVT = OperandVT.getVectorElementType();
1377 Operands[j] =
1378 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, OperandEltVT, Operand,
1379 DAG.getConstant(i, dl, TLI.getVectorIdxTy(
1380 DAG.getDataLayout())));
1381 } else {
1382 Operands[j] = Operand;
1385 SDValue Scalar = DAG.getNode(N->getOpcode(), dl, ChainVTs, Operands);
1386 Scalar.getNode()->setFlags(N->getFlags());
1388 //Add in the scalar as well as its chain value to the
1389 //result vectors.
1390 Scalars.push_back(Scalar);
1391 Chains.push_back(Scalar.getValue(1));
1394 for (; i < ResNE; ++i)
1395 Scalars.push_back(DAG.getUNDEF(EltVT));
1397 // Build a new factor node to connect the chain back together.
1398 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Chains);
1399 ReplaceValueWith(SDValue(N, 1), Chain);
1401 // Create a new BUILD_VECTOR node
1402 EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, ResNE);
1403 return DAG.getBuildVector(VecVT, dl, Scalars);
1406 void DAGTypeLegalizer::SplitVecRes_OverflowOp(SDNode *N, unsigned ResNo,
1407 SDValue &Lo, SDValue &Hi) {
1408 SDLoc dl(N);
1409 EVT ResVT = N->getValueType(0);
1410 EVT OvVT = N->getValueType(1);
1411 EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
1412 std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
1413 std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
1415 SDValue LoLHS, HiLHS, LoRHS, HiRHS;
1416 if (getTypeAction(ResVT) == TargetLowering::TypeSplitVector) {
1417 GetSplitVector(N->getOperand(0), LoLHS, HiLHS);
1418 GetSplitVector(N->getOperand(1), LoRHS, HiRHS);
1419 } else {
1420 std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(N, 0);
1421 std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(N, 1);
1424 unsigned Opcode = N->getOpcode();
1425 SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
1426 SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
1427 SDNode *LoNode = DAG.getNode(Opcode, dl, LoVTs, LoLHS, LoRHS).getNode();
1428 SDNode *HiNode = DAG.getNode(Opcode, dl, HiVTs, HiLHS, HiRHS).getNode();
1430 Lo = SDValue(LoNode, ResNo);
1431 Hi = SDValue(HiNode, ResNo);
1433 // Replace the other vector result not being explicitly split here.
1434 unsigned OtherNo = 1 - ResNo;
1435 EVT OtherVT = N->getValueType(OtherNo);
1436 if (getTypeAction(OtherVT) == TargetLowering::TypeSplitVector) {
1437 SetSplitVector(SDValue(N, OtherNo),
1438 SDValue(LoNode, OtherNo), SDValue(HiNode, OtherNo));
1439 } else {
1440 SDValue OtherVal = DAG.getNode(
1441 ISD::CONCAT_VECTORS, dl, OtherVT,
1442 SDValue(LoNode, OtherNo), SDValue(HiNode, OtherNo));
1443 ReplaceValueWith(SDValue(N, OtherNo), OtherVal);
1447 void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
1448 SDValue &Hi) {
1449 SDValue Vec = N->getOperand(0);
1450 SDValue Elt = N->getOperand(1);
1451 SDValue Idx = N->getOperand(2);
1452 SDLoc dl(N);
1453 GetSplitVector(Vec, Lo, Hi);
1455 if (ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Idx)) {
1456 unsigned IdxVal = CIdx->getZExtValue();
1457 unsigned LoNumElts = Lo.getValueType().getVectorNumElements();
1458 if (IdxVal < LoNumElts)
1459 Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl,
1460 Lo.getValueType(), Lo, Elt, Idx);
1461 else
1462 Hi =
1463 DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, Hi.getValueType(), Hi, Elt,
1464 DAG.getConstant(IdxVal - LoNumElts, dl,
1465 TLI.getVectorIdxTy(DAG.getDataLayout())));
1466 return;
1469 // See if the target wants to custom expand this node.
1470 if (CustomLowerNode(N, N->getValueType(0), true))
1471 return;
1473 // Make the vector elements byte-addressable if they aren't already.
1474 EVT VecVT = Vec.getValueType();
1475 EVT EltVT = VecVT.getVectorElementType();
1476 if (VecVT.getScalarSizeInBits() < 8) {
1477 EltVT = MVT::i8;
1478 VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
1479 VecVT.getVectorNumElements());
1480 Vec = DAG.getNode(ISD::ANY_EXTEND, dl, VecVT, Vec);
1481 // Extend the element type to match if needed.
1482 if (EltVT.bitsGT(Elt.getValueType()))
1483 Elt = DAG.getNode(ISD::ANY_EXTEND, dl, EltVT, Elt);
1486 // Spill the vector to the stack.
1487 SDValue StackPtr = DAG.CreateStackTemporary(VecVT);
1488 auto &MF = DAG.getMachineFunction();
1489 auto FrameIndex = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
1490 auto PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex);
1491 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo);
1493 // Store the new element. This may be larger than the vector element type,
1494 // so use a truncating store.
1495 SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
1496 Type *VecType = VecVT.getTypeForEVT(*DAG.getContext());
1497 unsigned Alignment = DAG.getDataLayout().getPrefTypeAlignment(VecType);
1498 Store = DAG.getTruncStore(Store, dl, Elt, EltPtr,
1499 MachinePointerInfo::getUnknownStack(MF), EltVT);
1501 EVT LoVT, HiVT;
1502 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
1504 // Load the Lo part from the stack slot.
1505 Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo);
1507 // Increment the pointer to the other part.
1508 unsigned IncrementSize = LoVT.getSizeInBits() / 8;
1509 StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr,
1510 DAG.getConstant(IncrementSize, dl,
1511 StackPtr.getValueType()));
1513 // Load the Hi part from the stack slot.
1514 Hi = DAG.getLoad(HiVT, dl, Store, StackPtr,
1515 PtrInfo.getWithOffset(IncrementSize),
1516 MinAlign(Alignment, IncrementSize));
1518 // If we adjusted the original type, we need to truncate the results.
1519 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1520 if (LoVT != Lo.getValueType())
1521 Lo = DAG.getNode(ISD::TRUNCATE, dl, LoVT, Lo);
1522 if (HiVT != Hi.getValueType())
1523 Hi = DAG.getNode(ISD::TRUNCATE, dl, HiVT, Hi);
1526 void DAGTypeLegalizer::SplitVecRes_SCALAR_TO_VECTOR(SDNode *N, SDValue &Lo,
1527 SDValue &Hi) {
1528 EVT LoVT, HiVT;
1529 SDLoc dl(N);
1530 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1531 Lo = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, LoVT, N->getOperand(0));
1532 Hi = DAG.getUNDEF(HiVT);
1535 void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo,
1536 SDValue &Hi) {
1537 assert(ISD::isUNINDEXEDLoad(LD) && "Indexed load during type legalization!");
1538 EVT LoVT, HiVT;
1539 SDLoc dl(LD);
1540 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(LD->getValueType(0));
1542 ISD::LoadExtType ExtType = LD->getExtensionType();
1543 SDValue Ch = LD->getChain();
1544 SDValue Ptr = LD->getBasePtr();
1545 SDValue Offset = DAG.getUNDEF(Ptr.getValueType());
1546 EVT MemoryVT = LD->getMemoryVT();
1547 unsigned Alignment = LD->getOriginalAlignment();
1548 MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
1549 AAMDNodes AAInfo = LD->getAAInfo();
1551 EVT LoMemVT, HiMemVT;
1552 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
1554 Lo = DAG.getLoad(ISD::UNINDEXED, ExtType, LoVT, dl, Ch, Ptr, Offset,
1555 LD->getPointerInfo(), LoMemVT, Alignment, MMOFlags, AAInfo);
1557 unsigned IncrementSize = LoMemVT.getSizeInBits()/8;
1558 Ptr = DAG.getObjectPtrOffset(dl, Ptr, IncrementSize);
1559 Hi = DAG.getLoad(ISD::UNINDEXED, ExtType, HiVT, dl, Ch, Ptr, Offset,
1560 LD->getPointerInfo().getWithOffset(IncrementSize), HiMemVT,
1561 Alignment, MMOFlags, AAInfo);
1563 // Build a factor node to remember that this load is independent of the
1564 // other one.
1565 Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
1566 Hi.getValue(1));
1568 // Legalize the chain result - switch anything that used the old chain to
1569 // use the new one.
1570 ReplaceValueWith(SDValue(LD, 1), Ch);
1573 void DAGTypeLegalizer::SplitVecRes_MLOAD(MaskedLoadSDNode *MLD,
1574 SDValue &Lo, SDValue &Hi) {
1575 EVT LoVT, HiVT;
1576 SDLoc dl(MLD);
1577 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->getValueType(0));
1579 SDValue Ch = MLD->getChain();
1580 SDValue Ptr = MLD->getBasePtr();
1581 SDValue Mask = MLD->getMask();
1582 SDValue PassThru = MLD->getPassThru();
1583 unsigned Alignment = MLD->getOriginalAlignment();
1584 ISD::LoadExtType ExtType = MLD->getExtensionType();
1586 // Split Mask operand
1587 SDValue MaskLo, MaskHi;
1588 if (Mask.getOpcode() == ISD::SETCC) {
1589 SplitVecRes_SETCC(Mask.getNode(), MaskLo, MaskHi);
1590 } else {
1591 if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector)
1592 GetSplitVector(Mask, MaskLo, MaskHi);
1593 else
1594 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
1597 EVT MemoryVT = MLD->getMemoryVT();
1598 EVT LoMemVT, HiMemVT;
1599 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
1601 SDValue PassThruLo, PassThruHi;
1602 if (getTypeAction(PassThru.getValueType()) == TargetLowering::TypeSplitVector)
1603 GetSplitVector(PassThru, PassThruLo, PassThruHi);
1604 else
1605 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
1607 MachineMemOperand *MMO = DAG.getMachineFunction().
1608 getMachineMemOperand(MLD->getPointerInfo(),
1609 MachineMemOperand::MOLoad, LoMemVT.getStoreSize(),
1610 Alignment, MLD->getAAInfo(), MLD->getRanges());
1612 Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr, MaskLo, PassThruLo, LoMemVT, MMO,
1613 ExtType, MLD->isExpandingLoad());
1615 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
1616 MLD->isExpandingLoad());
1617 unsigned HiOffset = LoMemVT.getStoreSize();
1619 MMO = DAG.getMachineFunction().getMachineMemOperand(
1620 MLD->getPointerInfo().getWithOffset(HiOffset), MachineMemOperand::MOLoad,
1621 HiMemVT.getStoreSize(), Alignment, MLD->getAAInfo(),
1622 MLD->getRanges());
1624 Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr, MaskHi, PassThruHi, HiMemVT, MMO,
1625 ExtType, MLD->isExpandingLoad());
1627 // Build a factor node to remember that this load is independent of the
1628 // other one.
1629 Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
1630 Hi.getValue(1));
1632 // Legalize the chain result - switch anything that used the old chain to
1633 // use the new one.
1634 ReplaceValueWith(SDValue(MLD, 1), Ch);
1638 void DAGTypeLegalizer::SplitVecRes_MGATHER(MaskedGatherSDNode *MGT,
1639 SDValue &Lo, SDValue &Hi) {
1640 EVT LoVT, HiVT;
1641 SDLoc dl(MGT);
1642 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MGT->getValueType(0));
1644 SDValue Ch = MGT->getChain();
1645 SDValue Ptr = MGT->getBasePtr();
1646 SDValue Mask = MGT->getMask();
1647 SDValue PassThru = MGT->getPassThru();
1648 SDValue Index = MGT->getIndex();
1649 SDValue Scale = MGT->getScale();
1650 unsigned Alignment = MGT->getOriginalAlignment();
1652 // Split Mask operand
1653 SDValue MaskLo, MaskHi;
1654 if (Mask.getOpcode() == ISD::SETCC) {
1655 SplitVecRes_SETCC(Mask.getNode(), MaskLo, MaskHi);
1656 } else {
1657 if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector)
1658 GetSplitVector(Mask, MaskLo, MaskHi);
1659 else
1660 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
1663 EVT MemoryVT = MGT->getMemoryVT();
1664 EVT LoMemVT, HiMemVT;
1665 // Split MemoryVT
1666 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
1668 SDValue PassThruLo, PassThruHi;
1669 if (getTypeAction(PassThru.getValueType()) == TargetLowering::TypeSplitVector)
1670 GetSplitVector(PassThru, PassThruLo, PassThruHi);
1671 else
1672 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
1674 SDValue IndexHi, IndexLo;
1675 if (getTypeAction(Index.getValueType()) == TargetLowering::TypeSplitVector)
1676 GetSplitVector(Index, IndexLo, IndexHi);
1677 else
1678 std::tie(IndexLo, IndexHi) = DAG.SplitVector(Index, dl);
1680 MachineMemOperand *MMO = DAG.getMachineFunction().
1681 getMachineMemOperand(MGT->getPointerInfo(),
1682 MachineMemOperand::MOLoad, LoMemVT.getStoreSize(),
1683 Alignment, MGT->getAAInfo(), MGT->getRanges());
1685 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo, Scale};
1686 Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoVT, dl, OpsLo,
1687 MMO, MGT->getIndexType());
1689 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi, Scale};
1690 Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiVT, dl, OpsHi,
1691 MMO, MGT->getIndexType());
1693 // Build a factor node to remember that this load is independent of the
1694 // other one.
1695 Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
1696 Hi.getValue(1));
1698 // Legalize the chain result - switch anything that used the old chain to
1699 // use the new one.
1700 ReplaceValueWith(SDValue(MGT, 1), Ch);
1704 void DAGTypeLegalizer::SplitVecRes_SETCC(SDNode *N, SDValue &Lo, SDValue &Hi) {
1705 assert(N->getValueType(0).isVector() &&
1706 N->getOperand(0).getValueType().isVector() &&
1707 "Operand types must be vectors");
1709 EVT LoVT, HiVT;
1710 SDLoc DL(N);
1711 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1713 // If the input also splits, handle it directly. Otherwise split it by hand.
1714 SDValue LL, LH, RL, RH;
1715 if (getTypeAction(N->getOperand(0).getValueType()) ==
1716 TargetLowering::TypeSplitVector)
1717 GetSplitVector(N->getOperand(0), LL, LH);
1718 else
1719 std::tie(LL, LH) = DAG.SplitVectorOperand(N, 0);
1721 if (getTypeAction(N->getOperand(1).getValueType()) ==
1722 TargetLowering::TypeSplitVector)
1723 GetSplitVector(N->getOperand(1), RL, RH);
1724 else
1725 std::tie(RL, RH) = DAG.SplitVectorOperand(N, 1);
1727 Lo = DAG.getNode(N->getOpcode(), DL, LoVT, LL, RL, N->getOperand(2));
1728 Hi = DAG.getNode(N->getOpcode(), DL, HiVT, LH, RH, N->getOperand(2));
1731 void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo,
1732 SDValue &Hi) {
1733 // Get the dest types - they may not match the input types, e.g. int_to_fp.
1734 EVT LoVT, HiVT;
1735 SDLoc dl(N);
1736 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1738 // If the input also splits, handle it directly for a compile time speedup.
1739 // Otherwise split it by hand.
1740 unsigned OpNo = N->isStrictFPOpcode() ? 1 : 0;
1741 EVT InVT = N->getOperand(OpNo).getValueType();
1742 if (getTypeAction(InVT) == TargetLowering::TypeSplitVector)
1743 GetSplitVector(N->getOperand(OpNo), Lo, Hi);
1744 else
1745 std::tie(Lo, Hi) = DAG.SplitVectorOperand(N, OpNo);
1747 if (N->getOpcode() == ISD::FP_ROUND) {
1748 Lo = DAG.getNode(N->getOpcode(), dl, LoVT, Lo, N->getOperand(1));
1749 Hi = DAG.getNode(N->getOpcode(), dl, HiVT, Hi, N->getOperand(1));
1750 } else if (N->getOpcode() == ISD::STRICT_FP_ROUND) {
1751 Lo = DAG.getNode(N->getOpcode(), dl, { LoVT, MVT::Other },
1752 { N->getOperand(0), Lo, N->getOperand(2) });
1753 Hi = DAG.getNode(N->getOpcode(), dl, { HiVT, MVT::Other },
1754 { N->getOperand(0), Hi, N->getOperand(2) });
1755 SDValue NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
1756 Lo.getValue(1), Hi.getValue(1));
1757 ReplaceValueWith(SDValue(N, 1), NewChain);
1758 } else if (N->isStrictFPOpcode()) {
1759 Lo = DAG.getNode(N->getOpcode(), dl, { LoVT, MVT::Other },
1760 { N->getOperand(0), Lo });
1761 Hi = DAG.getNode(N->getOpcode(), dl, { HiVT, MVT::Other },
1762 { N->getOperand(0), Hi });
1763 // Legalize the chain result - switch anything that used the old chain to
1764 // use the new one.
1765 SDValue NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
1766 Lo.getValue(1), Hi.getValue(1));
1767 ReplaceValueWith(SDValue(N, 1), NewChain);
1768 } else {
1769 Lo = DAG.getNode(N->getOpcode(), dl, LoVT, Lo);
1770 Hi = DAG.getNode(N->getOpcode(), dl, HiVT, Hi);
1774 void DAGTypeLegalizer::SplitVecRes_ExtendOp(SDNode *N, SDValue &Lo,
1775 SDValue &Hi) {
1776 SDLoc dl(N);
1777 EVT SrcVT = N->getOperand(0).getValueType();
1778 EVT DestVT = N->getValueType(0);
1779 EVT LoVT, HiVT;
1780 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
1782 // We can do better than a generic split operation if the extend is doing
1783 // more than just doubling the width of the elements and the following are
1784 // true:
1785 // - The number of vector elements is even,
1786 // - the source type is legal,
1787 // - the type of a split source is illegal,
1788 // - the type of an extended (by doubling element size) source is legal, and
1789 // - the type of that extended source when split is legal.
1791 // This won't necessarily completely legalize the operation, but it will
1792 // more effectively move in the right direction and prevent falling down
1793 // to scalarization in many cases due to the input vector being split too
1794 // far.
1795 unsigned NumElements = SrcVT.getVectorNumElements();
1796 if ((NumElements & 1) == 0 &&
1797 SrcVT.getSizeInBits() * 2 < DestVT.getSizeInBits()) {
1798 LLVMContext &Ctx = *DAG.getContext();
1799 EVT NewSrcVT = SrcVT.widenIntegerVectorElementType(Ctx);
1800 EVT SplitSrcVT = SrcVT.getHalfNumVectorElementsVT(Ctx);
1802 EVT SplitLoVT, SplitHiVT;
1803 std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
1804 if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
1805 TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
1806 LLVM_DEBUG(dbgs() << "Split vector extend via incremental extend:";
1807 N->dump(&DAG); dbgs() << "\n");
1808 // Extend the source vector by one step.
1809 SDValue NewSrc =
1810 DAG.getNode(N->getOpcode(), dl, NewSrcVT, N->getOperand(0));
1811 // Get the low and high halves of the new, extended one step, vector.
1812 std::tie(Lo, Hi) = DAG.SplitVector(NewSrc, dl);
1813 // Extend those vector halves the rest of the way.
1814 Lo = DAG.getNode(N->getOpcode(), dl, LoVT, Lo);
1815 Hi = DAG.getNode(N->getOpcode(), dl, HiVT, Hi);
1816 return;
1819 // Fall back to the generic unary operator splitting otherwise.
1820 SplitVecRes_UnaryOp(N, Lo, Hi);
1823 void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N,
1824 SDValue &Lo, SDValue &Hi) {
1825 // The low and high parts of the original input give four input vectors.
1826 SDValue Inputs[4];
1827 SDLoc dl(N);
1828 GetSplitVector(N->getOperand(0), Inputs[0], Inputs[1]);
1829 GetSplitVector(N->getOperand(1), Inputs[2], Inputs[3]);
1830 EVT NewVT = Inputs[0].getValueType();
1831 unsigned NewElts = NewVT.getVectorNumElements();
1833 // If Lo or Hi uses elements from at most two of the four input vectors, then
1834 // express it as a vector shuffle of those two inputs. Otherwise extract the
1835 // input elements by hand and construct the Lo/Hi output using a BUILD_VECTOR.
1836 SmallVector<int, 16> Ops;
1837 for (unsigned High = 0; High < 2; ++High) {
1838 SDValue &Output = High ? Hi : Lo;
1840 // Build a shuffle mask for the output, discovering on the fly which
1841 // input vectors to use as shuffle operands (recorded in InputUsed).
1842 // If building a suitable shuffle vector proves too hard, then bail
1843 // out with useBuildVector set.
1844 unsigned InputUsed[2] = { -1U, -1U }; // Not yet discovered.
1845 unsigned FirstMaskIdx = High * NewElts;
1846 bool useBuildVector = false;
1847 for (unsigned MaskOffset = 0; MaskOffset < NewElts; ++MaskOffset) {
1848 // The mask element. This indexes into the input.
1849 int Idx = N->getMaskElt(FirstMaskIdx + MaskOffset);
1851 // The input vector this mask element indexes into.
1852 unsigned Input = (unsigned)Idx / NewElts;
1854 if (Input >= array_lengthof(Inputs)) {
1855 // The mask element does not index into any input vector.
1856 Ops.push_back(-1);
1857 continue;
1860 // Turn the index into an offset from the start of the input vector.
1861 Idx -= Input * NewElts;
1863 // Find or create a shuffle vector operand to hold this input.
1864 unsigned OpNo;
1865 for (OpNo = 0; OpNo < array_lengthof(InputUsed); ++OpNo) {
1866 if (InputUsed[OpNo] == Input) {
1867 // This input vector is already an operand.
1868 break;
1869 } else if (InputUsed[OpNo] == -1U) {
1870 // Create a new operand for this input vector.
1871 InputUsed[OpNo] = Input;
1872 break;
1876 if (OpNo >= array_lengthof(InputUsed)) {
1877 // More than two input vectors used! Give up on trying to create a
1878 // shuffle vector. Insert all elements into a BUILD_VECTOR instead.
1879 useBuildVector = true;
1880 break;
1883 // Add the mask index for the new shuffle vector.
1884 Ops.push_back(Idx + OpNo * NewElts);
1887 if (useBuildVector) {
1888 EVT EltVT = NewVT.getVectorElementType();
1889 SmallVector<SDValue, 16> SVOps;
1891 // Extract the input elements by hand.
1892 for (unsigned MaskOffset = 0; MaskOffset < NewElts; ++MaskOffset) {
1893 // The mask element. This indexes into the input.
1894 int Idx = N->getMaskElt(FirstMaskIdx + MaskOffset);
1896 // The input vector this mask element indexes into.
1897 unsigned Input = (unsigned)Idx / NewElts;
1899 if (Input >= array_lengthof(Inputs)) {
1900 // The mask element is "undef" or indexes off the end of the input.
1901 SVOps.push_back(DAG.getUNDEF(EltVT));
1902 continue;
1905 // Turn the index into an offset from the start of the input vector.
1906 Idx -= Input * NewElts;
1908 // Extract the vector element by hand.
1909 SVOps.push_back(DAG.getNode(
1910 ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Inputs[Input],
1911 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))));
1914 // Construct the Lo/Hi output using a BUILD_VECTOR.
1915 Output = DAG.getBuildVector(NewVT, dl, SVOps);
1916 } else if (InputUsed[0] == -1U) {
1917 // No input vectors were used! The result is undefined.
1918 Output = DAG.getUNDEF(NewVT);
1919 } else {
1920 SDValue Op0 = Inputs[InputUsed[0]];
1921 // If only one input was used, use an undefined vector for the other.
1922 SDValue Op1 = InputUsed[1] == -1U ?
1923 DAG.getUNDEF(NewVT) : Inputs[InputUsed[1]];
1924 // At least one input vector was used. Create a new shuffle vector.
1925 Output = DAG.getVectorShuffle(NewVT, dl, Op0, Op1, Ops);
1928 Ops.clear();
1932 void DAGTypeLegalizer::SplitVecRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi) {
1933 EVT OVT = N->getValueType(0);
1934 EVT NVT = OVT.getHalfNumVectorElementsVT(*DAG.getContext());
1935 SDValue Chain = N->getOperand(0);
1936 SDValue Ptr = N->getOperand(1);
1937 SDValue SV = N->getOperand(2);
1938 SDLoc dl(N);
1940 const unsigned Alignment = DAG.getDataLayout().getABITypeAlignment(
1941 NVT.getTypeForEVT(*DAG.getContext()));
1943 Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment);
1944 Hi = DAG.getVAArg(NVT, dl, Lo.getValue(1), Ptr, SV, Alignment);
1945 Chain = Hi.getValue(1);
1947 // Modified the chain - switch anything that used the old chain to use
1948 // the new one.
1949 ReplaceValueWith(SDValue(N, 1), Chain);
1953 //===----------------------------------------------------------------------===//
1954 // Operand Vector Splitting
1955 //===----------------------------------------------------------------------===//
1957 /// This method is called when the specified operand of the specified node is
1958 /// found to need vector splitting. At this point, all of the result types of
1959 /// the node are known to be legal, but other operands of the node may need
1960 /// legalization as well as the specified one.
1961 bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) {
1962 LLVM_DEBUG(dbgs() << "Split node operand: "; N->dump(&DAG); dbgs() << "\n");
1963 SDValue Res = SDValue();
1965 // See if the target wants to custom split this node.
1966 if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
1967 return false;
1969 if (!Res.getNode()) {
1970 switch (N->getOpcode()) {
1971 default:
1972 #ifndef NDEBUG
1973 dbgs() << "SplitVectorOperand Op #" << OpNo << ": ";
1974 N->dump(&DAG);
1975 dbgs() << "\n";
1976 #endif
1977 report_fatal_error("Do not know how to split this operator's "
1978 "operand!\n");
1980 case ISD::SETCC: Res = SplitVecOp_VSETCC(N); break;
1981 case ISD::BITCAST: Res = SplitVecOp_BITCAST(N); break;
1982 case ISD::EXTRACT_SUBVECTOR: Res = SplitVecOp_EXTRACT_SUBVECTOR(N); break;
1983 case ISD::EXTRACT_VECTOR_ELT:Res = SplitVecOp_EXTRACT_VECTOR_ELT(N); break;
1984 case ISD::CONCAT_VECTORS: Res = SplitVecOp_CONCAT_VECTORS(N); break;
1985 case ISD::TRUNCATE:
1986 Res = SplitVecOp_TruncateHelper(N);
1987 break;
1988 case ISD::STRICT_FP_ROUND:
1989 case ISD::FP_ROUND: Res = SplitVecOp_FP_ROUND(N); break;
1990 case ISD::FCOPYSIGN: Res = SplitVecOp_FCOPYSIGN(N); break;
1991 case ISD::STORE:
1992 Res = SplitVecOp_STORE(cast<StoreSDNode>(N), OpNo);
1993 break;
1994 case ISD::MSTORE:
1995 Res = SplitVecOp_MSTORE(cast<MaskedStoreSDNode>(N), OpNo);
1996 break;
1997 case ISD::MSCATTER:
1998 Res = SplitVecOp_MSCATTER(cast<MaskedScatterSDNode>(N), OpNo);
1999 break;
2000 case ISD::MGATHER:
2001 Res = SplitVecOp_MGATHER(cast<MaskedGatherSDNode>(N), OpNo);
2002 break;
2003 case ISD::VSELECT:
2004 Res = SplitVecOp_VSELECT(N, OpNo);
2005 break;
2006 case ISD::SINT_TO_FP:
2007 case ISD::UINT_TO_FP:
2008 if (N->getValueType(0).bitsLT(N->getOperand(0).getValueType()))
2009 Res = SplitVecOp_TruncateHelper(N);
2010 else
2011 Res = SplitVecOp_UnaryOp(N);
2012 break;
2013 case ISD::FP_TO_SINT:
2014 case ISD::FP_TO_UINT:
2015 case ISD::STRICT_FP_TO_SINT:
2016 case ISD::STRICT_FP_TO_UINT:
2017 case ISD::CTTZ:
2018 case ISD::CTLZ:
2019 case ISD::CTPOP:
2020 case ISD::STRICT_FP_EXTEND:
2021 case ISD::FP_EXTEND:
2022 case ISD::SIGN_EXTEND:
2023 case ISD::ZERO_EXTEND:
2024 case ISD::ANY_EXTEND:
2025 case ISD::FTRUNC:
2026 case ISD::FCANONICALIZE:
2027 Res = SplitVecOp_UnaryOp(N);
2028 break;
2030 case ISD::ANY_EXTEND_VECTOR_INREG:
2031 case ISD::SIGN_EXTEND_VECTOR_INREG:
2032 case ISD::ZERO_EXTEND_VECTOR_INREG:
2033 Res = SplitVecOp_ExtVecInRegOp(N);
2034 break;
2036 case ISD::VECREDUCE_FADD:
2037 case ISD::VECREDUCE_FMUL:
2038 case ISD::VECREDUCE_ADD:
2039 case ISD::VECREDUCE_MUL:
2040 case ISD::VECREDUCE_AND:
2041 case ISD::VECREDUCE_OR:
2042 case ISD::VECREDUCE_XOR:
2043 case ISD::VECREDUCE_SMAX:
2044 case ISD::VECREDUCE_SMIN:
2045 case ISD::VECREDUCE_UMAX:
2046 case ISD::VECREDUCE_UMIN:
2047 case ISD::VECREDUCE_FMAX:
2048 case ISD::VECREDUCE_FMIN:
2049 Res = SplitVecOp_VECREDUCE(N, OpNo);
2050 break;
2054 // If the result is null, the sub-method took care of registering results etc.
2055 if (!Res.getNode()) return false;
2057 // If the result is N, the sub-method updated N in place. Tell the legalizer
2058 // core about this.
2059 if (Res.getNode() == N)
2060 return true;
2062 if (N->isStrictFPOpcode())
2063 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 2 &&
2064 "Invalid operand expansion");
2065 else
2066 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
2067 "Invalid operand expansion");
2069 ReplaceValueWith(SDValue(N, 0), Res);
2070 return false;
2073 SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(SDNode *N, unsigned OpNo) {
2074 // The only possibility for an illegal operand is the mask, since result type
2075 // legalization would have handled this node already otherwise.
2076 assert(OpNo == 0 && "Illegal operand must be mask");
2078 SDValue Mask = N->getOperand(0);
2079 SDValue Src0 = N->getOperand(1);
2080 SDValue Src1 = N->getOperand(2);
2081 EVT Src0VT = Src0.getValueType();
2082 SDLoc DL(N);
2083 assert(Mask.getValueType().isVector() && "VSELECT without a vector mask?");
2085 SDValue Lo, Hi;
2086 GetSplitVector(N->getOperand(0), Lo, Hi);
2087 assert(Lo.getValueType() == Hi.getValueType() &&
2088 "Lo and Hi have differing types");
2090 EVT LoOpVT, HiOpVT;
2091 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
2092 assert(LoOpVT == HiOpVT && "Asymmetric vector split?");
2094 SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
2095 std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0, DL);
2096 std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1, DL);
2097 std::tie(LoMask, HiMask) = DAG.SplitVector(Mask, DL);
2099 SDValue LoSelect =
2100 DAG.getNode(ISD::VSELECT, DL, LoOpVT, LoMask, LoOp0, LoOp1);
2101 SDValue HiSelect =
2102 DAG.getNode(ISD::VSELECT, DL, HiOpVT, HiMask, HiOp0, HiOp1);
2104 return DAG.getNode(ISD::CONCAT_VECTORS, DL, Src0VT, LoSelect, HiSelect);
2107 SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(SDNode *N, unsigned OpNo) {
2108 EVT ResVT = N->getValueType(0);
2109 SDValue Lo, Hi;
2110 SDLoc dl(N);
2112 SDValue VecOp = N->getOperand(OpNo);
2113 EVT VecVT = VecOp.getValueType();
2114 assert(VecVT.isVector() && "Can only split reduce vector operand");
2115 GetSplitVector(VecOp, Lo, Hi);
2116 EVT LoOpVT, HiOpVT;
2117 std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
2119 bool NoNaN = N->getFlags().hasNoNaNs();
2120 unsigned CombineOpc = 0;
2121 switch (N->getOpcode()) {
2122 case ISD::VECREDUCE_FADD: CombineOpc = ISD::FADD; break;
2123 case ISD::VECREDUCE_FMUL: CombineOpc = ISD::FMUL; break;
2124 case ISD::VECREDUCE_ADD: CombineOpc = ISD::ADD; break;
2125 case ISD::VECREDUCE_MUL: CombineOpc = ISD::MUL; break;
2126 case ISD::VECREDUCE_AND: CombineOpc = ISD::AND; break;
2127 case ISD::VECREDUCE_OR: CombineOpc = ISD::OR; break;
2128 case ISD::VECREDUCE_XOR: CombineOpc = ISD::XOR; break;
2129 case ISD::VECREDUCE_SMAX: CombineOpc = ISD::SMAX; break;
2130 case ISD::VECREDUCE_SMIN: CombineOpc = ISD::SMIN; break;
2131 case ISD::VECREDUCE_UMAX: CombineOpc = ISD::UMAX; break;
2132 case ISD::VECREDUCE_UMIN: CombineOpc = ISD::UMIN; break;
2133 case ISD::VECREDUCE_FMAX:
2134 CombineOpc = NoNaN ? ISD::FMAXNUM : ISD::FMAXIMUM;
2135 break;
2136 case ISD::VECREDUCE_FMIN:
2137 CombineOpc = NoNaN ? ISD::FMINNUM : ISD::FMINIMUM;
2138 break;
2139 default:
2140 llvm_unreachable("Unexpected reduce ISD node");
2143 // Use the appropriate scalar instruction on the split subvectors before
2144 // reducing the now partially reduced smaller vector.
2145 SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT, Lo, Hi, N->getFlags());
2146 return DAG.getNode(N->getOpcode(), dl, ResVT, Partial, N->getFlags());
2149 SDValue DAGTypeLegalizer::SplitVecOp_UnaryOp(SDNode *N) {
2150 // The result has a legal vector type, but the input needs splitting.
2151 EVT ResVT = N->getValueType(0);
2152 SDValue Lo, Hi;
2153 SDLoc dl(N);
2154 GetSplitVector(N->getOperand(N->isStrictFPOpcode() ? 1 : 0), Lo, Hi);
2155 EVT InVT = Lo.getValueType();
2157 EVT OutVT = EVT::getVectorVT(*DAG.getContext(), ResVT.getVectorElementType(),
2158 InVT.getVectorNumElements());
2160 if (N->isStrictFPOpcode()) {
2161 Lo = DAG.getNode(N->getOpcode(), dl, { OutVT, MVT::Other },
2162 { N->getOperand(0), Lo });
2163 Hi = DAG.getNode(N->getOpcode(), dl, { OutVT, MVT::Other },
2164 { N->getOperand(0), Hi });
2166 // Build a factor node to remember that this operation is independent
2167 // of the other one.
2168 SDValue Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
2169 Hi.getValue(1));
2171 // Legalize the chain result - switch anything that used the old chain to
2172 // use the new one.
2173 ReplaceValueWith(SDValue(N, 1), Ch);
2174 } else {
2175 Lo = DAG.getNode(N->getOpcode(), dl, OutVT, Lo);
2176 Hi = DAG.getNode(N->getOpcode(), dl, OutVT, Hi);
2179 return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi);
2182 SDValue DAGTypeLegalizer::SplitVecOp_BITCAST(SDNode *N) {
2183 // For example, i64 = BITCAST v4i16 on alpha. Typically the vector will
2184 // end up being split all the way down to individual components. Convert the
2185 // split pieces into integers and reassemble.
2186 SDValue Lo, Hi;
2187 GetSplitVector(N->getOperand(0), Lo, Hi);
2188 Lo = BitConvertToInteger(Lo);
2189 Hi = BitConvertToInteger(Hi);
2191 if (DAG.getDataLayout().isBigEndian())
2192 std::swap(Lo, Hi);
2194 return DAG.getNode(ISD::BITCAST, SDLoc(N), N->getValueType(0),
2195 JoinIntegers(Lo, Hi));
2198 SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N) {
2199 // We know that the extracted result type is legal.
2200 EVT SubVT = N->getValueType(0);
2201 SDValue Idx = N->getOperand(1);
2202 SDLoc dl(N);
2203 SDValue Lo, Hi;
2204 GetSplitVector(N->getOperand(0), Lo, Hi);
2206 uint64_t LoElts = Lo.getValueType().getVectorNumElements();
2207 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
2209 if (IdxVal < LoElts) {
2210 assert(IdxVal + SubVT.getVectorNumElements() <= LoElts &&
2211 "Extracted subvector crosses vector split!");
2212 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Lo, Idx);
2213 } else {
2214 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Hi,
2215 DAG.getConstant(IdxVal - LoElts, dl,
2216 Idx.getValueType()));
2220 SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
2221 SDValue Vec = N->getOperand(0);
2222 SDValue Idx = N->getOperand(1);
2223 EVT VecVT = Vec.getValueType();
2225 if (isa<ConstantSDNode>(Idx)) {
2226 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
2228 SDValue Lo, Hi;
2229 GetSplitVector(Vec, Lo, Hi);
2231 uint64_t LoElts = Lo.getValueType().getVectorNumElements();
2233 if (IdxVal < LoElts)
2234 return SDValue(DAG.UpdateNodeOperands(N, Lo, Idx), 0);
2235 return SDValue(DAG.UpdateNodeOperands(N, Hi,
2236 DAG.getConstant(IdxVal - LoElts, SDLoc(N),
2237 Idx.getValueType())), 0);
2240 // See if the target wants to custom expand this node.
2241 if (CustomLowerNode(N, N->getValueType(0), true))
2242 return SDValue();
2244 // Make the vector elements byte-addressable if they aren't already.
2245 SDLoc dl(N);
2246 EVT EltVT = VecVT.getVectorElementType();
2247 if (VecVT.getScalarSizeInBits() < 8) {
2248 EltVT = MVT::i8;
2249 VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
2250 VecVT.getVectorNumElements());
2251 Vec = DAG.getNode(ISD::ANY_EXTEND, dl, VecVT, Vec);
2254 // Store the vector to the stack.
2255 SDValue StackPtr = DAG.CreateStackTemporary(VecVT);
2256 auto &MF = DAG.getMachineFunction();
2257 auto FrameIndex = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
2258 auto PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex);
2259 SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo);
2261 // Load back the required element.
2262 StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
2264 // FIXME: This is to handle i1 vectors with elements promoted to i8.
2265 // i1 vector handling needs general improvement.
2266 if (N->getValueType(0).bitsLT(EltVT)) {
2267 SDValue Load = DAG.getLoad(EltVT, dl, Store, StackPtr,
2268 MachinePointerInfo::getUnknownStack(DAG.getMachineFunction()));
2269 return DAG.getZExtOrTrunc(Load, dl, N->getValueType(0));
2272 return DAG.getExtLoad(
2273 ISD::EXTLOAD, dl, N->getValueType(0), Store, StackPtr,
2274 MachinePointerInfo::getUnknownStack(DAG.getMachineFunction()), EltVT);
2277 SDValue DAGTypeLegalizer::SplitVecOp_ExtVecInRegOp(SDNode *N) {
2278 SDValue Lo, Hi;
2280 // *_EXTEND_VECTOR_INREG only reference the lower half of the input, so
2281 // splitting the result has the same effect as splitting the input operand.
2282 SplitVecRes_ExtVecInRegOp(N, Lo, Hi);
2284 return DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), N->getValueType(0), Lo, Hi);
2287 SDValue DAGTypeLegalizer::SplitVecOp_MGATHER(MaskedGatherSDNode *MGT,
2288 unsigned OpNo) {
2289 EVT LoVT, HiVT;
2290 SDLoc dl(MGT);
2291 std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MGT->getValueType(0));
2293 SDValue Ch = MGT->getChain();
2294 SDValue Ptr = MGT->getBasePtr();
2295 SDValue Index = MGT->getIndex();
2296 SDValue Scale = MGT->getScale();
2297 SDValue Mask = MGT->getMask();
2298 SDValue PassThru = MGT->getPassThru();
2299 unsigned Alignment = MGT->getOriginalAlignment();
2301 SDValue MaskLo, MaskHi;
2302 if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector)
2303 // Split Mask operand
2304 GetSplitVector(Mask, MaskLo, MaskHi);
2305 else
2306 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2308 EVT MemoryVT = MGT->getMemoryVT();
2309 EVT LoMemVT, HiMemVT;
2310 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2312 SDValue PassThruLo, PassThruHi;
2313 if (getTypeAction(PassThru.getValueType()) == TargetLowering::TypeSplitVector)
2314 GetSplitVector(PassThru, PassThruLo, PassThruHi);
2315 else
2316 std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2318 SDValue IndexHi, IndexLo;
2319 if (getTypeAction(Index.getValueType()) == TargetLowering::TypeSplitVector)
2320 GetSplitVector(Index, IndexLo, IndexHi);
2321 else
2322 std::tie(IndexLo, IndexHi) = DAG.SplitVector(Index, dl);
2324 MachineMemOperand *MMO = DAG.getMachineFunction().
2325 getMachineMemOperand(MGT->getPointerInfo(),
2326 MachineMemOperand::MOLoad, LoMemVT.getStoreSize(),
2327 Alignment, MGT->getAAInfo(), MGT->getRanges());
2329 SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo, Scale};
2330 SDValue Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoVT, dl,
2331 OpsLo, MMO, MGT->getIndexType());
2333 MMO = DAG.getMachineFunction().
2334 getMachineMemOperand(MGT->getPointerInfo(),
2335 MachineMemOperand::MOLoad, HiMemVT.getStoreSize(),
2336 Alignment, MGT->getAAInfo(),
2337 MGT->getRanges());
2339 SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi, Scale};
2340 SDValue Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiVT, dl,
2341 OpsHi, MMO, MGT->getIndexType());
2343 // Build a factor node to remember that this load is independent of the
2344 // other one.
2345 Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
2346 Hi.getValue(1));
2348 // Legalize the chain result - switch anything that used the old chain to
2349 // use the new one.
2350 ReplaceValueWith(SDValue(MGT, 1), Ch);
2352 SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, dl, MGT->getValueType(0), Lo,
2353 Hi);
2354 ReplaceValueWith(SDValue(MGT, 0), Res);
2355 return SDValue();
2358 SDValue DAGTypeLegalizer::SplitVecOp_MSTORE(MaskedStoreSDNode *N,
2359 unsigned OpNo) {
2360 SDValue Ch = N->getChain();
2361 SDValue Ptr = N->getBasePtr();
2362 SDValue Mask = N->getMask();
2363 SDValue Data = N->getValue();
2364 EVT MemoryVT = N->getMemoryVT();
2365 unsigned Alignment = N->getOriginalAlignment();
2366 SDLoc DL(N);
2368 EVT LoMemVT, HiMemVT;
2369 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2371 SDValue DataLo, DataHi;
2372 if (getTypeAction(Data.getValueType()) == TargetLowering::TypeSplitVector)
2373 // Split Data operand
2374 GetSplitVector(Data, DataLo, DataHi);
2375 else
2376 std::tie(DataLo, DataHi) = DAG.SplitVector(Data, DL);
2378 // Split Mask operand
2379 SDValue MaskLo, MaskHi;
2380 if (OpNo == 1 && Mask.getOpcode() == ISD::SETCC) {
2381 SplitVecRes_SETCC(Mask.getNode(), MaskLo, MaskHi);
2382 } else {
2383 if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector)
2384 GetSplitVector(Mask, MaskLo, MaskHi);
2385 else
2386 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, DL);
2389 SDValue Lo, Hi;
2390 MachineMemOperand *MMO = DAG.getMachineFunction().
2391 getMachineMemOperand(N->getPointerInfo(),
2392 MachineMemOperand::MOStore, LoMemVT.getStoreSize(),
2393 Alignment, N->getAAInfo(), N->getRanges());
2395 Lo = DAG.getMaskedStore(Ch, DL, DataLo, Ptr, MaskLo, LoMemVT, MMO,
2396 N->isTruncatingStore(),
2397 N->isCompressingStore());
2399 Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, DL, LoMemVT, DAG,
2400 N->isCompressingStore());
2401 unsigned HiOffset = LoMemVT.getStoreSize();
2403 MMO = DAG.getMachineFunction().getMachineMemOperand(
2404 N->getPointerInfo().getWithOffset(HiOffset), MachineMemOperand::MOStore,
2405 HiMemVT.getStoreSize(), Alignment, N->getAAInfo(),
2406 N->getRanges());
2408 Hi = DAG.getMaskedStore(Ch, DL, DataHi, Ptr, MaskHi, HiMemVT, MMO,
2409 N->isTruncatingStore(), N->isCompressingStore());
2411 // Build a factor node to remember that this store is independent of the
2412 // other one.
2413 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Lo, Hi);
2416 SDValue DAGTypeLegalizer::SplitVecOp_MSCATTER(MaskedScatterSDNode *N,
2417 unsigned OpNo) {
2418 SDValue Ch = N->getChain();
2419 SDValue Ptr = N->getBasePtr();
2420 SDValue Mask = N->getMask();
2421 SDValue Index = N->getIndex();
2422 SDValue Scale = N->getScale();
2423 SDValue Data = N->getValue();
2424 EVT MemoryVT = N->getMemoryVT();
2425 unsigned Alignment = N->getOriginalAlignment();
2426 SDLoc DL(N);
2428 // Split all operands
2429 EVT LoMemVT, HiMemVT;
2430 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2432 SDValue DataLo, DataHi;
2433 if (getTypeAction(Data.getValueType()) == TargetLowering::TypeSplitVector)
2434 // Split Data operand
2435 GetSplitVector(Data, DataLo, DataHi);
2436 else
2437 std::tie(DataLo, DataHi) = DAG.SplitVector(Data, DL);
2439 // Split Mask operand
2440 SDValue MaskLo, MaskHi;
2441 if (OpNo == 1 && Mask.getOpcode() == ISD::SETCC) {
2442 SplitVecRes_SETCC(Mask.getNode(), MaskLo, MaskHi);
2443 } else {
2444 if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector)
2445 GetSplitVector(Mask, MaskLo, MaskHi);
2446 else
2447 std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, DL);
2450 SDValue IndexHi, IndexLo;
2451 if (getTypeAction(Index.getValueType()) == TargetLowering::TypeSplitVector)
2452 GetSplitVector(Index, IndexLo, IndexHi);
2453 else
2454 std::tie(IndexLo, IndexHi) = DAG.SplitVector(Index, DL);
2456 SDValue Lo;
2457 MachineMemOperand *MMO = DAG.getMachineFunction().
2458 getMachineMemOperand(N->getPointerInfo(),
2459 MachineMemOperand::MOStore, LoMemVT.getStoreSize(),
2460 Alignment, N->getAAInfo(), N->getRanges());
2462 SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo, Scale};
2463 Lo = DAG.getMaskedScatter(DAG.getVTList(MVT::Other), DataLo.getValueType(),
2464 DL, OpsLo, MMO, N->getIndexType());
2466 MMO = DAG.getMachineFunction().
2467 getMachineMemOperand(N->getPointerInfo(),
2468 MachineMemOperand::MOStore, HiMemVT.getStoreSize(),
2469 Alignment, N->getAAInfo(), N->getRanges());
2471 // The order of the Scatter operation after split is well defined. The "Hi"
2472 // part comes after the "Lo". So these two operations should be chained one
2473 // after another.
2474 SDValue OpsHi[] = {Lo, DataHi, MaskHi, Ptr, IndexHi, Scale};
2475 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), DataHi.getValueType(),
2476 DL, OpsHi, MMO, N->getIndexType());
2479 SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
2480 assert(N->isUnindexed() && "Indexed store of vector?");
2481 assert(OpNo == 1 && "Can only split the stored value");
2482 SDLoc DL(N);
2484 bool isTruncating = N->isTruncatingStore();
2485 SDValue Ch = N->getChain();
2486 SDValue Ptr = N->getBasePtr();
2487 EVT MemoryVT = N->getMemoryVT();
2488 unsigned Alignment = N->getOriginalAlignment();
2489 MachineMemOperand::Flags MMOFlags = N->getMemOperand()->getFlags();
2490 AAMDNodes AAInfo = N->getAAInfo();
2491 SDValue Lo, Hi;
2492 GetSplitVector(N->getOperand(1), Lo, Hi);
2494 EVT LoMemVT, HiMemVT;
2495 std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2497 // Scalarize if the split halves are not byte-sized.
2498 if (!LoMemVT.isByteSized() || !HiMemVT.isByteSized())
2499 return TLI.scalarizeVectorStore(N, DAG);
2501 unsigned IncrementSize = LoMemVT.getSizeInBits()/8;
2503 if (isTruncating)
2504 Lo = DAG.getTruncStore(Ch, DL, Lo, Ptr, N->getPointerInfo(), LoMemVT,
2505 Alignment, MMOFlags, AAInfo);
2506 else
2507 Lo = DAG.getStore(Ch, DL, Lo, Ptr, N->getPointerInfo(), Alignment, MMOFlags,
2508 AAInfo);
2510 // Increment the pointer to the other half.
2511 Ptr = DAG.getObjectPtrOffset(DL, Ptr, IncrementSize);
2513 if (isTruncating)
2514 Hi = DAG.getTruncStore(Ch, DL, Hi, Ptr,
2515 N->getPointerInfo().getWithOffset(IncrementSize),
2516 HiMemVT, Alignment, MMOFlags, AAInfo);
2517 else
2518 Hi = DAG.getStore(Ch, DL, Hi, Ptr,
2519 N->getPointerInfo().getWithOffset(IncrementSize),
2520 Alignment, MMOFlags, AAInfo);
2522 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Lo, Hi);
2525 SDValue DAGTypeLegalizer::SplitVecOp_CONCAT_VECTORS(SDNode *N) {
2526 SDLoc DL(N);
2528 // The input operands all must have the same type, and we know the result
2529 // type is valid. Convert this to a buildvector which extracts all the
2530 // input elements.
2531 // TODO: If the input elements are power-two vectors, we could convert this to
2532 // a new CONCAT_VECTORS node with elements that are half-wide.
2533 SmallVector<SDValue, 32> Elts;
2534 EVT EltVT = N->getValueType(0).getVectorElementType();
2535 for (const SDValue &Op : N->op_values()) {
2536 for (unsigned i = 0, e = Op.getValueType().getVectorNumElements();
2537 i != e; ++i) {
2538 Elts.push_back(DAG.getNode(
2539 ISD::EXTRACT_VECTOR_ELT, DL, EltVT, Op,
2540 DAG.getConstant(i, DL, TLI.getVectorIdxTy(DAG.getDataLayout()))));
2544 return DAG.getBuildVector(N->getValueType(0), DL, Elts);
2547 SDValue DAGTypeLegalizer::SplitVecOp_TruncateHelper(SDNode *N) {
2548 // The result type is legal, but the input type is illegal. If splitting
2549 // ends up with the result type of each half still being legal, just
2550 // do that. If, however, that would result in an illegal result type,
2551 // we can try to get more clever with power-two vectors. Specifically,
2552 // split the input type, but also widen the result element size, then
2553 // concatenate the halves and truncate again. For example, consider a target
2554 // where v8i8 is legal and v8i32 is not (ARM, which doesn't have 256-bit
2555 // vectors). To perform a "%res = v8i8 trunc v8i32 %in" we do:
2556 // %inlo = v4i32 extract_subvector %in, 0
2557 // %inhi = v4i32 extract_subvector %in, 4
2558 // %lo16 = v4i16 trunc v4i32 %inlo
2559 // %hi16 = v4i16 trunc v4i32 %inhi
2560 // %in16 = v8i16 concat_vectors v4i16 %lo16, v4i16 %hi16
2561 // %res = v8i8 trunc v8i16 %in16
2563 // Without this transform, the original truncate would end up being
2564 // scalarized, which is pretty much always a last resort.
2565 SDValue InVec = N->getOperand(0);
2566 EVT InVT = InVec->getValueType(0);
2567 EVT OutVT = N->getValueType(0);
2568 unsigned NumElements = OutVT.getVectorNumElements();
2569 bool IsFloat = OutVT.isFloatingPoint();
2571 // Widening should have already made sure this is a power-two vector
2572 // if we're trying to split it at all. assert() that's true, just in case.
2573 assert(!(NumElements & 1) && "Splitting vector, but not in half!");
2575 unsigned InElementSize = InVT.getScalarSizeInBits();
2576 unsigned OutElementSize = OutVT.getScalarSizeInBits();
2578 // Determine the split output VT. If its legal we can just split dirctly.
2579 EVT LoOutVT, HiOutVT;
2580 std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
2581 assert(LoOutVT == HiOutVT && "Unequal split?");
2583 // If the input elements are only 1/2 the width of the result elements,
2584 // just use the normal splitting. Our trick only work if there's room
2585 // to split more than once.
2586 if (isTypeLegal(LoOutVT) ||
2587 InElementSize <= OutElementSize * 2)
2588 return SplitVecOp_UnaryOp(N);
2589 SDLoc DL(N);
2591 // Don't touch if this will be scalarized.
2592 EVT FinalVT = InVT;
2593 while (getTypeAction(FinalVT) == TargetLowering::TypeSplitVector)
2594 FinalVT = FinalVT.getHalfNumVectorElementsVT(*DAG.getContext());
2596 if (getTypeAction(FinalVT) == TargetLowering::TypeScalarizeVector)
2597 return SplitVecOp_UnaryOp(N);
2599 // Get the split input vector.
2600 SDValue InLoVec, InHiVec;
2601 GetSplitVector(InVec, InLoVec, InHiVec);
2603 // Truncate them to 1/2 the element size.
2604 EVT HalfElementVT = IsFloat ?
2605 EVT::getFloatingPointVT(InElementSize/2) :
2606 EVT::getIntegerVT(*DAG.getContext(), InElementSize/2);
2607 EVT HalfVT = EVT::getVectorVT(*DAG.getContext(), HalfElementVT,
2608 NumElements/2);
2609 SDValue HalfLo = DAG.getNode(N->getOpcode(), DL, HalfVT, InLoVec);
2610 SDValue HalfHi = DAG.getNode(N->getOpcode(), DL, HalfVT, InHiVec);
2611 // Concatenate them to get the full intermediate truncation result.
2612 EVT InterVT = EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
2613 SDValue InterVec = DAG.getNode(ISD::CONCAT_VECTORS, DL, InterVT, HalfLo,
2614 HalfHi);
2615 // Now finish up by truncating all the way down to the original result
2616 // type. This should normally be something that ends up being legal directly,
2617 // but in theory if a target has very wide vectors and an annoyingly
2618 // restricted set of legal types, this split can chain to build things up.
2619 return IsFloat
2620 ? DAG.getNode(ISD::FP_ROUND, DL, OutVT, InterVec,
2621 DAG.getTargetConstant(
2622 0, DL, TLI.getPointerTy(DAG.getDataLayout())))
2623 : DAG.getNode(ISD::TRUNCATE, DL, OutVT, InterVec);
2626 SDValue DAGTypeLegalizer::SplitVecOp_VSETCC(SDNode *N) {
2627 assert(N->getValueType(0).isVector() &&
2628 N->getOperand(0).getValueType().isVector() &&
2629 "Operand types must be vectors");
2630 // The result has a legal vector type, but the input needs splitting.
2631 SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
2632 SDLoc DL(N);
2633 GetSplitVector(N->getOperand(0), Lo0, Hi0);
2634 GetSplitVector(N->getOperand(1), Lo1, Hi1);
2635 unsigned PartElements = Lo0.getValueType().getVectorNumElements();
2636 EVT PartResVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, PartElements);
2637 EVT WideResVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, 2*PartElements);
2639 LoRes = DAG.getNode(ISD::SETCC, DL, PartResVT, Lo0, Lo1, N->getOperand(2));
2640 HiRes = DAG.getNode(ISD::SETCC, DL, PartResVT, Hi0, Hi1, N->getOperand(2));
2641 SDValue Con = DAG.getNode(ISD::CONCAT_VECTORS, DL, WideResVT, LoRes, HiRes);
2643 EVT OpVT = N->getOperand(0).getValueType();
2644 ISD::NodeType ExtendCode =
2645 TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT));
2646 return DAG.getNode(ExtendCode, DL, N->getValueType(0), Con);
2650 SDValue DAGTypeLegalizer::SplitVecOp_FP_ROUND(SDNode *N) {
2651 // The result has a legal vector type, but the input needs splitting.
2652 EVT ResVT = N->getValueType(0);
2653 SDValue Lo, Hi;
2654 SDLoc DL(N);
2655 GetSplitVector(N->getOperand(N->isStrictFPOpcode() ? 1 : 0), Lo, Hi);
2656 EVT InVT = Lo.getValueType();
2658 EVT OutVT = EVT::getVectorVT(*DAG.getContext(), ResVT.getVectorElementType(),
2659 InVT.getVectorNumElements());
2661 if (N->isStrictFPOpcode()) {
2662 Lo = DAG.getNode(N->getOpcode(), DL, { OutVT, MVT::Other },
2663 { N->getOperand(0), Lo, N->getOperand(2) });
2664 Hi = DAG.getNode(N->getOpcode(), DL, { OutVT, MVT::Other },
2665 { N->getOperand(0), Hi, N->getOperand(2) });
2666 // Legalize the chain result - switch anything that used the old chain to
2667 // use the new one.
2668 SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
2669 Lo.getValue(1), Hi.getValue(1));
2670 ReplaceValueWith(SDValue(N, 1), NewChain);
2671 } else {
2672 Lo = DAG.getNode(ISD::FP_ROUND, DL, OutVT, Lo, N->getOperand(1));
2673 Hi = DAG.getNode(ISD::FP_ROUND, DL, OutVT, Hi, N->getOperand(1));
2676 return DAG.getNode(ISD::CONCAT_VECTORS, DL, ResVT, Lo, Hi);
2679 SDValue DAGTypeLegalizer::SplitVecOp_FCOPYSIGN(SDNode *N) {
2680 // The result (and the first input) has a legal vector type, but the second
2681 // input needs splitting.
2682 return DAG.UnrollVectorOp(N, N->getValueType(0).getVectorNumElements());
2686 //===----------------------------------------------------------------------===//
2687 // Result Vector Widening
2688 //===----------------------------------------------------------------------===//
2690 void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
2691 LLVM_DEBUG(dbgs() << "Widen node result " << ResNo << ": "; N->dump(&DAG);
2692 dbgs() << "\n");
2694 // See if the target wants to custom widen this node.
2695 if (CustomWidenLowerNode(N, N->getValueType(ResNo)))
2696 return;
2698 SDValue Res = SDValue();
2699 switch (N->getOpcode()) {
2700 default:
2701 #ifndef NDEBUG
2702 dbgs() << "WidenVectorResult #" << ResNo << ": ";
2703 N->dump(&DAG);
2704 dbgs() << "\n";
2705 #endif
2706 llvm_unreachable("Do not know how to widen the result of this operator!");
2708 case ISD::MERGE_VALUES: Res = WidenVecRes_MERGE_VALUES(N, ResNo); break;
2709 case ISD::BITCAST: Res = WidenVecRes_BITCAST(N); break;
2710 case ISD::BUILD_VECTOR: Res = WidenVecRes_BUILD_VECTOR(N); break;
2711 case ISD::CONCAT_VECTORS: Res = WidenVecRes_CONCAT_VECTORS(N); break;
2712 case ISD::EXTRACT_SUBVECTOR: Res = WidenVecRes_EXTRACT_SUBVECTOR(N); break;
2713 case ISD::INSERT_VECTOR_ELT: Res = WidenVecRes_INSERT_VECTOR_ELT(N); break;
2714 case ISD::LOAD: Res = WidenVecRes_LOAD(N); break;
2715 case ISD::SCALAR_TO_VECTOR: Res = WidenVecRes_SCALAR_TO_VECTOR(N); break;
2716 case ISD::SIGN_EXTEND_INREG: Res = WidenVecRes_InregOp(N); break;
2717 case ISD::VSELECT:
2718 case ISD::SELECT: Res = WidenVecRes_SELECT(N); break;
2719 case ISD::SELECT_CC: Res = WidenVecRes_SELECT_CC(N); break;
2720 case ISD::SETCC: Res = WidenVecRes_SETCC(N); break;
2721 case ISD::UNDEF: Res = WidenVecRes_UNDEF(N); break;
2722 case ISD::VECTOR_SHUFFLE:
2723 Res = WidenVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N));
2724 break;
2725 case ISD::MLOAD:
2726 Res = WidenVecRes_MLOAD(cast<MaskedLoadSDNode>(N));
2727 break;
2728 case ISD::MGATHER:
2729 Res = WidenVecRes_MGATHER(cast<MaskedGatherSDNode>(N));
2730 break;
2732 case ISD::ADD:
2733 case ISD::AND:
2734 case ISD::MUL:
2735 case ISD::MULHS:
2736 case ISD::MULHU:
2737 case ISD::OR:
2738 case ISD::SUB:
2739 case ISD::XOR:
2740 case ISD::FMINNUM:
2741 case ISD::FMAXNUM:
2742 case ISD::FMINIMUM:
2743 case ISD::FMAXIMUM:
2744 case ISD::SMIN:
2745 case ISD::SMAX:
2746 case ISD::UMIN:
2747 case ISD::UMAX:
2748 case ISD::UADDSAT:
2749 case ISD::SADDSAT:
2750 case ISD::USUBSAT:
2751 case ISD::SSUBSAT:
2752 Res = WidenVecRes_Binary(N);
2753 break;
2755 case ISD::FADD:
2756 case ISD::FMUL:
2757 case ISD::FPOW:
2758 case ISD::FSUB:
2759 case ISD::FDIV:
2760 case ISD::FREM:
2761 case ISD::SDIV:
2762 case ISD::UDIV:
2763 case ISD::SREM:
2764 case ISD::UREM:
2765 Res = WidenVecRes_BinaryCanTrap(N);
2766 break;
2768 case ISD::SMULFIX:
2769 case ISD::SMULFIXSAT:
2770 case ISD::UMULFIX:
2771 case ISD::UMULFIXSAT:
2772 // These are binary operations, but with an extra operand that shouldn't
2773 // be widened (the scale).
2774 Res = WidenVecRes_BinaryWithExtraScalarOp(N);
2775 break;
2777 case ISD::STRICT_FADD:
2778 case ISD::STRICT_FSUB:
2779 case ISD::STRICT_FMUL:
2780 case ISD::STRICT_FDIV:
2781 case ISD::STRICT_FREM:
2782 case ISD::STRICT_FSQRT:
2783 case ISD::STRICT_FMA:
2784 case ISD::STRICT_FPOW:
2785 case ISD::STRICT_FPOWI:
2786 case ISD::STRICT_FSIN:
2787 case ISD::STRICT_FCOS:
2788 case ISD::STRICT_FEXP:
2789 case ISD::STRICT_FEXP2:
2790 case ISD::STRICT_FLOG:
2791 case ISD::STRICT_FLOG10:
2792 case ISD::STRICT_FLOG2:
2793 case ISD::STRICT_FRINT:
2794 case ISD::STRICT_FNEARBYINT:
2795 case ISD::STRICT_FMAXNUM:
2796 case ISD::STRICT_FMINNUM:
2797 case ISD::STRICT_FCEIL:
2798 case ISD::STRICT_FFLOOR:
2799 case ISD::STRICT_FROUND:
2800 case ISD::STRICT_FTRUNC:
2801 Res = WidenVecRes_StrictFP(N);
2802 break;
2804 case ISD::UADDO:
2805 case ISD::SADDO:
2806 case ISD::USUBO:
2807 case ISD::SSUBO:
2808 case ISD::UMULO:
2809 case ISD::SMULO:
2810 Res = WidenVecRes_OverflowOp(N, ResNo);
2811 break;
2813 case ISD::FCOPYSIGN:
2814 Res = WidenVecRes_FCOPYSIGN(N);
2815 break;
2817 case ISD::FPOWI:
2818 Res = WidenVecRes_POWI(N);
2819 break;
2821 case ISD::SHL:
2822 case ISD::SRA:
2823 case ISD::SRL:
2824 Res = WidenVecRes_Shift(N);
2825 break;
2827 case ISD::ANY_EXTEND_VECTOR_INREG:
2828 case ISD::SIGN_EXTEND_VECTOR_INREG:
2829 case ISD::ZERO_EXTEND_VECTOR_INREG:
2830 Res = WidenVecRes_EXTEND_VECTOR_INREG(N);
2831 break;
2833 case ISD::ANY_EXTEND:
2834 case ISD::FP_EXTEND:
2835 case ISD::FP_ROUND:
2836 case ISD::FP_TO_SINT:
2837 case ISD::FP_TO_UINT:
2838 case ISD::SIGN_EXTEND:
2839 case ISD::SINT_TO_FP:
2840 case ISD::TRUNCATE:
2841 case ISD::UINT_TO_FP:
2842 case ISD::ZERO_EXTEND:
2843 Res = WidenVecRes_Convert(N);
2844 break;
2846 case ISD::STRICT_FP_EXTEND:
2847 case ISD::STRICT_FP_ROUND:
2848 case ISD::STRICT_FP_TO_SINT:
2849 case ISD::STRICT_FP_TO_UINT:
2850 Res = WidenVecRes_Convert_StrictFP(N);
2851 break;
2853 case ISD::FABS:
2854 case ISD::FCEIL:
2855 case ISD::FCOS:
2856 case ISD::FEXP:
2857 case ISD::FEXP2:
2858 case ISD::FFLOOR:
2859 case ISD::FLOG:
2860 case ISD::FLOG10:
2861 case ISD::FLOG2:
2862 case ISD::FNEARBYINT:
2863 case ISD::FRINT:
2864 case ISD::FROUND:
2865 case ISD::FSIN:
2866 case ISD::FSQRT:
2867 case ISD::FTRUNC: {
2868 // We're going to widen this vector op to a legal type by padding with undef
2869 // elements. If the wide vector op is eventually going to be expanded to
2870 // scalar libcalls, then unroll into scalar ops now to avoid unnecessary
2871 // libcalls on the undef elements.
2872 EVT VT = N->getValueType(0);
2873 EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
2874 if (!TLI.isOperationLegalOrCustom(N->getOpcode(), WideVecVT) &&
2875 TLI.isOperationExpand(N->getOpcode(), VT.getScalarType())) {
2876 Res = DAG.UnrollVectorOp(N, WideVecVT.getVectorNumElements());
2877 break;
2880 // If the target has custom/legal support for the scalar FP intrinsic ops
2881 // (they are probably not destined to become libcalls), then widen those like
2882 // any other unary ops.
2883 LLVM_FALLTHROUGH;
2885 case ISD::ABS:
2886 case ISD::BITREVERSE:
2887 case ISD::BSWAP:
2888 case ISD::CTLZ:
2889 case ISD::CTLZ_ZERO_UNDEF:
2890 case ISD::CTPOP:
2891 case ISD::CTTZ:
2892 case ISD::CTTZ_ZERO_UNDEF:
2893 case ISD::FNEG:
2894 case ISD::FCANONICALIZE:
2895 Res = WidenVecRes_Unary(N);
2896 break;
2897 case ISD::FMA:
2898 Res = WidenVecRes_Ternary(N);
2899 break;
2902 // If Res is null, the sub-method took care of registering the result.
2903 if (Res.getNode())
2904 SetWidenedVector(SDValue(N, ResNo), Res);
2907 SDValue DAGTypeLegalizer::WidenVecRes_Ternary(SDNode *N) {
2908 // Ternary op widening.
2909 SDLoc dl(N);
2910 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
2911 SDValue InOp1 = GetWidenedVector(N->getOperand(0));
2912 SDValue InOp2 = GetWidenedVector(N->getOperand(1));
2913 SDValue InOp3 = GetWidenedVector(N->getOperand(2));
2914 return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
2917 SDValue DAGTypeLegalizer::WidenVecRes_Binary(SDNode *N) {
2918 // Binary op widening.
2919 SDLoc dl(N);
2920 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
2921 SDValue InOp1 = GetWidenedVector(N->getOperand(0));
2922 SDValue InOp2 = GetWidenedVector(N->getOperand(1));
2923 return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2, N->getFlags());
2926 SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(SDNode *N) {
2927 // Binary op widening, but with an extra operand that shouldn't be widened.
2928 SDLoc dl(N);
2929 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
2930 SDValue InOp1 = GetWidenedVector(N->getOperand(0));
2931 SDValue InOp2 = GetWidenedVector(N->getOperand(1));
2932 SDValue InOp3 = N->getOperand(2);
2933 return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
2934 N->getFlags());
2937 // Given a vector of operations that have been broken up to widen, see
2938 // if we can collect them together into the next widest legal VT. This
2939 // implementation is trap-safe.
2940 static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI,
2941 SmallVectorImpl<SDValue> &ConcatOps,
2942 unsigned ConcatEnd, EVT VT, EVT MaxVT,
2943 EVT WidenVT) {
2944 // Check to see if we have a single operation with the widen type.
2945 if (ConcatEnd == 1) {
2946 VT = ConcatOps[0].getValueType();
2947 if (VT == WidenVT)
2948 return ConcatOps[0];
2951 SDLoc dl(ConcatOps[0]);
2952 EVT WidenEltVT = WidenVT.getVectorElementType();
2954 // while (Some element of ConcatOps is not of type MaxVT) {
2955 // From the end of ConcatOps, collect elements of the same type and put
2956 // them into an op of the next larger supported type
2957 // }
2958 while (ConcatOps[ConcatEnd-1].getValueType() != MaxVT) {
2959 int Idx = ConcatEnd - 1;
2960 VT = ConcatOps[Idx--].getValueType();
2961 while (Idx >= 0 && ConcatOps[Idx].getValueType() == VT)
2962 Idx--;
2964 int NextSize = VT.isVector() ? VT.getVectorNumElements() : 1;
2965 EVT NextVT;
2966 do {
2967 NextSize *= 2;
2968 NextVT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NextSize);
2969 } while (!TLI.isTypeLegal(NextVT));
2971 if (!VT.isVector()) {
2972 // Scalar type, create an INSERT_VECTOR_ELEMENT of type NextVT
2973 SDValue VecOp = DAG.getUNDEF(NextVT);
2974 unsigned NumToInsert = ConcatEnd - Idx - 1;
2975 for (unsigned i = 0, OpIdx = Idx+1; i < NumToInsert; i++, OpIdx++) {
2976 VecOp = DAG.getNode(
2977 ISD::INSERT_VECTOR_ELT, dl, NextVT, VecOp, ConcatOps[OpIdx],
2978 DAG.getConstant(i, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
2980 ConcatOps[Idx+1] = VecOp;
2981 ConcatEnd = Idx + 2;
2982 } else {
2983 // Vector type, create a CONCAT_VECTORS of type NextVT
2984 SDValue undefVec = DAG.getUNDEF(VT);
2985 unsigned OpsToConcat = NextSize/VT.getVectorNumElements();
2986 SmallVector<SDValue, 16> SubConcatOps(OpsToConcat);
2987 unsigned RealVals = ConcatEnd - Idx - 1;
2988 unsigned SubConcatEnd = 0;
2989 unsigned SubConcatIdx = Idx + 1;
2990 while (SubConcatEnd < RealVals)
2991 SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
2992 while (SubConcatEnd < OpsToConcat)
2993 SubConcatOps[SubConcatEnd++] = undefVec;
2994 ConcatOps[SubConcatIdx] = DAG.getNode(ISD::CONCAT_VECTORS, dl,
2995 NextVT, SubConcatOps);
2996 ConcatEnd = SubConcatIdx + 1;
3000 // Check to see if we have a single operation with the widen type.
3001 if (ConcatEnd == 1) {
3002 VT = ConcatOps[0].getValueType();
3003 if (VT == WidenVT)
3004 return ConcatOps[0];
3007 // add undefs of size MaxVT until ConcatOps grows to length of WidenVT
3008 unsigned NumOps = WidenVT.getVectorNumElements()/MaxVT.getVectorNumElements();
3009 if (NumOps != ConcatEnd ) {
3010 SDValue UndefVal = DAG.getUNDEF(MaxVT);
3011 for (unsigned j = ConcatEnd; j < NumOps; ++j)
3012 ConcatOps[j] = UndefVal;
3014 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT,
3015 makeArrayRef(ConcatOps.data(), NumOps));
3018 SDValue DAGTypeLegalizer::WidenVecRes_BinaryCanTrap(SDNode *N) {
3019 // Binary op widening for operations that can trap.
3020 unsigned Opcode = N->getOpcode();
3021 SDLoc dl(N);
3022 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3023 EVT WidenEltVT = WidenVT.getVectorElementType();
3024 EVT VT = WidenVT;
3025 unsigned NumElts = VT.getVectorNumElements();
3026 const SDNodeFlags Flags = N->getFlags();
3027 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
3028 NumElts = NumElts / 2;
3029 VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts);
3032 if (NumElts != 1 && !TLI.canOpTrap(N->getOpcode(), VT)) {
3033 // Operation doesn't trap so just widen as normal.
3034 SDValue InOp1 = GetWidenedVector(N->getOperand(0));
3035 SDValue InOp2 = GetWidenedVector(N->getOperand(1));
3036 return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
3039 // No legal vector version so unroll the vector operation and then widen.
3040 if (NumElts == 1)
3041 return DAG.UnrollVectorOp(N, WidenVT.getVectorNumElements());
3043 // Since the operation can trap, apply operation on the original vector.
3044 EVT MaxVT = VT;
3045 SDValue InOp1 = GetWidenedVector(N->getOperand(0));
3046 SDValue InOp2 = GetWidenedVector(N->getOperand(1));
3047 unsigned CurNumElts = N->getValueType(0).getVectorNumElements();
3049 SmallVector<SDValue, 16> ConcatOps(CurNumElts);
3050 unsigned ConcatEnd = 0; // Current ConcatOps index.
3051 int Idx = 0; // Current Idx into input vectors.
3053 // NumElts := greatest legal vector size (at most WidenVT)
3054 // while (orig. vector has unhandled elements) {
3055 // take munches of size NumElts from the beginning and add to ConcatOps
3056 // NumElts := next smaller supported vector size or 1
3057 // }
3058 while (CurNumElts != 0) {
3059 while (CurNumElts >= NumElts) {
3060 SDValue EOp1 = DAG.getNode(
3061 ISD::EXTRACT_SUBVECTOR, dl, VT, InOp1,
3062 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
3063 SDValue EOp2 = DAG.getNode(
3064 ISD::EXTRACT_SUBVECTOR, dl, VT, InOp2,
3065 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
3066 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
3067 Idx += NumElts;
3068 CurNumElts -= NumElts;
3070 do {
3071 NumElts = NumElts / 2;
3072 VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts);
3073 } while (!TLI.isTypeLegal(VT) && NumElts != 1);
3075 if (NumElts == 1) {
3076 for (unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
3077 SDValue EOp1 = DAG.getNode(
3078 ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT, InOp1,
3079 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
3080 SDValue EOp2 = DAG.getNode(
3081 ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT, InOp2,
3082 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
3083 ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, WidenEltVT,
3084 EOp1, EOp2, Flags);
3086 CurNumElts = 0;
3090 return CollectOpsToWiden(DAG, TLI, ConcatOps, ConcatEnd, VT, MaxVT, WidenVT);
3093 SDValue DAGTypeLegalizer::WidenVecRes_StrictFP(SDNode *N) {
3094 // StrictFP op widening for operations that can trap.
3095 unsigned NumOpers = N->getNumOperands();
3096 unsigned Opcode = N->getOpcode();
3097 SDLoc dl(N);
3098 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3099 EVT WidenEltVT = WidenVT.getVectorElementType();
3100 EVT VT = WidenVT;
3101 unsigned NumElts = VT.getVectorNumElements();
3102 while (!TLI.isTypeLegal(VT) && NumElts != 1) {
3103 NumElts = NumElts / 2;
3104 VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts);
3107 // No legal vector version so unroll the vector operation and then widen.
3108 if (NumElts == 1)
3109 return UnrollVectorOp_StrictFP(N, WidenVT.getVectorNumElements());
3111 // Since the operation can trap, apply operation on the original vector.
3112 EVT MaxVT = VT;
3113 SmallVector<SDValue, 4> InOps;
3114 unsigned CurNumElts = N->getValueType(0).getVectorNumElements();
3116 SmallVector<SDValue, 16> ConcatOps(CurNumElts);
3117 SmallVector<SDValue, 16> Chains;
3118 unsigned ConcatEnd = 0; // Current ConcatOps index.
3119 int Idx = 0; // Current Idx into input vectors.
3121 // The Chain is the first operand.
3122 InOps.push_back(N->getOperand(0));
3124 // Now process the remaining operands.
3125 for (unsigned i = 1; i < NumOpers; ++i) {
3126 SDValue Oper = N->getOperand(i);
3128 if (Oper.getValueType().isVector()) {
3129 assert(Oper.getValueType() == N->getValueType(0) &&
3130 "Invalid operand type to widen!");
3131 Oper = GetWidenedVector(Oper);
3134 InOps.push_back(Oper);
3137 // NumElts := greatest legal vector size (at most WidenVT)
3138 // while (orig. vector has unhandled elements) {
3139 // take munches of size NumElts from the beginning and add to ConcatOps
3140 // NumElts := next smaller supported vector size or 1
3141 // }
3142 while (CurNumElts != 0) {
3143 while (CurNumElts >= NumElts) {
3144 SmallVector<SDValue, 4> EOps;
3146 for (unsigned i = 0; i < NumOpers; ++i) {
3147 SDValue Op = InOps[i];
3149 if (Op.getValueType().isVector())
3150 Op = DAG.getNode(
3151 ISD::EXTRACT_SUBVECTOR, dl, VT, Op,
3152 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
3154 EOps.push_back(Op);
3157 EVT OperVT[] = {VT, MVT::Other};
3158 SDValue Oper = DAG.getNode(Opcode, dl, OperVT, EOps);
3159 ConcatOps[ConcatEnd++] = Oper;
3160 Chains.push_back(Oper.getValue(1));
3161 Idx += NumElts;
3162 CurNumElts -= NumElts;
3164 do {
3165 NumElts = NumElts / 2;
3166 VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts);
3167 } while (!TLI.isTypeLegal(VT) && NumElts != 1);
3169 if (NumElts == 1) {
3170 for (unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
3171 SmallVector<SDValue, 4> EOps;
3173 for (unsigned i = 0; i < NumOpers; ++i) {
3174 SDValue Op = InOps[i];
3176 if (Op.getValueType().isVector())
3177 Op = DAG.getNode(
3178 ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT, Op,
3179 DAG.getConstant(Idx, dl,
3180 TLI.getVectorIdxTy(DAG.getDataLayout())));
3182 EOps.push_back(Op);
3185 EVT WidenVT[] = {WidenEltVT, MVT::Other};
3186 SDValue Oper = DAG.getNode(Opcode, dl, WidenVT, EOps);
3187 ConcatOps[ConcatEnd++] = Oper;
3188 Chains.push_back(Oper.getValue(1));
3190 CurNumElts = 0;
3194 // Build a factor node to remember all the Ops that have been created.
3195 SDValue NewChain;
3196 if (Chains.size() == 1)
3197 NewChain = Chains[0];
3198 else
3199 NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Chains);
3200 ReplaceValueWith(SDValue(N, 1), NewChain);
3202 return CollectOpsToWiden(DAG, TLI, ConcatOps, ConcatEnd, VT, MaxVT, WidenVT);
3205 SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(SDNode *N, unsigned ResNo) {
3206 SDLoc DL(N);
3207 EVT ResVT = N->getValueType(0);
3208 EVT OvVT = N->getValueType(1);
3209 EVT WideResVT, WideOvVT;
3210 SDValue WideLHS, WideRHS;
3212 // TODO: This might result in a widen/split loop.
3213 if (ResNo == 0) {
3214 WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
3215 WideOvVT = EVT::getVectorVT(
3216 *DAG.getContext(), OvVT.getVectorElementType(),
3217 WideResVT.getVectorNumElements());
3219 WideLHS = GetWidenedVector(N->getOperand(0));
3220 WideRHS = GetWidenedVector(N->getOperand(1));
3221 } else {
3222 WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
3223 WideResVT = EVT::getVectorVT(
3224 *DAG.getContext(), ResVT.getVectorElementType(),
3225 WideOvVT.getVectorNumElements());
3227 SDValue Zero = DAG.getConstant(
3228 0, DL, TLI.getVectorIdxTy(DAG.getDataLayout()));
3229 WideLHS = DAG.getNode(
3230 ISD::INSERT_SUBVECTOR, DL, WideResVT, DAG.getUNDEF(WideResVT),
3231 N->getOperand(0), Zero);
3232 WideRHS = DAG.getNode(
3233 ISD::INSERT_SUBVECTOR, DL, WideResVT, DAG.getUNDEF(WideResVT),
3234 N->getOperand(1), Zero);
3237 SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
3238 SDNode *WideNode = DAG.getNode(
3239 N->getOpcode(), DL, WideVTs, WideLHS, WideRHS).getNode();
3241 // Replace the other vector result not being explicitly widened here.
3242 unsigned OtherNo = 1 - ResNo;
3243 EVT OtherVT = N->getValueType(OtherNo);
3244 if (getTypeAction(OtherVT) == TargetLowering::TypeWidenVector) {
3245 SetWidenedVector(SDValue(N, OtherNo), SDValue(WideNode, OtherNo));
3246 } else {
3247 SDValue Zero = DAG.getConstant(
3248 0, DL, TLI.getVectorIdxTy(DAG.getDataLayout()));
3249 SDValue OtherVal = DAG.getNode(
3250 ISD::EXTRACT_SUBVECTOR, DL, OtherVT, SDValue(WideNode, OtherNo), Zero);
3251 ReplaceValueWith(SDValue(N, OtherNo), OtherVal);
3254 return SDValue(WideNode, ResNo);
3257 SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
3258 SDValue InOp = N->getOperand(0);
3259 SDLoc DL(N);
3261 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3262 unsigned WidenNumElts = WidenVT.getVectorNumElements();
3264 EVT InVT = InOp.getValueType();
3265 EVT InEltVT = InVT.getVectorElementType();
3266 EVT InWidenVT = EVT::getVectorVT(*DAG.getContext(), InEltVT, WidenNumElts);
3268 unsigned Opcode = N->getOpcode();
3269 unsigned InVTNumElts = InVT.getVectorNumElements();
3270 const SDNodeFlags Flags = N->getFlags();
3271 if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) {
3272 InOp = GetWidenedVector(N->getOperand(0));
3273 InVT = InOp.getValueType();
3274 InVTNumElts = InVT.getVectorNumElements();
3275 if (InVTNumElts == WidenNumElts) {
3276 if (N->getNumOperands() == 1)
3277 return DAG.getNode(Opcode, DL, WidenVT, InOp);
3278 return DAG.getNode(Opcode, DL, WidenVT, InOp, N->getOperand(1), Flags);
3280 if (WidenVT.getSizeInBits() == InVT.getSizeInBits()) {
3281 // If both input and result vector types are of same width, extend
3282 // operations should be done with SIGN/ZERO_EXTEND_VECTOR_INREG, which
3283 // accepts fewer elements in the result than in the input.
3284 if (Opcode == ISD::ANY_EXTEND)
3285 return DAG.getNode(ISD::ANY_EXTEND_VECTOR_INREG, DL, WidenVT, InOp);
3286 if (Opcode == ISD::SIGN_EXTEND)
3287 return DAG.getNode(ISD::SIGN_EXTEND_VECTOR_INREG, DL, WidenVT, InOp);
3288 if (Opcode == ISD::ZERO_EXTEND)
3289 return DAG.getNode(ISD::ZERO_EXTEND_VECTOR_INREG, DL, WidenVT, InOp);
3293 if (TLI.isTypeLegal(InWidenVT)) {
3294 // Because the result and the input are different vector types, widening
3295 // the result could create a legal type but widening the input might make
3296 // it an illegal type that might lead to repeatedly splitting the input
3297 // and then widening it. To avoid this, we widen the input only if
3298 // it results in a legal type.
3299 if (WidenNumElts % InVTNumElts == 0) {
3300 // Widen the input and call convert on the widened input vector.
3301 unsigned NumConcat = WidenNumElts/InVTNumElts;
3302 SmallVector<SDValue, 16> Ops(NumConcat, DAG.getUNDEF(InVT));
3303 Ops[0] = InOp;
3304 SDValue InVec = DAG.getNode(ISD::CONCAT_VECTORS, DL, InWidenVT, Ops);
3305 if (N->getNumOperands() == 1)
3306 return DAG.getNode(Opcode, DL, WidenVT, InVec);
3307 return DAG.getNode(Opcode, DL, WidenVT, InVec, N->getOperand(1), Flags);
3310 if (InVTNumElts % WidenNumElts == 0) {
3311 SDValue InVal = DAG.getNode(
3312 ISD::EXTRACT_SUBVECTOR, DL, InWidenVT, InOp,
3313 DAG.getConstant(0, DL, TLI.getVectorIdxTy(DAG.getDataLayout())));
3314 // Extract the input and convert the shorten input vector.
3315 if (N->getNumOperands() == 1)
3316 return DAG.getNode(Opcode, DL, WidenVT, InVal);
3317 return DAG.getNode(Opcode, DL, WidenVT, InVal, N->getOperand(1), Flags);
3321 // Otherwise unroll into some nasty scalar code and rebuild the vector.
3322 EVT EltVT = WidenVT.getVectorElementType();
3323 SmallVector<SDValue, 16> Ops(WidenNumElts, DAG.getUNDEF(EltVT));
3324 // Use the original element count so we don't do more scalar opts than
3325 // necessary.
3326 unsigned MinElts = N->getValueType(0).getVectorNumElements();
3327 for (unsigned i=0; i < MinElts; ++i) {
3328 SDValue Val = DAG.getNode(
3329 ISD::EXTRACT_VECTOR_ELT, DL, InEltVT, InOp,
3330 DAG.getConstant(i, DL, TLI.getVectorIdxTy(DAG.getDataLayout())));
3331 if (N->getNumOperands() == 1)
3332 Ops[i] = DAG.getNode(Opcode, DL, EltVT, Val);
3333 else
3334 Ops[i] = DAG.getNode(Opcode, DL, EltVT, Val, N->getOperand(1), Flags);
3337 return DAG.getBuildVector(WidenVT, DL, Ops);
3340 SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(SDNode *N) {
3341 SDValue InOp = N->getOperand(1);
3342 SDLoc DL(N);
3343 SmallVector<SDValue, 4> NewOps(N->op_begin(), N->op_end());
3345 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3346 unsigned WidenNumElts = WidenVT.getVectorNumElements();
3347 SmallVector<EVT, 2> WidenVTs = { WidenVT, MVT::Other };
3349 EVT InVT = InOp.getValueType();
3350 EVT InEltVT = InVT.getVectorElementType();
3352 unsigned Opcode = N->getOpcode();
3354 // FIXME: Optimizations need to be implemented here.
3356 // Otherwise unroll into some nasty scalar code and rebuild the vector.
3357 EVT EltVT = WidenVT.getVectorElementType();
3358 SmallVector<EVT, 2> EltVTs = { EltVT, MVT::Other };
3359 SmallVector<SDValue, 16> Ops(WidenNumElts, DAG.getUNDEF(EltVT));
3360 SmallVector<SDValue, 32> OpChains;
3361 // Use the original element count so we don't do more scalar opts than
3362 // necessary.
3363 unsigned MinElts = N->getValueType(0).getVectorNumElements();
3364 for (unsigned i=0; i < MinElts; ++i) {
3365 NewOps[1] = DAG.getNode(
3366 ISD::EXTRACT_VECTOR_ELT, DL, InEltVT, InOp,
3367 DAG.getConstant(i, DL, TLI.getVectorIdxTy(DAG.getDataLayout())));
3368 Ops[i] = DAG.getNode(Opcode, DL, EltVTs, NewOps);
3369 OpChains.push_back(Ops[i].getValue(1));
3371 SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OpChains);
3372 ReplaceValueWith(SDValue(N, 1), NewChain);
3374 return DAG.getBuildVector(WidenVT, DL, Ops);
3377 SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(SDNode *N) {
3378 unsigned Opcode = N->getOpcode();
3379 SDValue InOp = N->getOperand(0);
3380 SDLoc DL(N);
3382 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3383 EVT WidenSVT = WidenVT.getVectorElementType();
3384 unsigned WidenNumElts = WidenVT.getVectorNumElements();
3386 EVT InVT = InOp.getValueType();
3387 EVT InSVT = InVT.getVectorElementType();
3388 unsigned InVTNumElts = InVT.getVectorNumElements();
3390 if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) {
3391 InOp = GetWidenedVector(InOp);
3392 InVT = InOp.getValueType();
3393 if (InVT.getSizeInBits() == WidenVT.getSizeInBits()) {
3394 switch (Opcode) {
3395 case ISD::ANY_EXTEND_VECTOR_INREG:
3396 case ISD::SIGN_EXTEND_VECTOR_INREG:
3397 case ISD::ZERO_EXTEND_VECTOR_INREG:
3398 return DAG.getNode(Opcode, DL, WidenVT, InOp);
3403 // Unroll, extend the scalars and rebuild the vector.
3404 SmallVector<SDValue, 16> Ops;
3405 for (unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i != e; ++i) {
3406 SDValue Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, InSVT, InOp,
3407 DAG.getConstant(i, DL, TLI.getVectorIdxTy(DAG.getDataLayout())));
3408 switch (Opcode) {
3409 case ISD::ANY_EXTEND_VECTOR_INREG:
3410 Val = DAG.getNode(ISD::ANY_EXTEND, DL, WidenSVT, Val);
3411 break;
3412 case ISD::SIGN_EXTEND_VECTOR_INREG:
3413 Val = DAG.getNode(ISD::SIGN_EXTEND, DL, WidenSVT, Val);
3414 break;
3415 case ISD::ZERO_EXTEND_VECTOR_INREG:
3416 Val = DAG.getNode(ISD::ZERO_EXTEND, DL, WidenSVT, Val);
3417 break;
3418 default:
3419 llvm_unreachable("A *_EXTEND_VECTOR_INREG node was expected");
3421 Ops.push_back(Val);
3424 while (Ops.size() != WidenNumElts)
3425 Ops.push_back(DAG.getUNDEF(WidenSVT));
3427 return DAG.getBuildVector(WidenVT, DL, Ops);
3430 SDValue DAGTypeLegalizer::WidenVecRes_FCOPYSIGN(SDNode *N) {
3431 // If this is an FCOPYSIGN with same input types, we can treat it as a
3432 // normal (can trap) binary op.
3433 if (N->getOperand(0).getValueType() == N->getOperand(1).getValueType())
3434 return WidenVecRes_BinaryCanTrap(N);
3436 // If the types are different, fall back to unrolling.
3437 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3438 return DAG.UnrollVectorOp(N, WidenVT.getVectorNumElements());
3441 SDValue DAGTypeLegalizer::WidenVecRes_POWI(SDNode *N) {
3442 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3443 SDValue InOp = GetWidenedVector(N->getOperand(0));
3444 SDValue ShOp = N->getOperand(1);
3445 return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, InOp, ShOp);
3448 SDValue DAGTypeLegalizer::WidenVecRes_Shift(SDNode *N) {
3449 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3450 SDValue InOp = GetWidenedVector(N->getOperand(0));
3451 SDValue ShOp = N->getOperand(1);
3453 EVT ShVT = ShOp.getValueType();
3454 if (getTypeAction(ShVT) == TargetLowering::TypeWidenVector) {
3455 ShOp = GetWidenedVector(ShOp);
3456 ShVT = ShOp.getValueType();
3458 EVT ShWidenVT = EVT::getVectorVT(*DAG.getContext(),
3459 ShVT.getVectorElementType(),
3460 WidenVT.getVectorNumElements());
3461 if (ShVT != ShWidenVT)
3462 ShOp = ModifyToType(ShOp, ShWidenVT);
3464 return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, InOp, ShOp);
3467 SDValue DAGTypeLegalizer::WidenVecRes_Unary(SDNode *N) {
3468 // Unary op widening.
3469 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3470 SDValue InOp = GetWidenedVector(N->getOperand(0));
3471 return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, InOp);
3474 SDValue DAGTypeLegalizer::WidenVecRes_InregOp(SDNode *N) {
3475 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3476 EVT ExtVT = EVT::getVectorVT(*DAG.getContext(),
3477 cast<VTSDNode>(N->getOperand(1))->getVT()
3478 .getVectorElementType(),
3479 WidenVT.getVectorNumElements());
3480 SDValue WidenLHS = GetWidenedVector(N->getOperand(0));
3481 return DAG.getNode(N->getOpcode(), SDLoc(N),
3482 WidenVT, WidenLHS, DAG.getValueType(ExtVT));
3485 SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(SDNode *N, unsigned ResNo) {
3486 SDValue WidenVec = DisintegrateMERGE_VALUES(N, ResNo);
3487 return GetWidenedVector(WidenVec);
3490 SDValue DAGTypeLegalizer::WidenVecRes_BITCAST(SDNode *N) {
3491 SDValue InOp = N->getOperand(0);
3492 EVT InVT = InOp.getValueType();
3493 EVT VT = N->getValueType(0);
3494 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3495 SDLoc dl(N);
3497 switch (getTypeAction(InVT)) {
3498 case TargetLowering::TypeLegal:
3499 break;
3500 case TargetLowering::TypePromoteInteger:
3501 // If the incoming type is a vector that is being promoted, then
3502 // we know that the elements are arranged differently and that we
3503 // must perform the conversion using a stack slot.
3504 if (InVT.isVector())
3505 break;
3507 // If the InOp is promoted to the same size, convert it. Otherwise,
3508 // fall out of the switch and widen the promoted input.
3509 InOp = GetPromotedInteger(InOp);
3510 InVT = InOp.getValueType();
3511 if (WidenVT.bitsEq(InVT))
3512 return DAG.getNode(ISD::BITCAST, dl, WidenVT, InOp);
3513 break;
3514 case TargetLowering::TypeSoftenFloat:
3515 case TargetLowering::TypePromoteFloat:
3516 case TargetLowering::TypeExpandInteger:
3517 case TargetLowering::TypeExpandFloat:
3518 case TargetLowering::TypeScalarizeVector:
3519 case TargetLowering::TypeSplitVector:
3520 break;
3521 case TargetLowering::TypeWidenVector:
3522 // If the InOp is widened to the same size, convert it. Otherwise, fall
3523 // out of the switch and widen the widened input.
3524 InOp = GetWidenedVector(InOp);
3525 InVT = InOp.getValueType();
3526 if (WidenVT.bitsEq(InVT))
3527 // The input widens to the same size. Convert to the widen value.
3528 return DAG.getNode(ISD::BITCAST, dl, WidenVT, InOp);
3529 break;
3532 unsigned WidenSize = WidenVT.getSizeInBits();
3533 unsigned InSize = InVT.getSizeInBits();
3534 // x86mmx is not an acceptable vector element type, so don't try.
3535 if (WidenSize % InSize == 0 && InVT != MVT::x86mmx) {
3536 // Determine new input vector type. The new input vector type will use
3537 // the same element type (if its a vector) or use the input type as a
3538 // vector. It is the same size as the type to widen to.
3539 EVT NewInVT;
3540 unsigned NewNumElts = WidenSize / InSize;
3541 if (InVT.isVector()) {
3542 EVT InEltVT = InVT.getVectorElementType();
3543 NewInVT = EVT::getVectorVT(*DAG.getContext(), InEltVT,
3544 WidenSize / InEltVT.getSizeInBits());
3545 } else {
3546 NewInVT = EVT::getVectorVT(*DAG.getContext(), InVT, NewNumElts);
3549 if (TLI.isTypeLegal(NewInVT)) {
3550 SDValue NewVec;
3551 if (InVT.isVector()) {
3552 // Because the result and the input are different vector types, widening
3553 // the result could create a legal type but widening the input might make
3554 // it an illegal type that might lead to repeatedly splitting the input
3555 // and then widening it. To avoid this, we widen the input only if
3556 // it results in a legal type.
3557 SmallVector<SDValue, 16> Ops(NewNumElts, DAG.getUNDEF(InVT));
3558 Ops[0] = InOp;
3560 NewVec = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewInVT, Ops);
3561 } else {
3562 NewVec = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewInVT, InOp);
3564 return DAG.getNode(ISD::BITCAST, dl, WidenVT, NewVec);
3568 return CreateStackStoreLoad(InOp, WidenVT);
3571 SDValue DAGTypeLegalizer::WidenVecRes_BUILD_VECTOR(SDNode *N) {
3572 SDLoc dl(N);
3573 // Build a vector with undefined for the new nodes.
3574 EVT VT = N->getValueType(0);
3576 // Integer BUILD_VECTOR operands may be larger than the node's vector element
3577 // type. The UNDEFs need to have the same type as the existing operands.
3578 EVT EltVT = N->getOperand(0).getValueType();
3579 unsigned NumElts = VT.getVectorNumElements();
3581 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3582 unsigned WidenNumElts = WidenVT.getVectorNumElements();
3584 SmallVector<SDValue, 16> NewOps(N->op_begin(), N->op_end());
3585 assert(WidenNumElts >= NumElts && "Shrinking vector instead of widening!");
3586 NewOps.append(WidenNumElts - NumElts, DAG.getUNDEF(EltVT));
3588 return DAG.getBuildVector(WidenVT, dl, NewOps);
3591 SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) {
3592 EVT InVT = N->getOperand(0).getValueType();
3593 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3594 SDLoc dl(N);
3595 unsigned WidenNumElts = WidenVT.getVectorNumElements();
3596 unsigned NumInElts = InVT.getVectorNumElements();
3597 unsigned NumOperands = N->getNumOperands();
3599 bool InputWidened = false; // Indicates we need to widen the input.
3600 if (getTypeAction(InVT) != TargetLowering::TypeWidenVector) {
3601 if (WidenVT.getVectorNumElements() % InVT.getVectorNumElements() == 0) {
3602 // Add undef vectors to widen to correct length.
3603 unsigned NumConcat = WidenVT.getVectorNumElements() /
3604 InVT.getVectorNumElements();
3605 SDValue UndefVal = DAG.getUNDEF(InVT);
3606 SmallVector<SDValue, 16> Ops(NumConcat);
3607 for (unsigned i=0; i < NumOperands; ++i)
3608 Ops[i] = N->getOperand(i);
3609 for (unsigned i = NumOperands; i != NumConcat; ++i)
3610 Ops[i] = UndefVal;
3611 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, Ops);
3613 } else {
3614 InputWidened = true;
3615 if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
3616 // The inputs and the result are widen to the same value.
3617 unsigned i;
3618 for (i=1; i < NumOperands; ++i)
3619 if (!N->getOperand(i).isUndef())
3620 break;
3622 if (i == NumOperands)
3623 // Everything but the first operand is an UNDEF so just return the
3624 // widened first operand.
3625 return GetWidenedVector(N->getOperand(0));
3627 if (NumOperands == 2) {
3628 // Replace concat of two operands with a shuffle.
3629 SmallVector<int, 16> MaskOps(WidenNumElts, -1);
3630 for (unsigned i = 0; i < NumInElts; ++i) {
3631 MaskOps[i] = i;
3632 MaskOps[i + NumInElts] = i + WidenNumElts;
3634 return DAG.getVectorShuffle(WidenVT, dl,
3635 GetWidenedVector(N->getOperand(0)),
3636 GetWidenedVector(N->getOperand(1)),
3637 MaskOps);
3642 // Fall back to use extracts and build vector.
3643 EVT EltVT = WidenVT.getVectorElementType();
3644 SmallVector<SDValue, 16> Ops(WidenNumElts);
3645 unsigned Idx = 0;
3646 for (unsigned i=0; i < NumOperands; ++i) {
3647 SDValue InOp = N->getOperand(i);
3648 if (InputWidened)
3649 InOp = GetWidenedVector(InOp);
3650 for (unsigned j=0; j < NumInElts; ++j)
3651 Ops[Idx++] = DAG.getNode(
3652 ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
3653 DAG.getConstant(j, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
3655 SDValue UndefVal = DAG.getUNDEF(EltVT);
3656 for (; Idx < WidenNumElts; ++Idx)
3657 Ops[Idx] = UndefVal;
3658 return DAG.getBuildVector(WidenVT, dl, Ops);
3661 SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) {
3662 EVT VT = N->getValueType(0);
3663 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3664 unsigned WidenNumElts = WidenVT.getVectorNumElements();
3665 SDValue InOp = N->getOperand(0);
3666 SDValue Idx = N->getOperand(1);
3667 SDLoc dl(N);
3669 if (getTypeAction(InOp.getValueType()) == TargetLowering::TypeWidenVector)
3670 InOp = GetWidenedVector(InOp);
3672 EVT InVT = InOp.getValueType();
3674 // Check if we can just return the input vector after widening.
3675 uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
3676 if (IdxVal == 0 && InVT == WidenVT)
3677 return InOp;
3679 // Check if we can extract from the vector.
3680 unsigned InNumElts = InVT.getVectorNumElements();
3681 if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
3682 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, WidenVT, InOp, Idx);
3684 // We could try widening the input to the right length but for now, extract
3685 // the original elements, fill the rest with undefs and build a vector.
3686 SmallVector<SDValue, 16> Ops(WidenNumElts);
3687 EVT EltVT = VT.getVectorElementType();
3688 unsigned NumElts = VT.getVectorNumElements();
3689 unsigned i;
3690 for (i=0; i < NumElts; ++i)
3691 Ops[i] =
3692 DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
3693 DAG.getConstant(IdxVal + i, dl,
3694 TLI.getVectorIdxTy(DAG.getDataLayout())));
3696 SDValue UndefVal = DAG.getUNDEF(EltVT);
3697 for (; i < WidenNumElts; ++i)
3698 Ops[i] = UndefVal;
3699 return DAG.getBuildVector(WidenVT, dl, Ops);
3702 SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
3703 SDValue InOp = GetWidenedVector(N->getOperand(0));
3704 return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(N),
3705 InOp.getValueType(), InOp,
3706 N->getOperand(1), N->getOperand(2));
3709 SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) {
3710 LoadSDNode *LD = cast<LoadSDNode>(N);
3711 ISD::LoadExtType ExtType = LD->getExtensionType();
3713 SDValue Result;
3714 SmallVector<SDValue, 16> LdChain; // Chain for the series of load
3715 if (ExtType != ISD::NON_EXTLOAD)
3716 Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
3717 else
3718 Result = GenWidenVectorLoads(LdChain, LD);
3720 // If we generate a single load, we can use that for the chain. Otherwise,
3721 // build a factor node to remember the multiple loads are independent and
3722 // chain to that.
3723 SDValue NewChain;
3724 if (LdChain.size() == 1)
3725 NewChain = LdChain[0];
3726 else
3727 NewChain = DAG.getNode(ISD::TokenFactor, SDLoc(LD), MVT::Other, LdChain);
3729 // Modified the chain - switch anything that used the old chain to use
3730 // the new one.
3731 ReplaceValueWith(SDValue(N, 1), NewChain);
3733 return Result;
3736 SDValue DAGTypeLegalizer::WidenVecRes_MLOAD(MaskedLoadSDNode *N) {
3738 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),N->getValueType(0));
3739 SDValue Mask = N->getMask();
3740 EVT MaskVT = Mask.getValueType();
3741 SDValue PassThru = GetWidenedVector(N->getPassThru());
3742 ISD::LoadExtType ExtType = N->getExtensionType();
3743 SDLoc dl(N);
3745 // The mask should be widened as well
3746 EVT WideMaskVT = EVT::getVectorVT(*DAG.getContext(),
3747 MaskVT.getVectorElementType(),
3748 WidenVT.getVectorNumElements());
3749 Mask = ModifyToType(Mask, WideMaskVT, true);
3751 SDValue Res = DAG.getMaskedLoad(WidenVT, dl, N->getChain(), N->getBasePtr(),
3752 Mask, PassThru, N->getMemoryVT(),
3753 N->getMemOperand(), ExtType,
3754 N->isExpandingLoad());
3755 // Legalize the chain result - switch anything that used the old chain to
3756 // use the new one.
3757 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
3758 return Res;
3761 SDValue DAGTypeLegalizer::WidenVecRes_MGATHER(MaskedGatherSDNode *N) {
3763 EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3764 SDValue Mask = N->getMask();
3765 EVT MaskVT = Mask.getValueType();
3766 SDValue PassThru = GetWidenedVector(N->getPassThru());
3767 SDValue Scale = N->getScale();
3768 unsigned NumElts = WideVT.getVectorNumElements();
3769 SDLoc dl(N);
3771 // The mask should be widened as well
3772 EVT WideMaskVT = EVT::getVectorVT(*DAG.getContext(),
3773 MaskVT.getVectorElementType(),
3774 WideVT.getVectorNumElements());
3775 Mask = ModifyToType(Mask, WideMaskVT, true);
3777 // Widen the Index operand
3778 SDValue Index = N->getIndex();
3779 EVT WideIndexVT = EVT::getVectorVT(*DAG.getContext(),
3780 Index.getValueType().getScalarType(),
3781 NumElts);
3782 Index = ModifyToType(Index, WideIndexVT);
3783 SDValue Ops[] = { N->getChain(), PassThru, Mask, N->getBasePtr(), Index,
3784 Scale };
3785 SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
3786 N->getMemoryVT(), dl, Ops,
3787 N->getMemOperand(), N->getIndexType());
3789 // Legalize the chain result - switch anything that used the old chain to
3790 // use the new one.
3791 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
3792 return Res;
3795 SDValue DAGTypeLegalizer::WidenVecRes_SCALAR_TO_VECTOR(SDNode *N) {
3796 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
3797 return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N),
3798 WidenVT, N->getOperand(0));
3801 // Return true if this is a node that could have two SETCCs as operands.
3802 static inline bool isLogicalMaskOp(unsigned Opcode) {
3803 switch (Opcode) {
3804 case ISD::AND:
3805 case ISD::OR:
3806 case ISD::XOR:
3807 return true;
3809 return false;
3812 // This is used just for the assert in convertMask(). Check that this either
3813 // a SETCC or a previously handled SETCC by convertMask().
3814 #ifndef NDEBUG
3815 static inline bool isSETCCorConvertedSETCC(SDValue N) {
3816 if (N.getOpcode() == ISD::EXTRACT_SUBVECTOR)
3817 N = N.getOperand(0);
3818 else if (N.getOpcode() == ISD::CONCAT_VECTORS) {
3819 for (unsigned i = 1; i < N->getNumOperands(); ++i)
3820 if (!N->getOperand(i)->isUndef())
3821 return false;
3822 N = N.getOperand(0);
3825 if (N.getOpcode() == ISD::TRUNCATE)
3826 N = N.getOperand(0);
3827 else if (N.getOpcode() == ISD::SIGN_EXTEND)
3828 N = N.getOperand(0);
3830 if (isLogicalMaskOp(N.getOpcode()))
3831 return isSETCCorConvertedSETCC(N.getOperand(0)) &&
3832 isSETCCorConvertedSETCC(N.getOperand(1));
3834 return (N.getOpcode() == ISD::SETCC ||
3835 ISD::isBuildVectorOfConstantSDNodes(N.getNode()));
3837 #endif
3839 // Return a mask of vector type MaskVT to replace InMask. Also adjust MaskVT
3840 // to ToMaskVT if needed with vector extension or truncation.
3841 SDValue DAGTypeLegalizer::convertMask(SDValue InMask, EVT MaskVT,
3842 EVT ToMaskVT) {
3843 // Currently a SETCC or a AND/OR/XOR with two SETCCs are handled.
3844 // FIXME: This code seems to be too restrictive, we might consider
3845 // generalizing it or dropping it.
3846 assert(isSETCCorConvertedSETCC(InMask) && "Unexpected mask argument.");
3848 // Make a new Mask node, with a legal result VT.
3849 SmallVector<SDValue, 4> Ops;
3850 for (unsigned i = 0, e = InMask->getNumOperands(); i < e; ++i)
3851 Ops.push_back(InMask->getOperand(i));
3852 SDValue Mask = DAG.getNode(InMask->getOpcode(), SDLoc(InMask), MaskVT, Ops);
3854 // If MaskVT has smaller or bigger elements than ToMaskVT, a vector sign
3855 // extend or truncate is needed.
3856 LLVMContext &Ctx = *DAG.getContext();
3857 unsigned MaskScalarBits = MaskVT.getScalarSizeInBits();
3858 unsigned ToMaskScalBits = ToMaskVT.getScalarSizeInBits();
3859 if (MaskScalarBits < ToMaskScalBits) {
3860 EVT ExtVT = EVT::getVectorVT(Ctx, ToMaskVT.getVectorElementType(),
3861 MaskVT.getVectorNumElements());
3862 Mask = DAG.getNode(ISD::SIGN_EXTEND, SDLoc(Mask), ExtVT, Mask);
3863 } else if (MaskScalarBits > ToMaskScalBits) {
3864 EVT TruncVT = EVT::getVectorVT(Ctx, ToMaskVT.getVectorElementType(),
3865 MaskVT.getVectorNumElements());
3866 Mask = DAG.getNode(ISD::TRUNCATE, SDLoc(Mask), TruncVT, Mask);
3869 assert(Mask->getValueType(0).getScalarSizeInBits() ==
3870 ToMaskVT.getScalarSizeInBits() &&
3871 "Mask should have the right element size by now.");
3873 // Adjust Mask to the right number of elements.
3874 unsigned CurrMaskNumEls = Mask->getValueType(0).getVectorNumElements();
3875 if (CurrMaskNumEls > ToMaskVT.getVectorNumElements()) {
3876 MVT IdxTy = TLI.getVectorIdxTy(DAG.getDataLayout());
3877 SDValue ZeroIdx = DAG.getConstant(0, SDLoc(Mask), IdxTy);
3878 Mask = DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(Mask), ToMaskVT, Mask,
3879 ZeroIdx);
3880 } else if (CurrMaskNumEls < ToMaskVT.getVectorNumElements()) {
3881 unsigned NumSubVecs = (ToMaskVT.getVectorNumElements() / CurrMaskNumEls);
3882 EVT SubVT = Mask->getValueType(0);
3883 SmallVector<SDValue, 16> SubOps(NumSubVecs, DAG.getUNDEF(SubVT));
3884 SubOps[0] = Mask;
3885 Mask = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(Mask), ToMaskVT, SubOps);
3888 assert((Mask->getValueType(0) == ToMaskVT) &&
3889 "A mask of ToMaskVT should have been produced by now.");
3891 return Mask;
3894 // This method tries to handle VSELECT and its mask by legalizing operands
3895 // (which may require widening) and if needed adjusting the mask vector type
3896 // to match that of the VSELECT. Without it, many cases end up with
3897 // scalarization of the SETCC, with many unnecessary instructions.
3898 SDValue DAGTypeLegalizer::WidenVSELECTAndMask(SDNode *N) {
3899 LLVMContext &Ctx = *DAG.getContext();
3900 SDValue Cond = N->getOperand(0);
3902 if (N->getOpcode() != ISD::VSELECT)
3903 return SDValue();
3905 if (Cond->getOpcode() != ISD::SETCC && !isLogicalMaskOp(Cond->getOpcode()))
3906 return SDValue();
3908 // If this is a splitted VSELECT that was previously already handled, do
3909 // nothing.
3910 EVT CondVT = Cond->getValueType(0);
3911 if (CondVT.getScalarSizeInBits() != 1)
3912 return SDValue();
3914 EVT VSelVT = N->getValueType(0);
3915 // Only handle vector types which are a power of 2.
3916 if (!isPowerOf2_64(VSelVT.getSizeInBits()))
3917 return SDValue();
3919 // Don't touch if this will be scalarized.
3920 EVT FinalVT = VSelVT;
3921 while (getTypeAction(FinalVT) == TargetLowering::TypeSplitVector)
3922 FinalVT = FinalVT.getHalfNumVectorElementsVT(Ctx);
3924 if (FinalVT.getVectorNumElements() == 1)
3925 return SDValue();
3927 // If there is support for an i1 vector mask, don't touch.
3928 if (Cond.getOpcode() == ISD::SETCC) {
3929 EVT SetCCOpVT = Cond->getOperand(0).getValueType();
3930 while (TLI.getTypeAction(Ctx, SetCCOpVT) != TargetLowering::TypeLegal)
3931 SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
3932 EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
3933 if (SetCCResVT.getScalarSizeInBits() == 1)
3934 return SDValue();
3935 } else if (CondVT.getScalarType() == MVT::i1) {
3936 // If there is support for an i1 vector mask (or only scalar i1 conditions),
3937 // don't touch.
3938 while (TLI.getTypeAction(Ctx, CondVT) != TargetLowering::TypeLegal)
3939 CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
3941 if (CondVT.getScalarType() == MVT::i1)
3942 return SDValue();
3945 // Get the VT and operands for VSELECT, and widen if needed.
3946 SDValue VSelOp1 = N->getOperand(1);
3947 SDValue VSelOp2 = N->getOperand(2);
3948 if (getTypeAction(VSelVT) == TargetLowering::TypeWidenVector) {
3949 VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
3950 VSelOp1 = GetWidenedVector(VSelOp1);
3951 VSelOp2 = GetWidenedVector(VSelOp2);
3954 // The mask of the VSELECT should have integer elements.
3955 EVT ToMaskVT = VSelVT;
3956 if (!ToMaskVT.getScalarType().isInteger())
3957 ToMaskVT = ToMaskVT.changeVectorElementTypeToInteger();
3959 SDValue Mask;
3960 if (Cond->getOpcode() == ISD::SETCC) {
3961 EVT MaskVT = getSetCCResultType(Cond.getOperand(0).getValueType());
3962 Mask = convertMask(Cond, MaskVT, ToMaskVT);
3963 } else if (isLogicalMaskOp(Cond->getOpcode()) &&
3964 Cond->getOperand(0).getOpcode() == ISD::SETCC &&
3965 Cond->getOperand(1).getOpcode() == ISD::SETCC) {
3966 // Cond is (AND/OR/XOR (SETCC, SETCC))
3967 SDValue SETCC0 = Cond->getOperand(0);
3968 SDValue SETCC1 = Cond->getOperand(1);
3969 EVT VT0 = getSetCCResultType(SETCC0.getOperand(0).getValueType());
3970 EVT VT1 = getSetCCResultType(SETCC1.getOperand(0).getValueType());
3971 unsigned ScalarBits0 = VT0.getScalarSizeInBits();
3972 unsigned ScalarBits1 = VT1.getScalarSizeInBits();
3973 unsigned ScalarBits_ToMask = ToMaskVT.getScalarSizeInBits();
3974 EVT MaskVT;
3975 // If the two SETCCs have different VTs, either extend/truncate one of
3976 // them to the other "towards" ToMaskVT, or truncate one and extend the
3977 // other to ToMaskVT.
3978 if (ScalarBits0 != ScalarBits1) {
3979 EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
3980 EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
3981 if (ScalarBits_ToMask >= WideVT.getScalarSizeInBits())
3982 MaskVT = WideVT;
3983 else if (ScalarBits_ToMask <= NarrowVT.getScalarSizeInBits())
3984 MaskVT = NarrowVT;
3985 else
3986 MaskVT = ToMaskVT;
3987 } else
3988 // If the two SETCCs have the same VT, don't change it.
3989 MaskVT = VT0;
3991 // Make new SETCCs and logical nodes.
3992 SETCC0 = convertMask(SETCC0, VT0, MaskVT);
3993 SETCC1 = convertMask(SETCC1, VT1, MaskVT);
3994 Cond = DAG.getNode(Cond->getOpcode(), SDLoc(Cond), MaskVT, SETCC0, SETCC1);
3996 // Convert the logical op for VSELECT if needed.
3997 Mask = convertMask(Cond, MaskVT, ToMaskVT);
3998 } else
3999 return SDValue();
4001 return DAG.getNode(ISD::VSELECT, SDLoc(N), VSelVT, Mask, VSelOp1, VSelOp2);
4004 SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNode *N) {
4005 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4006 unsigned WidenNumElts = WidenVT.getVectorNumElements();
4008 SDValue Cond1 = N->getOperand(0);
4009 EVT CondVT = Cond1.getValueType();
4010 if (CondVT.isVector()) {
4011 if (SDValue Res = WidenVSELECTAndMask(N))
4012 return Res;
4014 EVT CondEltVT = CondVT.getVectorElementType();
4015 EVT CondWidenVT = EVT::getVectorVT(*DAG.getContext(),
4016 CondEltVT, WidenNumElts);
4017 if (getTypeAction(CondVT) == TargetLowering::TypeWidenVector)
4018 Cond1 = GetWidenedVector(Cond1);
4020 // If we have to split the condition there is no point in widening the
4021 // select. This would result in an cycle of widening the select ->
4022 // widening the condition operand -> splitting the condition operand ->
4023 // splitting the select -> widening the select. Instead split this select
4024 // further and widen the resulting type.
4025 if (getTypeAction(CondVT) == TargetLowering::TypeSplitVector) {
4026 SDValue SplitSelect = SplitVecOp_VSELECT(N, 0);
4027 SDValue Res = ModifyToType(SplitSelect, WidenVT);
4028 return Res;
4031 if (Cond1.getValueType() != CondWidenVT)
4032 Cond1 = ModifyToType(Cond1, CondWidenVT);
4035 SDValue InOp1 = GetWidenedVector(N->getOperand(1));
4036 SDValue InOp2 = GetWidenedVector(N->getOperand(2));
4037 assert(InOp1.getValueType() == WidenVT && InOp2.getValueType() == WidenVT);
4038 return DAG.getNode(N->getOpcode(), SDLoc(N),
4039 WidenVT, Cond1, InOp1, InOp2);
4042 SDValue DAGTypeLegalizer::WidenVecRes_SELECT_CC(SDNode *N) {
4043 SDValue InOp1 = GetWidenedVector(N->getOperand(2));
4044 SDValue InOp2 = GetWidenedVector(N->getOperand(3));
4045 return DAG.getNode(ISD::SELECT_CC, SDLoc(N),
4046 InOp1.getValueType(), N->getOperand(0),
4047 N->getOperand(1), InOp1, InOp2, N->getOperand(4));
4050 SDValue DAGTypeLegalizer::WidenVecRes_UNDEF(SDNode *N) {
4051 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4052 return DAG.getUNDEF(WidenVT);
4055 SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N) {
4056 EVT VT = N->getValueType(0);
4057 SDLoc dl(N);
4059 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4060 unsigned NumElts = VT.getVectorNumElements();
4061 unsigned WidenNumElts = WidenVT.getVectorNumElements();
4063 SDValue InOp1 = GetWidenedVector(N->getOperand(0));
4064 SDValue InOp2 = GetWidenedVector(N->getOperand(1));
4066 // Adjust mask based on new input vector length.
4067 SmallVector<int, 16> NewMask;
4068 for (unsigned i = 0; i != NumElts; ++i) {
4069 int Idx = N->getMaskElt(i);
4070 if (Idx < (int)NumElts)
4071 NewMask.push_back(Idx);
4072 else
4073 NewMask.push_back(Idx - NumElts + WidenNumElts);
4075 for (unsigned i = NumElts; i != WidenNumElts; ++i)
4076 NewMask.push_back(-1);
4077 return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
4080 SDValue DAGTypeLegalizer::WidenVecRes_SETCC(SDNode *N) {
4081 assert(N->getValueType(0).isVector() &&
4082 N->getOperand(0).getValueType().isVector() &&
4083 "Operands must be vectors");
4084 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4085 unsigned WidenNumElts = WidenVT.getVectorNumElements();
4087 SDValue InOp1 = N->getOperand(0);
4088 EVT InVT = InOp1.getValueType();
4089 assert(InVT.isVector() && "can not widen non-vector type");
4090 EVT WidenInVT = EVT::getVectorVT(*DAG.getContext(),
4091 InVT.getVectorElementType(), WidenNumElts);
4093 // The input and output types often differ here, and it could be that while
4094 // we'd prefer to widen the result type, the input operands have been split.
4095 // In this case, we also need to split the result of this node as well.
4096 if (getTypeAction(InVT) == TargetLowering::TypeSplitVector) {
4097 SDValue SplitVSetCC = SplitVecOp_VSETCC(N);
4098 SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
4099 return Res;
4102 // If the inputs also widen, handle them directly. Otherwise widen by hand.
4103 SDValue InOp2 = N->getOperand(1);
4104 if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) {
4105 InOp1 = GetWidenedVector(InOp1);
4106 InOp2 = GetWidenedVector(InOp2);
4107 } else {
4108 InOp1 = DAG.WidenVector(InOp1, SDLoc(N));
4109 InOp2 = DAG.WidenVector(InOp2, SDLoc(N));
4112 // Assume that the input and output will be widen appropriately. If not,
4113 // we will have to unroll it at some point.
4114 assert(InOp1.getValueType() == WidenInVT &&
4115 InOp2.getValueType() == WidenInVT &&
4116 "Input not widened to expected type!");
4117 (void)WidenInVT;
4118 return DAG.getNode(ISD::SETCC, SDLoc(N),
4119 WidenVT, InOp1, InOp2, N->getOperand(2));
4123 //===----------------------------------------------------------------------===//
4124 // Widen Vector Operand
4125 //===----------------------------------------------------------------------===//
4126 bool DAGTypeLegalizer::WidenVectorOperand(SDNode *N, unsigned OpNo) {
4127 LLVM_DEBUG(dbgs() << "Widen node operand " << OpNo << ": "; N->dump(&DAG);
4128 dbgs() << "\n");
4129 SDValue Res = SDValue();
4131 // See if the target wants to custom widen this node.
4132 if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
4133 return false;
4135 switch (N->getOpcode()) {
4136 default:
4137 #ifndef NDEBUG
4138 dbgs() << "WidenVectorOperand op #" << OpNo << ": ";
4139 N->dump(&DAG);
4140 dbgs() << "\n";
4141 #endif
4142 llvm_unreachable("Do not know how to widen this operator's operand!");
4144 case ISD::BITCAST: Res = WidenVecOp_BITCAST(N); break;
4145 case ISD::CONCAT_VECTORS: Res = WidenVecOp_CONCAT_VECTORS(N); break;
4146 case ISD::EXTRACT_SUBVECTOR: Res = WidenVecOp_EXTRACT_SUBVECTOR(N); break;
4147 case ISD::EXTRACT_VECTOR_ELT: Res = WidenVecOp_EXTRACT_VECTOR_ELT(N); break;
4148 case ISD::STORE: Res = WidenVecOp_STORE(N); break;
4149 case ISD::MSTORE: Res = WidenVecOp_MSTORE(N, OpNo); break;
4150 case ISD::MGATHER: Res = WidenVecOp_MGATHER(N, OpNo); break;
4151 case ISD::MSCATTER: Res = WidenVecOp_MSCATTER(N, OpNo); break;
4152 case ISD::SETCC: Res = WidenVecOp_SETCC(N); break;
4153 case ISD::VSELECT: Res = WidenVecOp_VSELECT(N); break;
4154 case ISD::FCOPYSIGN: Res = WidenVecOp_FCOPYSIGN(N); break;
4156 case ISD::ANY_EXTEND:
4157 case ISD::SIGN_EXTEND:
4158 case ISD::ZERO_EXTEND:
4159 Res = WidenVecOp_EXTEND(N);
4160 break;
4162 case ISD::FP_EXTEND:
4163 case ISD::STRICT_FP_EXTEND:
4164 case ISD::FP_TO_SINT:
4165 case ISD::STRICT_FP_TO_SINT:
4166 case ISD::FP_TO_UINT:
4167 case ISD::STRICT_FP_TO_UINT:
4168 case ISD::SINT_TO_FP:
4169 case ISD::UINT_TO_FP:
4170 case ISD::TRUNCATE:
4171 Res = WidenVecOp_Convert(N);
4172 break;
4174 case ISD::VECREDUCE_FADD:
4175 case ISD::VECREDUCE_FMUL:
4176 case ISD::VECREDUCE_ADD:
4177 case ISD::VECREDUCE_MUL:
4178 case ISD::VECREDUCE_AND:
4179 case ISD::VECREDUCE_OR:
4180 case ISD::VECREDUCE_XOR:
4181 case ISD::VECREDUCE_SMAX:
4182 case ISD::VECREDUCE_SMIN:
4183 case ISD::VECREDUCE_UMAX:
4184 case ISD::VECREDUCE_UMIN:
4185 case ISD::VECREDUCE_FMAX:
4186 case ISD::VECREDUCE_FMIN:
4187 Res = WidenVecOp_VECREDUCE(N);
4188 break;
4191 // If Res is null, the sub-method took care of registering the result.
4192 if (!Res.getNode()) return false;
4194 // If the result is N, the sub-method updated N in place. Tell the legalizer
4195 // core about this.
4196 if (Res.getNode() == N)
4197 return true;
4200 if (N->isStrictFPOpcode())
4201 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 2 &&
4202 "Invalid operand expansion");
4203 else
4204 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
4205 "Invalid operand expansion");
4207 ReplaceValueWith(SDValue(N, 0), Res);
4208 return false;
4211 SDValue DAGTypeLegalizer::WidenVecOp_EXTEND(SDNode *N) {
4212 SDLoc DL(N);
4213 EVT VT = N->getValueType(0);
4215 SDValue InOp = N->getOperand(0);
4216 assert(getTypeAction(InOp.getValueType()) ==
4217 TargetLowering::TypeWidenVector &&
4218 "Unexpected type action");
4219 InOp = GetWidenedVector(InOp);
4220 assert(VT.getVectorNumElements() <
4221 InOp.getValueType().getVectorNumElements() &&
4222 "Input wasn't widened!");
4224 // We may need to further widen the operand until it has the same total
4225 // vector size as the result.
4226 EVT InVT = InOp.getValueType();
4227 if (InVT.getSizeInBits() != VT.getSizeInBits()) {
4228 EVT InEltVT = InVT.getVectorElementType();
4229 for (int i = MVT::FIRST_VECTOR_VALUETYPE, e = MVT::LAST_VECTOR_VALUETYPE; i < e; ++i) {
4230 EVT FixedVT = (MVT::SimpleValueType)i;
4231 EVT FixedEltVT = FixedVT.getVectorElementType();
4232 if (TLI.isTypeLegal(FixedVT) &&
4233 FixedVT.getSizeInBits() == VT.getSizeInBits() &&
4234 FixedEltVT == InEltVT) {
4235 assert(FixedVT.getVectorNumElements() >= VT.getVectorNumElements() &&
4236 "Not enough elements in the fixed type for the operand!");
4237 assert(FixedVT.getVectorNumElements() != InVT.getVectorNumElements() &&
4238 "We can't have the same type as we started with!");
4239 if (FixedVT.getVectorNumElements() > InVT.getVectorNumElements())
4240 InOp = DAG.getNode(
4241 ISD::INSERT_SUBVECTOR, DL, FixedVT, DAG.getUNDEF(FixedVT), InOp,
4242 DAG.getConstant(0, DL, TLI.getVectorIdxTy(DAG.getDataLayout())));
4243 else
4244 InOp = DAG.getNode(
4245 ISD::EXTRACT_SUBVECTOR, DL, FixedVT, InOp,
4246 DAG.getConstant(0, DL, TLI.getVectorIdxTy(DAG.getDataLayout())));
4247 break;
4250 InVT = InOp.getValueType();
4251 if (InVT.getSizeInBits() != VT.getSizeInBits())
4252 // We couldn't find a legal vector type that was a widening of the input
4253 // and could be extended in-register to the result type, so we have to
4254 // scalarize.
4255 return WidenVecOp_Convert(N);
4258 // Use special DAG nodes to represent the operation of extending the
4259 // low lanes.
4260 switch (N->getOpcode()) {
4261 default:
4262 llvm_unreachable("Extend legalization on extend operation!");
4263 case ISD::ANY_EXTEND:
4264 return DAG.getNode(ISD::ANY_EXTEND_VECTOR_INREG, DL, VT, InOp);
4265 case ISD::SIGN_EXTEND:
4266 return DAG.getNode(ISD::SIGN_EXTEND_VECTOR_INREG, DL, VT, InOp);
4267 case ISD::ZERO_EXTEND:
4268 return DAG.getNode(ISD::ZERO_EXTEND_VECTOR_INREG, DL, VT, InOp);
4272 SDValue DAGTypeLegalizer::WidenVecOp_FCOPYSIGN(SDNode *N) {
4273 // The result (and first input) is legal, but the second input is illegal.
4274 // We can't do much to fix that, so just unroll and let the extracts off of
4275 // the second input be widened as needed later.
4276 return DAG.UnrollVectorOp(N);
4279 SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) {
4280 // Since the result is legal and the input is illegal.
4281 EVT VT = N->getValueType(0);
4282 EVT EltVT = VT.getVectorElementType();
4283 SDLoc dl(N);
4284 unsigned NumElts = VT.getVectorNumElements();
4285 SDValue InOp = N->getOperand(N->isStrictFPOpcode() ? 1 : 0);
4286 assert(getTypeAction(InOp.getValueType()) ==
4287 TargetLowering::TypeWidenVector &&
4288 "Unexpected type action");
4289 InOp = GetWidenedVector(InOp);
4290 EVT InVT = InOp.getValueType();
4291 unsigned Opcode = N->getOpcode();
4293 // See if a widened result type would be legal, if so widen the node.
4294 // FIXME: This isn't safe for StrictFP. Other optimization here is needed.
4295 EVT WideVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
4296 InVT.getVectorNumElements());
4297 if (TLI.isTypeLegal(WideVT) && !N->isStrictFPOpcode()) {
4298 SDValue Res;
4299 if (N->isStrictFPOpcode()) {
4300 Res = DAG.getNode(Opcode, dl, { WideVT, MVT::Other },
4301 { N->getOperand(0), InOp });
4302 // Legalize the chain result - switch anything that used the old chain to
4303 // use the new one.
4304 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
4305 } else
4306 Res = DAG.getNode(Opcode, dl, WideVT, InOp);
4307 return DAG.getNode(
4308 ISD::EXTRACT_SUBVECTOR, dl, VT, Res,
4309 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
4312 EVT InEltVT = InVT.getVectorElementType();
4314 // Unroll the convert into some scalar code and create a nasty build vector.
4315 SmallVector<SDValue, 16> Ops(NumElts);
4316 if (N->isStrictFPOpcode()) {
4317 SmallVector<SDValue, 4> NewOps(N->op_begin(), N->op_end());
4318 SmallVector<SDValue, 32> OpChains;
4319 for (unsigned i=0; i < NumElts; ++i) {
4320 NewOps[1] = DAG.getNode(
4321 ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp,
4322 DAG.getConstant(i, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
4323 Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
4324 OpChains.push_back(Ops[i].getValue(1));
4326 SDValue NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OpChains);
4327 ReplaceValueWith(SDValue(N, 1), NewChain);
4328 } else {
4329 for (unsigned i = 0; i < NumElts; ++i)
4330 Ops[i] = DAG.getNode(
4331 Opcode, dl, EltVT,
4332 DAG.getNode(
4333 ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp,
4334 DAG.getConstant(i, dl, TLI.getVectorIdxTy(DAG.getDataLayout()))));
4337 return DAG.getBuildVector(VT, dl, Ops);
4340 SDValue DAGTypeLegalizer::WidenVecOp_BITCAST(SDNode *N) {
4341 EVT VT = N->getValueType(0);
4342 SDValue InOp = GetWidenedVector(N->getOperand(0));
4343 EVT InWidenVT = InOp.getValueType();
4344 SDLoc dl(N);
4346 // Check if we can convert between two legal vector types and extract.
4347 unsigned InWidenSize = InWidenVT.getSizeInBits();
4348 unsigned Size = VT.getSizeInBits();
4349 // x86mmx is not an acceptable vector element type, so don't try.
4350 if (InWidenSize % Size == 0 && !VT.isVector() && VT != MVT::x86mmx) {
4351 unsigned NewNumElts = InWidenSize / Size;
4352 EVT NewVT = EVT::getVectorVT(*DAG.getContext(), VT, NewNumElts);
4353 if (TLI.isTypeLegal(NewVT)) {
4354 SDValue BitOp = DAG.getNode(ISD::BITCAST, dl, NewVT, InOp);
4355 return DAG.getNode(
4356 ISD::EXTRACT_VECTOR_ELT, dl, VT, BitOp,
4357 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
4361 // Handle a case like bitcast v12i8 -> v3i32. Normally that would get widened
4362 // to v16i8 -> v4i32, but for a target where v3i32 is legal but v12i8 is not,
4363 // we end up here. Handling the case here with EXTRACT_SUBVECTOR avoids
4364 // having to copy via memory.
4365 if (VT.isVector()) {
4366 EVT EltVT = VT.getVectorElementType();
4367 unsigned EltSize = EltVT.getSizeInBits();
4368 if (InWidenSize % EltSize == 0) {
4369 unsigned NewNumElts = InWidenSize / EltSize;
4370 EVT NewVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NewNumElts);
4371 if (TLI.isTypeLegal(NewVT)) {
4372 SDValue BitOp = DAG.getNode(ISD::BITCAST, dl, NewVT, InOp);
4373 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, BitOp,
4374 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
4379 return CreateStackStoreLoad(InOp, VT);
4382 SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) {
4383 EVT VT = N->getValueType(0);
4384 EVT EltVT = VT.getVectorElementType();
4385 EVT InVT = N->getOperand(0).getValueType();
4386 SDLoc dl(N);
4388 // If the widen width for this operand is the same as the width of the concat
4389 // and all but the first operand is undef, just use the widened operand.
4390 unsigned NumOperands = N->getNumOperands();
4391 if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
4392 unsigned i;
4393 for (i = 1; i < NumOperands; ++i)
4394 if (!N->getOperand(i).isUndef())
4395 break;
4397 if (i == NumOperands)
4398 return GetWidenedVector(N->getOperand(0));
4401 // Otherwise, fall back to a nasty build vector.
4402 unsigned NumElts = VT.getVectorNumElements();
4403 SmallVector<SDValue, 16> Ops(NumElts);
4405 unsigned NumInElts = InVT.getVectorNumElements();
4407 unsigned Idx = 0;
4408 for (unsigned i=0; i < NumOperands; ++i) {
4409 SDValue InOp = N->getOperand(i);
4410 assert(getTypeAction(InOp.getValueType()) ==
4411 TargetLowering::TypeWidenVector &&
4412 "Unexpected type action");
4413 InOp = GetWidenedVector(InOp);
4414 for (unsigned j=0; j < NumInElts; ++j)
4415 Ops[Idx++] = DAG.getNode(
4416 ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
4417 DAG.getConstant(j, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
4419 return DAG.getBuildVector(VT, dl, Ops);
4422 SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(SDNode *N) {
4423 SDValue InOp = GetWidenedVector(N->getOperand(0));
4424 return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(N),
4425 N->getValueType(0), InOp, N->getOperand(1));
4428 SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
4429 SDValue InOp = GetWidenedVector(N->getOperand(0));
4430 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N),
4431 N->getValueType(0), InOp, N->getOperand(1));
4434 SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) {
4435 // We have to widen the value, but we want only to store the original
4436 // vector type.
4437 StoreSDNode *ST = cast<StoreSDNode>(N);
4439 if (!ST->getMemoryVT().getScalarType().isByteSized())
4440 return TLI.scalarizeVectorStore(ST, DAG);
4442 SmallVector<SDValue, 16> StChain;
4443 if (ST->isTruncatingStore())
4444 GenWidenVectorTruncStores(StChain, ST);
4445 else
4446 GenWidenVectorStores(StChain, ST);
4448 if (StChain.size() == 1)
4449 return StChain[0];
4450 else
4451 return DAG.getNode(ISD::TokenFactor, SDLoc(ST), MVT::Other, StChain);
4454 SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(SDNode *N, unsigned OpNo) {
4455 assert((OpNo == 1 || OpNo == 3) &&
4456 "Can widen only data or mask operand of mstore");
4457 MaskedStoreSDNode *MST = cast<MaskedStoreSDNode>(N);
4458 SDValue Mask = MST->getMask();
4459 EVT MaskVT = Mask.getValueType();
4460 SDValue StVal = MST->getValue();
4461 SDLoc dl(N);
4463 if (OpNo == 1) {
4464 // Widen the value.
4465 StVal = GetWidenedVector(StVal);
4467 // The mask should be widened as well.
4468 EVT WideVT = StVal.getValueType();
4469 EVT WideMaskVT = EVT::getVectorVT(*DAG.getContext(),
4470 MaskVT.getVectorElementType(),
4471 WideVT.getVectorNumElements());
4472 Mask = ModifyToType(Mask, WideMaskVT, true);
4473 } else {
4474 // Widen the mask.
4475 EVT WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
4476 Mask = ModifyToType(Mask, WideMaskVT, true);
4478 EVT ValueVT = StVal.getValueType();
4479 EVT WideVT = EVT::getVectorVT(*DAG.getContext(),
4480 ValueVT.getVectorElementType(),
4481 WideMaskVT.getVectorNumElements());
4482 StVal = ModifyToType(StVal, WideVT);
4485 assert(Mask.getValueType().getVectorNumElements() ==
4486 StVal.getValueType().getVectorNumElements() &&
4487 "Mask and data vectors should have the same number of elements");
4488 return DAG.getMaskedStore(MST->getChain(), dl, StVal, MST->getBasePtr(),
4489 Mask, MST->getMemoryVT(), MST->getMemOperand(),
4490 false, MST->isCompressingStore());
4493 SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(SDNode *N, unsigned OpNo) {
4494 assert(OpNo == 4 && "Can widen only the index of mgather");
4495 auto *MG = cast<MaskedGatherSDNode>(N);
4496 SDValue DataOp = MG->getPassThru();
4497 SDValue Mask = MG->getMask();
4498 SDValue Scale = MG->getScale();
4500 // Just widen the index. It's allowed to have extra elements.
4501 SDValue Index = GetWidenedVector(MG->getIndex());
4503 SDLoc dl(N);
4504 SDValue Ops[] = {MG->getChain(), DataOp, Mask, MG->getBasePtr(), Index,
4505 Scale};
4506 SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl, Ops,
4507 MG->getMemOperand(), MG->getIndexType());
4508 ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
4509 ReplaceValueWith(SDValue(N, 0), Res.getValue(0));
4510 return SDValue();
4513 SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(SDNode *N, unsigned OpNo) {
4514 MaskedScatterSDNode *MSC = cast<MaskedScatterSDNode>(N);
4515 SDValue DataOp = MSC->getValue();
4516 SDValue Mask = MSC->getMask();
4517 SDValue Index = MSC->getIndex();
4518 SDValue Scale = MSC->getScale();
4520 if (OpNo == 1) {
4521 DataOp = GetWidenedVector(DataOp);
4522 unsigned NumElts = DataOp.getValueType().getVectorNumElements();
4524 // Widen index.
4525 EVT IndexVT = Index.getValueType();
4526 EVT WideIndexVT = EVT::getVectorVT(*DAG.getContext(),
4527 IndexVT.getVectorElementType(), NumElts);
4528 Index = ModifyToType(Index, WideIndexVT);
4530 // The mask should be widened as well.
4531 EVT MaskVT = Mask.getValueType();
4532 EVT WideMaskVT = EVT::getVectorVT(*DAG.getContext(),
4533 MaskVT.getVectorElementType(), NumElts);
4534 Mask = ModifyToType(Mask, WideMaskVT, true);
4535 } else if (OpNo == 4) {
4536 // Just widen the index. It's allowed to have extra elements.
4537 Index = GetWidenedVector(Index);
4538 } else
4539 llvm_unreachable("Can't widen this operand of mscatter");
4541 SDValue Ops[] = {MSC->getChain(), DataOp, Mask, MSC->getBasePtr(), Index,
4542 Scale};
4543 return DAG.getMaskedScatter(DAG.getVTList(MVT::Other),
4544 MSC->getMemoryVT(), SDLoc(N), Ops,
4545 MSC->getMemOperand(), MSC->getIndexType());
4548 SDValue DAGTypeLegalizer::WidenVecOp_SETCC(SDNode *N) {
4549 SDValue InOp0 = GetWidenedVector(N->getOperand(0));
4550 SDValue InOp1 = GetWidenedVector(N->getOperand(1));
4551 SDLoc dl(N);
4552 EVT VT = N->getValueType(0);
4554 // WARNING: In this code we widen the compare instruction with garbage.
4555 // This garbage may contain denormal floats which may be slow. Is this a real
4556 // concern ? Should we zero the unused lanes if this is a float compare ?
4558 // Get a new SETCC node to compare the newly widened operands.
4559 // Only some of the compared elements are legal.
4560 EVT SVT = getSetCCResultType(InOp0.getValueType());
4561 // The result type is legal, if its vXi1, keep vXi1 for the new SETCC.
4562 if (VT.getScalarType() == MVT::i1)
4563 SVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1,
4564 SVT.getVectorNumElements());
4566 SDValue WideSETCC = DAG.getNode(ISD::SETCC, SDLoc(N),
4567 SVT, InOp0, InOp1, N->getOperand(2));
4569 // Extract the needed results from the result vector.
4570 EVT ResVT = EVT::getVectorVT(*DAG.getContext(),
4571 SVT.getVectorElementType(),
4572 VT.getVectorNumElements());
4573 SDValue CC = DAG.getNode(
4574 ISD::EXTRACT_SUBVECTOR, dl, ResVT, WideSETCC,
4575 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
4577 EVT OpVT = N->getOperand(0).getValueType();
4578 ISD::NodeType ExtendCode =
4579 TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT));
4580 return DAG.getNode(ExtendCode, dl, VT, CC);
4583 SDValue DAGTypeLegalizer::WidenVecOp_VECREDUCE(SDNode *N) {
4584 SDLoc dl(N);
4585 SDValue Op = GetWidenedVector(N->getOperand(0));
4586 EVT OrigVT = N->getOperand(0).getValueType();
4587 EVT WideVT = Op.getValueType();
4588 EVT ElemVT = OrigVT.getVectorElementType();
4590 SDValue NeutralElem;
4591 switch (N->getOpcode()) {
4592 case ISD::VECREDUCE_ADD:
4593 case ISD::VECREDUCE_OR:
4594 case ISD::VECREDUCE_XOR:
4595 case ISD::VECREDUCE_UMAX:
4596 NeutralElem = DAG.getConstant(0, dl, ElemVT);
4597 break;
4598 case ISD::VECREDUCE_MUL:
4599 NeutralElem = DAG.getConstant(1, dl, ElemVT);
4600 break;
4601 case ISD::VECREDUCE_AND:
4602 case ISD::VECREDUCE_UMIN:
4603 NeutralElem = DAG.getAllOnesConstant(dl, ElemVT);
4604 break;
4605 case ISD::VECREDUCE_SMAX:
4606 NeutralElem = DAG.getConstant(
4607 APInt::getSignedMinValue(ElemVT.getSizeInBits()), dl, ElemVT);
4608 break;
4609 case ISD::VECREDUCE_SMIN:
4610 NeutralElem = DAG.getConstant(
4611 APInt::getSignedMaxValue(ElemVT.getSizeInBits()), dl, ElemVT);
4612 break;
4613 case ISD::VECREDUCE_FADD:
4614 NeutralElem = DAG.getConstantFP(0.0, dl, ElemVT);
4615 break;
4616 case ISD::VECREDUCE_FMUL:
4617 NeutralElem = DAG.getConstantFP(1.0, dl, ElemVT);
4618 break;
4619 case ISD::VECREDUCE_FMAX:
4620 NeutralElem = DAG.getConstantFP(
4621 std::numeric_limits<double>::infinity(), dl, ElemVT);
4622 break;
4623 case ISD::VECREDUCE_FMIN:
4624 NeutralElem = DAG.getConstantFP(
4625 -std::numeric_limits<double>::infinity(), dl, ElemVT);
4626 break;
4629 // Pad the vector with the neutral element.
4630 unsigned OrigElts = OrigVT.getVectorNumElements();
4631 unsigned WideElts = WideVT.getVectorNumElements();
4632 for (unsigned Idx = OrigElts; Idx < WideElts; Idx++)
4633 Op = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, WideVT, Op, NeutralElem,
4634 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
4636 return DAG.getNode(N->getOpcode(), dl, N->getValueType(0), Op, N->getFlags());
4639 SDValue DAGTypeLegalizer::WidenVecOp_VSELECT(SDNode *N) {
4640 // This only gets called in the case that the left and right inputs and
4641 // result are of a legal odd vector type, and the condition is illegal i1 of
4642 // the same odd width that needs widening.
4643 EVT VT = N->getValueType(0);
4644 assert(VT.isVector() && !VT.isPow2VectorType() && isTypeLegal(VT));
4646 SDValue Cond = GetWidenedVector(N->getOperand(0));
4647 SDValue LeftIn = DAG.WidenVector(N->getOperand(1), SDLoc(N));
4648 SDValue RightIn = DAG.WidenVector(N->getOperand(2), SDLoc(N));
4649 SDLoc DL(N);
4651 SDValue Select = DAG.getNode(N->getOpcode(), DL, LeftIn.getValueType(), Cond,
4652 LeftIn, RightIn);
4653 return DAG.getNode(
4654 ISD::EXTRACT_SUBVECTOR, DL, VT, Select,
4655 DAG.getConstant(0, DL, TLI.getVectorIdxTy(DAG.getDataLayout())));
4658 //===----------------------------------------------------------------------===//
4659 // Vector Widening Utilities
4660 //===----------------------------------------------------------------------===//
4662 // Utility function to find the type to chop up a widen vector for load/store
4663 // TLI: Target lowering used to determine legal types.
4664 // Width: Width left need to load/store.
4665 // WidenVT: The widen vector type to load to/store from
4666 // Align: If 0, don't allow use of a wider type
4667 // WidenEx: If Align is not 0, the amount additional we can load/store from.
4669 static EVT FindMemType(SelectionDAG& DAG, const TargetLowering &TLI,
4670 unsigned Width, EVT WidenVT,
4671 unsigned Align = 0, unsigned WidenEx = 0) {
4672 EVT WidenEltVT = WidenVT.getVectorElementType();
4673 unsigned WidenWidth = WidenVT.getSizeInBits();
4674 unsigned WidenEltWidth = WidenEltVT.getSizeInBits();
4675 unsigned AlignInBits = Align*8;
4677 // If we have one element to load/store, return it.
4678 EVT RetVT = WidenEltVT;
4679 if (Width == WidenEltWidth)
4680 return RetVT;
4682 // See if there is larger legal integer than the element type to load/store.
4683 unsigned VT;
4684 for (VT = (unsigned)MVT::LAST_INTEGER_VALUETYPE;
4685 VT >= (unsigned)MVT::FIRST_INTEGER_VALUETYPE; --VT) {
4686 EVT MemVT((MVT::SimpleValueType) VT);
4687 unsigned MemVTWidth = MemVT.getSizeInBits();
4688 if (MemVT.getSizeInBits() <= WidenEltWidth)
4689 break;
4690 auto Action = TLI.getTypeAction(*DAG.getContext(), MemVT);
4691 if ((Action == TargetLowering::TypeLegal ||
4692 Action == TargetLowering::TypePromoteInteger) &&
4693 (WidenWidth % MemVTWidth) == 0 &&
4694 isPowerOf2_32(WidenWidth / MemVTWidth) &&
4695 (MemVTWidth <= Width ||
4696 (Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
4697 if (MemVTWidth == WidenWidth)
4698 return MemVT;
4699 RetVT = MemVT;
4700 break;
4704 // See if there is a larger vector type to load/store that has the same vector
4705 // element type and is evenly divisible with the WidenVT.
4706 for (VT = (unsigned)MVT::LAST_VECTOR_VALUETYPE;
4707 VT >= (unsigned)MVT::FIRST_VECTOR_VALUETYPE; --VT) {
4708 EVT MemVT = (MVT::SimpleValueType) VT;
4709 unsigned MemVTWidth = MemVT.getSizeInBits();
4710 auto Action = TLI.getTypeAction(*DAG.getContext(), MemVT);
4711 if ((Action == TargetLowering::TypeLegal ||
4712 Action == TargetLowering::TypePromoteInteger) &&
4713 WidenEltVT == MemVT.getVectorElementType() &&
4714 (WidenWidth % MemVTWidth) == 0 &&
4715 isPowerOf2_32(WidenWidth / MemVTWidth) &&
4716 (MemVTWidth <= Width ||
4717 (Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
4718 if (RetVT.getSizeInBits() < MemVTWidth || MemVT == WidenVT)
4719 return MemVT;
4723 return RetVT;
4726 // Builds a vector type from scalar loads
4727 // VecTy: Resulting Vector type
4728 // LDOps: Load operators to build a vector type
4729 // [Start,End) the list of loads to use.
4730 static SDValue BuildVectorFromScalar(SelectionDAG& DAG, EVT VecTy,
4731 SmallVectorImpl<SDValue> &LdOps,
4732 unsigned Start, unsigned End) {
4733 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
4734 SDLoc dl(LdOps[Start]);
4735 EVT LdTy = LdOps[Start].getValueType();
4736 unsigned Width = VecTy.getSizeInBits();
4737 unsigned NumElts = Width / LdTy.getSizeInBits();
4738 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), LdTy, NumElts);
4740 unsigned Idx = 1;
4741 SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT,LdOps[Start]);
4743 for (unsigned i = Start + 1; i != End; ++i) {
4744 EVT NewLdTy = LdOps[i].getValueType();
4745 if (NewLdTy != LdTy) {
4746 NumElts = Width / NewLdTy.getSizeInBits();
4747 NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewLdTy, NumElts);
4748 VecOp = DAG.getNode(ISD::BITCAST, dl, NewVecVT, VecOp);
4749 // Readjust position and vector position based on new load type.
4750 Idx = Idx * LdTy.getSizeInBits() / NewLdTy.getSizeInBits();
4751 LdTy = NewLdTy;
4753 VecOp = DAG.getNode(
4754 ISD::INSERT_VECTOR_ELT, dl, NewVecVT, VecOp, LdOps[i],
4755 DAG.getConstant(Idx++, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
4757 return DAG.getNode(ISD::BITCAST, dl, VecTy, VecOp);
4760 SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
4761 LoadSDNode *LD) {
4762 // The strategy assumes that we can efficiently load power-of-two widths.
4763 // The routine chops the vector into the largest vector loads with the same
4764 // element type or scalar loads and then recombines it to the widen vector
4765 // type.
4766 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),LD->getValueType(0));
4767 unsigned WidenWidth = WidenVT.getSizeInBits();
4768 EVT LdVT = LD->getMemoryVT();
4769 SDLoc dl(LD);
4770 assert(LdVT.isVector() && WidenVT.isVector());
4771 assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType());
4773 // Load information
4774 SDValue Chain = LD->getChain();
4775 SDValue BasePtr = LD->getBasePtr();
4776 unsigned Align = LD->getAlignment();
4777 MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
4778 AAMDNodes AAInfo = LD->getAAInfo();
4780 int LdWidth = LdVT.getSizeInBits();
4781 int WidthDiff = WidenWidth - LdWidth;
4782 unsigned LdAlign = (!LD->isSimple()) ? 0 : Align; // Allow wider loads.
4784 // Find the vector type that can load from.
4785 EVT NewVT = FindMemType(DAG, TLI, LdWidth, WidenVT, LdAlign, WidthDiff);
4786 int NewVTWidth = NewVT.getSizeInBits();
4787 SDValue LdOp = DAG.getLoad(NewVT, dl, Chain, BasePtr, LD->getPointerInfo(),
4788 Align, MMOFlags, AAInfo);
4789 LdChain.push_back(LdOp.getValue(1));
4791 // Check if we can load the element with one instruction.
4792 if (LdWidth <= NewVTWidth) {
4793 if (!NewVT.isVector()) {
4794 unsigned NumElts = WidenWidth / NewVTWidth;
4795 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NumElts);
4796 SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
4797 return DAG.getNode(ISD::BITCAST, dl, WidenVT, VecOp);
4799 if (NewVT == WidenVT)
4800 return LdOp;
4802 assert(WidenWidth % NewVTWidth == 0);
4803 unsigned NumConcat = WidenWidth / NewVTWidth;
4804 SmallVector<SDValue, 16> ConcatOps(NumConcat);
4805 SDValue UndefVal = DAG.getUNDEF(NewVT);
4806 ConcatOps[0] = LdOp;
4807 for (unsigned i = 1; i != NumConcat; ++i)
4808 ConcatOps[i] = UndefVal;
4809 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, ConcatOps);
4812 // Load vector by using multiple loads from largest vector to scalar.
4813 SmallVector<SDValue, 16> LdOps;
4814 LdOps.push_back(LdOp);
4816 LdWidth -= NewVTWidth;
4817 unsigned Offset = 0;
4819 while (LdWidth > 0) {
4820 unsigned Increment = NewVTWidth / 8;
4821 Offset += Increment;
4822 BasePtr = DAG.getObjectPtrOffset(dl, BasePtr, Increment);
4824 SDValue L;
4825 if (LdWidth < NewVTWidth) {
4826 // The current type we are using is too large. Find a better size.
4827 NewVT = FindMemType(DAG, TLI, LdWidth, WidenVT, LdAlign, WidthDiff);
4828 NewVTWidth = NewVT.getSizeInBits();
4829 L = DAG.getLoad(NewVT, dl, Chain, BasePtr,
4830 LD->getPointerInfo().getWithOffset(Offset),
4831 MinAlign(Align, Increment), MMOFlags, AAInfo);
4832 LdChain.push_back(L.getValue(1));
4833 if (L->getValueType(0).isVector() && NewVTWidth >= LdWidth) {
4834 // Later code assumes the vector loads produced will be mergeable, so we
4835 // must pad the final entry up to the previous width. Scalars are
4836 // combined separately.
4837 SmallVector<SDValue, 16> Loads;
4838 Loads.push_back(L);
4839 unsigned size = L->getValueSizeInBits(0);
4840 while (size < LdOp->getValueSizeInBits(0)) {
4841 Loads.push_back(DAG.getUNDEF(L->getValueType(0)));
4842 size += L->getValueSizeInBits(0);
4844 L = DAG.getNode(ISD::CONCAT_VECTORS, dl, LdOp->getValueType(0), Loads);
4846 } else {
4847 L = DAG.getLoad(NewVT, dl, Chain, BasePtr,
4848 LD->getPointerInfo().getWithOffset(Offset),
4849 MinAlign(Align, Increment), MMOFlags, AAInfo);
4850 LdChain.push_back(L.getValue(1));
4853 LdOps.push_back(L);
4854 LdOp = L;
4856 LdWidth -= NewVTWidth;
4859 // Build the vector from the load operations.
4860 unsigned End = LdOps.size();
4861 if (!LdOps[0].getValueType().isVector())
4862 // All the loads are scalar loads.
4863 return BuildVectorFromScalar(DAG, WidenVT, LdOps, 0, End);
4865 // If the load contains vectors, build the vector using concat vector.
4866 // All of the vectors used to load are power-of-2, and the scalar loads can be
4867 // combined to make a power-of-2 vector.
4868 SmallVector<SDValue, 16> ConcatOps(End);
4869 int i = End - 1;
4870 int Idx = End;
4871 EVT LdTy = LdOps[i].getValueType();
4872 // First, combine the scalar loads to a vector.
4873 if (!LdTy.isVector()) {
4874 for (--i; i >= 0; --i) {
4875 LdTy = LdOps[i].getValueType();
4876 if (LdTy.isVector())
4877 break;
4879 ConcatOps[--Idx] = BuildVectorFromScalar(DAG, LdTy, LdOps, i + 1, End);
4881 ConcatOps[--Idx] = LdOps[i];
4882 for (--i; i >= 0; --i) {
4883 EVT NewLdTy = LdOps[i].getValueType();
4884 if (NewLdTy != LdTy) {
4885 // Create a larger vector.
4886 ConcatOps[End-1] = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewLdTy,
4887 makeArrayRef(&ConcatOps[Idx], End - Idx));
4888 Idx = End - 1;
4889 LdTy = NewLdTy;
4891 ConcatOps[--Idx] = LdOps[i];
4894 if (WidenWidth == LdTy.getSizeInBits() * (End - Idx))
4895 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT,
4896 makeArrayRef(&ConcatOps[Idx], End - Idx));
4898 // We need to fill the rest with undefs to build the vector.
4899 unsigned NumOps = WidenWidth / LdTy.getSizeInBits();
4900 SmallVector<SDValue, 16> WidenOps(NumOps);
4901 SDValue UndefVal = DAG.getUNDEF(LdTy);
4903 unsigned i = 0;
4904 for (; i != End-Idx; ++i)
4905 WidenOps[i] = ConcatOps[Idx+i];
4906 for (; i != NumOps; ++i)
4907 WidenOps[i] = UndefVal;
4909 return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, WidenOps);
4912 SDValue
4913 DAGTypeLegalizer::GenWidenVectorExtLoads(SmallVectorImpl<SDValue> &LdChain,
4914 LoadSDNode *LD,
4915 ISD::LoadExtType ExtType) {
4916 // For extension loads, it may not be more efficient to chop up the vector
4917 // and then extend it. Instead, we unroll the load and build a new vector.
4918 EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),LD->getValueType(0));
4919 EVT LdVT = LD->getMemoryVT();
4920 SDLoc dl(LD);
4921 assert(LdVT.isVector() && WidenVT.isVector());
4923 // Load information
4924 SDValue Chain = LD->getChain();
4925 SDValue BasePtr = LD->getBasePtr();
4926 unsigned Align = LD->getAlignment();
4927 MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
4928 AAMDNodes AAInfo = LD->getAAInfo();
4930 EVT EltVT = WidenVT.getVectorElementType();
4931 EVT LdEltVT = LdVT.getVectorElementType();
4932 unsigned NumElts = LdVT.getVectorNumElements();
4934 // Load each element and widen.
4935 unsigned WidenNumElts = WidenVT.getVectorNumElements();
4936 SmallVector<SDValue, 16> Ops(WidenNumElts);
4937 unsigned Increment = LdEltVT.getSizeInBits() / 8;
4938 Ops[0] =
4939 DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr, LD->getPointerInfo(),
4940 LdEltVT, Align, MMOFlags, AAInfo);
4941 LdChain.push_back(Ops[0].getValue(1));
4942 unsigned i = 0, Offset = Increment;
4943 for (i=1; i < NumElts; ++i, Offset += Increment) {
4944 SDValue NewBasePtr = DAG.getObjectPtrOffset(dl, BasePtr, Offset);
4945 Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
4946 LD->getPointerInfo().getWithOffset(Offset), LdEltVT,
4947 Align, MMOFlags, AAInfo);
4948 LdChain.push_back(Ops[i].getValue(1));
4951 // Fill the rest with undefs.
4952 SDValue UndefVal = DAG.getUNDEF(EltVT);
4953 for (; i != WidenNumElts; ++i)
4954 Ops[i] = UndefVal;
4956 return DAG.getBuildVector(WidenVT, dl, Ops);
4959 void DAGTypeLegalizer::GenWidenVectorStores(SmallVectorImpl<SDValue> &StChain,
4960 StoreSDNode *ST) {
4961 // The strategy assumes that we can efficiently store power-of-two widths.
4962 // The routine chops the vector into the largest vector stores with the same
4963 // element type or scalar stores.
4964 SDValue Chain = ST->getChain();
4965 SDValue BasePtr = ST->getBasePtr();
4966 unsigned Align = ST->getAlignment();
4967 MachineMemOperand::Flags MMOFlags = ST->getMemOperand()->getFlags();
4968 AAMDNodes AAInfo = ST->getAAInfo();
4969 SDValue ValOp = GetWidenedVector(ST->getValue());
4970 SDLoc dl(ST);
4972 EVT StVT = ST->getMemoryVT();
4973 unsigned StWidth = StVT.getSizeInBits();
4974 EVT ValVT = ValOp.getValueType();
4975 unsigned ValWidth = ValVT.getSizeInBits();
4976 EVT ValEltVT = ValVT.getVectorElementType();
4977 unsigned ValEltWidth = ValEltVT.getSizeInBits();
4978 assert(StVT.getVectorElementType() == ValEltVT);
4980 int Idx = 0; // current index to store
4981 unsigned Offset = 0; // offset from base to store
4982 while (StWidth != 0) {
4983 // Find the largest vector type we can store with.
4984 EVT NewVT = FindMemType(DAG, TLI, StWidth, ValVT);
4985 unsigned NewVTWidth = NewVT.getSizeInBits();
4986 unsigned Increment = NewVTWidth / 8;
4987 if (NewVT.isVector()) {
4988 unsigned NumVTElts = NewVT.getVectorNumElements();
4989 do {
4990 SDValue EOp = DAG.getNode(
4991 ISD::EXTRACT_SUBVECTOR, dl, NewVT, ValOp,
4992 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
4993 StChain.push_back(DAG.getStore(
4994 Chain, dl, EOp, BasePtr, ST->getPointerInfo().getWithOffset(Offset),
4995 MinAlign(Align, Offset), MMOFlags, AAInfo));
4996 StWidth -= NewVTWidth;
4997 Offset += Increment;
4998 Idx += NumVTElts;
5000 BasePtr = DAG.getObjectPtrOffset(dl, BasePtr, Increment);
5001 } while (StWidth != 0 && StWidth >= NewVTWidth);
5002 } else {
5003 // Cast the vector to the scalar type we can store.
5004 unsigned NumElts = ValWidth / NewVTWidth;
5005 EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NumElts);
5006 SDValue VecOp = DAG.getNode(ISD::BITCAST, dl, NewVecVT, ValOp);
5007 // Readjust index position based on new vector type.
5008 Idx = Idx * ValEltWidth / NewVTWidth;
5009 do {
5010 SDValue EOp = DAG.getNode(
5011 ISD::EXTRACT_VECTOR_ELT, dl, NewVT, VecOp,
5012 DAG.getConstant(Idx++, dl,
5013 TLI.getVectorIdxTy(DAG.getDataLayout())));
5014 StChain.push_back(DAG.getStore(
5015 Chain, dl, EOp, BasePtr, ST->getPointerInfo().getWithOffset(Offset),
5016 MinAlign(Align, Offset), MMOFlags, AAInfo));
5017 StWidth -= NewVTWidth;
5018 Offset += Increment;
5019 BasePtr = DAG.getObjectPtrOffset(dl, BasePtr, Increment);
5020 } while (StWidth != 0 && StWidth >= NewVTWidth);
5021 // Restore index back to be relative to the original widen element type.
5022 Idx = Idx * NewVTWidth / ValEltWidth;
5027 void
5028 DAGTypeLegalizer::GenWidenVectorTruncStores(SmallVectorImpl<SDValue> &StChain,
5029 StoreSDNode *ST) {
5030 // For extension loads, it may not be more efficient to truncate the vector
5031 // and then store it. Instead, we extract each element and then store it.
5032 SDValue Chain = ST->getChain();
5033 SDValue BasePtr = ST->getBasePtr();
5034 unsigned Align = ST->getAlignment();
5035 MachineMemOperand::Flags MMOFlags = ST->getMemOperand()->getFlags();
5036 AAMDNodes AAInfo = ST->getAAInfo();
5037 SDValue ValOp = GetWidenedVector(ST->getValue());
5038 SDLoc dl(ST);
5040 EVT StVT = ST->getMemoryVT();
5041 EVT ValVT = ValOp.getValueType();
5043 // It must be true that the wide vector type is bigger than where we need to
5044 // store.
5045 assert(StVT.isVector() && ValOp.getValueType().isVector());
5046 assert(StVT.bitsLT(ValOp.getValueType()));
5048 // For truncating stores, we can not play the tricks of chopping legal vector
5049 // types and bitcast it to the right type. Instead, we unroll the store.
5050 EVT StEltVT = StVT.getVectorElementType();
5051 EVT ValEltVT = ValVT.getVectorElementType();
5052 unsigned Increment = ValEltVT.getSizeInBits() / 8;
5053 unsigned NumElts = StVT.getVectorNumElements();
5054 SDValue EOp = DAG.getNode(
5055 ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp,
5056 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
5057 StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, BasePtr,
5058 ST->getPointerInfo(), StEltVT, Align,
5059 MMOFlags, AAInfo));
5060 unsigned Offset = Increment;
5061 for (unsigned i=1; i < NumElts; ++i, Offset += Increment) {
5062 SDValue NewBasePtr = DAG.getObjectPtrOffset(dl, BasePtr, Offset);
5063 SDValue EOp = DAG.getNode(
5064 ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp,
5065 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
5066 StChain.push_back(DAG.getTruncStore(
5067 Chain, dl, EOp, NewBasePtr, ST->getPointerInfo().getWithOffset(Offset),
5068 StEltVT, MinAlign(Align, Offset), MMOFlags, AAInfo));
5072 /// Modifies a vector input (widen or narrows) to a vector of NVT. The
5073 /// input vector must have the same element type as NVT.
5074 /// FillWithZeroes specifies that the vector should be widened with zeroes.
5075 SDValue DAGTypeLegalizer::ModifyToType(SDValue InOp, EVT NVT,
5076 bool FillWithZeroes) {
5077 // Note that InOp might have been widened so it might already have
5078 // the right width or it might need be narrowed.
5079 EVT InVT = InOp.getValueType();
5080 assert(InVT.getVectorElementType() == NVT.getVectorElementType() &&
5081 "input and widen element type must match");
5082 SDLoc dl(InOp);
5084 // Check if InOp already has the right width.
5085 if (InVT == NVT)
5086 return InOp;
5088 unsigned InNumElts = InVT.getVectorNumElements();
5089 unsigned WidenNumElts = NVT.getVectorNumElements();
5090 if (WidenNumElts > InNumElts && WidenNumElts % InNumElts == 0) {
5091 unsigned NumConcat = WidenNumElts / InNumElts;
5092 SmallVector<SDValue, 16> Ops(NumConcat);
5093 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, InVT) :
5094 DAG.getUNDEF(InVT);
5095 Ops[0] = InOp;
5096 for (unsigned i = 1; i != NumConcat; ++i)
5097 Ops[i] = FillVal;
5099 return DAG.getNode(ISD::CONCAT_VECTORS, dl, NVT, Ops);
5102 if (WidenNumElts < InNumElts && InNumElts % WidenNumElts)
5103 return DAG.getNode(
5104 ISD::EXTRACT_SUBVECTOR, dl, NVT, InOp,
5105 DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
5107 // Fall back to extract and build.
5108 SmallVector<SDValue, 16> Ops(WidenNumElts);
5109 EVT EltVT = NVT.getVectorElementType();
5110 unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
5111 unsigned Idx;
5112 for (Idx = 0; Idx < MinNumElts; ++Idx)
5113 Ops[Idx] = DAG.getNode(
5114 ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
5115 DAG.getConstant(Idx, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
5117 SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, EltVT) :
5118 DAG.getUNDEF(EltVT);
5119 for ( ; Idx < WidenNumElts; ++Idx)
5120 Ops[Idx] = FillVal;
5121 return DAG.getBuildVector(NVT, dl, Ops);