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