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