1 //===------- LegalizeVectorTypes.cpp - Legalization of vector types -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file performs vector type splitting and scalarization for LegalizeTypes.
10 // Scalarization is the act of changing a computation in an illegal one-element
11 // vector type to be a computation in its scalar element type.  For example,
12 // implementing <1 x f32> arithmetic in a scalar f32 register.  This is needed
13 // as a base case when scalarizing vector arithmetic like <4 x f32>, which
14 // eventually decomposes to scalars if the target doesn't support v4f32 or v2f32
15 // types.
16 // Splitting is the act of changing a computation in an invalid vector type to
17 // be a computation in two vectors of half the size.  For example, implementing
18 // <128 x f32> operations in terms of two <64 x f32> operations.
19 //
20 //===----------------------------------------------------------------------===//
21 
22 #include "LegalizeTypes.h"
23 #include "llvm/ADT/SmallBitVector.h"
24 #include "llvm/Analysis/MemoryLocation.h"
25 #include "llvm/Analysis/VectorUtils.h"
26 #include "llvm/IR/DataLayout.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/TypeSize.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include <numeric>
31 
32 using namespace llvm;
33 
34 #define DEBUG_TYPE "legalize-types"
35 
36 //===----------------------------------------------------------------------===//
37 //  Result Vector Scalarization: <1 x ty> -> ty.
38 //===----------------------------------------------------------------------===//
39 
ScalarizeVectorResult(SDNode * N,unsigned ResNo)40 void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
41   LLVM_DEBUG(dbgs() << "Scalarize node result " << ResNo << ": "; N->dump(&DAG);
42              dbgs() << "\n");
43   SDValue R = SDValue();
44 
45   switch (N->getOpcode()) {
46   default:
47 #ifndef NDEBUG
48     dbgs() << "ScalarizeVectorResult #" << ResNo << ": ";
49     N->dump(&DAG);
50     dbgs() << "\n";
51 #endif
52     report_fatal_error("Do not know how to scalarize the result of this "
53                        "operator!\n");
54 
55   case ISD::MERGE_VALUES:      R = ScalarizeVecRes_MERGE_VALUES(N, ResNo);break;
56   case ISD::BITCAST:           R = ScalarizeVecRes_BITCAST(N); break;
57   case ISD::BUILD_VECTOR:      R = ScalarizeVecRes_BUILD_VECTOR(N); break;
58   case ISD::EXTRACT_SUBVECTOR: R = ScalarizeVecRes_EXTRACT_SUBVECTOR(N); break;
59   case ISD::FP_ROUND:          R = ScalarizeVecRes_FP_ROUND(N); break;
60   case ISD::FPOWI:             R = ScalarizeVecRes_FPOWI(N); break;
61   case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break;
62   case ISD::LOAD:           R = ScalarizeVecRes_LOAD(cast<LoadSDNode>(N));break;
63   case ISD::SCALAR_TO_VECTOR:  R = ScalarizeVecRes_SCALAR_TO_VECTOR(N); break;
64   case ISD::SIGN_EXTEND_INREG: R = ScalarizeVecRes_InregOp(N); break;
65   case ISD::VSELECT:           R = ScalarizeVecRes_VSELECT(N); break;
66   case ISD::SELECT:            R = ScalarizeVecRes_SELECT(N); break;
67   case ISD::SELECT_CC:         R = ScalarizeVecRes_SELECT_CC(N); break;
68   case ISD::SETCC:             R = ScalarizeVecRes_SETCC(N); break;
69   case ISD::UNDEF:             R = ScalarizeVecRes_UNDEF(N); break;
70   case ISD::VECTOR_SHUFFLE:    R = ScalarizeVecRes_VECTOR_SHUFFLE(N); break;
71   case ISD::IS_FPCLASS:        R = ScalarizeVecRes_IS_FPCLASS(N); break;
72   case ISD::ANY_EXTEND_VECTOR_INREG:
73   case ISD::SIGN_EXTEND_VECTOR_INREG:
74   case ISD::ZERO_EXTEND_VECTOR_INREG:
75     R = ScalarizeVecRes_VecInregOp(N);
76     break;
77   case ISD::ABS:
78   case ISD::ANY_EXTEND:
79   case ISD::BITREVERSE:
80   case ISD::BSWAP:
81   case ISD::CTLZ:
82   case ISD::CTLZ_ZERO_UNDEF:
83   case ISD::CTPOP:
84   case ISD::CTTZ:
85   case ISD::CTTZ_ZERO_UNDEF:
86   case ISD::FABS:
87   case ISD::FCEIL:
88   case ISD::FCOS:
89   case ISD::FEXP:
90   case ISD::FEXP2:
91   case ISD::FFLOOR:
92   case ISD::FLOG:
93   case ISD::FLOG10:
94   case ISD::FLOG2:
95   case ISD::FNEARBYINT:
96   case ISD::FNEG:
97   case ISD::FREEZE:
98   case ISD::ARITH_FENCE:
99   case ISD::FP_EXTEND:
100   case ISD::FP_TO_SINT:
101   case ISD::FP_TO_UINT:
102   case ISD::FRINT:
103   case ISD::FROUND:
104   case ISD::FROUNDEVEN:
105   case ISD::FSIN:
106   case ISD::FSQRT:
107   case ISD::FTRUNC:
108   case ISD::SIGN_EXTEND:
109   case ISD::SINT_TO_FP:
110   case ISD::TRUNCATE:
111   case ISD::UINT_TO_FP:
112   case ISD::ZERO_EXTEND:
113   case ISD::FCANONICALIZE:
114     R = ScalarizeVecRes_UnaryOp(N);
115     break;
116 
117   case ISD::ADD:
118   case ISD::AND:
119   case ISD::FADD:
120   case ISD::FCOPYSIGN:
121   case ISD::FDIV:
122   case ISD::FMUL:
123   case ISD::FMINNUM:
124   case ISD::FMAXNUM:
125   case ISD::FMINNUM_IEEE:
126   case ISD::FMAXNUM_IEEE:
127   case ISD::FMINIMUM:
128   case ISD::FMAXIMUM:
129   case ISD::SMIN:
130   case ISD::SMAX:
131   case ISD::UMIN:
132   case ISD::UMAX:
133 
134   case ISD::SADDSAT:
135   case ISD::UADDSAT:
136   case ISD::SSUBSAT:
137   case ISD::USUBSAT:
138   case ISD::SSHLSAT:
139   case ISD::USHLSAT:
140 
141   case ISD::FPOW:
142   case ISD::FREM:
143   case ISD::FSUB:
144   case ISD::MUL:
145   case ISD::OR:
146   case ISD::SDIV:
147   case ISD::SREM:
148   case ISD::SUB:
149   case ISD::UDIV:
150   case ISD::UREM:
151   case ISD::XOR:
152   case ISD::SHL:
153   case ISD::SRA:
154   case ISD::SRL:
155   case ISD::ROTL:
156   case ISD::ROTR:
157     R = ScalarizeVecRes_BinOp(N);
158     break;
159   case ISD::FMA:
160   case ISD::FSHL:
161   case ISD::FSHR:
162     R = ScalarizeVecRes_TernaryOp(N);
163     break;
164 
165 #define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN)               \
166   case ISD::STRICT_##DAGN:
167 #include "llvm/IR/ConstrainedOps.def"
168     R = ScalarizeVecRes_StrictFPOp(N);
169     break;
170 
171   case ISD::FP_TO_UINT_SAT:
172   case ISD::FP_TO_SINT_SAT:
173     R = ScalarizeVecRes_FP_TO_XINT_SAT(N);
174     break;
175 
176   case ISD::UADDO:
177   case ISD::SADDO:
178   case ISD::USUBO:
179   case ISD::SSUBO:
180   case ISD::UMULO:
181   case ISD::SMULO:
182     R = ScalarizeVecRes_OverflowOp(N, ResNo);
183     break;
184   case ISD::SMULFIX:
185   case ISD::SMULFIXSAT:
186   case ISD::UMULFIX:
187   case ISD::UMULFIXSAT:
188   case ISD::SDIVFIX:
189   case ISD::SDIVFIXSAT:
190   case ISD::UDIVFIX:
191   case ISD::UDIVFIXSAT:
192     R = ScalarizeVecRes_FIX(N);
193     break;
194   }
195 
196   // If R is null, the sub-method took care of registering the result.
197   if (R.getNode())
198     SetScalarizedVector(SDValue(N, ResNo), R);
199 }
200 
ScalarizeVecRes_BinOp(SDNode * N)201 SDValue DAGTypeLegalizer::ScalarizeVecRes_BinOp(SDNode *N) {
202   SDValue LHS = GetScalarizedVector(N->getOperand(0));
203   SDValue RHS = GetScalarizedVector(N->getOperand(1));
204   return DAG.getNode(N->getOpcode(), SDLoc(N),
205                      LHS.getValueType(), LHS, RHS, N->getFlags());
206 }
207 
ScalarizeVecRes_TernaryOp(SDNode * N)208 SDValue DAGTypeLegalizer::ScalarizeVecRes_TernaryOp(SDNode *N) {
209   SDValue Op0 = GetScalarizedVector(N->getOperand(0));
210   SDValue Op1 = GetScalarizedVector(N->getOperand(1));
211   SDValue Op2 = GetScalarizedVector(N->getOperand(2));
212   return DAG.getNode(N->getOpcode(), SDLoc(N), Op0.getValueType(), Op0, Op1,
213                      Op2, N->getFlags());
214 }
215 
ScalarizeVecRes_FIX(SDNode * N)216 SDValue DAGTypeLegalizer::ScalarizeVecRes_FIX(SDNode *N) {
217   SDValue Op0 = GetScalarizedVector(N->getOperand(0));
218   SDValue Op1 = GetScalarizedVector(N->getOperand(1));
219   SDValue Op2 = N->getOperand(2);
220   return DAG.getNode(N->getOpcode(), SDLoc(N), Op0.getValueType(), Op0, Op1,
221                      Op2, N->getFlags());
222 }
223 
ScalarizeVecRes_StrictFPOp(SDNode * N)224 SDValue DAGTypeLegalizer::ScalarizeVecRes_StrictFPOp(SDNode *N) {
225   EVT VT = N->getValueType(0).getVectorElementType();
226   unsigned NumOpers = N->getNumOperands();
227   SDValue Chain = N->getOperand(0);
228   EVT ValueVTs[] = {VT, MVT::Other};
229   SDLoc dl(N);
230 
231   SmallVector<SDValue, 4> Opers(NumOpers);
232 
233   // The Chain is the first operand.
234   Opers[0] = Chain;
235 
236   // Now process the remaining operands.
237   for (unsigned i = 1; i < NumOpers; ++i) {
238     SDValue Oper = N->getOperand(i);
239     EVT OperVT = Oper.getValueType();
240 
241     if (OperVT.isVector()) {
242       if (getTypeAction(OperVT) == TargetLowering::TypeScalarizeVector)
243         Oper = GetScalarizedVector(Oper);
244       else
245         Oper = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
246                            OperVT.getVectorElementType(), Oper,
247                            DAG.getVectorIdxConstant(0, dl));
248     }
249 
250     Opers[i] = Oper;
251   }
252 
253   SDValue Result = DAG.getNode(N->getOpcode(), dl, DAG.getVTList(ValueVTs),
254                                Opers, N->getFlags());
255 
256   // Legalize the chain result - switch anything that used the old chain to
257   // use the new one.
258   ReplaceValueWith(SDValue(N, 1), Result.getValue(1));
259   return Result;
260 }
261 
ScalarizeVecRes_OverflowOp(SDNode * N,unsigned ResNo)262 SDValue DAGTypeLegalizer::ScalarizeVecRes_OverflowOp(SDNode *N,
263                                                      unsigned ResNo) {
264   SDLoc DL(N);
265   EVT ResVT = N->getValueType(0);
266   EVT OvVT = N->getValueType(1);
267 
268   SDValue ScalarLHS, ScalarRHS;
269   if (getTypeAction(ResVT) == TargetLowering::TypeScalarizeVector) {
270     ScalarLHS = GetScalarizedVector(N->getOperand(0));
271     ScalarRHS = GetScalarizedVector(N->getOperand(1));
272   } else {
273     SmallVector<SDValue, 1> ElemsLHS, ElemsRHS;
274     DAG.ExtractVectorElements(N->getOperand(0), ElemsLHS);
275     DAG.ExtractVectorElements(N->getOperand(1), ElemsRHS);
276     ScalarLHS = ElemsLHS[0];
277     ScalarRHS = ElemsRHS[0];
278   }
279 
280   SDVTList ScalarVTs = DAG.getVTList(
281       ResVT.getVectorElementType(), OvVT.getVectorElementType());
282   SDNode *ScalarNode = DAG.getNode(
283       N->getOpcode(), DL, ScalarVTs, ScalarLHS, ScalarRHS).getNode();
284   ScalarNode->setFlags(N->getFlags());
285 
286   // Replace the other vector result not being explicitly scalarized here.
287   unsigned OtherNo = 1 - ResNo;
288   EVT OtherVT = N->getValueType(OtherNo);
289   if (getTypeAction(OtherVT) == TargetLowering::TypeScalarizeVector) {
290     SetScalarizedVector(SDValue(N, OtherNo), SDValue(ScalarNode, OtherNo));
291   } else {
292     SDValue OtherVal = DAG.getNode(
293         ISD::SCALAR_TO_VECTOR, DL, OtherVT, SDValue(ScalarNode, OtherNo));
294     ReplaceValueWith(SDValue(N, OtherNo), OtherVal);
295   }
296 
297   return SDValue(ScalarNode, ResNo);
298 }
299 
ScalarizeVecRes_MERGE_VALUES(SDNode * N,unsigned ResNo)300 SDValue DAGTypeLegalizer::ScalarizeVecRes_MERGE_VALUES(SDNode *N,
301                                                        unsigned ResNo) {
302   SDValue Op = DisintegrateMERGE_VALUES(N, ResNo);
303   return GetScalarizedVector(Op);
304 }
305 
ScalarizeVecRes_BITCAST(SDNode * N)306 SDValue DAGTypeLegalizer::ScalarizeVecRes_BITCAST(SDNode *N) {
307   SDValue Op = N->getOperand(0);
308   if (Op.getValueType().isVector()
309       && Op.getValueType().getVectorNumElements() == 1
310       && !isSimpleLegalType(Op.getValueType()))
311     Op = GetScalarizedVector(Op);
312   EVT NewVT = N->getValueType(0).getVectorElementType();
313   return DAG.getNode(ISD::BITCAST, SDLoc(N),
314                      NewVT, Op);
315 }
316 
ScalarizeVecRes_BUILD_VECTOR(SDNode * N)317 SDValue DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(SDNode *N) {
318   EVT EltVT = N->getValueType(0).getVectorElementType();
319   SDValue InOp = N->getOperand(0);
320   // The BUILD_VECTOR operands may be of wider element types and
321   // we may need to truncate them back to the requested return type.
322   if (EltVT.isInteger())
323     return DAG.getNode(ISD::TRUNCATE, SDLoc(N), EltVT, InOp);
324   return InOp;
325 }
326 
ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode * N)327 SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N) {
328   return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N),
329                      N->getValueType(0).getVectorElementType(),
330                      N->getOperand(0), N->getOperand(1));
331 }
332 
ScalarizeVecRes_FP_ROUND(SDNode * N)333 SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_ROUND(SDNode *N) {
334   SDLoc DL(N);
335   SDValue Op = N->getOperand(0);
336   EVT OpVT = Op.getValueType();
337   // The result needs scalarizing, but it's not a given that the source does.
338   // See similar logic in ScalarizeVecRes_UnaryOp.
339   if (getTypeAction(OpVT) == TargetLowering::TypeScalarizeVector) {
340     Op = GetScalarizedVector(Op);
341   } else {
342     EVT VT = OpVT.getVectorElementType();
343     Op = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Op,
344                      DAG.getVectorIdxConstant(0, DL));
345   }
346   return DAG.getNode(ISD::FP_ROUND, DL,
347                      N->getValueType(0).getVectorElementType(), Op,
348                      N->getOperand(1));
349 }
350 
ScalarizeVecRes_FPOWI(SDNode * N)351 SDValue DAGTypeLegalizer::ScalarizeVecRes_FPOWI(SDNode *N) {
352   SDValue Op = GetScalarizedVector(N->getOperand(0));
353   return DAG.getNode(ISD::FPOWI, SDLoc(N),
354                      Op.getValueType(), Op, N->getOperand(1));
355 }
356 
ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode * N)357 SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N) {
358   // The value to insert may have a wider type than the vector element type,
359   // so be sure to truncate it to the element type if necessary.
360   SDValue Op = N->getOperand(1);
361   EVT EltVT = N->getValueType(0).getVectorElementType();
362   if (Op.getValueType() != EltVT)
363     // FIXME: Can this happen for floating point types?
364     Op = DAG.getNode(ISD::TRUNCATE, SDLoc(N), EltVT, Op);
365   return Op;
366 }
367 
ScalarizeVecRes_LOAD(LoadSDNode * N)368 SDValue DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) {
369   assert(N->isUnindexed() && "Indexed vector load?");
370 
371   SDValue Result = DAG.getLoad(
372       ISD::UNINDEXED, N->getExtensionType(),
373       N->getValueType(0).getVectorElementType(), SDLoc(N), N->getChain(),
374       N->getBasePtr(), DAG.getUNDEF(N->getBasePtr().getValueType()),
375       N->getPointerInfo(), N->getMemoryVT().getVectorElementType(),
376       N->getOriginalAlign(), N->getMemOperand()->getFlags(), N->getAAInfo());
377 
378   // Legalize the chain result - switch anything that used the old chain to
379   // use the new one.
380   ReplaceValueWith(SDValue(N, 1), Result.getValue(1));
381   return Result;
382 }
383 
ScalarizeVecRes_UnaryOp(SDNode * N)384 SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(SDNode *N) {
385   // Get the dest type - it doesn't always match the input type, e.g. int_to_fp.
386   EVT DestVT = N->getValueType(0).getVectorElementType();
387   SDValue Op = N->getOperand(0);
388   EVT OpVT = Op.getValueType();
389   SDLoc DL(N);
390   // The result needs scalarizing, but it's not a given that the source does.
391   // This is a workaround for targets where it's impossible to scalarize the
392   // result of a conversion, because the source type is legal.
393   // For instance, this happens on AArch64: v1i1 is illegal but v1i{8,16,32}
394   // are widened to v8i8, v4i16, and v2i32, which is legal, because v1i64 is
395   // legal and was not scalarized.
396   // See the similar logic in ScalarizeVecRes_SETCC
397   if (getTypeAction(OpVT) == TargetLowering::TypeScalarizeVector) {
398     Op = GetScalarizedVector(Op);
399   } else {
400     EVT VT = OpVT.getVectorElementType();
401     Op = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Op,
402                      DAG.getVectorIdxConstant(0, DL));
403   }
404   return DAG.getNode(N->getOpcode(), SDLoc(N), DestVT, Op, N->getFlags());
405 }
406 
ScalarizeVecRes_InregOp(SDNode * N)407 SDValue DAGTypeLegalizer::ScalarizeVecRes_InregOp(SDNode *N) {
408   EVT EltVT = N->getValueType(0).getVectorElementType();
409   EVT ExtVT = cast<VTSDNode>(N->getOperand(1))->getVT().getVectorElementType();
410   SDValue LHS = GetScalarizedVector(N->getOperand(0));
411   return DAG.getNode(N->getOpcode(), SDLoc(N), EltVT,
412                      LHS, DAG.getValueType(ExtVT));
413 }
414 
ScalarizeVecRes_VecInregOp(SDNode * N)415 SDValue DAGTypeLegalizer::ScalarizeVecRes_VecInregOp(SDNode *N) {
416   SDLoc DL(N);
417   SDValue Op = N->getOperand(0);
418 
419   EVT OpVT = Op.getValueType();
420   EVT OpEltVT = OpVT.getVectorElementType();
421   EVT EltVT = N->getValueType(0).getVectorElementType();
422 
423   if (getTypeAction(OpVT) == TargetLowering::TypeScalarizeVector) {
424     Op = GetScalarizedVector(Op);
425   } else {
426     Op = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, OpEltVT, Op,
427                      DAG.getVectorIdxConstant(0, DL));
428   }
429 
430   switch (N->getOpcode()) {
431   case ISD::ANY_EXTEND_VECTOR_INREG:
432     return DAG.getNode(ISD::ANY_EXTEND, DL, EltVT, Op);
433   case ISD::SIGN_EXTEND_VECTOR_INREG:
434     return DAG.getNode(ISD::SIGN_EXTEND, DL, EltVT, Op);
435   case ISD::ZERO_EXTEND_VECTOR_INREG:
436     return DAG.getNode(ISD::ZERO_EXTEND, DL, EltVT, Op);
437   }
438 
439   llvm_unreachable("Illegal extend_vector_inreg opcode");
440 }
441 
ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode * N)442 SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N) {
443   // If the operand is wider than the vector element type then it is implicitly
444   // truncated.  Make that explicit here.
445   EVT EltVT = N->getValueType(0).getVectorElementType();
446   SDValue InOp = N->getOperand(0);
447   if (InOp.getValueType() != EltVT)
448     return DAG.getNode(ISD::TRUNCATE, SDLoc(N), EltVT, InOp);
449   return InOp;
450 }
451 
ScalarizeVecRes_VSELECT(SDNode * N)452 SDValue DAGTypeLegalizer::ScalarizeVecRes_VSELECT(SDNode *N) {
453   SDValue Cond = N->getOperand(0);
454   EVT OpVT = Cond.getValueType();
455   SDLoc DL(N);
456   // The vselect result and true/value operands needs scalarizing, but it's
457   // not a given that the Cond does. For instance, in AVX512 v1i1 is legal.
458   // See the similar logic in ScalarizeVecRes_SETCC
459   if (getTypeAction(OpVT) == TargetLowering::TypeScalarizeVector) {
460     Cond = GetScalarizedVector(Cond);
461   } else {
462     EVT VT = OpVT.getVectorElementType();
463     Cond = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Cond,
464                        DAG.getVectorIdxConstant(0, DL));
465   }
466 
467   SDValue LHS = GetScalarizedVector(N->getOperand(1));
468   TargetLowering::BooleanContent ScalarBool =
469       TLI.getBooleanContents(false, false);
470   TargetLowering::BooleanContent VecBool = TLI.getBooleanContents(true, false);
471 
472   // If integer and float booleans have different contents then we can't
473   // reliably optimize in all cases. There is a full explanation for this in
474   // DAGCombiner::visitSELECT() where the same issue affects folding
475   // (select C, 0, 1) to (xor C, 1).
476   if (TLI.getBooleanContents(false, false) !=
477       TLI.getBooleanContents(false, true)) {
478     // At least try the common case where the boolean is generated by a
479     // comparison.
480     if (Cond->getOpcode() == ISD::SETCC) {
481       EVT OpVT = Cond->getOperand(0).getValueType();
482       ScalarBool = TLI.getBooleanContents(OpVT.getScalarType());
483       VecBool = TLI.getBooleanContents(OpVT);
484     } else
485       ScalarBool = TargetLowering::UndefinedBooleanContent;
486   }
487 
488   EVT CondVT = Cond.getValueType();
489   if (ScalarBool != VecBool) {
490     switch (ScalarBool) {
491       case TargetLowering::UndefinedBooleanContent:
492         break;
493       case TargetLowering::ZeroOrOneBooleanContent:
494         assert(VecBool == TargetLowering::UndefinedBooleanContent ||
495                VecBool == TargetLowering::ZeroOrNegativeOneBooleanContent);
496         // Vector read from all ones, scalar expects a single 1 so mask.
497         Cond = DAG.getNode(ISD::AND, SDLoc(N), CondVT,
498                            Cond, DAG.getConstant(1, SDLoc(N), CondVT));
499         break;
500       case TargetLowering::ZeroOrNegativeOneBooleanContent:
501         assert(VecBool == TargetLowering::UndefinedBooleanContent ||
502                VecBool == TargetLowering::ZeroOrOneBooleanContent);
503         // Vector reads from a one, scalar from all ones so sign extend.
504         Cond = DAG.getNode(ISD::SIGN_EXTEND_INREG, SDLoc(N), CondVT,
505                            Cond, DAG.getValueType(MVT::i1));
506         break;
507     }
508   }
509 
510   // Truncate the condition if needed
511   auto BoolVT = getSetCCResultType(CondVT);
512   if (BoolVT.bitsLT(CondVT))
513     Cond = DAG.getNode(ISD::TRUNCATE, SDLoc(N), BoolVT, Cond);
514 
515   return DAG.getSelect(SDLoc(N),
516                        LHS.getValueType(), Cond, LHS,
517                        GetScalarizedVector(N->getOperand(2)));
518 }
519 
ScalarizeVecRes_SELECT(SDNode * N)520 SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT(SDNode *N) {
521   SDValue LHS = GetScalarizedVector(N->getOperand(1));
522   return DAG.getSelect(SDLoc(N),
523                        LHS.getValueType(), N->getOperand(0), LHS,
524                        GetScalarizedVector(N->getOperand(2)));
525 }
526 
ScalarizeVecRes_SELECT_CC(SDNode * N)527 SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT_CC(SDNode *N) {
528   SDValue LHS = GetScalarizedVector(N->getOperand(2));
529   return DAG.getNode(ISD::SELECT_CC, SDLoc(N), LHS.getValueType(),
530                      N->getOperand(0), N->getOperand(1),
531                      LHS, GetScalarizedVector(N->getOperand(3)),
532                      N->getOperand(4));
533 }
534 
ScalarizeVecRes_UNDEF(SDNode * N)535 SDValue DAGTypeLegalizer::ScalarizeVecRes_UNDEF(SDNode *N) {
536   return DAG.getUNDEF(N->getValueType(0).getVectorElementType());
537 }
538 
ScalarizeVecRes_VECTOR_SHUFFLE(SDNode * N)539 SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N) {
540   // Figure out if the scalar is the LHS or RHS and return it.
541   SDValue Arg = N->getOperand(2).getOperand(0);
542   if (Arg.isUndef())
543     return DAG.getUNDEF(N->getValueType(0).getVectorElementType());
544   unsigned Op = !cast<ConstantSDNode>(Arg)->isZero();
545   return GetScalarizedVector(N->getOperand(Op));
546 }
547 
ScalarizeVecRes_FP_TO_XINT_SAT(SDNode * N)548 SDValue DAGTypeLegalizer::ScalarizeVecRes_FP_TO_XINT_SAT(SDNode *N) {
549   SDValue Src = N->getOperand(0);
550   EVT SrcVT = Src.getValueType();
551   SDLoc dl(N);
552 
553   // Handle case where result is scalarized but operand is not
554   if (getTypeAction(SrcVT) == TargetLowering::TypeScalarizeVector)
555     Src = GetScalarizedVector(Src);
556   else
557     Src = DAG.getNode(
558         ISD::EXTRACT_VECTOR_ELT, dl, SrcVT.getVectorElementType(), Src,
559         DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
560 
561   EVT DstVT = N->getValueType(0).getVectorElementType();
562   return DAG.getNode(N->getOpcode(), dl, DstVT, Src, N->getOperand(1));
563 }
564 
ScalarizeVecRes_SETCC(SDNode * N)565 SDValue DAGTypeLegalizer::ScalarizeVecRes_SETCC(SDNode *N) {
566   assert(N->getValueType(0).isVector() &&
567          N->getOperand(0).getValueType().isVector() &&
568          "Operand types must be vectors");
569   SDValue LHS = N->getOperand(0);
570   SDValue RHS = N->getOperand(1);
571   EVT OpVT = LHS.getValueType();
572   EVT NVT = N->getValueType(0).getVectorElementType();
573   SDLoc DL(N);
574 
575   // The result needs scalarizing, but it's not a given that the source does.
576   if (getTypeAction(OpVT) == TargetLowering::TypeScalarizeVector) {
577     LHS = GetScalarizedVector(LHS);
578     RHS = GetScalarizedVector(RHS);
579   } else {
580     EVT VT = OpVT.getVectorElementType();
581     LHS = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, LHS,
582                       DAG.getVectorIdxConstant(0, DL));
583     RHS = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, RHS,
584                       DAG.getVectorIdxConstant(0, DL));
585   }
586 
587   // Turn it into a scalar SETCC.
588   SDValue Res = DAG.getNode(ISD::SETCC, DL, MVT::i1, LHS, RHS,
589                             N->getOperand(2));
590   // Vectors may have a different boolean contents to scalars.  Promote the
591   // value appropriately.
592   ISD::NodeType ExtendCode =
593       TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT));
594   return DAG.getNode(ExtendCode, DL, NVT, Res);
595 }
596 
ScalarizeVecRes_IS_FPCLASS(SDNode * N)597 SDValue DAGTypeLegalizer::ScalarizeVecRes_IS_FPCLASS(SDNode *N) {
598   SDLoc DL(N);
599   SDValue Arg = N->getOperand(0);
600   SDValue Test = N->getOperand(1);
601   EVT ArgVT = Arg.getValueType();
602   EVT ResultVT = N->getValueType(0).getVectorElementType();
603 
604   if (getTypeAction(ArgVT) == TargetLowering::TypeScalarizeVector) {
605     Arg = GetScalarizedVector(Arg);
606   } else {
607     EVT VT = ArgVT.getVectorElementType();
608     Arg = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Arg,
609                       DAG.getVectorIdxConstant(0, DL));
610   }
611 
612   SDValue Res =
613       DAG.getNode(ISD::IS_FPCLASS, DL, MVT::i1, {Arg, Test}, N->getFlags());
614   // Vectors may have a different boolean contents to scalars.  Promote the
615   // value appropriately.
616   ISD::NodeType ExtendCode =
617       TargetLowering::getExtendForContent(TLI.getBooleanContents(ArgVT));
618   return DAG.getNode(ExtendCode, DL, ResultVT, Res);
619 }
620 
621 //===----------------------------------------------------------------------===//
622 //  Operand Vector Scalarization <1 x ty> -> ty.
623 //===----------------------------------------------------------------------===//
624 
ScalarizeVectorOperand(SDNode * N,unsigned OpNo)625 bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) {
626   LLVM_DEBUG(dbgs() << "Scalarize node operand " << OpNo << ": "; N->dump(&DAG);
627              dbgs() << "\n");
628   SDValue Res = SDValue();
629 
630   switch (N->getOpcode()) {
631   default:
632 #ifndef NDEBUG
633     dbgs() << "ScalarizeVectorOperand Op #" << OpNo << ": ";
634     N->dump(&DAG);
635     dbgs() << "\n";
636 #endif
637     report_fatal_error("Do not know how to scalarize this operator's "
638                        "operand!\n");
639   case ISD::BITCAST:
640     Res = ScalarizeVecOp_BITCAST(N);
641     break;
642   case ISD::ANY_EXTEND:
643   case ISD::ZERO_EXTEND:
644   case ISD::SIGN_EXTEND:
645   case ISD::TRUNCATE:
646   case ISD::FP_TO_SINT:
647   case ISD::FP_TO_UINT:
648   case ISD::SINT_TO_FP:
649   case ISD::UINT_TO_FP:
650     Res = ScalarizeVecOp_UnaryOp(N);
651     break;
652   case ISD::STRICT_SINT_TO_FP:
653   case ISD::STRICT_UINT_TO_FP:
654   case ISD::STRICT_FP_TO_SINT:
655   case ISD::STRICT_FP_TO_UINT:
656     Res = ScalarizeVecOp_UnaryOp_StrictFP(N);
657     break;
658   case ISD::CONCAT_VECTORS:
659     Res = ScalarizeVecOp_CONCAT_VECTORS(N);
660     break;
661   case ISD::EXTRACT_VECTOR_ELT:
662     Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(N);
663     break;
664   case ISD::VSELECT:
665     Res = ScalarizeVecOp_VSELECT(N);
666     break;
667   case ISD::SETCC:
668     Res = ScalarizeVecOp_VSETCC(N);
669     break;
670   case ISD::STORE:
671     Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(N), OpNo);
672     break;
673   case ISD::STRICT_FP_ROUND:
674     Res = ScalarizeVecOp_STRICT_FP_ROUND(N, OpNo);
675     break;
676   case ISD::FP_ROUND:
677     Res = ScalarizeVecOp_FP_ROUND(N, OpNo);
678     break;
679   case ISD::STRICT_FP_EXTEND:
680     Res = ScalarizeVecOp_STRICT_FP_EXTEND(N);
681     break;
682   case ISD::FP_EXTEND:
683     Res = ScalarizeVecOp_FP_EXTEND(N);
684     break;
685   case ISD::VECREDUCE_FADD:
686   case ISD::VECREDUCE_FMUL:
687   case ISD::VECREDUCE_ADD:
688   case ISD::VECREDUCE_MUL:
689   case ISD::VECREDUCE_AND:
690   case ISD::VECREDUCE_OR:
691   case ISD::VECREDUCE_XOR:
692   case ISD::VECREDUCE_SMAX:
693   case ISD::VECREDUCE_SMIN:
694   case ISD::VECREDUCE_UMAX:
695   case ISD::VECREDUCE_UMIN:
696   case ISD::VECREDUCE_FMAX:
697   case ISD::VECREDUCE_FMIN:
698     Res = ScalarizeVecOp_VECREDUCE(N);
699     break;
700   case ISD::VECREDUCE_SEQ_FADD:
701   case ISD::VECREDUCE_SEQ_FMUL:
702     Res = ScalarizeVecOp_VECREDUCE_SEQ(N);
703     break;
704   }
705 
706   // If the result is null, the sub-method took care of registering results etc.
707   if (!Res.getNode()) return false;
708 
709   // If the result is N, the sub-method updated N in place.  Tell the legalizer
710   // core about this.
711   if (Res.getNode() == N)
712     return true;
713 
714   assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
715          "Invalid operand expansion");
716 
717   ReplaceValueWith(SDValue(N, 0), Res);
718   return false;
719 }
720 
721 /// If the value to convert is a vector that needs to be scalarized, it must be
722 /// <1 x ty>. Convert the element instead.
ScalarizeVecOp_BITCAST(SDNode * N)723 SDValue DAGTypeLegalizer::ScalarizeVecOp_BITCAST(SDNode *N) {
724   SDValue Elt = GetScalarizedVector(N->getOperand(0));
725   return DAG.getNode(ISD::BITCAST, SDLoc(N),
726                      N->getValueType(0), Elt);
727 }
728 
729 /// If the input is a vector that needs to be scalarized, it must be <1 x ty>.
730 /// Do the operation on the element instead.
ScalarizeVecOp_UnaryOp(SDNode * N)731 SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp(SDNode *N) {
732   assert(N->getValueType(0).getVectorNumElements() == 1 &&
733          "Unexpected vector type!");
734   SDValue Elt = GetScalarizedVector(N->getOperand(0));
735   SDValue Op = DAG.getNode(N->getOpcode(), SDLoc(N),
736                            N->getValueType(0).getScalarType(), Elt);
737   // Revectorize the result so the types line up with what the uses of this
738   // expression expect.
739   return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Op);
740 }
741 
742 /// If the input is a vector that needs to be scalarized, it must be <1 x ty>.
743 /// Do the strict FP operation on the element instead.
ScalarizeVecOp_UnaryOp_StrictFP(SDNode * N)744 SDValue DAGTypeLegalizer::ScalarizeVecOp_UnaryOp_StrictFP(SDNode *N) {
745   assert(N->getValueType(0).getVectorNumElements() == 1 &&
746          "Unexpected vector type!");
747   SDValue Elt = GetScalarizedVector(N->getOperand(1));
748   SDValue Res = DAG.getNode(N->getOpcode(), SDLoc(N),
749                             { N->getValueType(0).getScalarType(), MVT::Other },
750                             { N->getOperand(0), Elt });
751   // Legalize the chain result - switch anything that used the old chain to
752   // use the new one.
753   ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
754   // Revectorize the result so the types line up with what the uses of this
755   // expression expect.
756   Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res);
757 
758   // Do our own replacement and return SDValue() to tell the caller that we
759   // handled all replacements since caller can only handle a single result.
760   ReplaceValueWith(SDValue(N, 0), Res);
761   return SDValue();
762 }
763 
764 /// The vectors to concatenate have length one - use a BUILD_VECTOR instead.
ScalarizeVecOp_CONCAT_VECTORS(SDNode * N)765 SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(SDNode *N) {
766   SmallVector<SDValue, 8> Ops(N->getNumOperands());
767   for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i)
768     Ops[i] = GetScalarizedVector(N->getOperand(i));
769   return DAG.getBuildVector(N->getValueType(0), SDLoc(N), Ops);
770 }
771 
772 /// If the input is a vector that needs to be scalarized, it must be <1 x ty>,
773 /// so just return the element, ignoring the index.
ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode * N)774 SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
775   EVT VT = N->getValueType(0);
776   SDValue Res = GetScalarizedVector(N->getOperand(0));
777   if (Res.getValueType() != VT)
778     Res = VT.isFloatingPoint()
779               ? DAG.getNode(ISD::FP_EXTEND, SDLoc(N), VT, Res)
780               : DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), VT, Res);
781   return Res;
782 }
783 
784 /// If the input condition is a vector that needs to be scalarized, it must be
785 /// <1 x i1>, so just convert to a normal ISD::SELECT
786 /// (still with vector output type since that was acceptable if we got here).
ScalarizeVecOp_VSELECT(SDNode * N)787 SDValue DAGTypeLegalizer::ScalarizeVecOp_VSELECT(SDNode *N) {
788   SDValue ScalarCond = GetScalarizedVector(N->getOperand(0));
789   EVT VT = N->getValueType(0);
790 
791   return DAG.getNode(ISD::SELECT, SDLoc(N), VT, ScalarCond, N->getOperand(1),
792                      N->getOperand(2));
793 }
794 
795 /// If the operand is a vector that needs to be scalarized then the
796 /// result must be v1i1, so just convert to a scalar SETCC and wrap
797 /// with a scalar_to_vector since the res type is legal if we got here
ScalarizeVecOp_VSETCC(SDNode * N)798 SDValue DAGTypeLegalizer::ScalarizeVecOp_VSETCC(SDNode *N) {
799   assert(N->getValueType(0).isVector() &&
800          N->getOperand(0).getValueType().isVector() &&
801          "Operand types must be vectors");
802   assert(N->getValueType(0) == MVT::v1i1 && "Expected v1i1 type");
803 
804   EVT VT = N->getValueType(0);
805   SDValue LHS = GetScalarizedVector(N->getOperand(0));
806   SDValue RHS = GetScalarizedVector(N->getOperand(1));
807 
808   EVT OpVT = N->getOperand(0).getValueType();
809   EVT NVT = VT.getVectorElementType();
810   SDLoc DL(N);
811   // Turn it into a scalar SETCC.
812   SDValue Res = DAG.getNode(ISD::SETCC, DL, MVT::i1, LHS, RHS,
813       N->getOperand(2));
814 
815   // Vectors may have a different boolean contents to scalars.  Promote the
816   // value appropriately.
817   ISD::NodeType ExtendCode =
818       TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT));
819 
820   Res = DAG.getNode(ExtendCode, DL, NVT, Res);
821 
822   return DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VT, Res);
823 }
824 
825 /// If the value to store is a vector that needs to be scalarized, it must be
826 /// <1 x ty>. Just store the element.
ScalarizeVecOp_STORE(StoreSDNode * N,unsigned OpNo)827 SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){
828   assert(N->isUnindexed() && "Indexed store of one-element vector?");
829   assert(OpNo == 1 && "Do not know how to scalarize this operand!");
830   SDLoc dl(N);
831 
832   if (N->isTruncatingStore())
833     return DAG.getTruncStore(
834         N->getChain(), dl, GetScalarizedVector(N->getOperand(1)),
835         N->getBasePtr(), N->getPointerInfo(),
836         N->getMemoryVT().getVectorElementType(), N->getOriginalAlign(),
837         N->getMemOperand()->getFlags(), N->getAAInfo());
838 
839   return DAG.getStore(N->getChain(), dl, GetScalarizedVector(N->getOperand(1)),
840                       N->getBasePtr(), N->getPointerInfo(),
841                       N->getOriginalAlign(), N->getMemOperand()->getFlags(),
842                       N->getAAInfo());
843 }
844 
845 /// If the value to round is a vector that needs to be scalarized, it must be
846 /// <1 x ty>. Convert the element instead.
ScalarizeVecOp_FP_ROUND(SDNode * N,unsigned OpNo)847 SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(SDNode *N, unsigned OpNo) {
848   assert(OpNo == 0 && "Wrong operand for scalarization!");
849   SDValue Elt = GetScalarizedVector(N->getOperand(0));
850   SDValue Res = DAG.getNode(ISD::FP_ROUND, SDLoc(N),
851                             N->getValueType(0).getVectorElementType(), Elt,
852                             N->getOperand(1));
853   return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res);
854 }
855 
ScalarizeVecOp_STRICT_FP_ROUND(SDNode * N,unsigned OpNo)856 SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(SDNode *N,
857                                                          unsigned OpNo) {
858   assert(OpNo == 1 && "Wrong operand for scalarization!");
859   SDValue Elt = GetScalarizedVector(N->getOperand(1));
860   SDValue Res = DAG.getNode(ISD::STRICT_FP_ROUND, SDLoc(N),
861                             { N->getValueType(0).getVectorElementType(),
862                               MVT::Other },
863                             { N->getOperand(0), Elt, N->getOperand(2) });
864   // Legalize the chain result - switch anything that used the old chain to
865   // use the new one.
866   ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
867 
868   Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res);
869 
870   // Do our own replacement and return SDValue() to tell the caller that we
871   // handled all replacements since caller can only handle a single result.
872   ReplaceValueWith(SDValue(N, 0), Res);
873   return SDValue();
874 }
875 
876 /// If the value to extend is a vector that needs to be scalarized, it must be
877 /// <1 x ty>. Convert the element instead.
ScalarizeVecOp_FP_EXTEND(SDNode * N)878 SDValue DAGTypeLegalizer::ScalarizeVecOp_FP_EXTEND(SDNode *N) {
879   SDValue Elt = GetScalarizedVector(N->getOperand(0));
880   SDValue Res = DAG.getNode(ISD::FP_EXTEND, SDLoc(N),
881                             N->getValueType(0).getVectorElementType(), Elt);
882   return DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res);
883 }
884 
885 /// If the value to extend is a vector that needs to be scalarized, it must be
886 /// <1 x ty>. Convert the element instead.
ScalarizeVecOp_STRICT_FP_EXTEND(SDNode * N)887 SDValue DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_EXTEND(SDNode *N) {
888   SDValue Elt = GetScalarizedVector(N->getOperand(1));
889   SDValue Res =
890       DAG.getNode(ISD::STRICT_FP_EXTEND, SDLoc(N),
891                   {N->getValueType(0).getVectorElementType(), MVT::Other},
892                   {N->getOperand(0), Elt});
893   // Legalize the chain result - switch anything that used the old chain to
894   // use the new one.
895   ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
896 
897   Res = DAG.getNode(ISD::SCALAR_TO_VECTOR, SDLoc(N), N->getValueType(0), Res);
898 
899   // Do our own replacement and return SDValue() to tell the caller that we
900   // handled all replacements since caller can only handle a single result.
901   ReplaceValueWith(SDValue(N, 0), Res);
902   return SDValue();
903 }
904 
ScalarizeVecOp_VECREDUCE(SDNode * N)905 SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE(SDNode *N) {
906   SDValue Res = GetScalarizedVector(N->getOperand(0));
907   // Result type may be wider than element type.
908   if (Res.getValueType() != N->getValueType(0))
909     Res = DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), N->getValueType(0), Res);
910   return Res;
911 }
912 
ScalarizeVecOp_VECREDUCE_SEQ(SDNode * N)913 SDValue DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE_SEQ(SDNode *N) {
914   SDValue AccOp = N->getOperand(0);
915   SDValue VecOp = N->getOperand(1);
916 
917   unsigned BaseOpc = ISD::getVecReduceBaseOpcode(N->getOpcode());
918 
919   SDValue Op = GetScalarizedVector(VecOp);
920   return DAG.getNode(BaseOpc, SDLoc(N), N->getValueType(0),
921                      AccOp, Op, N->getFlags());
922 }
923 
924 //===----------------------------------------------------------------------===//
925 //  Result Vector Splitting
926 //===----------------------------------------------------------------------===//
927 
928 /// This method is called when the specified result of the specified node is
929 /// found to need vector splitting. At this point, the node may also have
930 /// invalid operands or may have other results that need legalization, we just
931 /// know that (at least) one result needs vector splitting.
SplitVectorResult(SDNode * N,unsigned ResNo)932 void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
933   LLVM_DEBUG(dbgs() << "Split node result: "; N->dump(&DAG); dbgs() << "\n");
934   SDValue Lo, Hi;
935 
936   // See if the target wants to custom expand this node.
937   if (CustomLowerNode(N, N->getValueType(ResNo), true))
938     return;
939 
940   switch (N->getOpcode()) {
941   default:
942 #ifndef NDEBUG
943     dbgs() << "SplitVectorResult #" << ResNo << ": ";
944     N->dump(&DAG);
945     dbgs() << "\n";
946 #endif
947     report_fatal_error("Do not know how to split the result of this "
948                        "operator!\n");
949 
950   case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, ResNo, Lo, Hi); break;
951   case ISD::VSELECT:
952   case ISD::SELECT:
953   case ISD::VP_MERGE:
954   case ISD::VP_SELECT:    SplitRes_Select(N, Lo, Hi); break;
955   case ISD::SELECT_CC:    SplitRes_SELECT_CC(N, Lo, Hi); break;
956   case ISD::UNDEF:        SplitRes_UNDEF(N, Lo, Hi); break;
957   case ISD::BITCAST:           SplitVecRes_BITCAST(N, Lo, Hi); break;
958   case ISD::BUILD_VECTOR:      SplitVecRes_BUILD_VECTOR(N, Lo, Hi); break;
959   case ISD::CONCAT_VECTORS:    SplitVecRes_CONCAT_VECTORS(N, Lo, Hi); break;
960   case ISD::EXTRACT_SUBVECTOR: SplitVecRes_EXTRACT_SUBVECTOR(N, Lo, Hi); break;
961   case ISD::INSERT_SUBVECTOR:  SplitVecRes_INSERT_SUBVECTOR(N, Lo, Hi); break;
962   case ISD::FPOWI:             SplitVecRes_FPOWI(N, Lo, Hi); break;
963   case ISD::FCOPYSIGN:         SplitVecRes_FCOPYSIGN(N, Lo, Hi); break;
964   case ISD::IS_FPCLASS:        SplitVecRes_IS_FPCLASS(N, Lo, Hi); break;
965   case ISD::INSERT_VECTOR_ELT: SplitVecRes_INSERT_VECTOR_ELT(N, Lo, Hi); break;
966   case ISD::SPLAT_VECTOR:
967   case ISD::SCALAR_TO_VECTOR:
968     SplitVecRes_ScalarOp(N, Lo, Hi);
969     break;
970   case ISD::STEP_VECTOR:
971     SplitVecRes_STEP_VECTOR(N, Lo, Hi);
972     break;
973   case ISD::SIGN_EXTEND_INREG: SplitVecRes_InregOp(N, Lo, Hi); break;
974   case ISD::LOAD:
975     SplitVecRes_LOAD(cast<LoadSDNode>(N), Lo, Hi);
976     break;
977   case ISD::VP_LOAD:
978     SplitVecRes_VP_LOAD(cast<VPLoadSDNode>(N), Lo, Hi);
979     break;
980   case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
981     SplitVecRes_VP_STRIDED_LOAD(cast<VPStridedLoadSDNode>(N), Lo, Hi);
982     break;
983   case ISD::MLOAD:
984     SplitVecRes_MLOAD(cast<MaskedLoadSDNode>(N), Lo, Hi);
985     break;
986   case ISD::MGATHER:
987   case ISD::VP_GATHER:
988     SplitVecRes_Gather(cast<MemSDNode>(N), Lo, Hi, /*SplitSETCC*/ true);
989     break;
990   case ISD::SETCC:
991   case ISD::VP_SETCC:
992     SplitVecRes_SETCC(N, Lo, Hi);
993     break;
994   case ISD::VECTOR_REVERSE:
995     SplitVecRes_VECTOR_REVERSE(N, Lo, Hi);
996     break;
997   case ISD::VECTOR_SHUFFLE:
998     SplitVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N), Lo, Hi);
999     break;
1000   case ISD::VECTOR_SPLICE:
1001     SplitVecRes_VECTOR_SPLICE(N, Lo, Hi);
1002     break;
1003   case ISD::VAARG:
1004     SplitVecRes_VAARG(N, Lo, Hi);
1005     break;
1006 
1007   case ISD::ANY_EXTEND_VECTOR_INREG:
1008   case ISD::SIGN_EXTEND_VECTOR_INREG:
1009   case ISD::ZERO_EXTEND_VECTOR_INREG:
1010     SplitVecRes_ExtVecInRegOp(N, Lo, Hi);
1011     break;
1012 
1013   case ISD::ABS:
1014   case ISD::VP_ABS:
1015   case ISD::BITREVERSE:
1016   case ISD::VP_BITREVERSE:
1017   case ISD::BSWAP:
1018   case ISD::VP_BSWAP:
1019   case ISD::CTLZ:
1020   case ISD::VP_CTLZ:
1021   case ISD::CTTZ:
1022   case ISD::VP_CTTZ:
1023   case ISD::CTLZ_ZERO_UNDEF:
1024   case ISD::VP_CTLZ_ZERO_UNDEF:
1025   case ISD::CTTZ_ZERO_UNDEF:
1026   case ISD::VP_CTTZ_ZERO_UNDEF:
1027   case ISD::CTPOP:
1028   case ISD::VP_CTPOP:
1029   case ISD::FABS: case ISD::VP_FABS:
1030   case ISD::FCEIL:
1031   case ISD::VP_FCEIL:
1032   case ISD::FCOS:
1033   case ISD::FEXP:
1034   case ISD::FEXP2:
1035   case ISD::FFLOOR:
1036   case ISD::VP_FFLOOR:
1037   case ISD::FLOG:
1038   case ISD::FLOG10:
1039   case ISD::FLOG2:
1040   case ISD::FNEARBYINT:
1041   case ISD::VP_FNEARBYINT:
1042   case ISD::FNEG: case ISD::VP_FNEG:
1043   case ISD::FREEZE:
1044   case ISD::ARITH_FENCE:
1045   case ISD::FP_EXTEND:
1046   case ISD::VP_FP_EXTEND:
1047   case ISD::FP_ROUND:
1048   case ISD::VP_FP_ROUND:
1049   case ISD::FP_TO_SINT:
1050   case ISD::VP_FP_TO_SINT:
1051   case ISD::FP_TO_UINT:
1052   case ISD::VP_FP_TO_UINT:
1053   case ISD::FRINT:
1054   case ISD::VP_FRINT:
1055   case ISD::FROUND:
1056   case ISD::VP_FROUND:
1057   case ISD::FROUNDEVEN:
1058   case ISD::VP_FROUNDEVEN:
1059   case ISD::FSIN:
1060   case ISD::FSQRT: case ISD::VP_SQRT:
1061   case ISD::FTRUNC:
1062   case ISD::VP_FROUNDTOZERO:
1063   case ISD::SINT_TO_FP:
1064   case ISD::VP_SINT_TO_FP:
1065   case ISD::TRUNCATE:
1066   case ISD::VP_TRUNCATE:
1067   case ISD::UINT_TO_FP:
1068   case ISD::VP_UINT_TO_FP:
1069   case ISD::FCANONICALIZE:
1070     SplitVecRes_UnaryOp(N, Lo, Hi);
1071     break;
1072 
1073   case ISD::ANY_EXTEND:
1074   case ISD::SIGN_EXTEND:
1075   case ISD::ZERO_EXTEND:
1076   case ISD::VP_SIGN_EXTEND:
1077   case ISD::VP_ZERO_EXTEND:
1078     SplitVecRes_ExtendOp(N, Lo, Hi);
1079     break;
1080 
1081   case ISD::ADD: case ISD::VP_ADD:
1082   case ISD::SUB: case ISD::VP_SUB:
1083   case ISD::MUL: case ISD::VP_MUL:
1084   case ISD::MULHS:
1085   case ISD::MULHU:
1086   case ISD::FADD: case ISD::VP_FADD:
1087   case ISD::FSUB: case ISD::VP_FSUB:
1088   case ISD::FMUL: case ISD::VP_FMUL:
1089   case ISD::FMINNUM: case ISD::VP_FMINNUM:
1090   case ISD::FMAXNUM: case ISD::VP_FMAXNUM:
1091   case ISD::FMINIMUM:
1092   case ISD::FMAXIMUM:
1093   case ISD::SDIV: case ISD::VP_SDIV:
1094   case ISD::UDIV: case ISD::VP_UDIV:
1095   case ISD::FDIV: case ISD::VP_FDIV:
1096   case ISD::FPOW:
1097   case ISD::AND: case ISD::VP_AND:
1098   case ISD::OR: case ISD::VP_OR:
1099   case ISD::XOR: case ISD::VP_XOR:
1100   case ISD::SHL: case ISD::VP_SHL:
1101   case ISD::SRA: case ISD::VP_ASHR:
1102   case ISD::SRL: case ISD::VP_LSHR:
1103   case ISD::UREM: case ISD::VP_UREM:
1104   case ISD::SREM: case ISD::VP_SREM:
1105   case ISD::FREM: case ISD::VP_FREM:
1106   case ISD::SMIN: case ISD::VP_SMIN:
1107   case ISD::SMAX: case ISD::VP_SMAX:
1108   case ISD::UMIN: case ISD::VP_UMIN:
1109   case ISD::UMAX: case ISD::VP_UMAX:
1110   case ISD::SADDSAT:
1111   case ISD::UADDSAT:
1112   case ISD::SSUBSAT:
1113   case ISD::USUBSAT:
1114   case ISD::SSHLSAT:
1115   case ISD::USHLSAT:
1116   case ISD::ROTL:
1117   case ISD::ROTR:
1118   case ISD::VP_FCOPYSIGN:
1119     SplitVecRes_BinOp(N, Lo, Hi);
1120     break;
1121   case ISD::FMA: case ISD::VP_FMA:
1122   case ISD::FSHL:
1123   case ISD::VP_FSHL:
1124   case ISD::FSHR:
1125   case ISD::VP_FSHR:
1126     SplitVecRes_TernaryOp(N, Lo, Hi);
1127     break;
1128 
1129 #define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN)               \
1130   case ISD::STRICT_##DAGN:
1131 #include "llvm/IR/ConstrainedOps.def"
1132     SplitVecRes_StrictFPOp(N, Lo, Hi);
1133     break;
1134 
1135   case ISD::FP_TO_UINT_SAT:
1136   case ISD::FP_TO_SINT_SAT:
1137     SplitVecRes_FP_TO_XINT_SAT(N, Lo, Hi);
1138     break;
1139 
1140   case ISD::UADDO:
1141   case ISD::SADDO:
1142   case ISD::USUBO:
1143   case ISD::SSUBO:
1144   case ISD::UMULO:
1145   case ISD::SMULO:
1146     SplitVecRes_OverflowOp(N, ResNo, Lo, Hi);
1147     break;
1148   case ISD::SMULFIX:
1149   case ISD::SMULFIXSAT:
1150   case ISD::UMULFIX:
1151   case ISD::UMULFIXSAT:
1152   case ISD::SDIVFIX:
1153   case ISD::SDIVFIXSAT:
1154   case ISD::UDIVFIX:
1155   case ISD::UDIVFIXSAT:
1156     SplitVecRes_FIX(N, Lo, Hi);
1157     break;
1158   }
1159 
1160   // If Lo/Hi is null, the sub-method took care of registering results etc.
1161   if (Lo.getNode())
1162     SetSplitVector(SDValue(N, ResNo), Lo, Hi);
1163 }
1164 
IncrementPointer(MemSDNode * N,EVT MemVT,MachinePointerInfo & MPI,SDValue & Ptr,uint64_t * ScaledOffset)1165 void DAGTypeLegalizer::IncrementPointer(MemSDNode *N, EVT MemVT,
1166                                         MachinePointerInfo &MPI, SDValue &Ptr,
1167                                         uint64_t *ScaledOffset) {
1168   SDLoc DL(N);
1169   unsigned IncrementSize = MemVT.getSizeInBits().getKnownMinValue() / 8;
1170 
1171   if (MemVT.isScalableVector()) {
1172     SDNodeFlags Flags;
1173     SDValue BytesIncrement = DAG.getVScale(
1174         DL, Ptr.getValueType(),
1175         APInt(Ptr.getValueSizeInBits().getFixedValue(), IncrementSize));
1176     MPI = MachinePointerInfo(N->getPointerInfo().getAddrSpace());
1177     Flags.setNoUnsignedWrap(true);
1178     if (ScaledOffset)
1179       *ScaledOffset += IncrementSize;
1180     Ptr = DAG.getNode(ISD::ADD, DL, Ptr.getValueType(), Ptr, BytesIncrement,
1181                       Flags);
1182   } else {
1183     MPI = N->getPointerInfo().getWithOffset(IncrementSize);
1184     // Increment the pointer to the other half.
1185     Ptr = DAG.getObjectPtrOffset(DL, Ptr, TypeSize::Fixed(IncrementSize));
1186   }
1187 }
1188 
SplitMask(SDValue Mask)1189 std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(SDValue Mask) {
1190   return SplitMask(Mask, SDLoc(Mask));
1191 }
1192 
SplitMask(SDValue Mask,const SDLoc & DL)1193 std::pair<SDValue, SDValue> DAGTypeLegalizer::SplitMask(SDValue Mask,
1194                                                         const SDLoc &DL) {
1195   SDValue MaskLo, MaskHi;
1196   EVT MaskVT = Mask.getValueType();
1197   if (getTypeAction(MaskVT) == TargetLowering::TypeSplitVector)
1198     GetSplitVector(Mask, MaskLo, MaskHi);
1199   else
1200     std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, DL);
1201   return std::make_pair(MaskLo, MaskHi);
1202 }
1203 
SplitVecRes_BinOp(SDNode * N,SDValue & Lo,SDValue & Hi)1204 void DAGTypeLegalizer::SplitVecRes_BinOp(SDNode *N, SDValue &Lo, SDValue &Hi) {
1205   SDValue LHSLo, LHSHi;
1206   GetSplitVector(N->getOperand(0), LHSLo, LHSHi);
1207   SDValue RHSLo, RHSHi;
1208   GetSplitVector(N->getOperand(1), RHSLo, RHSHi);
1209   SDLoc dl(N);
1210 
1211   const SDNodeFlags Flags = N->getFlags();
1212   unsigned Opcode = N->getOpcode();
1213   if (N->getNumOperands() == 2) {
1214     Lo = DAG.getNode(Opcode, dl, LHSLo.getValueType(), LHSLo, RHSLo, Flags);
1215     Hi = DAG.getNode(Opcode, dl, LHSHi.getValueType(), LHSHi, RHSHi, Flags);
1216     return;
1217   }
1218 
1219   assert(N->getNumOperands() == 4 && "Unexpected number of operands!");
1220   assert(N->isVPOpcode() && "Expected VP opcode");
1221 
1222   SDValue MaskLo, MaskHi;
1223   std::tie(MaskLo, MaskHi) = SplitMask(N->getOperand(2));
1224 
1225   SDValue EVLLo, EVLHi;
1226   std::tie(EVLLo, EVLHi) =
1227       DAG.SplitEVL(N->getOperand(3), N->getValueType(0), dl);
1228 
1229   Lo = DAG.getNode(Opcode, dl, LHSLo.getValueType(),
1230                    {LHSLo, RHSLo, MaskLo, EVLLo}, Flags);
1231   Hi = DAG.getNode(Opcode, dl, LHSHi.getValueType(),
1232                    {LHSHi, RHSHi, MaskHi, EVLHi}, Flags);
1233 }
1234 
SplitVecRes_TernaryOp(SDNode * N,SDValue & Lo,SDValue & Hi)1235 void DAGTypeLegalizer::SplitVecRes_TernaryOp(SDNode *N, SDValue &Lo,
1236                                              SDValue &Hi) {
1237   SDValue Op0Lo, Op0Hi;
1238   GetSplitVector(N->getOperand(0), Op0Lo, Op0Hi);
1239   SDValue Op1Lo, Op1Hi;
1240   GetSplitVector(N->getOperand(1), Op1Lo, Op1Hi);
1241   SDValue Op2Lo, Op2Hi;
1242   GetSplitVector(N->getOperand(2), Op2Lo, Op2Hi);
1243   SDLoc dl(N);
1244 
1245   const SDNodeFlags Flags = N->getFlags();
1246   unsigned Opcode = N->getOpcode();
1247   if (N->getNumOperands() == 3) {
1248     Lo = DAG.getNode(Opcode, dl, Op0Lo.getValueType(), Op0Lo, Op1Lo, Op2Lo, Flags);
1249     Hi = DAG.getNode(Opcode, dl, Op0Hi.getValueType(), Op0Hi, Op1Hi, Op2Hi, Flags);
1250     return;
1251   }
1252 
1253   assert(N->getNumOperands() == 5 && "Unexpected number of operands!");
1254   assert(N->isVPOpcode() && "Expected VP opcode");
1255 
1256   SDValue MaskLo, MaskHi;
1257   std::tie(MaskLo, MaskHi) = SplitMask(N->getOperand(3));
1258 
1259   SDValue EVLLo, EVLHi;
1260   std::tie(EVLLo, EVLHi) =
1261       DAG.SplitEVL(N->getOperand(4), N->getValueType(0), dl);
1262 
1263   Lo = DAG.getNode(Opcode, dl, Op0Lo.getValueType(),
1264                    {Op0Lo, Op1Lo, Op2Lo, MaskLo, EVLLo}, Flags);
1265   Hi = DAG.getNode(Opcode, dl, Op0Hi.getValueType(),
1266                    {Op0Hi, Op1Hi, Op2Hi, MaskHi, EVLHi}, Flags);
1267 }
1268 
SplitVecRes_FIX(SDNode * N,SDValue & Lo,SDValue & Hi)1269 void DAGTypeLegalizer::SplitVecRes_FIX(SDNode *N, SDValue &Lo, SDValue &Hi) {
1270   SDValue LHSLo, LHSHi;
1271   GetSplitVector(N->getOperand(0), LHSLo, LHSHi);
1272   SDValue RHSLo, RHSHi;
1273   GetSplitVector(N->getOperand(1), RHSLo, RHSHi);
1274   SDLoc dl(N);
1275   SDValue Op2 = N->getOperand(2);
1276 
1277   unsigned Opcode = N->getOpcode();
1278   Lo = DAG.getNode(Opcode, dl, LHSLo.getValueType(), LHSLo, RHSLo, Op2,
1279                    N->getFlags());
1280   Hi = DAG.getNode(Opcode, dl, LHSHi.getValueType(), LHSHi, RHSHi, Op2,
1281                    N->getFlags());
1282 }
1283 
SplitVecRes_BITCAST(SDNode * N,SDValue & Lo,SDValue & Hi)1284 void DAGTypeLegalizer::SplitVecRes_BITCAST(SDNode *N, SDValue &Lo,
1285                                            SDValue &Hi) {
1286   // We know the result is a vector.  The input may be either a vector or a
1287   // scalar value.
1288   EVT LoVT, HiVT;
1289   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1290   SDLoc dl(N);
1291 
1292   SDValue InOp = N->getOperand(0);
1293   EVT InVT = InOp.getValueType();
1294 
1295   // Handle some special cases efficiently.
1296   switch (getTypeAction(InVT)) {
1297   case TargetLowering::TypeLegal:
1298   case TargetLowering::TypePromoteInteger:
1299   case TargetLowering::TypePromoteFloat:
1300   case TargetLowering::TypeSoftPromoteHalf:
1301   case TargetLowering::TypeSoftenFloat:
1302   case TargetLowering::TypeScalarizeVector:
1303   case TargetLowering::TypeWidenVector:
1304     break;
1305   case TargetLowering::TypeExpandInteger:
1306   case TargetLowering::TypeExpandFloat:
1307     // A scalar to vector conversion, where the scalar needs expansion.
1308     // If the vector is being split in two then we can just convert the
1309     // expanded pieces.
1310     if (LoVT == HiVT) {
1311       GetExpandedOp(InOp, Lo, Hi);
1312       if (DAG.getDataLayout().isBigEndian())
1313         std::swap(Lo, Hi);
1314       Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, Lo);
1315       Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, Hi);
1316       return;
1317     }
1318     break;
1319   case TargetLowering::TypeSplitVector:
1320     // If the input is a vector that needs to be split, convert each split
1321     // piece of the input now.
1322     GetSplitVector(InOp, Lo, Hi);
1323     Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, Lo);
1324     Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, Hi);
1325     return;
1326   case TargetLowering::TypeScalarizeScalableVector:
1327     report_fatal_error("Scalarization of scalable vectors is not supported.");
1328   }
1329 
1330   // In the general case, convert the input to an integer and split it by hand.
1331   EVT LoIntVT = EVT::getIntegerVT(*DAG.getContext(), LoVT.getSizeInBits());
1332   EVT HiIntVT = EVT::getIntegerVT(*DAG.getContext(), HiVT.getSizeInBits());
1333   if (DAG.getDataLayout().isBigEndian())
1334     std::swap(LoIntVT, HiIntVT);
1335 
1336   SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT, Lo, Hi);
1337 
1338   if (DAG.getDataLayout().isBigEndian())
1339     std::swap(Lo, Hi);
1340   Lo = DAG.getNode(ISD::BITCAST, dl, LoVT, Lo);
1341   Hi = DAG.getNode(ISD::BITCAST, dl, HiVT, Hi);
1342 }
1343 
SplitVecRes_BUILD_VECTOR(SDNode * N,SDValue & Lo,SDValue & Hi)1344 void DAGTypeLegalizer::SplitVecRes_BUILD_VECTOR(SDNode *N, SDValue &Lo,
1345                                                 SDValue &Hi) {
1346   EVT LoVT, HiVT;
1347   SDLoc dl(N);
1348   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1349   unsigned LoNumElts = LoVT.getVectorNumElements();
1350   SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+LoNumElts);
1351   Lo = DAG.getBuildVector(LoVT, dl, LoOps);
1352 
1353   SmallVector<SDValue, 8> HiOps(N->op_begin()+LoNumElts, N->op_end());
1354   Hi = DAG.getBuildVector(HiVT, dl, HiOps);
1355 }
1356 
SplitVecRes_CONCAT_VECTORS(SDNode * N,SDValue & Lo,SDValue & Hi)1357 void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo,
1358                                                   SDValue &Hi) {
1359   assert(!(N->getNumOperands() & 1) && "Unsupported CONCAT_VECTORS");
1360   SDLoc dl(N);
1361   unsigned NumSubvectors = N->getNumOperands() / 2;
1362   if (NumSubvectors == 1) {
1363     Lo = N->getOperand(0);
1364     Hi = N->getOperand(1);
1365     return;
1366   }
1367 
1368   EVT LoVT, HiVT;
1369   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1370 
1371   SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+NumSubvectors);
1372   Lo = DAG.getNode(ISD::CONCAT_VECTORS, dl, LoVT, LoOps);
1373 
1374   SmallVector<SDValue, 8> HiOps(N->op_begin()+NumSubvectors, N->op_end());
1375   Hi = DAG.getNode(ISD::CONCAT_VECTORS, dl, HiVT, HiOps);
1376 }
1377 
SplitVecRes_EXTRACT_SUBVECTOR(SDNode * N,SDValue & Lo,SDValue & Hi)1378 void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo,
1379                                                      SDValue &Hi) {
1380   SDValue Vec = N->getOperand(0);
1381   SDValue Idx = N->getOperand(1);
1382   SDLoc dl(N);
1383 
1384   EVT LoVT, HiVT;
1385   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1386 
1387   Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, LoVT, Vec, Idx);
1388   uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
1389   Hi = DAG.getNode(
1390       ISD::EXTRACT_SUBVECTOR, dl, HiVT, Vec,
1391       DAG.getVectorIdxConstant(IdxVal + LoVT.getVectorMinNumElements(), dl));
1392 }
1393 
SplitVecRes_INSERT_SUBVECTOR(SDNode * N,SDValue & Lo,SDValue & Hi)1394 void DAGTypeLegalizer::SplitVecRes_INSERT_SUBVECTOR(SDNode *N, SDValue &Lo,
1395                                                     SDValue &Hi) {
1396   SDValue Vec = N->getOperand(0);
1397   SDValue SubVec = N->getOperand(1);
1398   SDValue Idx = N->getOperand(2);
1399   SDLoc dl(N);
1400   GetSplitVector(Vec, Lo, Hi);
1401 
1402   EVT VecVT = Vec.getValueType();
1403   EVT LoVT = Lo.getValueType();
1404   EVT SubVecVT = SubVec.getValueType();
1405   unsigned VecElems = VecVT.getVectorMinNumElements();
1406   unsigned SubElems = SubVecVT.getVectorMinNumElements();
1407   unsigned LoElems = LoVT.getVectorMinNumElements();
1408 
1409   // If we know the index is in the first half, and we know the subvector
1410   // doesn't cross the boundary between the halves, we can avoid spilling the
1411   // vector, and insert into the lower half of the split vector directly.
1412   unsigned IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
1413   if (IdxVal + SubElems <= LoElems) {
1414     Lo = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, LoVT, Lo, SubVec, Idx);
1415     return;
1416   }
1417   // Similarly if the subvector is fully in the high half, but mind that we
1418   // can't tell whether a fixed-length subvector is fully within the high half
1419   // of a scalable vector.
1420   if (VecVT.isScalableVector() == SubVecVT.isScalableVector() &&
1421       IdxVal >= LoElems && IdxVal + SubElems <= VecElems) {
1422     Hi = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, Hi.getValueType(), Hi, SubVec,
1423                      DAG.getVectorIdxConstant(IdxVal - LoElems, dl));
1424     return;
1425   }
1426 
1427   // Spill the vector to the stack.
1428   // In cases where the vector is illegal it will be broken down into parts
1429   // and stored in parts - we should use the alignment for the smallest part.
1430   Align SmallestAlign = DAG.getReducedAlign(VecVT, /*UseABI=*/false);
1431   SDValue StackPtr =
1432       DAG.CreateStackTemporary(VecVT.getStoreSize(), SmallestAlign);
1433   auto &MF = DAG.getMachineFunction();
1434   auto FrameIndex = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
1435   auto PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex);
1436 
1437   SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1438                                SmallestAlign);
1439 
1440   // Store the new subvector into the specified index.
1441   SDValue SubVecPtr =
1442       TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVecVT, Idx);
1443   Store = DAG.getStore(Store, dl, SubVec, SubVecPtr,
1444                        MachinePointerInfo::getUnknownStack(MF));
1445 
1446   // Load the Lo part from the stack slot.
1447   Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, PtrInfo,
1448                    SmallestAlign);
1449 
1450   // Increment the pointer to the other part.
1451   auto *Load = cast<LoadSDNode>(Lo);
1452   MachinePointerInfo MPI = Load->getPointerInfo();
1453   IncrementPointer(Load, LoVT, MPI, StackPtr);
1454 
1455   // Load the Hi part from the stack slot.
1456   Hi = DAG.getLoad(Hi.getValueType(), dl, Store, StackPtr, MPI, SmallestAlign);
1457 }
1458 
SplitVecRes_FPOWI(SDNode * N,SDValue & Lo,SDValue & Hi)1459 void DAGTypeLegalizer::SplitVecRes_FPOWI(SDNode *N, SDValue &Lo,
1460                                          SDValue &Hi) {
1461   SDLoc dl(N);
1462   GetSplitVector(N->getOperand(0), Lo, Hi);
1463   Lo = DAG.getNode(ISD::FPOWI, dl, Lo.getValueType(), Lo, N->getOperand(1));
1464   Hi = DAG.getNode(ISD::FPOWI, dl, Hi.getValueType(), Hi, N->getOperand(1));
1465 }
1466 
SplitVecRes_FCOPYSIGN(SDNode * N,SDValue & Lo,SDValue & Hi)1467 void DAGTypeLegalizer::SplitVecRes_FCOPYSIGN(SDNode *N, SDValue &Lo,
1468                                              SDValue &Hi) {
1469   SDValue LHSLo, LHSHi;
1470   GetSplitVector(N->getOperand(0), LHSLo, LHSHi);
1471   SDLoc DL(N);
1472 
1473   SDValue RHSLo, RHSHi;
1474   SDValue RHS = N->getOperand(1);
1475   EVT RHSVT = RHS.getValueType();
1476   if (getTypeAction(RHSVT) == TargetLowering::TypeSplitVector)
1477     GetSplitVector(RHS, RHSLo, RHSHi);
1478   else
1479     std::tie(RHSLo, RHSHi) = DAG.SplitVector(RHS, SDLoc(RHS));
1480 
1481 
1482   Lo = DAG.getNode(ISD::FCOPYSIGN, DL, LHSLo.getValueType(), LHSLo, RHSLo);
1483   Hi = DAG.getNode(ISD::FCOPYSIGN, DL, LHSHi.getValueType(), LHSHi, RHSHi);
1484 }
1485 
SplitVecRes_IS_FPCLASS(SDNode * N,SDValue & Lo,SDValue & Hi)1486 void DAGTypeLegalizer::SplitVecRes_IS_FPCLASS(SDNode *N, SDValue &Lo,
1487                                               SDValue &Hi) {
1488   SDLoc DL(N);
1489   SDValue ArgLo, ArgHi;
1490   SDValue Test = N->getOperand(1);
1491   SDValue FpValue = N->getOperand(0);
1492   if (getTypeAction(FpValue.getValueType()) == TargetLowering::TypeSplitVector)
1493     GetSplitVector(FpValue, ArgLo, ArgHi);
1494   else
1495     std::tie(ArgLo, ArgHi) = DAG.SplitVector(FpValue, SDLoc(FpValue));
1496   EVT LoVT, HiVT;
1497   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1498 
1499   Lo = DAG.getNode(ISD::IS_FPCLASS, DL, LoVT, ArgLo, Test, N->getFlags());
1500   Hi = DAG.getNode(ISD::IS_FPCLASS, DL, HiVT, ArgHi, Test, N->getFlags());
1501 }
1502 
SplitVecRes_InregOp(SDNode * N,SDValue & Lo,SDValue & Hi)1503 void DAGTypeLegalizer::SplitVecRes_InregOp(SDNode *N, SDValue &Lo,
1504                                            SDValue &Hi) {
1505   SDValue LHSLo, LHSHi;
1506   GetSplitVector(N->getOperand(0), LHSLo, LHSHi);
1507   SDLoc dl(N);
1508 
1509   EVT LoVT, HiVT;
1510   std::tie(LoVT, HiVT) =
1511     DAG.GetSplitDestVTs(cast<VTSDNode>(N->getOperand(1))->getVT());
1512 
1513   Lo = DAG.getNode(N->getOpcode(), dl, LHSLo.getValueType(), LHSLo,
1514                    DAG.getValueType(LoVT));
1515   Hi = DAG.getNode(N->getOpcode(), dl, LHSHi.getValueType(), LHSHi,
1516                    DAG.getValueType(HiVT));
1517 }
1518 
SplitVecRes_ExtVecInRegOp(SDNode * N,SDValue & Lo,SDValue & Hi)1519 void DAGTypeLegalizer::SplitVecRes_ExtVecInRegOp(SDNode *N, SDValue &Lo,
1520                                                  SDValue &Hi) {
1521   unsigned Opcode = N->getOpcode();
1522   SDValue N0 = N->getOperand(0);
1523 
1524   SDLoc dl(N);
1525   SDValue InLo, InHi;
1526 
1527   if (getTypeAction(N0.getValueType()) == TargetLowering::TypeSplitVector)
1528     GetSplitVector(N0, InLo, InHi);
1529   else
1530     std::tie(InLo, InHi) = DAG.SplitVectorOperand(N, 0);
1531 
1532   EVT InLoVT = InLo.getValueType();
1533   unsigned InNumElements = InLoVT.getVectorNumElements();
1534 
1535   EVT OutLoVT, OutHiVT;
1536   std::tie(OutLoVT, OutHiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1537   unsigned OutNumElements = OutLoVT.getVectorNumElements();
1538   assert((2 * OutNumElements) <= InNumElements &&
1539          "Illegal extend vector in reg split");
1540 
1541   // *_EXTEND_VECTOR_INREG instructions extend the lowest elements of the
1542   // input vector (i.e. we only use InLo):
1543   // OutLo will extend the first OutNumElements from InLo.
1544   // OutHi will extend the next OutNumElements from InLo.
1545 
1546   // Shuffle the elements from InLo for OutHi into the bottom elements to
1547   // create a 'fake' InHi.
1548   SmallVector<int, 8> SplitHi(InNumElements, -1);
1549   for (unsigned i = 0; i != OutNumElements; ++i)
1550     SplitHi[i] = i + OutNumElements;
1551   InHi = DAG.getVectorShuffle(InLoVT, dl, InLo, DAG.getUNDEF(InLoVT), SplitHi);
1552 
1553   Lo = DAG.getNode(Opcode, dl, OutLoVT, InLo);
1554   Hi = DAG.getNode(Opcode, dl, OutHiVT, InHi);
1555 }
1556 
SplitVecRes_StrictFPOp(SDNode * N,SDValue & Lo,SDValue & Hi)1557 void DAGTypeLegalizer::SplitVecRes_StrictFPOp(SDNode *N, SDValue &Lo,
1558                                               SDValue &Hi) {
1559   unsigned NumOps = N->getNumOperands();
1560   SDValue Chain = N->getOperand(0);
1561   EVT LoVT, HiVT;
1562   SDLoc dl(N);
1563   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1564 
1565   SmallVector<SDValue, 4> OpsLo(NumOps);
1566   SmallVector<SDValue, 4> OpsHi(NumOps);
1567 
1568   // The Chain is the first operand.
1569   OpsLo[0] = Chain;
1570   OpsHi[0] = Chain;
1571 
1572   // Now process the remaining operands.
1573   for (unsigned i = 1; i < NumOps; ++i) {
1574     SDValue Op = N->getOperand(i);
1575     SDValue OpLo = Op;
1576     SDValue OpHi = Op;
1577 
1578     EVT InVT = Op.getValueType();
1579     if (InVT.isVector()) {
1580       // If the input also splits, handle it directly for a
1581       // compile time speedup. Otherwise split it by hand.
1582       if (getTypeAction(InVT) == TargetLowering::TypeSplitVector)
1583         GetSplitVector(Op, OpLo, OpHi);
1584       else
1585         std::tie(OpLo, OpHi) = DAG.SplitVectorOperand(N, i);
1586     }
1587 
1588     OpsLo[i] = OpLo;
1589     OpsHi[i] = OpHi;
1590   }
1591 
1592   EVT LoValueVTs[] = {LoVT, MVT::Other};
1593   EVT HiValueVTs[] = {HiVT, MVT::Other};
1594   Lo = DAG.getNode(N->getOpcode(), dl, DAG.getVTList(LoValueVTs), OpsLo,
1595                    N->getFlags());
1596   Hi = DAG.getNode(N->getOpcode(), dl, DAG.getVTList(HiValueVTs), OpsHi,
1597                    N->getFlags());
1598 
1599   // Build a factor node to remember that this Op is independent of the
1600   // other one.
1601   Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
1602                       Lo.getValue(1), Hi.getValue(1));
1603 
1604   // Legalize the chain result - switch anything that used the old chain to
1605   // use the new one.
1606   ReplaceValueWith(SDValue(N, 1), Chain);
1607 }
1608 
UnrollVectorOp_StrictFP(SDNode * N,unsigned ResNE)1609 SDValue DAGTypeLegalizer::UnrollVectorOp_StrictFP(SDNode *N, unsigned ResNE) {
1610   SDValue Chain = N->getOperand(0);
1611   EVT VT = N->getValueType(0);
1612   unsigned NE = VT.getVectorNumElements();
1613   EVT EltVT = VT.getVectorElementType();
1614   SDLoc dl(N);
1615 
1616   SmallVector<SDValue, 8> Scalars;
1617   SmallVector<SDValue, 4> Operands(N->getNumOperands());
1618 
1619   // If ResNE is 0, fully unroll the vector op.
1620   if (ResNE == 0)
1621     ResNE = NE;
1622   else if (NE > ResNE)
1623     NE = ResNE;
1624 
1625   //The results of each unrolled operation, including the chain.
1626   EVT ChainVTs[] = {EltVT, MVT::Other};
1627   SmallVector<SDValue, 8> Chains;
1628 
1629   unsigned i;
1630   for (i = 0; i != NE; ++i) {
1631     Operands[0] = Chain;
1632     for (unsigned j = 1, e = N->getNumOperands(); j != e; ++j) {
1633       SDValue Operand = N->getOperand(j);
1634       EVT OperandVT = Operand.getValueType();
1635       if (OperandVT.isVector()) {
1636         EVT OperandEltVT = OperandVT.getVectorElementType();
1637         Operands[j] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, OperandEltVT,
1638                                   Operand, DAG.getVectorIdxConstant(i, dl));
1639       } else {
1640         Operands[j] = Operand;
1641       }
1642     }
1643     SDValue Scalar = DAG.getNode(N->getOpcode(), dl, ChainVTs, Operands);
1644     Scalar.getNode()->setFlags(N->getFlags());
1645 
1646     //Add in the scalar as well as its chain value to the
1647     //result vectors.
1648     Scalars.push_back(Scalar);
1649     Chains.push_back(Scalar.getValue(1));
1650   }
1651 
1652   for (; i < ResNE; ++i)
1653     Scalars.push_back(DAG.getUNDEF(EltVT));
1654 
1655   // Build a new factor node to connect the chain back together.
1656   Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Chains);
1657   ReplaceValueWith(SDValue(N, 1), Chain);
1658 
1659   // Create a new BUILD_VECTOR node
1660   EVT VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT, ResNE);
1661   return DAG.getBuildVector(VecVT, dl, Scalars);
1662 }
1663 
SplitVecRes_OverflowOp(SDNode * N,unsigned ResNo,SDValue & Lo,SDValue & Hi)1664 void DAGTypeLegalizer::SplitVecRes_OverflowOp(SDNode *N, unsigned ResNo,
1665                                               SDValue &Lo, SDValue &Hi) {
1666   SDLoc dl(N);
1667   EVT ResVT = N->getValueType(0);
1668   EVT OvVT = N->getValueType(1);
1669   EVT LoResVT, HiResVT, LoOvVT, HiOvVT;
1670   std::tie(LoResVT, HiResVT) = DAG.GetSplitDestVTs(ResVT);
1671   std::tie(LoOvVT, HiOvVT) = DAG.GetSplitDestVTs(OvVT);
1672 
1673   SDValue LoLHS, HiLHS, LoRHS, HiRHS;
1674   if (getTypeAction(ResVT) == TargetLowering::TypeSplitVector) {
1675     GetSplitVector(N->getOperand(0), LoLHS, HiLHS);
1676     GetSplitVector(N->getOperand(1), LoRHS, HiRHS);
1677   } else {
1678     std::tie(LoLHS, HiLHS) = DAG.SplitVectorOperand(N, 0);
1679     std::tie(LoRHS, HiRHS) = DAG.SplitVectorOperand(N, 1);
1680   }
1681 
1682   unsigned Opcode = N->getOpcode();
1683   SDVTList LoVTs = DAG.getVTList(LoResVT, LoOvVT);
1684   SDVTList HiVTs = DAG.getVTList(HiResVT, HiOvVT);
1685   SDNode *LoNode = DAG.getNode(Opcode, dl, LoVTs, LoLHS, LoRHS).getNode();
1686   SDNode *HiNode = DAG.getNode(Opcode, dl, HiVTs, HiLHS, HiRHS).getNode();
1687   LoNode->setFlags(N->getFlags());
1688   HiNode->setFlags(N->getFlags());
1689 
1690   Lo = SDValue(LoNode, ResNo);
1691   Hi = SDValue(HiNode, ResNo);
1692 
1693   // Replace the other vector result not being explicitly split here.
1694   unsigned OtherNo = 1 - ResNo;
1695   EVT OtherVT = N->getValueType(OtherNo);
1696   if (getTypeAction(OtherVT) == TargetLowering::TypeSplitVector) {
1697     SetSplitVector(SDValue(N, OtherNo),
1698                    SDValue(LoNode, OtherNo), SDValue(HiNode, OtherNo));
1699   } else {
1700     SDValue OtherVal = DAG.getNode(
1701         ISD::CONCAT_VECTORS, dl, OtherVT,
1702         SDValue(LoNode, OtherNo), SDValue(HiNode, OtherNo));
1703     ReplaceValueWith(SDValue(N, OtherNo), OtherVal);
1704   }
1705 }
1706 
SplitVecRes_INSERT_VECTOR_ELT(SDNode * N,SDValue & Lo,SDValue & Hi)1707 void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo,
1708                                                      SDValue &Hi) {
1709   SDValue Vec = N->getOperand(0);
1710   SDValue Elt = N->getOperand(1);
1711   SDValue Idx = N->getOperand(2);
1712   SDLoc dl(N);
1713   GetSplitVector(Vec, Lo, Hi);
1714 
1715   if (ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Idx)) {
1716     unsigned IdxVal = CIdx->getZExtValue();
1717     unsigned LoNumElts = Lo.getValueType().getVectorMinNumElements();
1718     if (IdxVal < LoNumElts) {
1719       Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl,
1720                        Lo.getValueType(), Lo, Elt, Idx);
1721       return;
1722     } else if (!Vec.getValueType().isScalableVector()) {
1723       Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, Hi.getValueType(), Hi, Elt,
1724                        DAG.getVectorIdxConstant(IdxVal - LoNumElts, dl));
1725       return;
1726     }
1727   }
1728 
1729   // See if the target wants to custom expand this node.
1730   if (CustomLowerNode(N, N->getValueType(0), true))
1731     return;
1732 
1733   // Make the vector elements byte-addressable if they aren't already.
1734   EVT VecVT = Vec.getValueType();
1735   EVT EltVT = VecVT.getVectorElementType();
1736   if (VecVT.getScalarSizeInBits() < 8) {
1737     EltVT = MVT::i8;
1738     VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
1739                              VecVT.getVectorElementCount());
1740     Vec = DAG.getNode(ISD::ANY_EXTEND, dl, VecVT, Vec);
1741     // Extend the element type to match if needed.
1742     if (EltVT.bitsGT(Elt.getValueType()))
1743       Elt = DAG.getNode(ISD::ANY_EXTEND, dl, EltVT, Elt);
1744   }
1745 
1746   // Spill the vector to the stack.
1747   // In cases where the vector is illegal it will be broken down into parts
1748   // and stored in parts - we should use the alignment for the smallest part.
1749   Align SmallestAlign = DAG.getReducedAlign(VecVT, /*UseABI=*/false);
1750   SDValue StackPtr =
1751       DAG.CreateStackTemporary(VecVT.getStoreSize(), SmallestAlign);
1752   auto &MF = DAG.getMachineFunction();
1753   auto FrameIndex = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
1754   auto PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex);
1755 
1756   SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
1757                                SmallestAlign);
1758 
1759   // Store the new element.  This may be larger than the vector element type,
1760   // so use a truncating store.
1761   SDValue EltPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
1762   Store = DAG.getTruncStore(
1763       Store, dl, Elt, EltPtr, MachinePointerInfo::getUnknownStack(MF), EltVT,
1764       commonAlignment(SmallestAlign,
1765                       EltVT.getFixedSizeInBits() / 8));
1766 
1767   EVT LoVT, HiVT;
1768   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VecVT);
1769 
1770   // Load the Lo part from the stack slot.
1771   Lo = DAG.getLoad(LoVT, dl, Store, StackPtr, PtrInfo, SmallestAlign);
1772 
1773   // Increment the pointer to the other part.
1774   auto Load = cast<LoadSDNode>(Lo);
1775   MachinePointerInfo MPI = Load->getPointerInfo();
1776   IncrementPointer(Load, LoVT, MPI, StackPtr);
1777 
1778   Hi = DAG.getLoad(HiVT, dl, Store, StackPtr, MPI, SmallestAlign);
1779 
1780   // If we adjusted the original type, we need to truncate the results.
1781   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1782   if (LoVT != Lo.getValueType())
1783     Lo = DAG.getNode(ISD::TRUNCATE, dl, LoVT, Lo);
1784   if (HiVT != Hi.getValueType())
1785     Hi = DAG.getNode(ISD::TRUNCATE, dl, HiVT, Hi);
1786 }
1787 
SplitVecRes_STEP_VECTOR(SDNode * N,SDValue & Lo,SDValue & Hi)1788 void DAGTypeLegalizer::SplitVecRes_STEP_VECTOR(SDNode *N, SDValue &Lo,
1789                                                SDValue &Hi) {
1790   EVT LoVT, HiVT;
1791   SDLoc dl(N);
1792   assert(N->getValueType(0).isScalableVector() &&
1793          "Only scalable vectors are supported for STEP_VECTOR");
1794   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1795   SDValue Step = N->getOperand(0);
1796 
1797   Lo = DAG.getNode(ISD::STEP_VECTOR, dl, LoVT, Step);
1798 
1799   // Hi = Lo + (EltCnt * Step)
1800   EVT EltVT = Step.getValueType();
1801   APInt StepVal = cast<ConstantSDNode>(Step)->getAPIntValue();
1802   SDValue StartOfHi =
1803       DAG.getVScale(dl, EltVT, StepVal * LoVT.getVectorMinNumElements());
1804   StartOfHi = DAG.getSExtOrTrunc(StartOfHi, dl, HiVT.getVectorElementType());
1805   StartOfHi = DAG.getNode(ISD::SPLAT_VECTOR, dl, HiVT, StartOfHi);
1806 
1807   Hi = DAG.getNode(ISD::STEP_VECTOR, dl, HiVT, Step);
1808   Hi = DAG.getNode(ISD::ADD, dl, HiVT, Hi, StartOfHi);
1809 }
1810 
SplitVecRes_ScalarOp(SDNode * N,SDValue & Lo,SDValue & Hi)1811 void DAGTypeLegalizer::SplitVecRes_ScalarOp(SDNode *N, SDValue &Lo,
1812                                             SDValue &Hi) {
1813   EVT LoVT, HiVT;
1814   SDLoc dl(N);
1815   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
1816   Lo = DAG.getNode(N->getOpcode(), dl, LoVT, N->getOperand(0));
1817   if (N->getOpcode() == ISD::SCALAR_TO_VECTOR) {
1818     Hi = DAG.getUNDEF(HiVT);
1819   } else {
1820     assert(N->getOpcode() == ISD::SPLAT_VECTOR && "Unexpected opcode");
1821     Hi = Lo;
1822   }
1823 }
1824 
SplitVecRes_LOAD(LoadSDNode * LD,SDValue & Lo,SDValue & Hi)1825 void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo,
1826                                         SDValue &Hi) {
1827   assert(ISD::isUNINDEXEDLoad(LD) && "Indexed load during type legalization!");
1828   EVT LoVT, HiVT;
1829   SDLoc dl(LD);
1830   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(LD->getValueType(0));
1831 
1832   ISD::LoadExtType ExtType = LD->getExtensionType();
1833   SDValue Ch = LD->getChain();
1834   SDValue Ptr = LD->getBasePtr();
1835   SDValue Offset = DAG.getUNDEF(Ptr.getValueType());
1836   EVT MemoryVT = LD->getMemoryVT();
1837   MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
1838   AAMDNodes AAInfo = LD->getAAInfo();
1839 
1840   EVT LoMemVT, HiMemVT;
1841   std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
1842 
1843   if (!LoMemVT.isByteSized() || !HiMemVT.isByteSized()) {
1844     SDValue Value, NewChain;
1845     std::tie(Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
1846     std::tie(Lo, Hi) = DAG.SplitVector(Value, dl);
1847     ReplaceValueWith(SDValue(LD, 1), NewChain);
1848     return;
1849   }
1850 
1851   Lo = DAG.getLoad(ISD::UNINDEXED, ExtType, LoVT, dl, Ch, Ptr, Offset,
1852                    LD->getPointerInfo(), LoMemVT, LD->getOriginalAlign(),
1853                    MMOFlags, AAInfo);
1854 
1855   MachinePointerInfo MPI;
1856   IncrementPointer(LD, LoMemVT, MPI, Ptr);
1857 
1858   Hi = DAG.getLoad(ISD::UNINDEXED, ExtType, HiVT, dl, Ch, Ptr, Offset, MPI,
1859                    HiMemVT, LD->getOriginalAlign(), MMOFlags, AAInfo);
1860 
1861   // Build a factor node to remember that this load is independent of the
1862   // other one.
1863   Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
1864                    Hi.getValue(1));
1865 
1866   // Legalize the chain result - switch anything that used the old chain to
1867   // use the new one.
1868   ReplaceValueWith(SDValue(LD, 1), Ch);
1869 }
1870 
SplitVecRes_VP_LOAD(VPLoadSDNode * LD,SDValue & Lo,SDValue & Hi)1871 void DAGTypeLegalizer::SplitVecRes_VP_LOAD(VPLoadSDNode *LD, SDValue &Lo,
1872                                            SDValue &Hi) {
1873   assert(LD->isUnindexed() && "Indexed VP load during type legalization!");
1874   EVT LoVT, HiVT;
1875   SDLoc dl(LD);
1876   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(LD->getValueType(0));
1877 
1878   ISD::LoadExtType ExtType = LD->getExtensionType();
1879   SDValue Ch = LD->getChain();
1880   SDValue Ptr = LD->getBasePtr();
1881   SDValue Offset = LD->getOffset();
1882   assert(Offset.isUndef() && "Unexpected indexed variable-length load offset");
1883   Align Alignment = LD->getOriginalAlign();
1884   SDValue Mask = LD->getMask();
1885   SDValue EVL = LD->getVectorLength();
1886   EVT MemoryVT = LD->getMemoryVT();
1887 
1888   EVT LoMemVT, HiMemVT;
1889   bool HiIsEmpty = false;
1890   std::tie(LoMemVT, HiMemVT) =
1891       DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
1892 
1893   // Split Mask operand
1894   SDValue MaskLo, MaskHi;
1895   if (Mask.getOpcode() == ISD::SETCC) {
1896     SplitVecRes_SETCC(Mask.getNode(), MaskLo, MaskHi);
1897   } else {
1898     if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector)
1899       GetSplitVector(Mask, MaskLo, MaskHi);
1900     else
1901       std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
1902   }
1903 
1904   // Split EVL operand
1905   SDValue EVLLo, EVLHi;
1906   std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL, LD->getValueType(0), dl);
1907 
1908   MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
1909       LD->getPointerInfo(), MachineMemOperand::MOLoad,
1910       MemoryLocation::UnknownSize, Alignment, LD->getAAInfo(), LD->getRanges());
1911 
1912   Lo =
1913       DAG.getLoadVP(LD->getAddressingMode(), ExtType, LoVT, dl, Ch, Ptr, Offset,
1914                     MaskLo, EVLLo, LoMemVT, MMO, LD->isExpandingLoad());
1915 
1916   if (HiIsEmpty) {
1917     // The hi vp_load has zero storage size. We therefore simply set it to
1918     // the low vp_load and rely on subsequent removal from the chain.
1919     Hi = Lo;
1920   } else {
1921     // Generate hi vp_load.
1922     Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
1923                                      LD->isExpandingLoad());
1924 
1925     MachinePointerInfo MPI;
1926     if (LoMemVT.isScalableVector())
1927       MPI = MachinePointerInfo(LD->getPointerInfo().getAddrSpace());
1928     else
1929       MPI = LD->getPointerInfo().getWithOffset(
1930           LoMemVT.getStoreSize().getFixedValue());
1931 
1932     MMO = DAG.getMachineFunction().getMachineMemOperand(
1933         MPI, MachineMemOperand::MOLoad, MemoryLocation::UnknownSize, Alignment,
1934         LD->getAAInfo(), LD->getRanges());
1935 
1936     Hi = DAG.getLoadVP(LD->getAddressingMode(), ExtType, HiVT, dl, Ch, Ptr,
1937                        Offset, MaskHi, EVLHi, HiMemVT, MMO,
1938                        LD->isExpandingLoad());
1939   }
1940 
1941   // Build a factor node to remember that this load is independent of the
1942   // other one.
1943   Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
1944                    Hi.getValue(1));
1945 
1946   // Legalize the chain result - switch anything that used the old chain to
1947   // use the new one.
1948   ReplaceValueWith(SDValue(LD, 1), Ch);
1949 }
1950 
SplitVecRes_VP_STRIDED_LOAD(VPStridedLoadSDNode * SLD,SDValue & Lo,SDValue & Hi)1951 void DAGTypeLegalizer::SplitVecRes_VP_STRIDED_LOAD(VPStridedLoadSDNode *SLD,
1952                                                    SDValue &Lo, SDValue &Hi) {
1953   assert(SLD->isUnindexed() &&
1954          "Indexed VP strided load during type legalization!");
1955   assert(SLD->getOffset().isUndef() &&
1956          "Unexpected indexed variable-length load offset");
1957 
1958   SDLoc DL(SLD);
1959 
1960   EVT LoVT, HiVT;
1961   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(SLD->getValueType(0));
1962 
1963   EVT LoMemVT, HiMemVT;
1964   bool HiIsEmpty = false;
1965   std::tie(LoMemVT, HiMemVT) =
1966       DAG.GetDependentSplitDestVTs(SLD->getMemoryVT(), LoVT, &HiIsEmpty);
1967 
1968   SDValue Mask = SLD->getMask();
1969   SDValue LoMask, HiMask;
1970   if (Mask.getOpcode() == ISD::SETCC) {
1971     SplitVecRes_SETCC(Mask.getNode(), LoMask, HiMask);
1972   } else {
1973     if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector)
1974       GetSplitVector(Mask, LoMask, HiMask);
1975     else
1976       std::tie(LoMask, HiMask) = DAG.SplitVector(Mask, DL);
1977   }
1978 
1979   SDValue LoEVL, HiEVL;
1980   std::tie(LoEVL, HiEVL) =
1981       DAG.SplitEVL(SLD->getVectorLength(), SLD->getValueType(0), DL);
1982 
1983   // Generate the low vp_strided_load
1984   Lo = DAG.getStridedLoadVP(
1985       SLD->getAddressingMode(), SLD->getExtensionType(), LoVT, DL,
1986       SLD->getChain(), SLD->getBasePtr(), SLD->getOffset(), SLD->getStride(),
1987       LoMask, LoEVL, LoMemVT, SLD->getMemOperand(), SLD->isExpandingLoad());
1988 
1989   if (HiIsEmpty) {
1990     // The high vp_strided_load has zero storage size. We therefore simply set
1991     // it to the low vp_strided_load and rely on subsequent removal from the
1992     // chain.
1993     Hi = Lo;
1994   } else {
1995     // Generate the high vp_strided_load.
1996     // To calculate the high base address, we need to sum to the low base
1997     // address stride number of bytes for each element already loaded by low,
1998     // that is: Ptr = Ptr + (LoEVL * Stride)
1999     EVT PtrVT = SLD->getBasePtr().getValueType();
2000     SDValue Increment =
2001         DAG.getNode(ISD::MUL, DL, PtrVT, LoEVL,
2002                     DAG.getSExtOrTrunc(SLD->getStride(), DL, PtrVT));
2003     SDValue Ptr =
2004         DAG.getNode(ISD::ADD, DL, PtrVT, SLD->getBasePtr(), Increment);
2005 
2006     Align Alignment = SLD->getOriginalAlign();
2007     if (LoMemVT.isScalableVector())
2008       Alignment = commonAlignment(
2009           Alignment, LoMemVT.getSizeInBits().getKnownMinValue() / 8);
2010 
2011     MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2012         MachinePointerInfo(SLD->getPointerInfo().getAddrSpace()),
2013         MachineMemOperand::MOLoad, MemoryLocation::UnknownSize, Alignment,
2014         SLD->getAAInfo(), SLD->getRanges());
2015 
2016     Hi = DAG.getStridedLoadVP(SLD->getAddressingMode(), SLD->getExtensionType(),
2017                               HiVT, DL, SLD->getChain(), Ptr, SLD->getOffset(),
2018                               SLD->getStride(), HiMask, HiEVL, HiMemVT, MMO,
2019                               SLD->isExpandingLoad());
2020   }
2021 
2022   // Build a factor node to remember that this load is independent of the
2023   // other one.
2024   SDValue Ch = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Lo.getValue(1),
2025                            Hi.getValue(1));
2026 
2027   // Legalize the chain result - switch anything that used the old chain to
2028   // use the new one.
2029   ReplaceValueWith(SDValue(SLD, 1), Ch);
2030 }
2031 
SplitVecRes_MLOAD(MaskedLoadSDNode * MLD,SDValue & Lo,SDValue & Hi)2032 void DAGTypeLegalizer::SplitVecRes_MLOAD(MaskedLoadSDNode *MLD,
2033                                          SDValue &Lo, SDValue &Hi) {
2034   assert(MLD->isUnindexed() && "Indexed masked load during type legalization!");
2035   EVT LoVT, HiVT;
2036   SDLoc dl(MLD);
2037   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(MLD->getValueType(0));
2038 
2039   SDValue Ch = MLD->getChain();
2040   SDValue Ptr = MLD->getBasePtr();
2041   SDValue Offset = MLD->getOffset();
2042   assert(Offset.isUndef() && "Unexpected indexed masked load offset");
2043   SDValue Mask = MLD->getMask();
2044   SDValue PassThru = MLD->getPassThru();
2045   Align Alignment = MLD->getOriginalAlign();
2046   ISD::LoadExtType ExtType = MLD->getExtensionType();
2047 
2048   // Split Mask operand
2049   SDValue MaskLo, MaskHi;
2050   if (Mask.getOpcode() == ISD::SETCC) {
2051     SplitVecRes_SETCC(Mask.getNode(), MaskLo, MaskHi);
2052   } else {
2053     if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector)
2054       GetSplitVector(Mask, MaskLo, MaskHi);
2055     else
2056       std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, dl);
2057   }
2058 
2059   EVT MemoryVT = MLD->getMemoryVT();
2060   EVT LoMemVT, HiMemVT;
2061   bool HiIsEmpty = false;
2062   std::tie(LoMemVT, HiMemVT) =
2063       DAG.GetDependentSplitDestVTs(MemoryVT, LoVT, &HiIsEmpty);
2064 
2065   SDValue PassThruLo, PassThruHi;
2066   if (getTypeAction(PassThru.getValueType()) == TargetLowering::TypeSplitVector)
2067     GetSplitVector(PassThru, PassThruLo, PassThruHi);
2068   else
2069     std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2070 
2071   MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2072       MLD->getPointerInfo(), MachineMemOperand::MOLoad,
2073       MemoryLocation::UnknownSize, Alignment, MLD->getAAInfo(),
2074       MLD->getRanges());
2075 
2076   Lo = DAG.getMaskedLoad(LoVT, dl, Ch, Ptr, Offset, MaskLo, PassThruLo, LoMemVT,
2077                          MMO, MLD->getAddressingMode(), ExtType,
2078                          MLD->isExpandingLoad());
2079 
2080   if (HiIsEmpty) {
2081     // The hi masked load has zero storage size. We therefore simply set it to
2082     // the low masked load and rely on subsequent removal from the chain.
2083     Hi = Lo;
2084   } else {
2085     // Generate hi masked load.
2086     Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, dl, LoMemVT, DAG,
2087                                      MLD->isExpandingLoad());
2088 
2089     MachinePointerInfo MPI;
2090     if (LoMemVT.isScalableVector())
2091       MPI = MachinePointerInfo(MLD->getPointerInfo().getAddrSpace());
2092     else
2093       MPI = MLD->getPointerInfo().getWithOffset(
2094           LoMemVT.getStoreSize().getFixedValue());
2095 
2096     MMO = DAG.getMachineFunction().getMachineMemOperand(
2097         MPI, MachineMemOperand::MOLoad, MemoryLocation::UnknownSize, Alignment,
2098         MLD->getAAInfo(), MLD->getRanges());
2099 
2100     Hi = DAG.getMaskedLoad(HiVT, dl, Ch, Ptr, Offset, MaskHi, PassThruHi,
2101                            HiMemVT, MMO, MLD->getAddressingMode(), ExtType,
2102                            MLD->isExpandingLoad());
2103   }
2104 
2105   // Build a factor node to remember that this load is independent of the
2106   // other one.
2107   Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
2108                    Hi.getValue(1));
2109 
2110   // Legalize the chain result - switch anything that used the old chain to
2111   // use the new one.
2112   ReplaceValueWith(SDValue(MLD, 1), Ch);
2113 
2114 }
2115 
SplitVecRes_Gather(MemSDNode * N,SDValue & Lo,SDValue & Hi,bool SplitSETCC)2116 void DAGTypeLegalizer::SplitVecRes_Gather(MemSDNode *N, SDValue &Lo,
2117                                           SDValue &Hi, bool SplitSETCC) {
2118   EVT LoVT, HiVT;
2119   SDLoc dl(N);
2120   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
2121 
2122   SDValue Ch = N->getChain();
2123   SDValue Ptr = N->getBasePtr();
2124   struct Operands {
2125     SDValue Mask;
2126     SDValue Index;
2127     SDValue Scale;
2128   } Ops = [&]() -> Operands {
2129     if (auto *MSC = dyn_cast<MaskedGatherSDNode>(N)) {
2130       return {MSC->getMask(), MSC->getIndex(), MSC->getScale()};
2131     }
2132     auto *VPSC = cast<VPGatherSDNode>(N);
2133     return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale()};
2134   }();
2135 
2136   EVT MemoryVT = N->getMemoryVT();
2137   Align Alignment = N->getOriginalAlign();
2138 
2139   // Split Mask operand
2140   SDValue MaskLo, MaskHi;
2141   if (SplitSETCC && Ops.Mask.getOpcode() == ISD::SETCC) {
2142     SplitVecRes_SETCC(Ops.Mask.getNode(), MaskLo, MaskHi);
2143   } else {
2144     std::tie(MaskLo, MaskHi) = SplitMask(Ops.Mask, dl);
2145   }
2146 
2147   EVT LoMemVT, HiMemVT;
2148   // Split MemoryVT
2149   std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
2150 
2151   SDValue IndexHi, IndexLo;
2152   if (getTypeAction(Ops.Index.getValueType()) ==
2153       TargetLowering::TypeSplitVector)
2154     GetSplitVector(Ops.Index, IndexLo, IndexHi);
2155   else
2156     std::tie(IndexLo, IndexHi) = DAG.SplitVector(Ops.Index, dl);
2157 
2158   MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
2159       N->getPointerInfo(), MachineMemOperand::MOLoad,
2160       MemoryLocation::UnknownSize, Alignment, N->getAAInfo(), N->getRanges());
2161 
2162   if (auto *MGT = dyn_cast<MaskedGatherSDNode>(N)) {
2163     SDValue PassThru = MGT->getPassThru();
2164     SDValue PassThruLo, PassThruHi;
2165     if (getTypeAction(PassThru.getValueType()) ==
2166         TargetLowering::TypeSplitVector)
2167       GetSplitVector(PassThru, PassThruLo, PassThruHi);
2168     else
2169       std::tie(PassThruLo, PassThruHi) = DAG.SplitVector(PassThru, dl);
2170 
2171     ISD::LoadExtType ExtType = MGT->getExtensionType();
2172     ISD::MemIndexType IndexTy = MGT->getIndexType();
2173 
2174     SDValue OpsLo[] = {Ch, PassThruLo, MaskLo, Ptr, IndexLo, Ops.Scale};
2175     Lo = DAG.getMaskedGather(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl,
2176                              OpsLo, MMO, IndexTy, ExtType);
2177 
2178     SDValue OpsHi[] = {Ch, PassThruHi, MaskHi, Ptr, IndexHi, Ops.Scale};
2179     Hi = DAG.getMaskedGather(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl,
2180                              OpsHi, MMO, IndexTy, ExtType);
2181   } else {
2182     auto *VPGT = cast<VPGatherSDNode>(N);
2183     SDValue EVLLo, EVLHi;
2184     std::tie(EVLLo, EVLHi) =
2185         DAG.SplitEVL(VPGT->getVectorLength(), MemoryVT, dl);
2186 
2187     SDValue OpsLo[] = {Ch, Ptr, IndexLo, Ops.Scale, MaskLo, EVLLo};
2188     Lo = DAG.getGatherVP(DAG.getVTList(LoVT, MVT::Other), LoMemVT, dl, OpsLo,
2189                          MMO, VPGT->getIndexType());
2190 
2191     SDValue OpsHi[] = {Ch, Ptr, IndexHi, Ops.Scale, MaskHi, EVLHi};
2192     Hi = DAG.getGatherVP(DAG.getVTList(HiVT, MVT::Other), HiMemVT, dl, OpsHi,
2193                          MMO, VPGT->getIndexType());
2194   }
2195 
2196   // Build a factor node to remember that this load is independent of the
2197   // other one.
2198   Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
2199                    Hi.getValue(1));
2200 
2201   // Legalize the chain result - switch anything that used the old chain to
2202   // use the new one.
2203   ReplaceValueWith(SDValue(N, 1), Ch);
2204 }
2205 
SplitVecRes_SETCC(SDNode * N,SDValue & Lo,SDValue & Hi)2206 void DAGTypeLegalizer::SplitVecRes_SETCC(SDNode *N, SDValue &Lo, SDValue &Hi) {
2207   assert(N->getValueType(0).isVector() &&
2208          N->getOperand(0).getValueType().isVector() &&
2209          "Operand types must be vectors");
2210 
2211   EVT LoVT, HiVT;
2212   SDLoc DL(N);
2213   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
2214 
2215   // If the input also splits, handle it directly. Otherwise split it by hand.
2216   SDValue LL, LH, RL, RH;
2217   if (getTypeAction(N->getOperand(0).getValueType()) ==
2218       TargetLowering::TypeSplitVector)
2219     GetSplitVector(N->getOperand(0), LL, LH);
2220   else
2221     std::tie(LL, LH) = DAG.SplitVectorOperand(N, 0);
2222 
2223   if (getTypeAction(N->getOperand(1).getValueType()) ==
2224       TargetLowering::TypeSplitVector)
2225     GetSplitVector(N->getOperand(1), RL, RH);
2226   else
2227     std::tie(RL, RH) = DAG.SplitVectorOperand(N, 1);
2228 
2229   if (N->getOpcode() == ISD::SETCC) {
2230     Lo = DAG.getNode(N->getOpcode(), DL, LoVT, LL, RL, N->getOperand(2));
2231     Hi = DAG.getNode(N->getOpcode(), DL, HiVT, LH, RH, N->getOperand(2));
2232   } else {
2233     assert(N->getOpcode() == ISD::VP_SETCC && "Expected VP_SETCC opcode");
2234     SDValue MaskLo, MaskHi, EVLLo, EVLHi;
2235     std::tie(MaskLo, MaskHi) = SplitMask(N->getOperand(3));
2236     std::tie(EVLLo, EVLHi) =
2237         DAG.SplitEVL(N->getOperand(4), N->getValueType(0), DL);
2238     Lo = DAG.getNode(N->getOpcode(), DL, LoVT, LL, RL, N->getOperand(2), MaskLo,
2239                      EVLLo);
2240     Hi = DAG.getNode(N->getOpcode(), DL, HiVT, LH, RH, N->getOperand(2), MaskHi,
2241                      EVLHi);
2242   }
2243 }
2244 
SplitVecRes_UnaryOp(SDNode * N,SDValue & Lo,SDValue & Hi)2245 void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo,
2246                                            SDValue &Hi) {
2247   // Get the dest types - they may not match the input types, e.g. int_to_fp.
2248   EVT LoVT, HiVT;
2249   SDLoc dl(N);
2250   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
2251 
2252   // If the input also splits, handle it directly for a compile time speedup.
2253   // Otherwise split it by hand.
2254   EVT InVT = N->getOperand(0).getValueType();
2255   if (getTypeAction(InVT) == TargetLowering::TypeSplitVector)
2256     GetSplitVector(N->getOperand(0), Lo, Hi);
2257   else
2258     std::tie(Lo, Hi) = DAG.SplitVectorOperand(N, 0);
2259 
2260   const SDNodeFlags Flags = N->getFlags();
2261   unsigned Opcode = N->getOpcode();
2262   if (N->getNumOperands() <= 2) {
2263     if (Opcode == ISD::FP_ROUND) {
2264       Lo = DAG.getNode(Opcode, dl, LoVT, Lo, N->getOperand(1), Flags);
2265       Hi = DAG.getNode(Opcode, dl, HiVT, Hi, N->getOperand(1), Flags);
2266     } else {
2267       Lo = DAG.getNode(Opcode, dl, LoVT, Lo, Flags);
2268       Hi = DAG.getNode(Opcode, dl, HiVT, Hi, Flags);
2269     }
2270     return;
2271   }
2272 
2273   assert(N->getNumOperands() == 3 && "Unexpected number of operands!");
2274   assert(N->isVPOpcode() && "Expected VP opcode");
2275 
2276   SDValue MaskLo, MaskHi;
2277   std::tie(MaskLo, MaskHi) = SplitMask(N->getOperand(1));
2278 
2279   SDValue EVLLo, EVLHi;
2280   std::tie(EVLLo, EVLHi) =
2281       DAG.SplitEVL(N->getOperand(2), N->getValueType(0), dl);
2282 
2283   Lo = DAG.getNode(Opcode, dl, LoVT, {Lo, MaskLo, EVLLo}, Flags);
2284   Hi = DAG.getNode(Opcode, dl, HiVT, {Hi, MaskHi, EVLHi}, Flags);
2285 }
2286 
SplitVecRes_ExtendOp(SDNode * N,SDValue & Lo,SDValue & Hi)2287 void DAGTypeLegalizer::SplitVecRes_ExtendOp(SDNode *N, SDValue &Lo,
2288                                             SDValue &Hi) {
2289   SDLoc dl(N);
2290   EVT SrcVT = N->getOperand(0).getValueType();
2291   EVT DestVT = N->getValueType(0);
2292   EVT LoVT, HiVT;
2293   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
2294 
2295   // We can do better than a generic split operation if the extend is doing
2296   // more than just doubling the width of the elements and the following are
2297   // true:
2298   //   - The number of vector elements is even,
2299   //   - the source type is legal,
2300   //   - the type of a split source is illegal,
2301   //   - the type of an extended (by doubling element size) source is legal, and
2302   //   - the type of that extended source when split is legal.
2303   //
2304   // This won't necessarily completely legalize the operation, but it will
2305   // more effectively move in the right direction and prevent falling down
2306   // to scalarization in many cases due to the input vector being split too
2307   // far.
2308   if (SrcVT.getVectorElementCount().isKnownEven() &&
2309       SrcVT.getScalarSizeInBits() * 2 < DestVT.getScalarSizeInBits()) {
2310     LLVMContext &Ctx = *DAG.getContext();
2311     EVT NewSrcVT = SrcVT.widenIntegerVectorElementType(Ctx);
2312     EVT SplitSrcVT = SrcVT.getHalfNumVectorElementsVT(Ctx);
2313 
2314     EVT SplitLoVT, SplitHiVT;
2315     std::tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
2316     if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
2317         TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
2318       LLVM_DEBUG(dbgs() << "Split vector extend via incremental extend:";
2319                  N->dump(&DAG); dbgs() << "\n");
2320       if (!N->isVPOpcode()) {
2321         // Extend the source vector by one step.
2322         SDValue NewSrc =
2323             DAG.getNode(N->getOpcode(), dl, NewSrcVT, N->getOperand(0));
2324         // Get the low and high halves of the new, extended one step, vector.
2325         std::tie(Lo, Hi) = DAG.SplitVector(NewSrc, dl);
2326         // Extend those vector halves the rest of the way.
2327         Lo = DAG.getNode(N->getOpcode(), dl, LoVT, Lo);
2328         Hi = DAG.getNode(N->getOpcode(), dl, HiVT, Hi);
2329         return;
2330       }
2331 
2332       // Extend the source vector by one step.
2333       SDValue NewSrc =
2334           DAG.getNode(N->getOpcode(), dl, NewSrcVT, N->getOperand(0),
2335                       N->getOperand(1), N->getOperand(2));
2336       // Get the low and high halves of the new, extended one step, vector.
2337       std::tie(Lo, Hi) = DAG.SplitVector(NewSrc, dl);
2338 
2339       SDValue MaskLo, MaskHi;
2340       std::tie(MaskLo, MaskHi) = SplitMask(N->getOperand(1));
2341 
2342       SDValue EVLLo, EVLHi;
2343       std::tie(EVLLo, EVLHi) =
2344           DAG.SplitEVL(N->getOperand(2), N->getValueType(0), dl);
2345       // Extend those vector halves the rest of the way.
2346       Lo = DAG.getNode(N->getOpcode(), dl, LoVT, {Lo, MaskLo, EVLLo});
2347       Hi = DAG.getNode(N->getOpcode(), dl, HiVT, {Hi, MaskHi, EVLHi});
2348       return;
2349     }
2350   }
2351   // Fall back to the generic unary operator splitting otherwise.
2352   SplitVecRes_UnaryOp(N, Lo, Hi);
2353 }
2354 
SplitVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode * N,SDValue & Lo,SDValue & Hi)2355 void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N,
2356                                                   SDValue &Lo, SDValue &Hi) {
2357   // The low and high parts of the original input give four input vectors.
2358   SDValue Inputs[4];
2359   SDLoc DL(N);
2360   GetSplitVector(N->getOperand(0), Inputs[0], Inputs[1]);
2361   GetSplitVector(N->getOperand(1), Inputs[2], Inputs[3]);
2362   EVT NewVT = Inputs[0].getValueType();
2363   unsigned NewElts = NewVT.getVectorNumElements();
2364 
2365   auto &&IsConstant = [](const SDValue &N) {
2366     APInt SplatValue;
2367     return N.getResNo() == 0 &&
2368            (ISD::isConstantSplatVector(N.getNode(), SplatValue) ||
2369             ISD::isBuildVectorOfConstantSDNodes(N.getNode()));
2370   };
2371   auto &&BuildVector = [NewElts, &DAG = DAG, NewVT, &DL](SDValue &Input1,
2372                                                          SDValue &Input2,
2373                                                          ArrayRef<int> Mask) {
2374     assert(Input1->getOpcode() == ISD::BUILD_VECTOR &&
2375            Input2->getOpcode() == ISD::BUILD_VECTOR &&
2376            "Expected build vector node.");
2377     EVT EltVT = NewVT.getVectorElementType();
2378     SmallVector<SDValue> Ops(NewElts, DAG.getUNDEF(EltVT));
2379     for (unsigned I = 0; I < NewElts; ++I) {
2380       if (Mask[I] == UndefMaskElem)
2381         continue;
2382       unsigned Idx = Mask[I];
2383       if (Idx >= NewElts)
2384         Ops[I] = Input2.getOperand(Idx - NewElts);
2385       else
2386         Ops[I] = Input1.getOperand(Idx);
2387       // Make the type of all elements the same as the element type.
2388       if (Ops[I].getValueType().bitsGT(EltVT))
2389         Ops[I] = DAG.getNode(ISD::TRUNCATE, DL, EltVT, Ops[I]);
2390     }
2391     return DAG.getBuildVector(NewVT, DL, Ops);
2392   };
2393 
2394   // If Lo or Hi uses elements from at most two of the four input vectors, then
2395   // express it as a vector shuffle of those two inputs.  Otherwise extract the
2396   // input elements by hand and construct the Lo/Hi output using a BUILD_VECTOR.
2397   SmallVector<int> OrigMask(N->getMask());
2398   // Try to pack incoming shuffles/inputs.
2399   auto &&TryPeekThroughShufflesInputs = [&Inputs, &NewVT, this, NewElts,
2400                                          &DL](SmallVectorImpl<int> &Mask) {
2401     // Check if all inputs are shuffles of the same operands or non-shuffles.
2402     MapVector<std::pair<SDValue, SDValue>, SmallVector<unsigned>> ShufflesIdxs;
2403     for (unsigned Idx = 0; Idx < std::size(Inputs); ++Idx) {
2404       SDValue Input = Inputs[Idx];
2405       auto *Shuffle = dyn_cast<ShuffleVectorSDNode>(Input.getNode());
2406       if (!Shuffle ||
2407           Input.getOperand(0).getValueType() != Input.getValueType())
2408         continue;
2409       ShufflesIdxs[std::make_pair(Input.getOperand(0), Input.getOperand(1))]
2410           .push_back(Idx);
2411       ShufflesIdxs[std::make_pair(Input.getOperand(1), Input.getOperand(0))]
2412           .push_back(Idx);
2413     }
2414     for (auto &P : ShufflesIdxs) {
2415       if (P.second.size() < 2)
2416         continue;
2417       // Use shuffles operands instead of shuffles themselves.
2418       // 1. Adjust mask.
2419       for (int &Idx : Mask) {
2420         if (Idx == UndefMaskElem)
2421           continue;
2422         unsigned SrcRegIdx = Idx / NewElts;
2423         if (Inputs[SrcRegIdx].isUndef()) {
2424           Idx = UndefMaskElem;
2425           continue;
2426         }
2427         auto *Shuffle =
2428             dyn_cast<ShuffleVectorSDNode>(Inputs[SrcRegIdx].getNode());
2429         if (!Shuffle || !is_contained(P.second, SrcRegIdx))
2430           continue;
2431         int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
2432         if (MaskElt == UndefMaskElem) {
2433           Idx = UndefMaskElem;
2434           continue;
2435         }
2436         Idx = MaskElt % NewElts +
2437               P.second[Shuffle->getOperand(MaskElt / NewElts) == P.first.first
2438                            ? 0
2439                            : 1] *
2440                   NewElts;
2441       }
2442       // 2. Update inputs.
2443       Inputs[P.second[0]] = P.first.first;
2444       Inputs[P.second[1]] = P.first.second;
2445       // Clear the pair data.
2446       P.second.clear();
2447       ShufflesIdxs[std::make_pair(P.first.second, P.first.first)].clear();
2448     }
2449     // Check if any concat_vectors can be simplified.
2450     SmallBitVector UsedSubVector(2 * std::size(Inputs));
2451     for (int &Idx : Mask) {
2452       if (Idx == UndefMaskElem)
2453         continue;
2454       unsigned SrcRegIdx = Idx / NewElts;
2455       if (Inputs[SrcRegIdx].isUndef()) {
2456         Idx = UndefMaskElem;
2457         continue;
2458       }
2459       TargetLowering::LegalizeTypeAction TypeAction =
2460           getTypeAction(Inputs[SrcRegIdx].getValueType());
2461       if (Inputs[SrcRegIdx].getOpcode() == ISD::CONCAT_VECTORS &&
2462           Inputs[SrcRegIdx].getNumOperands() == 2 &&
2463           !Inputs[SrcRegIdx].getOperand(1).isUndef() &&
2464           (TypeAction == TargetLowering::TypeLegal ||
2465            TypeAction == TargetLowering::TypeWidenVector))
2466         UsedSubVector.set(2 * SrcRegIdx + (Idx % NewElts) / (NewElts / 2));
2467     }
2468     if (UsedSubVector.count() > 1) {
2469       SmallVector<SmallVector<std::pair<unsigned, int>, 2>> Pairs;
2470       for (unsigned I = 0; I < std::size(Inputs); ++I) {
2471         if (UsedSubVector.test(2 * I) == UsedSubVector.test(2 * I + 1))
2472           continue;
2473         if (Pairs.empty() || Pairs.back().size() == 2)
2474           Pairs.emplace_back();
2475         if (UsedSubVector.test(2 * I)) {
2476           Pairs.back().emplace_back(I, 0);
2477         } else {
2478           assert(UsedSubVector.test(2 * I + 1) &&
2479                  "Expected to be used one of the subvectors.");
2480           Pairs.back().emplace_back(I, 1);
2481         }
2482       }
2483       if (!Pairs.empty() && Pairs.front().size() > 1) {
2484         // Adjust mask.
2485         for (int &Idx : Mask) {
2486           if (Idx == UndefMaskElem)
2487             continue;
2488           unsigned SrcRegIdx = Idx / NewElts;
2489           auto *It = find_if(
2490               Pairs, [SrcRegIdx](ArrayRef<std::pair<unsigned, int>> Idxs) {
2491                 return Idxs.front().first == SrcRegIdx ||
2492                        Idxs.back().first == SrcRegIdx;
2493               });
2494           if (It == Pairs.end())
2495             continue;
2496           Idx = It->front().first * NewElts + (Idx % NewElts) % (NewElts / 2) +
2497                 (SrcRegIdx == It->front().first ? 0 : (NewElts / 2));
2498         }
2499         // Adjust inputs.
2500         for (ArrayRef<std::pair<unsigned, int>> Idxs : Pairs) {
2501           Inputs[Idxs.front().first] = DAG.getNode(
2502               ISD::CONCAT_VECTORS, DL,
2503               Inputs[Idxs.front().first].getValueType(),
2504               Inputs[Idxs.front().first].getOperand(Idxs.front().second),
2505               Inputs[Idxs.back().first].getOperand(Idxs.back().second));
2506         }
2507       }
2508     }
2509     bool Changed;
2510     do {
2511       // Try to remove extra shuffles (except broadcasts) and shuffles with the
2512       // reused operands.
2513       Changed = false;
2514       for (unsigned I = 0; I < std::size(Inputs); ++I) {
2515         auto *Shuffle = dyn_cast<ShuffleVectorSDNode>(Inputs[I].getNode());
2516         if (!Shuffle)
2517           continue;
2518         if (Shuffle->getOperand(0).getValueType() != NewVT)
2519           continue;
2520         int Op = -1;
2521         if (!Inputs[I].hasOneUse() && Shuffle->getOperand(1).isUndef() &&
2522             !Shuffle->isSplat()) {
2523           Op = 0;
2524         } else if (!Inputs[I].hasOneUse() &&
2525                    !Shuffle->getOperand(1).isUndef()) {
2526           // Find the only used operand, if possible.
2527           for (int &Idx : Mask) {
2528             if (Idx == UndefMaskElem)
2529               continue;
2530             unsigned SrcRegIdx = Idx / NewElts;
2531             if (SrcRegIdx != I)
2532               continue;
2533             int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
2534             if (MaskElt == UndefMaskElem) {
2535               Idx = UndefMaskElem;
2536               continue;
2537             }
2538             int OpIdx = MaskElt / NewElts;
2539             if (Op == -1) {
2540               Op = OpIdx;
2541               continue;
2542             }
2543             if (Op != OpIdx) {
2544               Op = -1;
2545               break;
2546             }
2547           }
2548         }
2549         if (Op < 0) {
2550           // Try to check if one of the shuffle operands is used already.
2551           for (int OpIdx = 0; OpIdx < 2; ++OpIdx) {
2552             if (Shuffle->getOperand(OpIdx).isUndef())
2553               continue;
2554             auto *It = find(Inputs, Shuffle->getOperand(OpIdx));
2555             if (It == std::end(Inputs))
2556               continue;
2557             int FoundOp = std::distance(std::begin(Inputs), It);
2558             // Found that operand is used already.
2559             // 1. Fix the mask for the reused operand.
2560             for (int &Idx : Mask) {
2561               if (Idx == UndefMaskElem)
2562                 continue;
2563               unsigned SrcRegIdx = Idx / NewElts;
2564               if (SrcRegIdx != I)
2565                 continue;
2566               int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
2567               if (MaskElt == UndefMaskElem) {
2568                 Idx = UndefMaskElem;
2569                 continue;
2570               }
2571               int MaskIdx = MaskElt / NewElts;
2572               if (OpIdx == MaskIdx)
2573                 Idx = MaskElt % NewElts + FoundOp * NewElts;
2574             }
2575             // 2. Set Op to the unused OpIdx.
2576             Op = (OpIdx + 1) % 2;
2577             break;
2578           }
2579         }
2580         if (Op >= 0) {
2581           Changed = true;
2582           Inputs[I] = Shuffle->getOperand(Op);
2583           // Adjust mask.
2584           for (int &Idx : Mask) {
2585             if (Idx == UndefMaskElem)
2586               continue;
2587             unsigned SrcRegIdx = Idx / NewElts;
2588             if (SrcRegIdx != I)
2589               continue;
2590             int MaskElt = Shuffle->getMaskElt(Idx % NewElts);
2591             int OpIdx = MaskElt / NewElts;
2592             if (OpIdx != Op)
2593               continue;
2594             Idx = MaskElt % NewElts + SrcRegIdx * NewElts;
2595           }
2596         }
2597       }
2598     } while (Changed);
2599   };
2600   TryPeekThroughShufflesInputs(OrigMask);
2601   // Proces unique inputs.
2602   auto &&MakeUniqueInputs = [&Inputs, &IsConstant,
2603                              NewElts](SmallVectorImpl<int> &Mask) {
2604     SetVector<SDValue> UniqueInputs;
2605     SetVector<SDValue> UniqueConstantInputs;
2606     for (const auto &I : Inputs) {
2607       if (IsConstant(I))
2608         UniqueConstantInputs.insert(I);
2609       else if (!I.isUndef())
2610         UniqueInputs.insert(I);
2611     }
2612     // Adjust mask in case of reused inputs. Also, need to insert constant
2613     // inputs at first, otherwise it affects the final outcome.
2614     if (UniqueInputs.size() != std::size(Inputs)) {
2615       auto &&UniqueVec = UniqueInputs.takeVector();
2616       auto &&UniqueConstantVec = UniqueConstantInputs.takeVector();
2617       unsigned ConstNum = UniqueConstantVec.size();
2618       for (int &Idx : Mask) {
2619         if (Idx == UndefMaskElem)
2620           continue;
2621         unsigned SrcRegIdx = Idx / NewElts;
2622         if (Inputs[SrcRegIdx].isUndef()) {
2623           Idx = UndefMaskElem;
2624           continue;
2625         }
2626         const auto It = find(UniqueConstantVec, Inputs[SrcRegIdx]);
2627         if (It != UniqueConstantVec.end()) {
2628           Idx = (Idx % NewElts) +
2629                 NewElts * std::distance(UniqueConstantVec.begin(), It);
2630           assert(Idx >= 0 && "Expected defined mask idx.");
2631           continue;
2632         }
2633         const auto RegIt = find(UniqueVec, Inputs[SrcRegIdx]);
2634         assert(RegIt != UniqueVec.end() && "Cannot find non-const value.");
2635         Idx = (Idx % NewElts) +
2636               NewElts * (std::distance(UniqueVec.begin(), RegIt) + ConstNum);
2637         assert(Idx >= 0 && "Expected defined mask idx.");
2638       }
2639       copy(UniqueConstantVec, std::begin(Inputs));
2640       copy(UniqueVec, std::next(std::begin(Inputs), ConstNum));
2641     }
2642   };
2643   MakeUniqueInputs(OrigMask);
2644   SDValue OrigInputs[4];
2645   copy(Inputs, std::begin(OrigInputs));
2646   for (unsigned High = 0; High < 2; ++High) {
2647     SDValue &Output = High ? Hi : Lo;
2648 
2649     // Build a shuffle mask for the output, discovering on the fly which
2650     // input vectors to use as shuffle operands.
2651     unsigned FirstMaskIdx = High * NewElts;
2652     SmallVector<int> Mask(NewElts * std::size(Inputs), UndefMaskElem);
2653     copy(ArrayRef(OrigMask).slice(FirstMaskIdx, NewElts), Mask.begin());
2654     assert(!Output && "Expected default initialized initial value.");
2655     TryPeekThroughShufflesInputs(Mask);
2656     MakeUniqueInputs(Mask);
2657     SDValue TmpInputs[4];
2658     copy(Inputs, std::begin(TmpInputs));
2659     // Track changes in the output registers.
2660     int UsedIdx = -1;
2661     bool SecondIteration = false;
2662     auto &&AccumulateResults = [&UsedIdx, &SecondIteration](unsigned Idx) {
2663       if (UsedIdx < 0) {
2664         UsedIdx = Idx;
2665         return false;
2666       }
2667       if (UsedIdx >= 0 && static_cast<unsigned>(UsedIdx) == Idx)
2668         SecondIteration = true;
2669       return SecondIteration;
2670     };
2671     processShuffleMasks(
2672         Mask, std::size(Inputs), std::size(Inputs),
2673         /*NumOfUsedRegs=*/1,
2674         [&Output, &DAG = DAG, NewVT]() { Output = DAG.getUNDEF(NewVT); },
2675         [&Output, &DAG = DAG, NewVT, &DL, &Inputs,
2676          &BuildVector](ArrayRef<int> Mask, unsigned Idx, unsigned /*Unused*/) {
2677           if (Inputs[Idx]->getOpcode() == ISD::BUILD_VECTOR)
2678             Output = BuildVector(Inputs[Idx], Inputs[Idx], Mask);
2679           else
2680             Output = DAG.getVectorShuffle(NewVT, DL, Inputs[Idx],
2681                                           DAG.getUNDEF(NewVT), Mask);
2682           Inputs[Idx] = Output;
2683         },
2684         [&AccumulateResults, &Output, &DAG = DAG, NewVT, &DL, &Inputs,
2685          &TmpInputs,
2686          &BuildVector](ArrayRef<int> Mask, unsigned Idx1, unsigned Idx2) {
2687           if (AccumulateResults(Idx1)) {
2688             if (Inputs[Idx1]->getOpcode() == ISD::BUILD_VECTOR &&
2689                 Inputs[Idx2]->getOpcode() == ISD::BUILD_VECTOR)
2690               Output = BuildVector(Inputs[Idx1], Inputs[Idx2], Mask);
2691             else
2692               Output = DAG.getVectorShuffle(NewVT, DL, Inputs[Idx1],
2693                                             Inputs[Idx2], Mask);
2694           } else {
2695             if (TmpInputs[Idx1]->getOpcode() == ISD::BUILD_VECTOR &&
2696                 TmpInputs[Idx2]->getOpcode() == ISD::BUILD_VECTOR)
2697               Output = BuildVector(TmpInputs[Idx1], TmpInputs[Idx2], Mask);
2698             else
2699               Output = DAG.getVectorShuffle(NewVT, DL, TmpInputs[Idx1],
2700                                             TmpInputs[Idx2], Mask);
2701           }
2702           Inputs[Idx1] = Output;
2703         });
2704     copy(OrigInputs, std::begin(Inputs));
2705   }
2706 }
2707 
SplitVecRes_VAARG(SDNode * N,SDValue & Lo,SDValue & Hi)2708 void DAGTypeLegalizer::SplitVecRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi) {
2709   EVT OVT = N->getValueType(0);
2710   EVT NVT = OVT.getHalfNumVectorElementsVT(*DAG.getContext());
2711   SDValue Chain = N->getOperand(0);
2712   SDValue Ptr = N->getOperand(1);
2713   SDValue SV = N->getOperand(2);
2714   SDLoc dl(N);
2715 
2716   const Align Alignment =
2717       DAG.getDataLayout().getABITypeAlign(NVT.getTypeForEVT(*DAG.getContext()));
2718 
2719   Lo = DAG.getVAArg(NVT, dl, Chain, Ptr, SV, Alignment.value());
2720   Hi = DAG.getVAArg(NVT, dl, Lo.getValue(1), Ptr, SV, Alignment.value());
2721   Chain = Hi.getValue(1);
2722 
2723   // Modified the chain - switch anything that used the old chain to use
2724   // the new one.
2725   ReplaceValueWith(SDValue(N, 1), Chain);
2726 }
2727 
SplitVecRes_FP_TO_XINT_SAT(SDNode * N,SDValue & Lo,SDValue & Hi)2728 void DAGTypeLegalizer::SplitVecRes_FP_TO_XINT_SAT(SDNode *N, SDValue &Lo,
2729                                                   SDValue &Hi) {
2730   EVT DstVTLo, DstVTHi;
2731   std::tie(DstVTLo, DstVTHi) = DAG.GetSplitDestVTs(N->getValueType(0));
2732   SDLoc dl(N);
2733 
2734   SDValue SrcLo, SrcHi;
2735   EVT SrcVT = N->getOperand(0).getValueType();
2736   if (getTypeAction(SrcVT) == TargetLowering::TypeSplitVector)
2737     GetSplitVector(N->getOperand(0), SrcLo, SrcHi);
2738   else
2739     std::tie(SrcLo, SrcHi) = DAG.SplitVectorOperand(N, 0);
2740 
2741   Lo = DAG.getNode(N->getOpcode(), dl, DstVTLo, SrcLo, N->getOperand(1));
2742   Hi = DAG.getNode(N->getOpcode(), dl, DstVTHi, SrcHi, N->getOperand(1));
2743 }
2744 
SplitVecRes_VECTOR_REVERSE(SDNode * N,SDValue & Lo,SDValue & Hi)2745 void DAGTypeLegalizer::SplitVecRes_VECTOR_REVERSE(SDNode *N, SDValue &Lo,
2746                                                   SDValue &Hi) {
2747   SDValue InLo, InHi;
2748   GetSplitVector(N->getOperand(0), InLo, InHi);
2749   SDLoc DL(N);
2750 
2751   Lo = DAG.getNode(ISD::VECTOR_REVERSE, DL, InHi.getValueType(), InHi);
2752   Hi = DAG.getNode(ISD::VECTOR_REVERSE, DL, InLo.getValueType(), InLo);
2753 }
2754 
SplitVecRes_VECTOR_SPLICE(SDNode * N,SDValue & Lo,SDValue & Hi)2755 void DAGTypeLegalizer::SplitVecRes_VECTOR_SPLICE(SDNode *N, SDValue &Lo,
2756                                                  SDValue &Hi) {
2757   EVT VT = N->getValueType(0);
2758   SDLoc DL(N);
2759 
2760   EVT LoVT, HiVT;
2761   std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(VT);
2762 
2763   SDValue Expanded = TLI.expandVectorSplice(N, DAG);
2764   Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LoVT, Expanded,
2765                    DAG.getVectorIdxConstant(0, DL));
2766   Hi =
2767       DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HiVT, Expanded,
2768                   DAG.getVectorIdxConstant(LoVT.getVectorMinNumElements(), DL));
2769 }
2770 
2771 //===----------------------------------------------------------------------===//
2772 //  Operand Vector Splitting
2773 //===----------------------------------------------------------------------===//
2774 
2775 /// This method is called when the specified operand of the specified node is
2776 /// found to need vector splitting. At this point, all of the result types of
2777 /// the node are known to be legal, but other operands of the node may need
2778 /// legalization as well as the specified one.
SplitVectorOperand(SDNode * N,unsigned OpNo)2779 bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) {
2780   LLVM_DEBUG(dbgs() << "Split node operand: "; N->dump(&DAG); dbgs() << "\n");
2781   SDValue Res = SDValue();
2782 
2783   // See if the target wants to custom split this node.
2784   if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
2785     return false;
2786 
2787   switch (N->getOpcode()) {
2788   default:
2789 #ifndef NDEBUG
2790     dbgs() << "SplitVectorOperand Op #" << OpNo << ": ";
2791     N->dump(&DAG);
2792     dbgs() << "\n";
2793 #endif
2794     report_fatal_error("Do not know how to split this operator's "
2795                        "operand!\n");
2796 
2797   case ISD::VP_SETCC:
2798   case ISD::SETCC:             Res = SplitVecOp_VSETCC(N); break;
2799   case ISD::BITCAST:           Res = SplitVecOp_BITCAST(N); break;
2800   case ISD::EXTRACT_SUBVECTOR: Res = SplitVecOp_EXTRACT_SUBVECTOR(N); break;
2801   case ISD::INSERT_SUBVECTOR:  Res = SplitVecOp_INSERT_SUBVECTOR(N, OpNo); break;
2802   case ISD::EXTRACT_VECTOR_ELT:Res = SplitVecOp_EXTRACT_VECTOR_ELT(N); break;
2803   case ISD::CONCAT_VECTORS:    Res = SplitVecOp_CONCAT_VECTORS(N); break;
2804   case ISD::VP_TRUNCATE:
2805   case ISD::TRUNCATE:
2806     Res = SplitVecOp_TruncateHelper(N);
2807     break;
2808   case ISD::STRICT_FP_ROUND:
2809   case ISD::VP_FP_ROUND:
2810   case ISD::FP_ROUND:          Res = SplitVecOp_FP_ROUND(N); break;
2811   case ISD::FCOPYSIGN:         Res = SplitVecOp_FCOPYSIGN(N); break;
2812   case ISD::STORE:
2813     Res = SplitVecOp_STORE(cast<StoreSDNode>(N), OpNo);
2814     break;
2815   case ISD::VP_STORE:
2816     Res = SplitVecOp_VP_STORE(cast<VPStoreSDNode>(N), OpNo);
2817     break;
2818   case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
2819     Res = SplitVecOp_VP_STRIDED_STORE(cast<VPStridedStoreSDNode>(N), OpNo);
2820     break;
2821   case ISD::MSTORE:
2822     Res = SplitVecOp_MSTORE(cast<MaskedStoreSDNode>(N), OpNo);
2823     break;
2824   case ISD::MSCATTER:
2825   case ISD::VP_SCATTER:
2826     Res = SplitVecOp_Scatter(cast<MemSDNode>(N), OpNo);
2827     break;
2828   case ISD::MGATHER:
2829   case ISD::VP_GATHER:
2830     Res = SplitVecOp_Gather(cast<MemSDNode>(N), OpNo);
2831     break;
2832   case ISD::VSELECT:
2833     Res = SplitVecOp_VSELECT(N, OpNo);
2834     break;
2835   case ISD::STRICT_SINT_TO_FP:
2836   case ISD::STRICT_UINT_TO_FP:
2837   case ISD::SINT_TO_FP:
2838   case ISD::UINT_TO_FP:
2839   case ISD::VP_SINT_TO_FP:
2840   case ISD::VP_UINT_TO_FP:
2841     if (N->getValueType(0).bitsLT(
2842             N->getOperand(N->isStrictFPOpcode() ? 1 : 0).getValueType()))
2843       Res = SplitVecOp_TruncateHelper(N);
2844     else
2845       Res = SplitVecOp_UnaryOp(N);
2846     break;
2847   case ISD::FP_TO_SINT_SAT:
2848   case ISD::FP_TO_UINT_SAT:
2849     Res = SplitVecOp_FP_TO_XINT_SAT(N);
2850     break;
2851   case ISD::FP_TO_SINT:
2852   case ISD::FP_TO_UINT:
2853   case ISD::VP_FP_TO_SINT:
2854   case ISD::VP_FP_TO_UINT:
2855   case ISD::STRICT_FP_TO_SINT:
2856   case ISD::STRICT_FP_TO_UINT:
2857   case ISD::STRICT_FP_EXTEND:
2858   case ISD::FP_EXTEND:
2859   case ISD::SIGN_EXTEND:
2860   case ISD::ZERO_EXTEND:
2861   case ISD::ANY_EXTEND:
2862   case ISD::FTRUNC:
2863     Res = SplitVecOp_UnaryOp(N);
2864     break;
2865 
2866   case ISD::ANY_EXTEND_VECTOR_INREG:
2867   case ISD::SIGN_EXTEND_VECTOR_INREG:
2868   case ISD::ZERO_EXTEND_VECTOR_INREG:
2869     Res = SplitVecOp_ExtVecInRegOp(N);
2870     break;
2871 
2872   case ISD::VECREDUCE_FADD:
2873   case ISD::VECREDUCE_FMUL:
2874   case ISD::VECREDUCE_ADD:
2875   case ISD::VECREDUCE_MUL:
2876   case ISD::VECREDUCE_AND:
2877   case ISD::VECREDUCE_OR:
2878   case ISD::VECREDUCE_XOR:
2879   case ISD::VECREDUCE_SMAX:
2880   case ISD::VECREDUCE_SMIN:
2881   case ISD::VECREDUCE_UMAX:
2882   case ISD::VECREDUCE_UMIN:
2883   case ISD::VECREDUCE_FMAX:
2884   case ISD::VECREDUCE_FMIN:
2885     Res = SplitVecOp_VECREDUCE(N, OpNo);
2886     break;
2887   case ISD::VECREDUCE_SEQ_FADD:
2888   case ISD::VECREDUCE_SEQ_FMUL:
2889     Res = SplitVecOp_VECREDUCE_SEQ(N);
2890     break;
2891   case ISD::VP_REDUCE_FADD:
2892   case ISD::VP_REDUCE_SEQ_FADD:
2893   case ISD::VP_REDUCE_FMUL:
2894   case ISD::VP_REDUCE_SEQ_FMUL:
2895   case ISD::VP_REDUCE_ADD:
2896   case ISD::VP_REDUCE_MUL:
2897   case ISD::VP_REDUCE_AND:
2898   case ISD::VP_REDUCE_OR:
2899   case ISD::VP_REDUCE_XOR:
2900   case ISD::VP_REDUCE_SMAX:
2901   case ISD::VP_REDUCE_SMIN:
2902   case ISD::VP_REDUCE_UMAX:
2903   case ISD::VP_REDUCE_UMIN:
2904   case ISD::VP_REDUCE_FMAX:
2905   case ISD::VP_REDUCE_FMIN:
2906     Res = SplitVecOp_VP_REDUCE(N, OpNo);
2907     break;
2908   }
2909 
2910   // If the result is null, the sub-method took care of registering results etc.
2911   if (!Res.getNode()) return false;
2912 
2913   // If the result is N, the sub-method updated N in place.  Tell the legalizer
2914   // core about this.
2915   if (Res.getNode() == N)
2916     return true;
2917 
2918   if (N->isStrictFPOpcode())
2919     assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 2 &&
2920            "Invalid operand expansion");
2921   else
2922     assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
2923          "Invalid operand expansion");
2924 
2925   ReplaceValueWith(SDValue(N, 0), Res);
2926   return false;
2927 }
2928 
SplitVecOp_VSELECT(SDNode * N,unsigned OpNo)2929 SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(SDNode *N, unsigned OpNo) {
2930   // The only possibility for an illegal operand is the mask, since result type
2931   // legalization would have handled this node already otherwise.
2932   assert(OpNo == 0 && "Illegal operand must be mask");
2933 
2934   SDValue Mask = N->getOperand(0);
2935   SDValue Src0 = N->getOperand(1);
2936   SDValue Src1 = N->getOperand(2);
2937   EVT Src0VT = Src0.getValueType();
2938   SDLoc DL(N);
2939   assert(Mask.getValueType().isVector() && "VSELECT without a vector mask?");
2940 
2941   SDValue Lo, Hi;
2942   GetSplitVector(N->getOperand(0), Lo, Hi);
2943   assert(Lo.getValueType() == Hi.getValueType() &&
2944          "Lo and Hi have differing types");
2945 
2946   EVT LoOpVT, HiOpVT;
2947   std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
2948   assert(LoOpVT == HiOpVT && "Asymmetric vector split?");
2949 
2950   SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
2951   std::tie(LoOp0, HiOp0) = DAG.SplitVector(Src0, DL);
2952   std::tie(LoOp1, HiOp1) = DAG.SplitVector(Src1, DL);
2953   std::tie(LoMask, HiMask) = DAG.SplitVector(Mask, DL);
2954 
2955   SDValue LoSelect =
2956     DAG.getNode(ISD::VSELECT, DL, LoOpVT, LoMask, LoOp0, LoOp1);
2957   SDValue HiSelect =
2958     DAG.getNode(ISD::VSELECT, DL, HiOpVT, HiMask, HiOp0, HiOp1);
2959 
2960   return DAG.getNode(ISD::CONCAT_VECTORS, DL, Src0VT, LoSelect, HiSelect);
2961 }
2962 
SplitVecOp_VECREDUCE(SDNode * N,unsigned OpNo)2963 SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE(SDNode *N, unsigned OpNo) {
2964   EVT ResVT = N->getValueType(0);
2965   SDValue Lo, Hi;
2966   SDLoc dl(N);
2967 
2968   SDValue VecOp = N->getOperand(OpNo);
2969   EVT VecVT = VecOp.getValueType();
2970   assert(VecVT.isVector() && "Can only split reduce vector operand");
2971   GetSplitVector(VecOp, Lo, Hi);
2972   EVT LoOpVT, HiOpVT;
2973   std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
2974 
2975   // Use the appropriate scalar instruction on the split subvectors before
2976   // reducing the now partially reduced smaller vector.
2977   unsigned CombineOpc = ISD::getVecReduceBaseOpcode(N->getOpcode());
2978   SDValue Partial = DAG.getNode(CombineOpc, dl, LoOpVT, Lo, Hi, N->getFlags());
2979   return DAG.getNode(N->getOpcode(), dl, ResVT, Partial, N->getFlags());
2980 }
2981 
SplitVecOp_VECREDUCE_SEQ(SDNode * N)2982 SDValue DAGTypeLegalizer::SplitVecOp_VECREDUCE_SEQ(SDNode *N) {
2983   EVT ResVT = N->getValueType(0);
2984   SDValue Lo, Hi;
2985   SDLoc dl(N);
2986 
2987   SDValue AccOp = N->getOperand(0);
2988   SDValue VecOp = N->getOperand(1);
2989   SDNodeFlags Flags = N->getFlags();
2990 
2991   EVT VecVT = VecOp.getValueType();
2992   assert(VecVT.isVector() && "Can only split reduce vector operand");
2993   GetSplitVector(VecOp, Lo, Hi);
2994   EVT LoOpVT, HiOpVT;
2995   std::tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(VecVT);
2996 
2997   // Reduce low half.
2998   SDValue Partial = DAG.getNode(N->getOpcode(), dl, ResVT, AccOp, Lo, Flags);
2999 
3000   // Reduce high half, using low half result as initial value.
3001   return DAG.getNode(N->getOpcode(), dl, ResVT, Partial, Hi, Flags);
3002 }
3003 
SplitVecOp_VP_REDUCE(SDNode * N,unsigned OpNo)3004 SDValue DAGTypeLegalizer::SplitVecOp_VP_REDUCE(SDNode *N, unsigned OpNo) {
3005   assert(N->isVPOpcode() && "Expected VP opcode");
3006   assert(OpNo == 1 && "Can only split reduce vector operand");
3007 
3008   unsigned Opc = N->getOpcode();
3009   EVT ResVT = N->getValueType(0);
3010   SDValue Lo, Hi;
3011   SDLoc dl(N);
3012 
3013   SDValue VecOp = N->getOperand(OpNo);
3014   EVT VecVT = VecOp.getValueType();
3015   assert(VecVT.isVector() && "Can only split reduce vector operand");
3016   GetSplitVector(VecOp, Lo, Hi);
3017 
3018   SDValue MaskLo, MaskHi;
3019   std::tie(MaskLo, MaskHi) = SplitMask(N->getOperand(2));
3020 
3021   SDValue EVLLo, EVLHi;
3022   std::tie(EVLLo, EVLHi) = DAG.SplitEVL(N->getOperand(3), VecVT, dl);
3023 
3024   const SDNodeFlags Flags = N->getFlags();
3025 
3026   SDValue ResLo =
3027       DAG.getNode(Opc, dl, ResVT, {N->getOperand(0), Lo, MaskLo, EVLLo}, Flags);
3028   return DAG.getNode(Opc, dl, ResVT, {ResLo, Hi, MaskHi, EVLHi}, Flags);
3029 }
3030 
SplitVecOp_UnaryOp(SDNode * N)3031 SDValue DAGTypeLegalizer::SplitVecOp_UnaryOp(SDNode *N) {
3032   // The result has a legal vector type, but the input needs splitting.
3033   EVT ResVT = N->getValueType(0);
3034   SDValue Lo, Hi;
3035   SDLoc dl(N);
3036   GetSplitVector(N->getOperand(N->isStrictFPOpcode() ? 1 : 0), Lo, Hi);
3037   EVT InVT = Lo.getValueType();
3038 
3039   EVT OutVT = EVT::getVectorVT(*DAG.getContext(), ResVT.getVectorElementType(),
3040                                InVT.getVectorElementCount());
3041 
3042   if (N->isStrictFPOpcode()) {
3043     Lo = DAG.getNode(N->getOpcode(), dl, { OutVT, MVT::Other },
3044                      { N->getOperand(0), Lo });
3045     Hi = DAG.getNode(N->getOpcode(), dl, { OutVT, MVT::Other },
3046                      { N->getOperand(0), Hi });
3047 
3048     // Build a factor node to remember that this operation is independent
3049     // of the other one.
3050     SDValue Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
3051                              Hi.getValue(1));
3052 
3053     // Legalize the chain result - switch anything that used the old chain to
3054     // use the new one.
3055     ReplaceValueWith(SDValue(N, 1), Ch);
3056   } else if (N->getNumOperands() == 3) {
3057     assert(N->isVPOpcode() && "Expected VP opcode");
3058     SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3059     std::tie(MaskLo, MaskHi) = SplitMask(N->getOperand(1));
3060     std::tie(EVLLo, EVLHi) =
3061         DAG.SplitEVL(N->getOperand(2), N->getValueType(0), dl);
3062     Lo = DAG.getNode(N->getOpcode(), dl, OutVT, Lo, MaskLo, EVLLo);
3063     Hi = DAG.getNode(N->getOpcode(), dl, OutVT, Hi, MaskHi, EVLHi);
3064   } else {
3065     Lo = DAG.getNode(N->getOpcode(), dl, OutVT, Lo);
3066     Hi = DAG.getNode(N->getOpcode(), dl, OutVT, Hi);
3067   }
3068 
3069   return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi);
3070 }
3071 
SplitVecOp_BITCAST(SDNode * N)3072 SDValue DAGTypeLegalizer::SplitVecOp_BITCAST(SDNode *N) {
3073   // For example, i64 = BITCAST v4i16 on alpha.  Typically the vector will
3074   // end up being split all the way down to individual components.  Convert the
3075   // split pieces into integers and reassemble.
3076   SDValue Lo, Hi;
3077   GetSplitVector(N->getOperand(0), Lo, Hi);
3078   Lo = BitConvertToInteger(Lo);
3079   Hi = BitConvertToInteger(Hi);
3080 
3081   if (DAG.getDataLayout().isBigEndian())
3082     std::swap(Lo, Hi);
3083 
3084   return DAG.getNode(ISD::BITCAST, SDLoc(N), N->getValueType(0),
3085                      JoinIntegers(Lo, Hi));
3086 }
3087 
SplitVecOp_INSERT_SUBVECTOR(SDNode * N,unsigned OpNo)3088 SDValue DAGTypeLegalizer::SplitVecOp_INSERT_SUBVECTOR(SDNode *N,
3089                                                       unsigned OpNo) {
3090   assert(OpNo == 1 && "Invalid OpNo; can only split SubVec.");
3091   // We know that the result type is legal.
3092   EVT ResVT = N->getValueType(0);
3093 
3094   SDValue Vec = N->getOperand(0);
3095   SDValue SubVec = N->getOperand(1);
3096   SDValue Idx = N->getOperand(2);
3097   SDLoc dl(N);
3098 
3099   SDValue Lo, Hi;
3100   GetSplitVector(SubVec, Lo, Hi);
3101 
3102   uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
3103   uint64_t LoElts = Lo.getValueType().getVectorMinNumElements();
3104 
3105   SDValue FirstInsertion =
3106       DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, Vec, Lo, Idx);
3107   SDValue SecondInsertion =
3108       DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, FirstInsertion, Hi,
3109                   DAG.getVectorIdxConstant(IdxVal + LoElts, dl));
3110 
3111   return SecondInsertion;
3112 }
3113 
SplitVecOp_EXTRACT_SUBVECTOR(SDNode * N)3114 SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N) {
3115   // We know that the extracted result type is legal.
3116   EVT SubVT = N->getValueType(0);
3117   SDValue Idx = N->getOperand(1);
3118   SDLoc dl(N);
3119   SDValue Lo, Hi;
3120 
3121   GetSplitVector(N->getOperand(0), Lo, Hi);
3122 
3123   uint64_t LoEltsMin = Lo.getValueType().getVectorMinNumElements();
3124   uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
3125 
3126   if (IdxVal < LoEltsMin) {
3127     assert(IdxVal + SubVT.getVectorMinNumElements() <= LoEltsMin &&
3128            "Extracted subvector crosses vector split!");
3129     return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Lo, Idx);
3130   } else if (SubVT.isScalableVector() ==
3131              N->getOperand(0).getValueType().isScalableVector())
3132     return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Hi,
3133                        DAG.getVectorIdxConstant(IdxVal - LoEltsMin, dl));
3134 
3135   // After this point the DAG node only permits extracting fixed-width
3136   // subvectors from scalable vectors.
3137   assert(SubVT.isFixedLengthVector() &&
3138          "Extracting scalable subvector from fixed-width unsupported");
3139 
3140   // If the element type is i1 and we're not promoting the result, then we may
3141   // end up loading the wrong data since the bits are packed tightly into
3142   // bytes. For example, if we extract a v4i1 (legal) from a nxv4i1 (legal)
3143   // type at index 4, then we will load a byte starting at index 0.
3144   if (SubVT.getScalarType() == MVT::i1)
3145     report_fatal_error("Don't know how to extract fixed-width predicate "
3146                        "subvector from a scalable predicate vector");
3147 
3148   // Spill the vector to the stack. We should use the alignment for
3149   // the smallest part.
3150   SDValue Vec = N->getOperand(0);
3151   EVT VecVT = Vec.getValueType();
3152   Align SmallestAlign = DAG.getReducedAlign(VecVT, /*UseABI=*/false);
3153   SDValue StackPtr =
3154       DAG.CreateStackTemporary(VecVT.getStoreSize(), SmallestAlign);
3155   auto &MF = DAG.getMachineFunction();
3156   auto FrameIndex = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
3157   auto PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex);
3158 
3159   SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
3160                                SmallestAlign);
3161 
3162   // Extract the subvector by loading the correct part.
3163   StackPtr = TLI.getVectorSubVecPointer(DAG, StackPtr, VecVT, SubVT, Idx);
3164 
3165   return DAG.getLoad(
3166       SubVT, dl, Store, StackPtr,
3167       MachinePointerInfo::getUnknownStack(DAG.getMachineFunction()));
3168 }
3169 
SplitVecOp_EXTRACT_VECTOR_ELT(SDNode * N)3170 SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
3171   SDValue Vec = N->getOperand(0);
3172   SDValue Idx = N->getOperand(1);
3173   EVT VecVT = Vec.getValueType();
3174 
3175   if (const ConstantSDNode *Index = dyn_cast<ConstantSDNode>(Idx)) {
3176     uint64_t IdxVal = Index->getZExtValue();
3177 
3178     SDValue Lo, Hi;
3179     GetSplitVector(Vec, Lo, Hi);
3180 
3181     uint64_t LoElts = Lo.getValueType().getVectorMinNumElements();
3182 
3183     if (IdxVal < LoElts)
3184       return SDValue(DAG.UpdateNodeOperands(N, Lo, Idx), 0);
3185     else if (!Vec.getValueType().isScalableVector())
3186       return SDValue(DAG.UpdateNodeOperands(N, Hi,
3187                                     DAG.getConstant(IdxVal - LoElts, SDLoc(N),
3188                                                     Idx.getValueType())), 0);
3189   }
3190 
3191   // See if the target wants to custom expand this node.
3192   if (CustomLowerNode(N, N->getValueType(0), true))
3193     return SDValue();
3194 
3195   // Make the vector elements byte-addressable if they aren't already.
3196   SDLoc dl(N);
3197   EVT EltVT = VecVT.getVectorElementType();
3198   if (VecVT.getScalarSizeInBits() < 8) {
3199     EltVT = MVT::i8;
3200     VecVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
3201                              VecVT.getVectorElementCount());
3202     Vec = DAG.getNode(ISD::ANY_EXTEND, dl, VecVT, Vec);
3203   }
3204 
3205   // Store the vector to the stack.
3206   // In cases where the vector is illegal it will be broken down into parts
3207   // and stored in parts - we should use the alignment for the smallest part.
3208   Align SmallestAlign = DAG.getReducedAlign(VecVT, /*UseABI=*/false);
3209   SDValue StackPtr =
3210       DAG.CreateStackTemporary(VecVT.getStoreSize(), SmallestAlign);
3211   auto &MF = DAG.getMachineFunction();
3212   auto FrameIndex = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
3213   auto PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex);
3214   SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo,
3215                                SmallestAlign);
3216 
3217   // Load back the required element.
3218   StackPtr = TLI.getVectorElementPointer(DAG, StackPtr, VecVT, Idx);
3219 
3220   // FIXME: This is to handle i1 vectors with elements promoted to i8.
3221   // i1 vector handling needs general improvement.
3222   if (N->getValueType(0).bitsLT(EltVT)) {
3223     SDValue Load = DAG.getLoad(EltVT, dl, Store, StackPtr,
3224       MachinePointerInfo::getUnknownStack(DAG.getMachineFunction()));
3225     return DAG.getZExtOrTrunc(Load, dl, N->getValueType(0));
3226   }
3227 
3228   return DAG.getExtLoad(
3229       ISD::EXTLOAD, dl, N->getValueType(0), Store, StackPtr,
3230       MachinePointerInfo::getUnknownStack(DAG.getMachineFunction()), EltVT,
3231       commonAlignment(SmallestAlign, EltVT.getFixedSizeInBits() / 8));
3232 }
3233 
SplitVecOp_ExtVecInRegOp(SDNode * N)3234 SDValue DAGTypeLegalizer::SplitVecOp_ExtVecInRegOp(SDNode *N) {
3235   SDValue Lo, Hi;
3236 
3237   // *_EXTEND_VECTOR_INREG only reference the lower half of the input, so
3238   // splitting the result has the same effect as splitting the input operand.
3239   SplitVecRes_ExtVecInRegOp(N, Lo, Hi);
3240 
3241   return DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(N), N->getValueType(0), Lo, Hi);
3242 }
3243 
SplitVecOp_Gather(MemSDNode * N,unsigned OpNo)3244 SDValue DAGTypeLegalizer::SplitVecOp_Gather(MemSDNode *N, unsigned OpNo) {
3245   (void)OpNo;
3246   SDValue Lo, Hi;
3247   SplitVecRes_Gather(N, Lo, Hi);
3248 
3249   SDValue Res = DAG.getNode(ISD::CONCAT_VECTORS, N, N->getValueType(0), Lo, Hi);
3250   ReplaceValueWith(SDValue(N, 0), Res);
3251   return SDValue();
3252 }
3253 
SplitVecOp_VP_STORE(VPStoreSDNode * N,unsigned OpNo)3254 SDValue DAGTypeLegalizer::SplitVecOp_VP_STORE(VPStoreSDNode *N, unsigned OpNo) {
3255   assert(N->isUnindexed() && "Indexed vp_store of vector?");
3256   SDValue Ch = N->getChain();
3257   SDValue Ptr = N->getBasePtr();
3258   SDValue Offset = N->getOffset();
3259   assert(Offset.isUndef() && "Unexpected VP store offset");
3260   SDValue Mask = N->getMask();
3261   SDValue EVL = N->getVectorLength();
3262   SDValue Data = N->getValue();
3263   Align Alignment = N->getOriginalAlign();
3264   SDLoc DL(N);
3265 
3266   SDValue DataLo, DataHi;
3267   if (getTypeAction(Data.getValueType()) == TargetLowering::TypeSplitVector)
3268     // Split Data operand
3269     GetSplitVector(Data, DataLo, DataHi);
3270   else
3271     std::tie(DataLo, DataHi) = DAG.SplitVector(Data, DL);
3272 
3273   // Split Mask operand
3274   SDValue MaskLo, MaskHi;
3275   if (OpNo == 1 && Mask.getOpcode() == ISD::SETCC) {
3276     SplitVecRes_SETCC(Mask.getNode(), MaskLo, MaskHi);
3277   } else {
3278     if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector)
3279       GetSplitVector(Mask, MaskLo, MaskHi);
3280     else
3281       std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, DL);
3282   }
3283 
3284   EVT MemoryVT = N->getMemoryVT();
3285   EVT LoMemVT, HiMemVT;
3286   bool HiIsEmpty = false;
3287   std::tie(LoMemVT, HiMemVT) =
3288       DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.getValueType(), &HiIsEmpty);
3289 
3290   // Split EVL
3291   SDValue EVLLo, EVLHi;
3292   std::tie(EVLLo, EVLHi) = DAG.SplitEVL(EVL, Data.getValueType(), DL);
3293 
3294   SDValue Lo, Hi;
3295   MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
3296       N->getPointerInfo(), MachineMemOperand::MOStore,
3297       MemoryLocation::UnknownSize, Alignment, N->getAAInfo(), N->getRanges());
3298 
3299   Lo = DAG.getStoreVP(Ch, DL, DataLo, Ptr, Offset, MaskLo, EVLLo, LoMemVT, MMO,
3300                       N->getAddressingMode(), N->isTruncatingStore(),
3301                       N->isCompressingStore());
3302 
3303   // If the hi vp_store has zero storage size, only the lo vp_store is needed.
3304   if (HiIsEmpty)
3305     return Lo;
3306 
3307   Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, DL, LoMemVT, DAG,
3308                                    N->isCompressingStore());
3309 
3310   MachinePointerInfo MPI;
3311   if (LoMemVT.isScalableVector()) {
3312     Alignment = commonAlignment(Alignment,
3313                                 LoMemVT.getSizeInBits().getKnownMinValue() / 8);
3314     MPI = MachinePointerInfo(N->getPointerInfo().getAddrSpace());
3315   } else
3316     MPI = N->getPointerInfo().getWithOffset(
3317         LoMemVT.getStoreSize().getFixedValue());
3318 
3319   MMO = DAG.getMachineFunction().getMachineMemOperand(
3320       MPI, MachineMemOperand::MOStore, MemoryLocation::UnknownSize, Alignment,
3321       N->getAAInfo(), N->getRanges());
3322 
3323   Hi = DAG.getStoreVP(Ch, DL, DataHi, Ptr, Offset, MaskHi, EVLHi, HiMemVT, MMO,
3324                       N->getAddressingMode(), N->isTruncatingStore(),
3325                       N->isCompressingStore());
3326 
3327   // Build a factor node to remember that this store is independent of the
3328   // other one.
3329   return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Lo, Hi);
3330 }
3331 
SplitVecOp_VP_STRIDED_STORE(VPStridedStoreSDNode * N,unsigned OpNo)3332 SDValue DAGTypeLegalizer::SplitVecOp_VP_STRIDED_STORE(VPStridedStoreSDNode *N,
3333                                                       unsigned OpNo) {
3334   assert(N->isUnindexed() && "Indexed vp_strided_store of a vector?");
3335   assert(N->getOffset().isUndef() && "Unexpected VP strided store offset");
3336 
3337   SDLoc DL(N);
3338 
3339   SDValue Data = N->getValue();
3340   SDValue LoData, HiData;
3341   if (getTypeAction(Data.getValueType()) == TargetLowering::TypeSplitVector)
3342     GetSplitVector(Data, LoData, HiData);
3343   else
3344     std::tie(LoData, HiData) = DAG.SplitVector(Data, DL);
3345 
3346   EVT LoMemVT, HiMemVT;
3347   bool HiIsEmpty = false;
3348   std::tie(LoMemVT, HiMemVT) = DAG.GetDependentSplitDestVTs(
3349       N->getMemoryVT(), LoData.getValueType(), &HiIsEmpty);
3350 
3351   SDValue Mask = N->getMask();
3352   SDValue LoMask, HiMask;
3353   if (OpNo == 1 && Mask.getOpcode() == ISD::SETCC)
3354     SplitVecRes_SETCC(Mask.getNode(), LoMask, HiMask);
3355   else if (getTypeAction(Mask.getValueType()) ==
3356            TargetLowering::TypeSplitVector)
3357     GetSplitVector(Mask, LoMask, HiMask);
3358   else
3359     std::tie(LoMask, HiMask) = DAG.SplitVector(Mask, DL);
3360 
3361   SDValue LoEVL, HiEVL;
3362   std::tie(LoEVL, HiEVL) =
3363       DAG.SplitEVL(N->getVectorLength(), Data.getValueType(), DL);
3364 
3365   // Generate the low vp_strided_store
3366   SDValue Lo = DAG.getStridedStoreVP(
3367       N->getChain(), DL, LoData, N->getBasePtr(), N->getOffset(),
3368       N->getStride(), LoMask, LoEVL, LoMemVT, N->getMemOperand(),
3369       N->getAddressingMode(), N->isTruncatingStore(), N->isCompressingStore());
3370 
3371   // If the high vp_strided_store has zero storage size, only the low
3372   // vp_strided_store is needed.
3373   if (HiIsEmpty)
3374     return Lo;
3375 
3376   // Generate the high vp_strided_store.
3377   // To calculate the high base address, we need to sum to the low base
3378   // address stride number of bytes for each element already stored by low,
3379   // that is: Ptr = Ptr + (LoEVL * Stride)
3380   EVT PtrVT = N->getBasePtr().getValueType();
3381   SDValue Increment =
3382       DAG.getNode(ISD::MUL, DL, PtrVT, LoEVL,
3383                   DAG.getSExtOrTrunc(N->getStride(), DL, PtrVT));
3384   SDValue Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, N->getBasePtr(), Increment);
3385 
3386   Align Alignment = N->getOriginalAlign();
3387   if (LoMemVT.isScalableVector())
3388     Alignment = commonAlignment(Alignment,
3389                                 LoMemVT.getSizeInBits().getKnownMinValue() / 8);
3390 
3391   MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
3392       MachinePointerInfo(N->getPointerInfo().getAddrSpace()),
3393       MachineMemOperand::MOStore, MemoryLocation::UnknownSize, Alignment,
3394       N->getAAInfo(), N->getRanges());
3395 
3396   SDValue Hi = DAG.getStridedStoreVP(
3397       N->getChain(), DL, HiData, Ptr, N->getOffset(), N->getStride(), HiMask,
3398       HiEVL, HiMemVT, MMO, N->getAddressingMode(), N->isTruncatingStore(),
3399       N->isCompressingStore());
3400 
3401   // Build a factor node to remember that this store is independent of the
3402   // other one.
3403   return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Lo, Hi);
3404 }
3405 
SplitVecOp_MSTORE(MaskedStoreSDNode * N,unsigned OpNo)3406 SDValue DAGTypeLegalizer::SplitVecOp_MSTORE(MaskedStoreSDNode *N,
3407                                             unsigned OpNo) {
3408   assert(N->isUnindexed() && "Indexed masked store of vector?");
3409   SDValue Ch  = N->getChain();
3410   SDValue Ptr = N->getBasePtr();
3411   SDValue Offset = N->getOffset();
3412   assert(Offset.isUndef() && "Unexpected indexed masked store offset");
3413   SDValue Mask = N->getMask();
3414   SDValue Data = N->getValue();
3415   Align Alignment = N->getOriginalAlign();
3416   SDLoc DL(N);
3417 
3418   SDValue DataLo, DataHi;
3419   if (getTypeAction(Data.getValueType()) == TargetLowering::TypeSplitVector)
3420     // Split Data operand
3421     GetSplitVector(Data, DataLo, DataHi);
3422   else
3423     std::tie(DataLo, DataHi) = DAG.SplitVector(Data, DL);
3424 
3425   // Split Mask operand
3426   SDValue MaskLo, MaskHi;
3427   if (OpNo == 1 && Mask.getOpcode() == ISD::SETCC) {
3428     SplitVecRes_SETCC(Mask.getNode(), MaskLo, MaskHi);
3429   } else {
3430     if (getTypeAction(Mask.getValueType()) == TargetLowering::TypeSplitVector)
3431       GetSplitVector(Mask, MaskLo, MaskHi);
3432     else
3433       std::tie(MaskLo, MaskHi) = DAG.SplitVector(Mask, DL);
3434   }
3435 
3436   EVT MemoryVT = N->getMemoryVT();
3437   EVT LoMemVT, HiMemVT;
3438   bool HiIsEmpty = false;
3439   std::tie(LoMemVT, HiMemVT) =
3440       DAG.GetDependentSplitDestVTs(MemoryVT, DataLo.getValueType(), &HiIsEmpty);
3441 
3442   SDValue Lo, Hi, Res;
3443   MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
3444       N->getPointerInfo(), MachineMemOperand::MOStore,
3445       MemoryLocation::UnknownSize, Alignment, N->getAAInfo(), N->getRanges());
3446 
3447   Lo = DAG.getMaskedStore(Ch, DL, DataLo, Ptr, Offset, MaskLo, LoMemVT, MMO,
3448                           N->getAddressingMode(), N->isTruncatingStore(),
3449                           N->isCompressingStore());
3450 
3451   if (HiIsEmpty) {
3452     // The hi masked store has zero storage size.
3453     // Only the lo masked store is needed.
3454     Res = Lo;
3455   } else {
3456 
3457     Ptr = TLI.IncrementMemoryAddress(Ptr, MaskLo, DL, LoMemVT, DAG,
3458                                      N->isCompressingStore());
3459 
3460     MachinePointerInfo MPI;
3461     if (LoMemVT.isScalableVector()) {
3462       Alignment = commonAlignment(
3463           Alignment, LoMemVT.getSizeInBits().getKnownMinValue() / 8);
3464       MPI = MachinePointerInfo(N->getPointerInfo().getAddrSpace());
3465     } else
3466       MPI = N->getPointerInfo().getWithOffset(
3467           LoMemVT.getStoreSize().getFixedValue());
3468 
3469     MMO = DAG.getMachineFunction().getMachineMemOperand(
3470         MPI, MachineMemOperand::MOStore, MemoryLocation::UnknownSize, Alignment,
3471         N->getAAInfo(), N->getRanges());
3472 
3473     Hi = DAG.getMaskedStore(Ch, DL, DataHi, Ptr, Offset, MaskHi, HiMemVT, MMO,
3474                             N->getAddressingMode(), N->isTruncatingStore(),
3475                             N->isCompressingStore());
3476 
3477     // Build a factor node to remember that this store is independent of the
3478     // other one.
3479     Res = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Lo, Hi);
3480   }
3481 
3482   return Res;
3483 }
3484 
SplitVecOp_Scatter(MemSDNode * N,unsigned OpNo)3485 SDValue DAGTypeLegalizer::SplitVecOp_Scatter(MemSDNode *N, unsigned OpNo) {
3486   SDValue Ch = N->getChain();
3487   SDValue Ptr = N->getBasePtr();
3488   EVT MemoryVT = N->getMemoryVT();
3489   Align Alignment = N->getOriginalAlign();
3490   SDLoc DL(N);
3491   struct Operands {
3492     SDValue Mask;
3493     SDValue Index;
3494     SDValue Scale;
3495     SDValue Data;
3496   } Ops = [&]() -> Operands {
3497     if (auto *MSC = dyn_cast<MaskedScatterSDNode>(N)) {
3498       return {MSC->getMask(), MSC->getIndex(), MSC->getScale(),
3499               MSC->getValue()};
3500     }
3501     auto *VPSC = cast<VPScatterSDNode>(N);
3502     return {VPSC->getMask(), VPSC->getIndex(), VPSC->getScale(),
3503             VPSC->getValue()};
3504   }();
3505   // Split all operands
3506 
3507   EVT LoMemVT, HiMemVT;
3508   std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
3509 
3510   SDValue DataLo, DataHi;
3511   if (getTypeAction(Ops.Data.getValueType()) == TargetLowering::TypeSplitVector)
3512     // Split Data operand
3513     GetSplitVector(Ops.Data, DataLo, DataHi);
3514   else
3515     std::tie(DataLo, DataHi) = DAG.SplitVector(Ops.Data, DL);
3516 
3517   // Split Mask operand
3518   SDValue MaskLo, MaskHi;
3519   if (OpNo == 1 && Ops.Mask.getOpcode() == ISD::SETCC) {
3520     SplitVecRes_SETCC(Ops.Mask.getNode(), MaskLo, MaskHi);
3521   } else {
3522     std::tie(MaskLo, MaskHi) = SplitMask(Ops.Mask, DL);
3523   }
3524 
3525   SDValue IndexHi, IndexLo;
3526   if (getTypeAction(Ops.Index.getValueType()) ==
3527       TargetLowering::TypeSplitVector)
3528     GetSplitVector(Ops.Index, IndexLo, IndexHi);
3529   else
3530     std::tie(IndexLo, IndexHi) = DAG.SplitVector(Ops.Index, DL);
3531 
3532   SDValue Lo;
3533   MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
3534       N->getPointerInfo(), MachineMemOperand::MOStore,
3535       MemoryLocation::UnknownSize, Alignment, N->getAAInfo(), N->getRanges());
3536 
3537   if (auto *MSC = dyn_cast<MaskedScatterSDNode>(N)) {
3538     SDValue OpsLo[] = {Ch, DataLo, MaskLo, Ptr, IndexLo, Ops.Scale};
3539     Lo =
3540         DAG.getMaskedScatter(DAG.getVTList(MVT::Other), LoMemVT, DL, OpsLo, MMO,
3541                              MSC->getIndexType(), MSC->isTruncatingStore());
3542 
3543     // The order of the Scatter operation after split is well defined. The "Hi"
3544     // part comes after the "Lo". So these two operations should be chained one
3545     // after another.
3546     SDValue OpsHi[] = {Lo, DataHi, MaskHi, Ptr, IndexHi, Ops.Scale};
3547     return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), HiMemVT, DL, OpsHi,
3548                                 MMO, MSC->getIndexType(),
3549                                 MSC->isTruncatingStore());
3550   }
3551   auto *VPSC = cast<VPScatterSDNode>(N);
3552   SDValue EVLLo, EVLHi;
3553   std::tie(EVLLo, EVLHi) =
3554       DAG.SplitEVL(VPSC->getVectorLength(), Ops.Data.getValueType(), DL);
3555 
3556   SDValue OpsLo[] = {Ch, DataLo, Ptr, IndexLo, Ops.Scale, MaskLo, EVLLo};
3557   Lo = DAG.getScatterVP(DAG.getVTList(MVT::Other), LoMemVT, DL, OpsLo, MMO,
3558                         VPSC->getIndexType());
3559 
3560   // The order of the Scatter operation after split is well defined. The "Hi"
3561   // part comes after the "Lo". So these two operations should be chained one
3562   // after another.
3563   SDValue OpsHi[] = {Lo, DataHi, Ptr, IndexHi, Ops.Scale, MaskHi, EVLHi};
3564   return DAG.getScatterVP(DAG.getVTList(MVT::Other), HiMemVT, DL, OpsHi, MMO,
3565                           VPSC->getIndexType());
3566 }
3567 
SplitVecOp_STORE(StoreSDNode * N,unsigned OpNo)3568 SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
3569   assert(N->isUnindexed() && "Indexed store of vector?");
3570   assert(OpNo == 1 && "Can only split the stored value");
3571   SDLoc DL(N);
3572 
3573   bool isTruncating = N->isTruncatingStore();
3574   SDValue Ch  = N->getChain();
3575   SDValue Ptr = N->getBasePtr();
3576   EVT MemoryVT = N->getMemoryVT();
3577   Align Alignment = N->getOriginalAlign();
3578   MachineMemOperand::Flags MMOFlags = N->getMemOperand()->getFlags();
3579   AAMDNodes AAInfo = N->getAAInfo();
3580   SDValue Lo, Hi;
3581   GetSplitVector(N->getOperand(1), Lo, Hi);
3582 
3583   EVT LoMemVT, HiMemVT;
3584   std::tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
3585 
3586   // Scalarize if the split halves are not byte-sized.
3587   if (!LoMemVT.isByteSized() || !HiMemVT.isByteSized())
3588     return TLI.scalarizeVectorStore(N, DAG);
3589 
3590   if (isTruncating)
3591     Lo = DAG.getTruncStore(Ch, DL, Lo, Ptr, N->getPointerInfo(), LoMemVT,
3592                            Alignment, MMOFlags, AAInfo);
3593   else
3594     Lo = DAG.getStore(Ch, DL, Lo, Ptr, N->getPointerInfo(), Alignment, MMOFlags,
3595                       AAInfo);
3596 
3597   MachinePointerInfo MPI;
3598   IncrementPointer(N, LoMemVT, MPI, Ptr);
3599 
3600   if (isTruncating)
3601     Hi = DAG.getTruncStore(Ch, DL, Hi, Ptr, MPI,
3602                            HiMemVT, Alignment, MMOFlags, AAInfo);
3603   else
3604     Hi = DAG.getStore(Ch, DL, Hi, Ptr, MPI, Alignment, MMOFlags, AAInfo);
3605 
3606   return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Lo, Hi);
3607 }
3608 
SplitVecOp_CONCAT_VECTORS(SDNode * N)3609 SDValue DAGTypeLegalizer::SplitVecOp_CONCAT_VECTORS(SDNode *N) {
3610   SDLoc DL(N);
3611 
3612   // The input operands all must have the same type, and we know the result
3613   // type is valid.  Convert this to a buildvector which extracts all the
3614   // input elements.
3615   // TODO: If the input elements are power-two vectors, we could convert this to
3616   // a new CONCAT_VECTORS node with elements that are half-wide.
3617   SmallVector<SDValue, 32> Elts;
3618   EVT EltVT = N->getValueType(0).getVectorElementType();
3619   for (const SDValue &Op : N->op_values()) {
3620     for (unsigned i = 0, e = Op.getValueType().getVectorNumElements();
3621          i != e; ++i) {
3622       Elts.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, Op,
3623                                  DAG.getVectorIdxConstant(i, DL)));
3624     }
3625   }
3626 
3627   return DAG.getBuildVector(N->getValueType(0), DL, Elts);
3628 }
3629 
SplitVecOp_TruncateHelper(SDNode * N)3630 SDValue DAGTypeLegalizer::SplitVecOp_TruncateHelper(SDNode *N) {
3631   // The result type is legal, but the input type is illegal.  If splitting
3632   // ends up with the result type of each half still being legal, just
3633   // do that.  If, however, that would result in an illegal result type,
3634   // we can try to get more clever with power-two vectors. Specifically,
3635   // split the input type, but also widen the result element size, then
3636   // concatenate the halves and truncate again.  For example, consider a target
3637   // where v8i8 is legal and v8i32 is not (ARM, which doesn't have 256-bit
3638   // vectors). To perform a "%res = v8i8 trunc v8i32 %in" we do:
3639   //   %inlo = v4i32 extract_subvector %in, 0
3640   //   %inhi = v4i32 extract_subvector %in, 4
3641   //   %lo16 = v4i16 trunc v4i32 %inlo
3642   //   %hi16 = v4i16 trunc v4i32 %inhi
3643   //   %in16 = v8i16 concat_vectors v4i16 %lo16, v4i16 %hi16
3644   //   %res = v8i8 trunc v8i16 %in16
3645   //
3646   // Without this transform, the original truncate would end up being
3647   // scalarized, which is pretty much always a last resort.
3648   unsigned OpNo = N->isStrictFPOpcode() ? 1 : 0;
3649   SDValue InVec = N->getOperand(OpNo);
3650   EVT InVT = InVec->getValueType(0);
3651   EVT OutVT = N->getValueType(0);
3652   ElementCount NumElements = OutVT.getVectorElementCount();
3653   bool IsFloat = OutVT.isFloatingPoint();
3654 
3655   unsigned InElementSize = InVT.getScalarSizeInBits();
3656   unsigned OutElementSize = OutVT.getScalarSizeInBits();
3657 
3658   // Determine the split output VT. If its legal we can just split dirctly.
3659   EVT LoOutVT, HiOutVT;
3660   std::tie(LoOutVT, HiOutVT) = DAG.GetSplitDestVTs(OutVT);
3661   assert(LoOutVT == HiOutVT && "Unequal split?");
3662 
3663   // If the input elements are only 1/2 the width of the result elements,
3664   // just use the normal splitting. Our trick only work if there's room
3665   // to split more than once.
3666   if (isTypeLegal(LoOutVT) ||
3667       InElementSize <= OutElementSize * 2)
3668     return SplitVecOp_UnaryOp(N);
3669   SDLoc DL(N);
3670 
3671   // Don't touch if this will be scalarized.
3672   EVT FinalVT = InVT;
3673   while (getTypeAction(FinalVT) == TargetLowering::TypeSplitVector)
3674     FinalVT = FinalVT.getHalfNumVectorElementsVT(*DAG.getContext());
3675 
3676   if (getTypeAction(FinalVT) == TargetLowering::TypeScalarizeVector)
3677     return SplitVecOp_UnaryOp(N);
3678 
3679   // Get the split input vector.
3680   SDValue InLoVec, InHiVec;
3681   GetSplitVector(InVec, InLoVec, InHiVec);
3682 
3683   // Truncate them to 1/2 the element size.
3684   //
3685   // This assumes the number of elements is a power of two; any vector that
3686   // isn't should be widened, not split.
3687   EVT HalfElementVT = IsFloat ?
3688     EVT::getFloatingPointVT(InElementSize/2) :
3689     EVT::getIntegerVT(*DAG.getContext(), InElementSize/2);
3690   EVT HalfVT = EVT::getVectorVT(*DAG.getContext(), HalfElementVT,
3691                                 NumElements.divideCoefficientBy(2));
3692 
3693   SDValue HalfLo;
3694   SDValue HalfHi;
3695   SDValue Chain;
3696   if (N->isStrictFPOpcode()) {
3697     HalfLo = DAG.getNode(N->getOpcode(), DL, {HalfVT, MVT::Other},
3698                          {N->getOperand(0), InLoVec});
3699     HalfHi = DAG.getNode(N->getOpcode(), DL, {HalfVT, MVT::Other},
3700                          {N->getOperand(0), InHiVec});
3701     // Legalize the chain result - switch anything that used the old chain to
3702     // use the new one.
3703     Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, HalfLo.getValue(1),
3704                         HalfHi.getValue(1));
3705   } else {
3706     HalfLo = DAG.getNode(N->getOpcode(), DL, HalfVT, InLoVec);
3707     HalfHi = DAG.getNode(N->getOpcode(), DL, HalfVT, InHiVec);
3708   }
3709 
3710   // Concatenate them to get the full intermediate truncation result.
3711   EVT InterVT = EVT::getVectorVT(*DAG.getContext(), HalfElementVT, NumElements);
3712   SDValue InterVec = DAG.getNode(ISD::CONCAT_VECTORS, DL, InterVT, HalfLo,
3713                                  HalfHi);
3714   // Now finish up by truncating all the way down to the original result
3715   // type. This should normally be something that ends up being legal directly,
3716   // but in theory if a target has very wide vectors and an annoyingly
3717   // restricted set of legal types, this split can chain to build things up.
3718 
3719   if (N->isStrictFPOpcode()) {
3720     SDValue Res = DAG.getNode(
3721         ISD::STRICT_FP_ROUND, DL, {OutVT, MVT::Other},
3722         {Chain, InterVec,
3723          DAG.getTargetConstant(0, DL, TLI.getPointerTy(DAG.getDataLayout()))});
3724     // Relink the chain
3725     ReplaceValueWith(SDValue(N, 1), SDValue(Res.getNode(), 1));
3726     return Res;
3727   }
3728 
3729   return IsFloat
3730              ? DAG.getNode(ISD::FP_ROUND, DL, OutVT, InterVec,
3731                            DAG.getTargetConstant(
3732                                0, DL, TLI.getPointerTy(DAG.getDataLayout())))
3733              : DAG.getNode(ISD::TRUNCATE, DL, OutVT, InterVec);
3734 }
3735 
SplitVecOp_VSETCC(SDNode * N)3736 SDValue DAGTypeLegalizer::SplitVecOp_VSETCC(SDNode *N) {
3737   assert(N->getValueType(0).isVector() &&
3738          N->getOperand(0).getValueType().isVector() &&
3739          "Operand types must be vectors");
3740   // The result has a legal vector type, but the input needs splitting.
3741   SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes;
3742   SDLoc DL(N);
3743   GetSplitVector(N->getOperand(0), Lo0, Hi0);
3744   GetSplitVector(N->getOperand(1), Lo1, Hi1);
3745   auto PartEltCnt = Lo0.getValueType().getVectorElementCount();
3746 
3747   LLVMContext &Context = *DAG.getContext();
3748   EVT PartResVT = EVT::getVectorVT(Context, MVT::i1, PartEltCnt);
3749   EVT WideResVT = EVT::getVectorVT(Context, MVT::i1, PartEltCnt*2);
3750 
3751   if (N->getOpcode() == ISD::SETCC) {
3752     LoRes = DAG.getNode(ISD::SETCC, DL, PartResVT, Lo0, Lo1, N->getOperand(2));
3753     HiRes = DAG.getNode(ISD::SETCC, DL, PartResVT, Hi0, Hi1, N->getOperand(2));
3754   } else {
3755     assert(N->getOpcode() == ISD::VP_SETCC && "Expected VP_SETCC opcode");
3756     SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3757     std::tie(MaskLo, MaskHi) = SplitMask(N->getOperand(3));
3758     std::tie(EVLLo, EVLHi) =
3759         DAG.SplitEVL(N->getOperand(4), N->getValueType(0), DL);
3760     LoRes = DAG.getNode(ISD::VP_SETCC, DL, PartResVT, Lo0, Lo1,
3761                         N->getOperand(2), MaskLo, EVLLo);
3762     HiRes = DAG.getNode(ISD::VP_SETCC, DL, PartResVT, Hi0, Hi1,
3763                         N->getOperand(2), MaskHi, EVLHi);
3764   }
3765   SDValue Con = DAG.getNode(ISD::CONCAT_VECTORS, DL, WideResVT, LoRes, HiRes);
3766 
3767   EVT OpVT = N->getOperand(0).getValueType();
3768   ISD::NodeType ExtendCode =
3769       TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT));
3770   return DAG.getNode(ExtendCode, DL, N->getValueType(0), Con);
3771 }
3772 
3773 
SplitVecOp_FP_ROUND(SDNode * N)3774 SDValue DAGTypeLegalizer::SplitVecOp_FP_ROUND(SDNode *N) {
3775   // The result has a legal vector type, but the input needs splitting.
3776   EVT ResVT = N->getValueType(0);
3777   SDValue Lo, Hi;
3778   SDLoc DL(N);
3779   GetSplitVector(N->getOperand(N->isStrictFPOpcode() ? 1 : 0), Lo, Hi);
3780   EVT InVT = Lo.getValueType();
3781 
3782   EVT OutVT = EVT::getVectorVT(*DAG.getContext(), ResVT.getVectorElementType(),
3783                                InVT.getVectorElementCount());
3784 
3785   if (N->isStrictFPOpcode()) {
3786     Lo = DAG.getNode(N->getOpcode(), DL, { OutVT, MVT::Other },
3787                      { N->getOperand(0), Lo, N->getOperand(2) });
3788     Hi = DAG.getNode(N->getOpcode(), DL, { OutVT, MVT::Other },
3789                      { N->getOperand(0), Hi, N->getOperand(2) });
3790     // Legalize the chain result - switch anything that used the old chain to
3791     // use the new one.
3792     SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
3793                                    Lo.getValue(1), Hi.getValue(1));
3794     ReplaceValueWith(SDValue(N, 1), NewChain);
3795   } else if (N->getOpcode() == ISD::VP_FP_ROUND) {
3796     SDValue MaskLo, MaskHi, EVLLo, EVLHi;
3797     std::tie(MaskLo, MaskHi) = SplitMask(N->getOperand(1));
3798     std::tie(EVLLo, EVLHi) =
3799         DAG.SplitEVL(N->getOperand(2), N->getValueType(0), DL);
3800     Lo = DAG.getNode(ISD::VP_FP_ROUND, DL, OutVT, Lo, MaskLo, EVLLo);
3801     Hi = DAG.getNode(ISD::VP_FP_ROUND, DL, OutVT, Hi, MaskHi, EVLHi);
3802   } else {
3803     Lo = DAG.getNode(ISD::FP_ROUND, DL, OutVT, Lo, N->getOperand(1));
3804     Hi = DAG.getNode(ISD::FP_ROUND, DL, OutVT, Hi, N->getOperand(1));
3805   }
3806 
3807   return DAG.getNode(ISD::CONCAT_VECTORS, DL, ResVT, Lo, Hi);
3808 }
3809 
SplitVecOp_FCOPYSIGN(SDNode * N)3810 SDValue DAGTypeLegalizer::SplitVecOp_FCOPYSIGN(SDNode *N) {
3811   // The result (and the first input) has a legal vector type, but the second
3812   // input needs splitting.
3813 
3814   SDLoc DL(N);
3815 
3816   EVT LHSLoVT, LHSHiVT;
3817   std::tie(LHSLoVT, LHSHiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
3818 
3819   if (!isTypeLegal(LHSLoVT) || !isTypeLegal(LHSHiVT))
3820     return DAG.UnrollVectorOp(N, N->getValueType(0).getVectorNumElements());
3821 
3822   SDValue LHSLo, LHSHi;
3823   std::tie(LHSLo, LHSHi) =
3824       DAG.SplitVector(N->getOperand(0), DL, LHSLoVT, LHSHiVT);
3825 
3826   SDValue RHSLo, RHSHi;
3827   std::tie(RHSLo, RHSHi) = DAG.SplitVector(N->getOperand(1), DL);
3828 
3829   SDValue Lo = DAG.getNode(ISD::FCOPYSIGN, DL, LHSLoVT, LHSLo, RHSLo);
3830   SDValue Hi = DAG.getNode(ISD::FCOPYSIGN, DL, LHSHiVT, LHSHi, RHSHi);
3831 
3832   return DAG.getNode(ISD::CONCAT_VECTORS, DL, N->getValueType(0), Lo, Hi);
3833 }
3834 
SplitVecOp_FP_TO_XINT_SAT(SDNode * N)3835 SDValue DAGTypeLegalizer::SplitVecOp_FP_TO_XINT_SAT(SDNode *N) {
3836   EVT ResVT = N->getValueType(0);
3837   SDValue Lo, Hi;
3838   SDLoc dl(N);
3839   GetSplitVector(N->getOperand(0), Lo, Hi);
3840   EVT InVT = Lo.getValueType();
3841 
3842   EVT NewResVT =
3843       EVT::getVectorVT(*DAG.getContext(), ResVT.getVectorElementType(),
3844                        InVT.getVectorElementCount());
3845 
3846   Lo = DAG.getNode(N->getOpcode(), dl, NewResVT, Lo, N->getOperand(1));
3847   Hi = DAG.getNode(N->getOpcode(), dl, NewResVT, Hi, N->getOperand(1));
3848 
3849   return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi);
3850 }
3851 
3852 //===----------------------------------------------------------------------===//
3853 //  Result Vector Widening
3854 //===----------------------------------------------------------------------===//
3855 
WidenVectorResult(SDNode * N,unsigned ResNo)3856 void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) {
3857   LLVM_DEBUG(dbgs() << "Widen node result " << ResNo << ": "; N->dump(&DAG);
3858              dbgs() << "\n");
3859 
3860   // See if the target wants to custom widen this node.
3861   if (CustomWidenLowerNode(N, N->getValueType(ResNo)))
3862     return;
3863 
3864   SDValue Res = SDValue();
3865 
3866   auto unrollExpandedOp = [&]() {
3867     // We're going to widen this vector op to a legal type by padding with undef
3868     // elements. If the wide vector op is eventually going to be expanded to
3869     // scalar libcalls, then unroll into scalar ops now to avoid unnecessary
3870     // libcalls on the undef elements.
3871     EVT VT = N->getValueType(0);
3872     EVT WideVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
3873     if (!TLI.isOperationLegalOrCustom(N->getOpcode(), WideVecVT) &&
3874         TLI.isOperationExpand(N->getOpcode(), VT.getScalarType())) {
3875       Res = DAG.UnrollVectorOp(N, WideVecVT.getVectorNumElements());
3876       return true;
3877     }
3878     return false;
3879   };
3880 
3881   switch (N->getOpcode()) {
3882   default:
3883 #ifndef NDEBUG
3884     dbgs() << "WidenVectorResult #" << ResNo << ": ";
3885     N->dump(&DAG);
3886     dbgs() << "\n";
3887 #endif
3888     llvm_unreachable("Do not know how to widen the result of this operator!");
3889 
3890   case ISD::MERGE_VALUES:      Res = WidenVecRes_MERGE_VALUES(N, ResNo); break;
3891   case ISD::BITCAST:           Res = WidenVecRes_BITCAST(N); break;
3892   case ISD::BUILD_VECTOR:      Res = WidenVecRes_BUILD_VECTOR(N); break;
3893   case ISD::CONCAT_VECTORS:    Res = WidenVecRes_CONCAT_VECTORS(N); break;
3894   case ISD::INSERT_SUBVECTOR:
3895     Res = WidenVecRes_INSERT_SUBVECTOR(N);
3896     break;
3897   case ISD::EXTRACT_SUBVECTOR: Res = WidenVecRes_EXTRACT_SUBVECTOR(N); break;
3898   case ISD::INSERT_VECTOR_ELT: Res = WidenVecRes_INSERT_VECTOR_ELT(N); break;
3899   case ISD::LOAD:              Res = WidenVecRes_LOAD(N); break;
3900   case ISD::STEP_VECTOR:
3901   case ISD::SPLAT_VECTOR:
3902   case ISD::SCALAR_TO_VECTOR:
3903     Res = WidenVecRes_ScalarOp(N);
3904     break;
3905   case ISD::SIGN_EXTEND_INREG: Res = WidenVecRes_InregOp(N); break;
3906   case ISD::VSELECT:
3907   case ISD::SELECT:
3908   case ISD::VP_SELECT:
3909   case ISD::VP_MERGE:
3910     Res = WidenVecRes_Select(N);
3911     break;
3912   case ISD::SELECT_CC:         Res = WidenVecRes_SELECT_CC(N); break;
3913   case ISD::VP_SETCC:
3914   case ISD::SETCC:             Res = WidenVecRes_SETCC(N); break;
3915   case ISD::UNDEF:             Res = WidenVecRes_UNDEF(N); break;
3916   case ISD::VECTOR_SHUFFLE:
3917     Res = WidenVecRes_VECTOR_SHUFFLE(cast<ShuffleVectorSDNode>(N));
3918     break;
3919   case ISD::VP_LOAD:
3920     Res = WidenVecRes_VP_LOAD(cast<VPLoadSDNode>(N));
3921     break;
3922   case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
3923     Res = WidenVecRes_VP_STRIDED_LOAD(cast<VPStridedLoadSDNode>(N));
3924     break;
3925   case ISD::MLOAD:
3926     Res = WidenVecRes_MLOAD(cast<MaskedLoadSDNode>(N));
3927     break;
3928   case ISD::MGATHER:
3929     Res = WidenVecRes_MGATHER(cast<MaskedGatherSDNode>(N));
3930     break;
3931   case ISD::VP_GATHER:
3932     Res = WidenVecRes_VP_GATHER(cast<VPGatherSDNode>(N));
3933     break;
3934   case ISD::VECTOR_REVERSE:
3935     Res = WidenVecRes_VECTOR_REVERSE(N);
3936     break;
3937 
3938   case ISD::ADD: case ISD::VP_ADD:
3939   case ISD::AND: case ISD::VP_AND:
3940   case ISD::MUL: case ISD::VP_MUL:
3941   case ISD::MULHS:
3942   case ISD::MULHU:
3943   case ISD::OR: case ISD::VP_OR:
3944   case ISD::SUB: case ISD::VP_SUB:
3945   case ISD::XOR: case ISD::VP_XOR:
3946   case ISD::SHL: case ISD::VP_SHL:
3947   case ISD::SRA: case ISD::VP_ASHR:
3948   case ISD::SRL: case ISD::VP_LSHR:
3949   case ISD::FMINNUM: case ISD::VP_FMINNUM:
3950   case ISD::FMAXNUM: case ISD::VP_FMAXNUM:
3951   case ISD::FMINIMUM:
3952   case ISD::FMAXIMUM:
3953   case ISD::SMIN: case ISD::VP_SMIN:
3954   case ISD::SMAX: case ISD::VP_SMAX:
3955   case ISD::UMIN: case ISD::VP_UMIN:
3956   case ISD::UMAX: case ISD::VP_UMAX:
3957   case ISD::UADDSAT:
3958   case ISD::SADDSAT:
3959   case ISD::USUBSAT:
3960   case ISD::SSUBSAT:
3961   case ISD::SSHLSAT:
3962   case ISD::USHLSAT:
3963   case ISD::ROTL:
3964   case ISD::ROTR:
3965   case ISD::AVGFLOORS:
3966   case ISD::AVGFLOORU:
3967   case ISD::AVGCEILS:
3968   case ISD::AVGCEILU:
3969   // Vector-predicated binary op widening. Note that -- unlike the
3970   // unpredicated versions -- we don't have to worry about trapping on
3971   // operations like UDIV, FADD, etc., as we pass on the original vector
3972   // length parameter. This means the widened elements containing garbage
3973   // aren't active.
3974   case ISD::VP_SDIV:
3975   case ISD::VP_UDIV:
3976   case ISD::VP_SREM:
3977   case ISD::VP_UREM:
3978   case ISD::VP_FADD:
3979   case ISD::VP_FSUB:
3980   case ISD::VP_FMUL:
3981   case ISD::VP_FDIV:
3982   case ISD::VP_FREM:
3983   case ISD::VP_FCOPYSIGN:
3984     Res = WidenVecRes_Binary(N);
3985     break;
3986 
3987   case ISD::FPOW:
3988   case ISD::FREM:
3989     if (unrollExpandedOp())
3990       break;
3991     // If the target has custom/legal support for the scalar FP intrinsic ops
3992     // (they are probably not destined to become libcalls), then widen those
3993     // like any other binary ops.
3994     [[fallthrough]];
3995 
3996   case ISD::FADD:
3997   case ISD::FMUL:
3998   case ISD::FSUB:
3999   case ISD::FDIV:
4000   case ISD::SDIV:
4001   case ISD::UDIV:
4002   case ISD::SREM:
4003   case ISD::UREM:
4004     Res = WidenVecRes_BinaryCanTrap(N);
4005     break;
4006 
4007   case ISD::SMULFIX:
4008   case ISD::SMULFIXSAT:
4009   case ISD::UMULFIX:
4010   case ISD::UMULFIXSAT:
4011     // These are binary operations, but with an extra operand that shouldn't
4012     // be widened (the scale).
4013     Res = WidenVecRes_BinaryWithExtraScalarOp(N);
4014     break;
4015 
4016 #define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN)               \
4017   case ISD::STRICT_##DAGN:
4018 #include "llvm/IR/ConstrainedOps.def"
4019     Res = WidenVecRes_StrictFP(N);
4020     break;
4021 
4022   case ISD::UADDO:
4023   case ISD::SADDO:
4024   case ISD::USUBO:
4025   case ISD::SSUBO:
4026   case ISD::UMULO:
4027   case ISD::SMULO:
4028     Res = WidenVecRes_OverflowOp(N, ResNo);
4029     break;
4030 
4031   case ISD::FCOPYSIGN:
4032     Res = WidenVecRes_FCOPYSIGN(N);
4033     break;
4034 
4035   case ISD::IS_FPCLASS:
4036     Res = WidenVecRes_IS_FPCLASS(N);
4037     break;
4038 
4039   case ISD::FPOWI:
4040     Res = WidenVecRes_POWI(N);
4041     break;
4042 
4043   case ISD::ANY_EXTEND_VECTOR_INREG:
4044   case ISD::SIGN_EXTEND_VECTOR_INREG:
4045   case ISD::ZERO_EXTEND_VECTOR_INREG:
4046     Res = WidenVecRes_EXTEND_VECTOR_INREG(N);
4047     break;
4048 
4049   case ISD::ANY_EXTEND:
4050   case ISD::FP_EXTEND:
4051   case ISD::VP_FP_EXTEND:
4052   case ISD::FP_ROUND:
4053   case ISD::VP_FP_ROUND:
4054   case ISD::FP_TO_SINT:
4055   case ISD::VP_FP_TO_SINT:
4056   case ISD::FP_TO_UINT:
4057   case ISD::VP_FP_TO_UINT:
4058   case ISD::SIGN_EXTEND:
4059   case ISD::VP_SIGN_EXTEND:
4060   case ISD::SINT_TO_FP:
4061   case ISD::VP_SINT_TO_FP:
4062   case ISD::VP_TRUNCATE:
4063   case ISD::TRUNCATE:
4064   case ISD::UINT_TO_FP:
4065   case ISD::VP_UINT_TO_FP:
4066   case ISD::ZERO_EXTEND:
4067   case ISD::VP_ZERO_EXTEND:
4068     Res = WidenVecRes_Convert(N);
4069     break;
4070 
4071   case ISD::FP_TO_SINT_SAT:
4072   case ISD::FP_TO_UINT_SAT:
4073     Res = WidenVecRes_FP_TO_XINT_SAT(N);
4074     break;
4075 
4076   case ISD::FABS:
4077   case ISD::FCEIL:
4078   case ISD::FCOS:
4079   case ISD::FEXP:
4080   case ISD::FEXP2:
4081   case ISD::FFLOOR:
4082   case ISD::FLOG:
4083   case ISD::FLOG10:
4084   case ISD::FLOG2:
4085   case ISD::FNEARBYINT:
4086   case ISD::FRINT:
4087   case ISD::FROUND:
4088   case ISD::FROUNDEVEN:
4089   case ISD::FSIN:
4090   case ISD::FSQRT:
4091   case ISD::FTRUNC:
4092     if (unrollExpandedOp())
4093       break;
4094     // If the target has custom/legal support for the scalar FP intrinsic ops
4095     // (they are probably not destined to become libcalls), then widen those
4096     // like any other unary ops.
4097     [[fallthrough]];
4098 
4099   case ISD::ABS:
4100   case ISD::VP_ABS:
4101   case ISD::BITREVERSE:
4102   case ISD::VP_BITREVERSE:
4103   case ISD::BSWAP:
4104   case ISD::VP_BSWAP:
4105   case ISD::CTLZ:
4106   case ISD::VP_CTLZ:
4107   case ISD::CTLZ_ZERO_UNDEF:
4108   case ISD::VP_CTLZ_ZERO_UNDEF:
4109   case ISD::CTPOP:
4110   case ISD::VP_CTPOP:
4111   case ISD::CTTZ:
4112   case ISD::VP_CTTZ:
4113   case ISD::CTTZ_ZERO_UNDEF:
4114   case ISD::VP_CTTZ_ZERO_UNDEF:
4115   case ISD::FNEG: case ISD::VP_FNEG:
4116   case ISD::VP_FABS:
4117   case ISD::VP_SQRT:
4118   case ISD::VP_FCEIL:
4119   case ISD::VP_FFLOOR:
4120   case ISD::VP_FRINT:
4121   case ISD::VP_FNEARBYINT:
4122   case ISD::VP_FROUND:
4123   case ISD::VP_FROUNDEVEN:
4124   case ISD::VP_FROUNDTOZERO:
4125   case ISD::FREEZE:
4126   case ISD::ARITH_FENCE:
4127   case ISD::FCANONICALIZE:
4128     Res = WidenVecRes_Unary(N);
4129     break;
4130   case ISD::FMA: case ISD::VP_FMA:
4131   case ISD::FSHL:
4132   case ISD::VP_FSHL:
4133   case ISD::FSHR:
4134   case ISD::VP_FSHR:
4135     Res = WidenVecRes_Ternary(N);
4136     break;
4137   }
4138 
4139   // If Res is null, the sub-method took care of registering the result.
4140   if (Res.getNode())
4141     SetWidenedVector(SDValue(N, ResNo), Res);
4142 }
4143 
WidenVecRes_Ternary(SDNode * N)4144 SDValue DAGTypeLegalizer::WidenVecRes_Ternary(SDNode *N) {
4145   // Ternary op widening.
4146   SDLoc dl(N);
4147   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4148   SDValue InOp1 = GetWidenedVector(N->getOperand(0));
4149   SDValue InOp2 = GetWidenedVector(N->getOperand(1));
4150   SDValue InOp3 = GetWidenedVector(N->getOperand(2));
4151   if (N->getNumOperands() == 3)
4152     return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3);
4153 
4154   assert(N->getNumOperands() == 5 && "Unexpected number of operands!");
4155   assert(N->isVPOpcode() && "Expected VP opcode");
4156 
4157   SDValue Mask =
4158       GetWidenedMask(N->getOperand(3), WidenVT.getVectorElementCount());
4159   return DAG.getNode(N->getOpcode(), dl, WidenVT,
4160                      {InOp1, InOp2, InOp3, Mask, N->getOperand(4)});
4161 }
4162 
WidenVecRes_Binary(SDNode * N)4163 SDValue DAGTypeLegalizer::WidenVecRes_Binary(SDNode *N) {
4164   // Binary op widening.
4165   SDLoc dl(N);
4166   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4167   SDValue InOp1 = GetWidenedVector(N->getOperand(0));
4168   SDValue InOp2 = GetWidenedVector(N->getOperand(1));
4169   if (N->getNumOperands() == 2)
4170     return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2,
4171                        N->getFlags());
4172 
4173   assert(N->getNumOperands() == 4 && "Unexpected number of operands!");
4174   assert(N->isVPOpcode() && "Expected VP opcode");
4175 
4176   SDValue Mask =
4177       GetWidenedMask(N->getOperand(2), WidenVT.getVectorElementCount());
4178   return DAG.getNode(N->getOpcode(), dl, WidenVT,
4179                      {InOp1, InOp2, Mask, N->getOperand(3)}, N->getFlags());
4180 }
4181 
WidenVecRes_BinaryWithExtraScalarOp(SDNode * N)4182 SDValue DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(SDNode *N) {
4183   // Binary op widening, but with an extra operand that shouldn't be widened.
4184   SDLoc dl(N);
4185   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4186   SDValue InOp1 = GetWidenedVector(N->getOperand(0));
4187   SDValue InOp2 = GetWidenedVector(N->getOperand(1));
4188   SDValue InOp3 = N->getOperand(2);
4189   return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2, InOp3,
4190                      N->getFlags());
4191 }
4192 
4193 // Given a vector of operations that have been broken up to widen, see
4194 // if we can collect them together into the next widest legal VT. This
4195 // implementation is trap-safe.
CollectOpsToWiden(SelectionDAG & DAG,const TargetLowering & TLI,SmallVectorImpl<SDValue> & ConcatOps,unsigned ConcatEnd,EVT VT,EVT MaxVT,EVT WidenVT)4196 static SDValue CollectOpsToWiden(SelectionDAG &DAG, const TargetLowering &TLI,
4197                                  SmallVectorImpl<SDValue> &ConcatOps,
4198                                  unsigned ConcatEnd, EVT VT, EVT MaxVT,
4199                                  EVT WidenVT) {
4200   // Check to see if we have a single operation with the widen type.
4201   if (ConcatEnd == 1) {
4202     VT = ConcatOps[0].getValueType();
4203     if (VT == WidenVT)
4204       return ConcatOps[0];
4205   }
4206 
4207   SDLoc dl(ConcatOps[0]);
4208   EVT WidenEltVT = WidenVT.getVectorElementType();
4209 
4210   // while (Some element of ConcatOps is not of type MaxVT) {
4211   //   From the end of ConcatOps, collect elements of the same type and put
4212   //   them into an op of the next larger supported type
4213   // }
4214   while (ConcatOps[ConcatEnd-1].getValueType() != MaxVT) {
4215     int Idx = ConcatEnd - 1;
4216     VT = ConcatOps[Idx--].getValueType();
4217     while (Idx >= 0 && ConcatOps[Idx].getValueType() == VT)
4218       Idx--;
4219 
4220     int NextSize = VT.isVector() ? VT.getVectorNumElements() : 1;
4221     EVT NextVT;
4222     do {
4223       NextSize *= 2;
4224       NextVT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NextSize);
4225     } while (!TLI.isTypeLegal(NextVT));
4226 
4227     if (!VT.isVector()) {
4228       // Scalar type, create an INSERT_VECTOR_ELEMENT of type NextVT
4229       SDValue VecOp = DAG.getUNDEF(NextVT);
4230       unsigned NumToInsert = ConcatEnd - Idx - 1;
4231       for (unsigned i = 0, OpIdx = Idx+1; i < NumToInsert; i++, OpIdx++) {
4232         VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NextVT, VecOp,
4233                             ConcatOps[OpIdx], DAG.getVectorIdxConstant(i, dl));
4234       }
4235       ConcatOps[Idx+1] = VecOp;
4236       ConcatEnd = Idx + 2;
4237     } else {
4238       // Vector type, create a CONCAT_VECTORS of type NextVT
4239       SDValue undefVec = DAG.getUNDEF(VT);
4240       unsigned OpsToConcat = NextSize/VT.getVectorNumElements();
4241       SmallVector<SDValue, 16> SubConcatOps(OpsToConcat);
4242       unsigned RealVals = ConcatEnd - Idx - 1;
4243       unsigned SubConcatEnd = 0;
4244       unsigned SubConcatIdx = Idx + 1;
4245       while (SubConcatEnd < RealVals)
4246         SubConcatOps[SubConcatEnd++] = ConcatOps[++Idx];
4247       while (SubConcatEnd < OpsToConcat)
4248         SubConcatOps[SubConcatEnd++] = undefVec;
4249       ConcatOps[SubConcatIdx] = DAG.getNode(ISD::CONCAT_VECTORS, dl,
4250                                             NextVT, SubConcatOps);
4251       ConcatEnd = SubConcatIdx + 1;
4252     }
4253   }
4254 
4255   // Check to see if we have a single operation with the widen type.
4256   if (ConcatEnd == 1) {
4257     VT = ConcatOps[0].getValueType();
4258     if (VT == WidenVT)
4259       return ConcatOps[0];
4260   }
4261 
4262   // add undefs of size MaxVT until ConcatOps grows to length of WidenVT
4263   unsigned NumOps = WidenVT.getVectorNumElements()/MaxVT.getVectorNumElements();
4264   if (NumOps != ConcatEnd ) {
4265     SDValue UndefVal = DAG.getUNDEF(MaxVT);
4266     for (unsigned j = ConcatEnd; j < NumOps; ++j)
4267       ConcatOps[j] = UndefVal;
4268   }
4269   return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT,
4270                      ArrayRef(ConcatOps.data(), NumOps));
4271 }
4272 
WidenVecRes_BinaryCanTrap(SDNode * N)4273 SDValue DAGTypeLegalizer::WidenVecRes_BinaryCanTrap(SDNode *N) {
4274   // Binary op widening for operations that can trap.
4275   unsigned Opcode = N->getOpcode();
4276   SDLoc dl(N);
4277   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4278   EVT WidenEltVT = WidenVT.getVectorElementType();
4279   EVT VT = WidenVT;
4280   unsigned NumElts = VT.getVectorMinNumElements();
4281   const SDNodeFlags Flags = N->getFlags();
4282   while (!TLI.isTypeLegal(VT) && NumElts != 1) {
4283     NumElts = NumElts / 2;
4284     VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts);
4285   }
4286 
4287   if (NumElts != 1 && !TLI.canOpTrap(N->getOpcode(), VT)) {
4288     // Operation doesn't trap so just widen as normal.
4289     SDValue InOp1 = GetWidenedVector(N->getOperand(0));
4290     SDValue InOp2 = GetWidenedVector(N->getOperand(1));
4291     return DAG.getNode(N->getOpcode(), dl, WidenVT, InOp1, InOp2, Flags);
4292   }
4293 
4294   // FIXME: Improve support for scalable vectors.
4295   assert(!VT.isScalableVector() && "Scalable vectors not handled yet.");
4296 
4297   // No legal vector version so unroll the vector operation and then widen.
4298   if (NumElts == 1)
4299     return DAG.UnrollVectorOp(N, WidenVT.getVectorNumElements());
4300 
4301   // Since the operation can trap, apply operation on the original vector.
4302   EVT MaxVT = VT;
4303   SDValue InOp1 = GetWidenedVector(N->getOperand(0));
4304   SDValue InOp2 = GetWidenedVector(N->getOperand(1));
4305   unsigned CurNumElts = N->getValueType(0).getVectorNumElements();
4306 
4307   SmallVector<SDValue, 16> ConcatOps(CurNumElts);
4308   unsigned ConcatEnd = 0;  // Current ConcatOps index.
4309   int Idx = 0;        // Current Idx into input vectors.
4310 
4311   // NumElts := greatest legal vector size (at most WidenVT)
4312   // while (orig. vector has unhandled elements) {
4313   //   take munches of size NumElts from the beginning and add to ConcatOps
4314   //   NumElts := next smaller supported vector size or 1
4315   // }
4316   while (CurNumElts != 0) {
4317     while (CurNumElts >= NumElts) {
4318       SDValue EOp1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, InOp1,
4319                                  DAG.getVectorIdxConstant(Idx, dl));
4320       SDValue EOp2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, InOp2,
4321                                  DAG.getVectorIdxConstant(Idx, dl));
4322       ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, VT, EOp1, EOp2, Flags);
4323       Idx += NumElts;
4324       CurNumElts -= NumElts;
4325     }
4326     do {
4327       NumElts = NumElts / 2;
4328       VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts);
4329     } while (!TLI.isTypeLegal(VT) && NumElts != 1);
4330 
4331     if (NumElts == 1) {
4332       for (unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
4333         SDValue EOp1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT,
4334                                    InOp1, DAG.getVectorIdxConstant(Idx, dl));
4335         SDValue EOp2 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT,
4336                                    InOp2, DAG.getVectorIdxConstant(Idx, dl));
4337         ConcatOps[ConcatEnd++] = DAG.getNode(Opcode, dl, WidenEltVT,
4338                                              EOp1, EOp2, Flags);
4339       }
4340       CurNumElts = 0;
4341     }
4342   }
4343 
4344   return CollectOpsToWiden(DAG, TLI, ConcatOps, ConcatEnd, VT, MaxVT, WidenVT);
4345 }
4346 
WidenVecRes_StrictFP(SDNode * N)4347 SDValue DAGTypeLegalizer::WidenVecRes_StrictFP(SDNode *N) {
4348   switch (N->getOpcode()) {
4349   case ISD::STRICT_FSETCC:
4350   case ISD::STRICT_FSETCCS:
4351     return WidenVecRes_STRICT_FSETCC(N);
4352   case ISD::STRICT_FP_EXTEND:
4353   case ISD::STRICT_FP_ROUND:
4354   case ISD::STRICT_FP_TO_SINT:
4355   case ISD::STRICT_FP_TO_UINT:
4356   case ISD::STRICT_SINT_TO_FP:
4357   case ISD::STRICT_UINT_TO_FP:
4358    return WidenVecRes_Convert_StrictFP(N);
4359   default:
4360     break;
4361   }
4362 
4363   // StrictFP op widening for operations that can trap.
4364   unsigned NumOpers = N->getNumOperands();
4365   unsigned Opcode = N->getOpcode();
4366   SDLoc dl(N);
4367   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4368   EVT WidenEltVT = WidenVT.getVectorElementType();
4369   EVT VT = WidenVT;
4370   unsigned NumElts = VT.getVectorNumElements();
4371   while (!TLI.isTypeLegal(VT) && NumElts != 1) {
4372     NumElts = NumElts / 2;
4373     VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts);
4374   }
4375 
4376   // No legal vector version so unroll the vector operation and then widen.
4377   if (NumElts == 1)
4378     return UnrollVectorOp_StrictFP(N, WidenVT.getVectorNumElements());
4379 
4380   // Since the operation can trap, apply operation on the original vector.
4381   EVT MaxVT = VT;
4382   SmallVector<SDValue, 4> InOps;
4383   unsigned CurNumElts = N->getValueType(0).getVectorNumElements();
4384 
4385   SmallVector<SDValue, 16> ConcatOps(CurNumElts);
4386   SmallVector<SDValue, 16> Chains;
4387   unsigned ConcatEnd = 0;  // Current ConcatOps index.
4388   int Idx = 0;        // Current Idx into input vectors.
4389 
4390   // The Chain is the first operand.
4391   InOps.push_back(N->getOperand(0));
4392 
4393   // Now process the remaining operands.
4394   for (unsigned i = 1; i < NumOpers; ++i) {
4395     SDValue Oper = N->getOperand(i);
4396 
4397     if (Oper.getValueType().isVector()) {
4398       assert(Oper.getValueType() == N->getValueType(0) &&
4399              "Invalid operand type to widen!");
4400       Oper = GetWidenedVector(Oper);
4401     }
4402 
4403     InOps.push_back(Oper);
4404   }
4405 
4406   // NumElts := greatest legal vector size (at most WidenVT)
4407   // while (orig. vector has unhandled elements) {
4408   //   take munches of size NumElts from the beginning and add to ConcatOps
4409   //   NumElts := next smaller supported vector size or 1
4410   // }
4411   while (CurNumElts != 0) {
4412     while (CurNumElts >= NumElts) {
4413       SmallVector<SDValue, 4> EOps;
4414 
4415       for (unsigned i = 0; i < NumOpers; ++i) {
4416         SDValue Op = InOps[i];
4417 
4418         if (Op.getValueType().isVector())
4419           Op = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, Op,
4420                            DAG.getVectorIdxConstant(Idx, dl));
4421 
4422         EOps.push_back(Op);
4423       }
4424 
4425       EVT OperVT[] = {VT, MVT::Other};
4426       SDValue Oper = DAG.getNode(Opcode, dl, OperVT, EOps);
4427       ConcatOps[ConcatEnd++] = Oper;
4428       Chains.push_back(Oper.getValue(1));
4429       Idx += NumElts;
4430       CurNumElts -= NumElts;
4431     }
4432     do {
4433       NumElts = NumElts / 2;
4434       VT = EVT::getVectorVT(*DAG.getContext(), WidenEltVT, NumElts);
4435     } while (!TLI.isTypeLegal(VT) && NumElts != 1);
4436 
4437     if (NumElts == 1) {
4438       for (unsigned i = 0; i != CurNumElts; ++i, ++Idx) {
4439         SmallVector<SDValue, 4> EOps;
4440 
4441         for (unsigned i = 0; i < NumOpers; ++i) {
4442           SDValue Op = InOps[i];
4443 
4444           if (Op.getValueType().isVector())
4445             Op = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, WidenEltVT, Op,
4446                              DAG.getVectorIdxConstant(Idx, dl));
4447 
4448           EOps.push_back(Op);
4449         }
4450 
4451         EVT WidenVT[] = {WidenEltVT, MVT::Other};
4452         SDValue Oper = DAG.getNode(Opcode, dl, WidenVT, EOps);
4453         ConcatOps[ConcatEnd++] = Oper;
4454         Chains.push_back(Oper.getValue(1));
4455       }
4456       CurNumElts = 0;
4457     }
4458   }
4459 
4460   // Build a factor node to remember all the Ops that have been created.
4461   SDValue NewChain;
4462   if (Chains.size() == 1)
4463     NewChain = Chains[0];
4464   else
4465     NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Chains);
4466   ReplaceValueWith(SDValue(N, 1), NewChain);
4467 
4468   return CollectOpsToWiden(DAG, TLI, ConcatOps, ConcatEnd, VT, MaxVT, WidenVT);
4469 }
4470 
WidenVecRes_OverflowOp(SDNode * N,unsigned ResNo)4471 SDValue DAGTypeLegalizer::WidenVecRes_OverflowOp(SDNode *N, unsigned ResNo) {
4472   SDLoc DL(N);
4473   EVT ResVT = N->getValueType(0);
4474   EVT OvVT = N->getValueType(1);
4475   EVT WideResVT, WideOvVT;
4476   SDValue WideLHS, WideRHS;
4477 
4478   // TODO: This might result in a widen/split loop.
4479   if (ResNo == 0) {
4480     WideResVT = TLI.getTypeToTransformTo(*DAG.getContext(), ResVT);
4481     WideOvVT = EVT::getVectorVT(
4482         *DAG.getContext(), OvVT.getVectorElementType(),
4483         WideResVT.getVectorNumElements());
4484 
4485     WideLHS = GetWidenedVector(N->getOperand(0));
4486     WideRHS = GetWidenedVector(N->getOperand(1));
4487   } else {
4488     WideOvVT = TLI.getTypeToTransformTo(*DAG.getContext(), OvVT);
4489     WideResVT = EVT::getVectorVT(
4490         *DAG.getContext(), ResVT.getVectorElementType(),
4491         WideOvVT.getVectorNumElements());
4492 
4493     SDValue Zero = DAG.getVectorIdxConstant(0, DL);
4494     WideLHS = DAG.getNode(
4495         ISD::INSERT_SUBVECTOR, DL, WideResVT, DAG.getUNDEF(WideResVT),
4496         N->getOperand(0), Zero);
4497     WideRHS = DAG.getNode(
4498         ISD::INSERT_SUBVECTOR, DL, WideResVT, DAG.getUNDEF(WideResVT),
4499         N->getOperand(1), Zero);
4500   }
4501 
4502   SDVTList WideVTs = DAG.getVTList(WideResVT, WideOvVT);
4503   SDNode *WideNode = DAG.getNode(
4504       N->getOpcode(), DL, WideVTs, WideLHS, WideRHS).getNode();
4505 
4506   // Replace the other vector result not being explicitly widened here.
4507   unsigned OtherNo = 1 - ResNo;
4508   EVT OtherVT = N->getValueType(OtherNo);
4509   if (getTypeAction(OtherVT) == TargetLowering::TypeWidenVector) {
4510     SetWidenedVector(SDValue(N, OtherNo), SDValue(WideNode, OtherNo));
4511   } else {
4512     SDValue Zero = DAG.getVectorIdxConstant(0, DL);
4513     SDValue OtherVal = DAG.getNode(
4514         ISD::EXTRACT_SUBVECTOR, DL, OtherVT, SDValue(WideNode, OtherNo), Zero);
4515     ReplaceValueWith(SDValue(N, OtherNo), OtherVal);
4516   }
4517 
4518   return SDValue(WideNode, ResNo);
4519 }
4520 
WidenVecRes_Convert(SDNode * N)4521 SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) {
4522   LLVMContext &Ctx = *DAG.getContext();
4523   SDValue InOp = N->getOperand(0);
4524   SDLoc DL(N);
4525 
4526   EVT WidenVT = TLI.getTypeToTransformTo(Ctx, N->getValueType(0));
4527   ElementCount WidenEC = WidenVT.getVectorElementCount();
4528 
4529   EVT InVT = InOp.getValueType();
4530 
4531   unsigned Opcode = N->getOpcode();
4532   const SDNodeFlags Flags = N->getFlags();
4533 
4534   // Handle the case of ZERO_EXTEND where the promoted InVT element size does
4535   // not equal that of WidenVT.
4536   if (N->getOpcode() == ISD::ZERO_EXTEND &&
4537       getTypeAction(InVT) == TargetLowering::TypePromoteInteger &&
4538       TLI.getTypeToTransformTo(Ctx, InVT).getScalarSizeInBits() !=
4539       WidenVT.getScalarSizeInBits()) {
4540     InOp = ZExtPromotedInteger(InOp);
4541     InVT = InOp.getValueType();
4542     if (WidenVT.getScalarSizeInBits() < InVT.getScalarSizeInBits())
4543       Opcode = ISD::TRUNCATE;
4544   }
4545 
4546   EVT InEltVT = InVT.getVectorElementType();
4547   EVT InWidenVT = EVT::getVectorVT(Ctx, InEltVT, WidenEC);
4548   ElementCount InVTEC = InVT.getVectorElementCount();
4549 
4550   if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) {
4551     InOp = GetWidenedVector(N->getOperand(0));
4552     InVT = InOp.getValueType();
4553     InVTEC = InVT.getVectorElementCount();
4554     if (InVTEC == WidenEC) {
4555       if (N->getNumOperands() == 1)
4556         return DAG.getNode(Opcode, DL, WidenVT, InOp);
4557       if (N->getNumOperands() == 3) {
4558         assert(N->isVPOpcode() && "Expected VP opcode");
4559         SDValue Mask =
4560             GetWidenedMask(N->getOperand(1), WidenVT.getVectorElementCount());
4561         return DAG.getNode(Opcode, DL, WidenVT, InOp, Mask, N->getOperand(2));
4562       }
4563       return DAG.getNode(Opcode, DL, WidenVT, InOp, N->getOperand(1), Flags);
4564     }
4565     if (WidenVT.getSizeInBits() == InVT.getSizeInBits()) {
4566       // If both input and result vector types are of same width, extend
4567       // operations should be done with SIGN/ZERO_EXTEND_VECTOR_INREG, which
4568       // accepts fewer elements in the result than in the input.
4569       if (Opcode == ISD::ANY_EXTEND)
4570         return DAG.getNode(ISD::ANY_EXTEND_VECTOR_INREG, DL, WidenVT, InOp);
4571       if (Opcode == ISD::SIGN_EXTEND)
4572         return DAG.getNode(ISD::SIGN_EXTEND_VECTOR_INREG, DL, WidenVT, InOp);
4573       if (Opcode == ISD::ZERO_EXTEND)
4574         return DAG.getNode(ISD::ZERO_EXTEND_VECTOR_INREG, DL, WidenVT, InOp);
4575     }
4576   }
4577 
4578   if (TLI.isTypeLegal(InWidenVT)) {
4579     // Because the result and the input are different vector types, widening
4580     // the result could create a legal type but widening the input might make
4581     // it an illegal type that might lead to repeatedly splitting the input
4582     // and then widening it. To avoid this, we widen the input only if
4583     // it results in a legal type.
4584     if (WidenEC.isKnownMultipleOf(InVTEC.getKnownMinValue())) {
4585       // Widen the input and call convert on the widened input vector.
4586       unsigned NumConcat =
4587           WidenEC.getKnownMinValue() / InVTEC.getKnownMinValue();
4588       SmallVector<SDValue, 16> Ops(NumConcat, DAG.getUNDEF(InVT));
4589       Ops[0] = InOp;
4590       SDValue InVec = DAG.getNode(ISD::CONCAT_VECTORS, DL, InWidenVT, Ops);
4591       if (N->getNumOperands() == 1)
4592         return DAG.getNode(Opcode, DL, WidenVT, InVec);
4593       return DAG.getNode(Opcode, DL, WidenVT, InVec, N->getOperand(1), Flags);
4594     }
4595 
4596     if (InVTEC.isKnownMultipleOf(WidenEC.getKnownMinValue())) {
4597       SDValue InVal = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, InWidenVT, InOp,
4598                                   DAG.getVectorIdxConstant(0, DL));
4599       // Extract the input and convert the shorten input vector.
4600       if (N->getNumOperands() == 1)
4601         return DAG.getNode(Opcode, DL, WidenVT, InVal);
4602       return DAG.getNode(Opcode, DL, WidenVT, InVal, N->getOperand(1), Flags);
4603     }
4604   }
4605 
4606   // Otherwise unroll into some nasty scalar code and rebuild the vector.
4607   EVT EltVT = WidenVT.getVectorElementType();
4608   SmallVector<SDValue, 16> Ops(WidenEC.getFixedValue(), DAG.getUNDEF(EltVT));
4609   // Use the original element count so we don't do more scalar opts than
4610   // necessary.
4611   unsigned MinElts = N->getValueType(0).getVectorNumElements();
4612   for (unsigned i=0; i < MinElts; ++i) {
4613     SDValue Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, InEltVT, InOp,
4614                               DAG.getVectorIdxConstant(i, DL));
4615     if (N->getNumOperands() == 1)
4616       Ops[i] = DAG.getNode(Opcode, DL, EltVT, Val);
4617     else
4618       Ops[i] = DAG.getNode(Opcode, DL, EltVT, Val, N->getOperand(1), Flags);
4619   }
4620 
4621   return DAG.getBuildVector(WidenVT, DL, Ops);
4622 }
4623 
WidenVecRes_FP_TO_XINT_SAT(SDNode * N)4624 SDValue DAGTypeLegalizer::WidenVecRes_FP_TO_XINT_SAT(SDNode *N) {
4625   SDLoc dl(N);
4626   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4627   ElementCount WidenNumElts = WidenVT.getVectorElementCount();
4628 
4629   SDValue Src = N->getOperand(0);
4630   EVT SrcVT = Src.getValueType();
4631 
4632   // Also widen the input.
4633   if (getTypeAction(SrcVT) == TargetLowering::TypeWidenVector) {
4634     Src = GetWidenedVector(Src);
4635     SrcVT = Src.getValueType();
4636   }
4637 
4638   // Input and output not widened to the same size, give up.
4639   if (WidenNumElts != SrcVT.getVectorElementCount())
4640     return DAG.UnrollVectorOp(N, WidenNumElts.getKnownMinValue());
4641 
4642   return DAG.getNode(N->getOpcode(), dl, WidenVT, Src, N->getOperand(1));
4643 }
4644 
WidenVecRes_Convert_StrictFP(SDNode * N)4645 SDValue DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(SDNode *N) {
4646   SDValue InOp = N->getOperand(1);
4647   SDLoc DL(N);
4648   SmallVector<SDValue, 4> NewOps(N->op_begin(), N->op_end());
4649 
4650   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4651   unsigned WidenNumElts = WidenVT.getVectorNumElements();
4652 
4653   EVT InVT = InOp.getValueType();
4654   EVT InEltVT = InVT.getVectorElementType();
4655 
4656   unsigned Opcode = N->getOpcode();
4657 
4658   // FIXME: Optimizations need to be implemented here.
4659 
4660   // Otherwise unroll into some nasty scalar code and rebuild the vector.
4661   EVT EltVT = WidenVT.getVectorElementType();
4662   std::array<EVT, 2> EltVTs = {{EltVT, MVT::Other}};
4663   SmallVector<SDValue, 16> Ops(WidenNumElts, DAG.getUNDEF(EltVT));
4664   SmallVector<SDValue, 32> OpChains;
4665   // Use the original element count so we don't do more scalar opts than
4666   // necessary.
4667   unsigned MinElts = N->getValueType(0).getVectorNumElements();
4668   for (unsigned i=0; i < MinElts; ++i) {
4669     NewOps[1] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, InEltVT, InOp,
4670                             DAG.getVectorIdxConstant(i, DL));
4671     Ops[i] = DAG.getNode(Opcode, DL, EltVTs, NewOps);
4672     OpChains.push_back(Ops[i].getValue(1));
4673   }
4674   SDValue NewChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OpChains);
4675   ReplaceValueWith(SDValue(N, 1), NewChain);
4676 
4677   return DAG.getBuildVector(WidenVT, DL, Ops);
4678 }
4679 
WidenVecRes_EXTEND_VECTOR_INREG(SDNode * N)4680 SDValue DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(SDNode *N) {
4681   unsigned Opcode = N->getOpcode();
4682   SDValue InOp = N->getOperand(0);
4683   SDLoc DL(N);
4684 
4685   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4686   EVT WidenSVT = WidenVT.getVectorElementType();
4687   unsigned WidenNumElts = WidenVT.getVectorNumElements();
4688 
4689   EVT InVT = InOp.getValueType();
4690   EVT InSVT = InVT.getVectorElementType();
4691   unsigned InVTNumElts = InVT.getVectorNumElements();
4692 
4693   if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) {
4694     InOp = GetWidenedVector(InOp);
4695     InVT = InOp.getValueType();
4696     if (InVT.getSizeInBits() == WidenVT.getSizeInBits()) {
4697       switch (Opcode) {
4698       case ISD::ANY_EXTEND_VECTOR_INREG:
4699       case ISD::SIGN_EXTEND_VECTOR_INREG:
4700       case ISD::ZERO_EXTEND_VECTOR_INREG:
4701         return DAG.getNode(Opcode, DL, WidenVT, InOp);
4702       }
4703     }
4704   }
4705 
4706   // Unroll, extend the scalars and rebuild the vector.
4707   SmallVector<SDValue, 16> Ops;
4708   for (unsigned i = 0, e = std::min(InVTNumElts, WidenNumElts); i != e; ++i) {
4709     SDValue Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, InSVT, InOp,
4710                               DAG.getVectorIdxConstant(i, DL));
4711     switch (Opcode) {
4712     case ISD::ANY_EXTEND_VECTOR_INREG:
4713       Val = DAG.getNode(ISD::ANY_EXTEND, DL, WidenSVT, Val);
4714       break;
4715     case ISD::SIGN_EXTEND_VECTOR_INREG:
4716       Val = DAG.getNode(ISD::SIGN_EXTEND, DL, WidenSVT, Val);
4717       break;
4718     case ISD::ZERO_EXTEND_VECTOR_INREG:
4719       Val = DAG.getNode(ISD::ZERO_EXTEND, DL, WidenSVT, Val);
4720       break;
4721     default:
4722       llvm_unreachable("A *_EXTEND_VECTOR_INREG node was expected");
4723     }
4724     Ops.push_back(Val);
4725   }
4726 
4727   while (Ops.size() != WidenNumElts)
4728     Ops.push_back(DAG.getUNDEF(WidenSVT));
4729 
4730   return DAG.getBuildVector(WidenVT, DL, Ops);
4731 }
4732 
WidenVecRes_FCOPYSIGN(SDNode * N)4733 SDValue DAGTypeLegalizer::WidenVecRes_FCOPYSIGN(SDNode *N) {
4734   // If this is an FCOPYSIGN with same input types, we can treat it as a
4735   // normal (can trap) binary op.
4736   if (N->getOperand(0).getValueType() == N->getOperand(1).getValueType())
4737     return WidenVecRes_BinaryCanTrap(N);
4738 
4739   // If the types are different, fall back to unrolling.
4740   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4741   return DAG.UnrollVectorOp(N, WidenVT.getVectorNumElements());
4742 }
4743 
WidenVecRes_IS_FPCLASS(SDNode * N)4744 SDValue DAGTypeLegalizer::WidenVecRes_IS_FPCLASS(SDNode *N) {
4745   SDValue FpValue = N->getOperand(0);
4746   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4747   if (getTypeAction(FpValue.getValueType()) != TargetLowering::TypeWidenVector)
4748     return DAG.UnrollVectorOp(N, WidenVT.getVectorNumElements());
4749   SDValue Arg = GetWidenedVector(FpValue);
4750   return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, {Arg, N->getOperand(1)},
4751                      N->getFlags());
4752 }
4753 
WidenVecRes_POWI(SDNode * N)4754 SDValue DAGTypeLegalizer::WidenVecRes_POWI(SDNode *N) {
4755   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4756   SDValue InOp = GetWidenedVector(N->getOperand(0));
4757   SDValue ShOp = N->getOperand(1);
4758   return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, InOp, ShOp);
4759 }
4760 
WidenVecRes_Unary(SDNode * N)4761 SDValue DAGTypeLegalizer::WidenVecRes_Unary(SDNode *N) {
4762   // Unary op widening.
4763   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4764   SDValue InOp = GetWidenedVector(N->getOperand(0));
4765   if (N->getNumOperands() == 1)
4766     return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, InOp);
4767 
4768   assert(N->getNumOperands() == 3 && "Unexpected number of operands!");
4769   assert(N->isVPOpcode() && "Expected VP opcode");
4770 
4771   SDValue Mask =
4772       GetWidenedMask(N->getOperand(1), WidenVT.getVectorElementCount());
4773   return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT,
4774                      {InOp, Mask, N->getOperand(2)});
4775 }
4776 
WidenVecRes_InregOp(SDNode * N)4777 SDValue DAGTypeLegalizer::WidenVecRes_InregOp(SDNode *N) {
4778   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4779   EVT ExtVT = EVT::getVectorVT(*DAG.getContext(),
4780                                cast<VTSDNode>(N->getOperand(1))->getVT()
4781                                  .getVectorElementType(),
4782                                WidenVT.getVectorNumElements());
4783   SDValue WidenLHS = GetWidenedVector(N->getOperand(0));
4784   return DAG.getNode(N->getOpcode(), SDLoc(N),
4785                      WidenVT, WidenLHS, DAG.getValueType(ExtVT));
4786 }
4787 
WidenVecRes_MERGE_VALUES(SDNode * N,unsigned ResNo)4788 SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(SDNode *N, unsigned ResNo) {
4789   SDValue WidenVec = DisintegrateMERGE_VALUES(N, ResNo);
4790   return GetWidenedVector(WidenVec);
4791 }
4792 
WidenVecRes_BITCAST(SDNode * N)4793 SDValue DAGTypeLegalizer::WidenVecRes_BITCAST(SDNode *N) {
4794   SDValue InOp = N->getOperand(0);
4795   EVT InVT = InOp.getValueType();
4796   EVT VT = N->getValueType(0);
4797   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4798   SDLoc dl(N);
4799 
4800   switch (getTypeAction(InVT)) {
4801   case TargetLowering::TypeLegal:
4802     break;
4803   case TargetLowering::TypeScalarizeScalableVector:
4804     report_fatal_error("Scalarization of scalable vectors is not supported.");
4805   case TargetLowering::TypePromoteInteger: {
4806     // If the incoming type is a vector that is being promoted, then
4807     // we know that the elements are arranged differently and that we
4808     // must perform the conversion using a stack slot.
4809     if (InVT.isVector())
4810       break;
4811 
4812     // If the InOp is promoted to the same size, convert it.  Otherwise,
4813     // fall out of the switch and widen the promoted input.
4814     SDValue NInOp = GetPromotedInteger(InOp);
4815     EVT NInVT = NInOp.getValueType();
4816     if (WidenVT.bitsEq(NInVT)) {
4817       // For big endian targets we need to shift the input integer or the
4818       // interesting bits will end up at the wrong place.
4819       if (DAG.getDataLayout().isBigEndian()) {
4820         unsigned ShiftAmt = NInVT.getSizeInBits() - InVT.getSizeInBits();
4821         EVT ShiftAmtTy = TLI.getShiftAmountTy(NInVT, DAG.getDataLayout());
4822         assert(ShiftAmt < WidenVT.getSizeInBits() && "Too large shift amount!");
4823         NInOp = DAG.getNode(ISD::SHL, dl, NInVT, NInOp,
4824                            DAG.getConstant(ShiftAmt, dl, ShiftAmtTy));
4825       }
4826       return DAG.getNode(ISD::BITCAST, dl, WidenVT, NInOp);
4827     }
4828     InOp = NInOp;
4829     InVT = NInVT;
4830     break;
4831   }
4832   case TargetLowering::TypeSoftenFloat:
4833   case TargetLowering::TypePromoteFloat:
4834   case TargetLowering::TypeSoftPromoteHalf:
4835   case TargetLowering::TypeExpandInteger:
4836   case TargetLowering::TypeExpandFloat:
4837   case TargetLowering::TypeScalarizeVector:
4838   case TargetLowering::TypeSplitVector:
4839     break;
4840   case TargetLowering::TypeWidenVector:
4841     // If the InOp is widened to the same size, convert it.  Otherwise, fall
4842     // out of the switch and widen the widened input.
4843     InOp = GetWidenedVector(InOp);
4844     InVT = InOp.getValueType();
4845     if (WidenVT.bitsEq(InVT))
4846       // The input widens to the same size. Convert to the widen value.
4847       return DAG.getNode(ISD::BITCAST, dl, WidenVT, InOp);
4848     break;
4849   }
4850 
4851   unsigned WidenSize = WidenVT.getSizeInBits();
4852   unsigned InSize = InVT.getSizeInBits();
4853   unsigned InScalarSize = InVT.getScalarSizeInBits();
4854   // x86mmx is not an acceptable vector element type, so don't try.
4855   if (WidenSize % InScalarSize == 0 && InVT != MVT::x86mmx) {
4856     // Determine new input vector type.  The new input vector type will use
4857     // the same element type (if its a vector) or use the input type as a
4858     // vector.  It is the same size as the type to widen to.
4859     EVT NewInVT;
4860     unsigned NewNumParts = WidenSize / InSize;
4861     if (InVT.isVector()) {
4862       EVT InEltVT = InVT.getVectorElementType();
4863       NewInVT = EVT::getVectorVT(*DAG.getContext(), InEltVT,
4864                                  WidenSize / InEltVT.getSizeInBits());
4865     } else {
4866       NewInVT = EVT::getVectorVT(*DAG.getContext(), InVT, NewNumParts);
4867     }
4868 
4869     if (TLI.isTypeLegal(NewInVT)) {
4870       SDValue NewVec;
4871       if (InVT.isVector()) {
4872         // Because the result and the input are different vector types, widening
4873         // the result could create a legal type but widening the input might
4874         // make it an illegal type that might lead to repeatedly splitting the
4875         // input and then widening it. To avoid this, we widen the input only if
4876         // it results in a legal type.
4877         if (WidenSize % InSize == 0) {
4878           SmallVector<SDValue, 16> Ops(NewNumParts, DAG.getUNDEF(InVT));
4879           Ops[0] = InOp;
4880 
4881           NewVec = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewInVT, Ops);
4882         } else {
4883           SmallVector<SDValue, 16> Ops;
4884           DAG.ExtractVectorElements(InOp, Ops);
4885           Ops.append(WidenSize / InScalarSize - Ops.size(),
4886                      DAG.getUNDEF(InVT.getVectorElementType()));
4887 
4888           NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl, NewInVT, Ops);
4889         }
4890       } else {
4891         NewVec = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewInVT, InOp);
4892       }
4893       return DAG.getNode(ISD::BITCAST, dl, WidenVT, NewVec);
4894     }
4895   }
4896 
4897   return CreateStackStoreLoad(InOp, WidenVT);
4898 }
4899 
WidenVecRes_BUILD_VECTOR(SDNode * N)4900 SDValue DAGTypeLegalizer::WidenVecRes_BUILD_VECTOR(SDNode *N) {
4901   SDLoc dl(N);
4902   // Build a vector with undefined for the new nodes.
4903   EVT VT = N->getValueType(0);
4904 
4905   // Integer BUILD_VECTOR operands may be larger than the node's vector element
4906   // type. The UNDEFs need to have the same type as the existing operands.
4907   EVT EltVT = N->getOperand(0).getValueType();
4908   unsigned NumElts = VT.getVectorNumElements();
4909 
4910   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
4911   unsigned WidenNumElts = WidenVT.getVectorNumElements();
4912 
4913   SmallVector<SDValue, 16> NewOps(N->op_begin(), N->op_end());
4914   assert(WidenNumElts >= NumElts && "Shrinking vector instead of widening!");
4915   NewOps.append(WidenNumElts - NumElts, DAG.getUNDEF(EltVT));
4916 
4917   return DAG.getBuildVector(WidenVT, dl, NewOps);
4918 }
4919 
WidenVecRes_CONCAT_VECTORS(SDNode * N)4920 SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) {
4921   EVT InVT = N->getOperand(0).getValueType();
4922   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
4923   SDLoc dl(N);
4924   unsigned NumOperands = N->getNumOperands();
4925 
4926   bool InputWidened = false; // Indicates we need to widen the input.
4927   if (getTypeAction(InVT) != TargetLowering::TypeWidenVector) {
4928     unsigned WidenNumElts = WidenVT.getVectorMinNumElements();
4929     unsigned NumInElts = InVT.getVectorMinNumElements();
4930     if (WidenNumElts % NumInElts == 0) {
4931       // Add undef vectors to widen to correct length.
4932       unsigned NumConcat = WidenNumElts / NumInElts;
4933       SDValue UndefVal = DAG.getUNDEF(InVT);
4934       SmallVector<SDValue, 16> Ops(NumConcat);
4935       for (unsigned i=0; i < NumOperands; ++i)
4936         Ops[i] = N->getOperand(i);
4937       for (unsigned i = NumOperands; i != NumConcat; ++i)
4938         Ops[i] = UndefVal;
4939       return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, Ops);
4940     }
4941   } else {
4942     InputWidened = true;
4943     if (WidenVT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
4944       // The inputs and the result are widen to the same value.
4945       unsigned i;
4946       for (i=1; i < NumOperands; ++i)
4947         if (!N->getOperand(i).isUndef())
4948           break;
4949 
4950       if (i == NumOperands)
4951         // Everything but the first operand is an UNDEF so just return the
4952         // widened first operand.
4953         return GetWidenedVector(N->getOperand(0));
4954 
4955       if (NumOperands == 2) {
4956         assert(!WidenVT.isScalableVector() &&
4957                "Cannot use vector shuffles to widen CONCAT_VECTOR result");
4958         unsigned WidenNumElts = WidenVT.getVectorNumElements();
4959         unsigned NumInElts = InVT.getVectorNumElements();
4960 
4961         // Replace concat of two operands with a shuffle.
4962         SmallVector<int, 16> MaskOps(WidenNumElts, -1);
4963         for (unsigned i = 0; i < NumInElts; ++i) {
4964           MaskOps[i] = i;
4965           MaskOps[i + NumInElts] = i + WidenNumElts;
4966         }
4967         return DAG.getVectorShuffle(WidenVT, dl,
4968                                     GetWidenedVector(N->getOperand(0)),
4969                                     GetWidenedVector(N->getOperand(1)),
4970                                     MaskOps);
4971       }
4972     }
4973   }
4974 
4975   assert(!WidenVT.isScalableVector() &&
4976          "Cannot use build vectors to widen CONCAT_VECTOR result");
4977   unsigned WidenNumElts = WidenVT.getVectorNumElements();
4978   unsigned NumInElts = InVT.getVectorNumElements();
4979 
4980   // Fall back to use extracts and build vector.
4981   EVT EltVT = WidenVT.getVectorElementType();
4982   SmallVector<SDValue, 16> Ops(WidenNumElts);
4983   unsigned Idx = 0;
4984   for (unsigned i=0; i < NumOperands; ++i) {
4985     SDValue InOp = N->getOperand(i);
4986     if (InputWidened)
4987       InOp = GetWidenedVector(InOp);
4988     for (unsigned j = 0; j < NumInElts; ++j)
4989       Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
4990                                DAG.getVectorIdxConstant(j, dl));
4991   }
4992   SDValue UndefVal = DAG.getUNDEF(EltVT);
4993   for (; Idx < WidenNumElts; ++Idx)
4994     Ops[Idx] = UndefVal;
4995   return DAG.getBuildVector(WidenVT, dl, Ops);
4996 }
4997 
WidenVecRes_INSERT_SUBVECTOR(SDNode * N)4998 SDValue DAGTypeLegalizer::WidenVecRes_INSERT_SUBVECTOR(SDNode *N) {
4999   EVT VT = N->getValueType(0);
5000   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5001   SDValue InOp1 = GetWidenedVector(N->getOperand(0));
5002   SDValue InOp2 = N->getOperand(1);
5003   SDValue Idx = N->getOperand(2);
5004   SDLoc dl(N);
5005   return DAG.getNode(ISD::INSERT_SUBVECTOR, dl, WidenVT, InOp1, InOp2, Idx);
5006 }
5007 
WidenVecRes_EXTRACT_SUBVECTOR(SDNode * N)5008 SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) {
5009   EVT VT = N->getValueType(0);
5010   EVT EltVT = VT.getVectorElementType();
5011   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5012   SDValue InOp = N->getOperand(0);
5013   SDValue Idx = N->getOperand(1);
5014   SDLoc dl(N);
5015 
5016   auto InOpTypeAction = getTypeAction(InOp.getValueType());
5017   if (InOpTypeAction == TargetLowering::TypeWidenVector)
5018     InOp = GetWidenedVector(InOp);
5019 
5020   EVT InVT = InOp.getValueType();
5021 
5022   // Check if we can just return the input vector after widening.
5023   uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
5024   if (IdxVal == 0 && InVT == WidenVT)
5025     return InOp;
5026 
5027   // Check if we can extract from the vector.
5028   unsigned WidenNumElts = WidenVT.getVectorMinNumElements();
5029   unsigned InNumElts = InVT.getVectorMinNumElements();
5030   unsigned VTNumElts = VT.getVectorMinNumElements();
5031   assert(IdxVal % VTNumElts == 0 &&
5032          "Expected Idx to be a multiple of subvector minimum vector length");
5033   if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts)
5034     return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, WidenVT, InOp, Idx);
5035 
5036   if (VT.isScalableVector()) {
5037     // Try to split the operation up into smaller extracts and concat the
5038     // results together, e.g.
5039     //    nxv6i64 extract_subvector(nxv12i64, 6)
5040     // <->
5041     //  nxv8i64 concat(
5042     //    nxv2i64 extract_subvector(nxv16i64, 6)
5043     //    nxv2i64 extract_subvector(nxv16i64, 8)
5044     //    nxv2i64 extract_subvector(nxv16i64, 10)
5045     //    undef)
5046     unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
5047     assert((IdxVal % GCD) == 0 && "Expected Idx to be a multiple of the broken "
5048                                   "down type's element count");
5049     EVT PartVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
5050                                   ElementCount::getScalable(GCD));
5051     // Avoid recursion around e.g. nxv1i8.
5052     if (getTypeAction(PartVT) != TargetLowering::TypeWidenVector) {
5053       SmallVector<SDValue> Parts;
5054       unsigned I = 0;
5055       for (; I < VTNumElts / GCD; ++I)
5056         Parts.push_back(
5057             DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, PartVT, InOp,
5058                         DAG.getVectorIdxConstant(IdxVal + I * GCD, dl)));
5059       for (; I < WidenNumElts / GCD; ++I)
5060         Parts.push_back(DAG.getUNDEF(PartVT));
5061 
5062       return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, Parts);
5063     }
5064 
5065     report_fatal_error("Don't know how to widen the result of "
5066                        "EXTRACT_SUBVECTOR for scalable vectors");
5067   }
5068 
5069   // We could try widening the input to the right length but for now, extract
5070   // the original elements, fill the rest with undefs and build a vector.
5071   SmallVector<SDValue, 16> Ops(WidenNumElts);
5072   unsigned i;
5073   for (i = 0; i < VTNumElts; ++i)
5074     Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
5075                          DAG.getVectorIdxConstant(IdxVal + i, dl));
5076 
5077   SDValue UndefVal = DAG.getUNDEF(EltVT);
5078   for (; i < WidenNumElts; ++i)
5079     Ops[i] = UndefVal;
5080   return DAG.getBuildVector(WidenVT, dl, Ops);
5081 }
5082 
WidenVecRes_INSERT_VECTOR_ELT(SDNode * N)5083 SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) {
5084   SDValue InOp = GetWidenedVector(N->getOperand(0));
5085   return DAG.getNode(ISD::INSERT_VECTOR_ELT, SDLoc(N),
5086                      InOp.getValueType(), InOp,
5087                      N->getOperand(1), N->getOperand(2));
5088 }
5089 
WidenVecRes_LOAD(SDNode * N)5090 SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) {
5091   LoadSDNode *LD = cast<LoadSDNode>(N);
5092   ISD::LoadExtType ExtType = LD->getExtensionType();
5093 
5094   // A vector must always be stored in memory as-is, i.e. without any padding
5095   // between the elements, since various code depend on it, e.g. in the
5096   // handling of a bitcast of a vector type to int, which may be done with a
5097   // vector store followed by an integer load. A vector that does not have
5098   // elements that are byte-sized must therefore be stored as an integer
5099   // built out of the extracted vector elements.
5100   if (!LD->getMemoryVT().isByteSized()) {
5101     SDValue Value, NewChain;
5102     std::tie(Value, NewChain) = TLI.scalarizeVectorLoad(LD, DAG);
5103     ReplaceValueWith(SDValue(LD, 0), Value);
5104     ReplaceValueWith(SDValue(LD, 1), NewChain);
5105     return SDValue();
5106   }
5107 
5108   SDValue Result;
5109   SmallVector<SDValue, 16> LdChain;  // Chain for the series of load
5110   if (ExtType != ISD::NON_EXTLOAD)
5111     Result = GenWidenVectorExtLoads(LdChain, LD, ExtType);
5112   else
5113     Result = GenWidenVectorLoads(LdChain, LD);
5114 
5115   if (Result) {
5116     // If we generate a single load, we can use that for the chain.  Otherwise,
5117     // build a factor node to remember the multiple loads are independent and
5118     // chain to that.
5119     SDValue NewChain;
5120     if (LdChain.size() == 1)
5121       NewChain = LdChain[0];
5122     else
5123       NewChain = DAG.getNode(ISD::TokenFactor, SDLoc(LD), MVT::Other, LdChain);
5124 
5125     // Modified the chain - switch anything that used the old chain to use
5126     // the new one.
5127     ReplaceValueWith(SDValue(N, 1), NewChain);
5128 
5129     return Result;
5130   }
5131 
5132   // Generate a vector-predicated load if it is custom/legal on the target. To
5133   // avoid possible recursion, only do this if the widened mask type is legal.
5134   // FIXME: Not all targets may support EVL in VP_LOAD. These will have been
5135   // removed from the IR by the ExpandVectorPredication pass but we're
5136   // reintroducing them here.
5137   EVT LdVT = LD->getMemoryVT();
5138   EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), LdVT);
5139   EVT WideMaskVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1,
5140                                     WideVT.getVectorElementCount());
5141   if (ExtType == ISD::NON_EXTLOAD && WideVT.isScalableVector() &&
5142       TLI.isOperationLegalOrCustom(ISD::VP_LOAD, WideVT) &&
5143       TLI.isTypeLegal(WideMaskVT)) {
5144     SDLoc DL(N);
5145     SDValue Mask = DAG.getAllOnesConstant(DL, WideMaskVT);
5146     MVT EVLVT = TLI.getVPExplicitVectorLengthTy();
5147     unsigned NumVTElts = LdVT.getVectorMinNumElements();
5148     SDValue EVL =
5149         DAG.getVScale(DL, EVLVT, APInt(EVLVT.getScalarSizeInBits(), NumVTElts));
5150     const auto *MMO = LD->getMemOperand();
5151     SDValue NewLoad =
5152         DAG.getLoadVP(WideVT, DL, LD->getChain(), LD->getBasePtr(), Mask, EVL,
5153                       MMO->getPointerInfo(), MMO->getAlign(), MMO->getFlags(),
5154                       MMO->getAAInfo());
5155 
5156     // Modified the chain - switch anything that used the old chain to use
5157     // the new one.
5158     ReplaceValueWith(SDValue(N, 1), NewLoad.getValue(1));
5159 
5160     return NewLoad;
5161   }
5162 
5163   report_fatal_error("Unable to widen vector load");
5164 }
5165 
WidenVecRes_VP_LOAD(VPLoadSDNode * N)5166 SDValue DAGTypeLegalizer::WidenVecRes_VP_LOAD(VPLoadSDNode *N) {
5167   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5168   SDValue Mask = N->getMask();
5169   SDValue EVL = N->getVectorLength();
5170   ISD::LoadExtType ExtType = N->getExtensionType();
5171   SDLoc dl(N);
5172 
5173   // The mask should be widened as well
5174   assert(getTypeAction(Mask.getValueType()) ==
5175              TargetLowering::TypeWidenVector &&
5176          "Unable to widen binary VP op");
5177   Mask = GetWidenedVector(Mask);
5178   assert(Mask.getValueType().getVectorElementCount() ==
5179              TLI.getTypeToTransformTo(*DAG.getContext(), Mask.getValueType())
5180                  .getVectorElementCount() &&
5181          "Unable to widen vector load");
5182 
5183   SDValue Res =
5184       DAG.getLoadVP(N->getAddressingMode(), ExtType, WidenVT, dl, N->getChain(),
5185                     N->getBasePtr(), N->getOffset(), Mask, EVL,
5186                     N->getMemoryVT(), N->getMemOperand(), N->isExpandingLoad());
5187   // Legalize the chain result - switch anything that used the old chain to
5188   // use the new one.
5189   ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
5190   return Res;
5191 }
5192 
WidenVecRes_VP_STRIDED_LOAD(VPStridedLoadSDNode * N)5193 SDValue DAGTypeLegalizer::WidenVecRes_VP_STRIDED_LOAD(VPStridedLoadSDNode *N) {
5194   SDLoc DL(N);
5195 
5196   // The mask should be widened as well
5197   SDValue Mask = N->getMask();
5198   assert(getTypeAction(Mask.getValueType()) ==
5199              TargetLowering::TypeWidenVector &&
5200          "Unable to widen VP strided load");
5201   Mask = GetWidenedVector(Mask);
5202 
5203   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5204   assert(Mask.getValueType().getVectorElementCount() ==
5205              WidenVT.getVectorElementCount() &&
5206          "Data and mask vectors should have the same number of elements");
5207 
5208   SDValue Res = DAG.getStridedLoadVP(
5209       N->getAddressingMode(), N->getExtensionType(), WidenVT, DL, N->getChain(),
5210       N->getBasePtr(), N->getOffset(), N->getStride(), Mask,
5211       N->getVectorLength(), N->getMemoryVT(), N->getMemOperand(),
5212       N->isExpandingLoad());
5213 
5214   // Legalize the chain result - switch anything that used the old chain to
5215   // use the new one.
5216   ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
5217   return Res;
5218 }
5219 
WidenVecRes_MLOAD(MaskedLoadSDNode * N)5220 SDValue DAGTypeLegalizer::WidenVecRes_MLOAD(MaskedLoadSDNode *N) {
5221 
5222   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),N->getValueType(0));
5223   SDValue Mask = N->getMask();
5224   EVT MaskVT = Mask.getValueType();
5225   SDValue PassThru = GetWidenedVector(N->getPassThru());
5226   ISD::LoadExtType ExtType = N->getExtensionType();
5227   SDLoc dl(N);
5228 
5229   // The mask should be widened as well
5230   EVT WideMaskVT = EVT::getVectorVT(*DAG.getContext(),
5231                                     MaskVT.getVectorElementType(),
5232                                     WidenVT.getVectorNumElements());
5233   Mask = ModifyToType(Mask, WideMaskVT, true);
5234 
5235   SDValue Res = DAG.getMaskedLoad(
5236       WidenVT, dl, N->getChain(), N->getBasePtr(), N->getOffset(), Mask,
5237       PassThru, N->getMemoryVT(), N->getMemOperand(), N->getAddressingMode(),
5238       ExtType, N->isExpandingLoad());
5239   // Legalize the chain result - switch anything that used the old chain to
5240   // use the new one.
5241   ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
5242   return Res;
5243 }
5244 
WidenVecRes_MGATHER(MaskedGatherSDNode * N)5245 SDValue DAGTypeLegalizer::WidenVecRes_MGATHER(MaskedGatherSDNode *N) {
5246 
5247   EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5248   SDValue Mask = N->getMask();
5249   EVT MaskVT = Mask.getValueType();
5250   SDValue PassThru = GetWidenedVector(N->getPassThru());
5251   SDValue Scale = N->getScale();
5252   unsigned NumElts = WideVT.getVectorNumElements();
5253   SDLoc dl(N);
5254 
5255   // The mask should be widened as well
5256   EVT WideMaskVT = EVT::getVectorVT(*DAG.getContext(),
5257                                     MaskVT.getVectorElementType(),
5258                                     WideVT.getVectorNumElements());
5259   Mask = ModifyToType(Mask, WideMaskVT, true);
5260 
5261   // Widen the Index operand
5262   SDValue Index = N->getIndex();
5263   EVT WideIndexVT = EVT::getVectorVT(*DAG.getContext(),
5264                                      Index.getValueType().getScalarType(),
5265                                      NumElts);
5266   Index = ModifyToType(Index, WideIndexVT);
5267   SDValue Ops[] = { N->getChain(), PassThru, Mask, N->getBasePtr(), Index,
5268                     Scale };
5269 
5270   // Widen the MemoryType
5271   EVT WideMemVT = EVT::getVectorVT(*DAG.getContext(),
5272                                    N->getMemoryVT().getScalarType(), NumElts);
5273   SDValue Res = DAG.getMaskedGather(DAG.getVTList(WideVT, MVT::Other),
5274                                     WideMemVT, dl, Ops, N->getMemOperand(),
5275                                     N->getIndexType(), N->getExtensionType());
5276 
5277   // Legalize the chain result - switch anything that used the old chain to
5278   // use the new one.
5279   ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
5280   return Res;
5281 }
5282 
WidenVecRes_VP_GATHER(VPGatherSDNode * N)5283 SDValue DAGTypeLegalizer::WidenVecRes_VP_GATHER(VPGatherSDNode *N) {
5284   EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5285   SDValue Mask = N->getMask();
5286   SDValue Scale = N->getScale();
5287   ElementCount WideEC = WideVT.getVectorElementCount();
5288   SDLoc dl(N);
5289 
5290   SDValue Index = GetWidenedVector(N->getIndex());
5291   EVT WideMemVT = EVT::getVectorVT(*DAG.getContext(),
5292                                    N->getMemoryVT().getScalarType(), WideEC);
5293   Mask = GetWidenedMask(Mask, WideEC);
5294 
5295   SDValue Ops[] = {N->getChain(), N->getBasePtr(),     Index, Scale,
5296                    Mask,          N->getVectorLength()};
5297   SDValue Res = DAG.getGatherVP(DAG.getVTList(WideVT, MVT::Other), WideMemVT,
5298                                 dl, Ops, N->getMemOperand(), N->getIndexType());
5299 
5300   // Legalize the chain result - switch anything that used the old chain to
5301   // use the new one.
5302   ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
5303   return Res;
5304 }
5305 
WidenVecRes_ScalarOp(SDNode * N)5306 SDValue DAGTypeLegalizer::WidenVecRes_ScalarOp(SDNode *N) {
5307   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5308   return DAG.getNode(N->getOpcode(), SDLoc(N), WidenVT, N->getOperand(0));
5309 }
5310 
5311 // Return true is this is a SETCC node or a strict version of it.
isSETCCOp(unsigned Opcode)5312 static inline bool isSETCCOp(unsigned Opcode) {
5313   switch (Opcode) {
5314   case ISD::SETCC:
5315   case ISD::STRICT_FSETCC:
5316   case ISD::STRICT_FSETCCS:
5317     return true;
5318   }
5319   return false;
5320 }
5321 
5322 // Return true if this is a node that could have two SETCCs as operands.
isLogicalMaskOp(unsigned Opcode)5323 static inline bool isLogicalMaskOp(unsigned Opcode) {
5324   switch (Opcode) {
5325   case ISD::AND:
5326   case ISD::OR:
5327   case ISD::XOR:
5328     return true;
5329   }
5330   return false;
5331 }
5332 
5333 // If N is a SETCC or a strict variant of it, return the type
5334 // of the compare operands.
getSETCCOperandType(SDValue N)5335 static inline EVT getSETCCOperandType(SDValue N) {
5336   unsigned OpNo = N->isStrictFPOpcode() ? 1 : 0;
5337   return N->getOperand(OpNo).getValueType();
5338 }
5339 
5340 // This is used just for the assert in convertMask(). Check that this either
5341 // a SETCC or a previously handled SETCC by convertMask().
5342 #ifndef NDEBUG
isSETCCorConvertedSETCC(SDValue N)5343 static inline bool isSETCCorConvertedSETCC(SDValue N) {
5344   if (N.getOpcode() == ISD::EXTRACT_SUBVECTOR)
5345     N = N.getOperand(0);
5346   else if (N.getOpcode() == ISD::CONCAT_VECTORS) {
5347     for (unsigned i = 1; i < N->getNumOperands(); ++i)
5348       if (!N->getOperand(i)->isUndef())
5349         return false;
5350     N = N.getOperand(0);
5351   }
5352 
5353   if (N.getOpcode() == ISD::TRUNCATE)
5354     N = N.getOperand(0);
5355   else if (N.getOpcode() == ISD::SIGN_EXTEND)
5356     N = N.getOperand(0);
5357 
5358   if (isLogicalMaskOp(N.getOpcode()))
5359     return isSETCCorConvertedSETCC(N.getOperand(0)) &&
5360            isSETCCorConvertedSETCC(N.getOperand(1));
5361 
5362   return (isSETCCOp(N.getOpcode()) ||
5363           ISD::isBuildVectorOfConstantSDNodes(N.getNode()));
5364 }
5365 #endif
5366 
5367 // Return a mask of vector type MaskVT to replace InMask. Also adjust MaskVT
5368 // to ToMaskVT if needed with vector extension or truncation.
convertMask(SDValue InMask,EVT MaskVT,EVT ToMaskVT)5369 SDValue DAGTypeLegalizer::convertMask(SDValue InMask, EVT MaskVT,
5370                                       EVT ToMaskVT) {
5371   // Currently a SETCC or a AND/OR/XOR with two SETCCs are handled.
5372   // FIXME: This code seems to be too restrictive, we might consider
5373   // generalizing it or dropping it.
5374   assert(isSETCCorConvertedSETCC(InMask) && "Unexpected mask argument.");
5375 
5376   // Make a new Mask node, with a legal result VT.
5377   SDValue Mask;
5378   SmallVector<SDValue, 4> Ops;
5379   for (unsigned i = 0, e = InMask->getNumOperands(); i < e; ++i)
5380     Ops.push_back(InMask->getOperand(i));
5381   if (InMask->isStrictFPOpcode()) {
5382     Mask = DAG.getNode(InMask->getOpcode(), SDLoc(InMask),
5383                        { MaskVT, MVT::Other }, Ops);
5384     ReplaceValueWith(InMask.getValue(1), Mask.getValue(1));
5385   }
5386   else
5387     Mask = DAG.getNode(InMask->getOpcode(), SDLoc(InMask), MaskVT, Ops);
5388 
5389   // If MaskVT has smaller or bigger elements than ToMaskVT, a vector sign
5390   // extend or truncate is needed.
5391   LLVMContext &Ctx = *DAG.getContext();
5392   unsigned MaskScalarBits = MaskVT.getScalarSizeInBits();
5393   unsigned ToMaskScalBits = ToMaskVT.getScalarSizeInBits();
5394   if (MaskScalarBits < ToMaskScalBits) {
5395     EVT ExtVT = EVT::getVectorVT(Ctx, ToMaskVT.getVectorElementType(),
5396                                  MaskVT.getVectorNumElements());
5397     Mask = DAG.getNode(ISD::SIGN_EXTEND, SDLoc(Mask), ExtVT, Mask);
5398   } else if (MaskScalarBits > ToMaskScalBits) {
5399     EVT TruncVT = EVT::getVectorVT(Ctx, ToMaskVT.getVectorElementType(),
5400                                    MaskVT.getVectorNumElements());
5401     Mask = DAG.getNode(ISD::TRUNCATE, SDLoc(Mask), TruncVT, Mask);
5402   }
5403 
5404   assert(Mask->getValueType(0).getScalarSizeInBits() ==
5405              ToMaskVT.getScalarSizeInBits() &&
5406          "Mask should have the right element size by now.");
5407 
5408   // Adjust Mask to the right number of elements.
5409   unsigned CurrMaskNumEls = Mask->getValueType(0).getVectorNumElements();
5410   if (CurrMaskNumEls > ToMaskVT.getVectorNumElements()) {
5411     SDValue ZeroIdx = DAG.getVectorIdxConstant(0, SDLoc(Mask));
5412     Mask = DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(Mask), ToMaskVT, Mask,
5413                        ZeroIdx);
5414   } else if (CurrMaskNumEls < ToMaskVT.getVectorNumElements()) {
5415     unsigned NumSubVecs = (ToMaskVT.getVectorNumElements() / CurrMaskNumEls);
5416     EVT SubVT = Mask->getValueType(0);
5417     SmallVector<SDValue, 16> SubOps(NumSubVecs, DAG.getUNDEF(SubVT));
5418     SubOps[0] = Mask;
5419     Mask = DAG.getNode(ISD::CONCAT_VECTORS, SDLoc(Mask), ToMaskVT, SubOps);
5420   }
5421 
5422   assert((Mask->getValueType(0) == ToMaskVT) &&
5423          "A mask of ToMaskVT should have been produced by now.");
5424 
5425   return Mask;
5426 }
5427 
5428 // This method tries to handle some special cases for the vselect mask
5429 // and if needed adjusting the mask vector type to match that of the VSELECT.
5430 // Without it, many cases end up with scalarization of the SETCC, with many
5431 // unnecessary instructions.
WidenVSELECTMask(SDNode * N)5432 SDValue DAGTypeLegalizer::WidenVSELECTMask(SDNode *N) {
5433   LLVMContext &Ctx = *DAG.getContext();
5434   SDValue Cond = N->getOperand(0);
5435 
5436   if (N->getOpcode() != ISD::VSELECT)
5437     return SDValue();
5438 
5439   if (!isSETCCOp(Cond->getOpcode()) && !isLogicalMaskOp(Cond->getOpcode()))
5440     return SDValue();
5441 
5442   // If this is a splitted VSELECT that was previously already handled, do
5443   // nothing.
5444   EVT CondVT = Cond->getValueType(0);
5445   if (CondVT.getScalarSizeInBits() != 1)
5446     return SDValue();
5447 
5448   EVT VSelVT = N->getValueType(0);
5449 
5450   // This method can't handle scalable vector types.
5451   // FIXME: This support could be added in the future.
5452   if (VSelVT.isScalableVector())
5453     return SDValue();
5454 
5455   // Only handle vector types which are a power of 2.
5456   if (!isPowerOf2_64(VSelVT.getSizeInBits()))
5457     return SDValue();
5458 
5459   // Don't touch if this will be scalarized.
5460   EVT FinalVT = VSelVT;
5461   while (getTypeAction(FinalVT) == TargetLowering::TypeSplitVector)
5462     FinalVT = FinalVT.getHalfNumVectorElementsVT(Ctx);
5463 
5464   if (FinalVT.getVectorNumElements() == 1)
5465     return SDValue();
5466 
5467   // If there is support for an i1 vector mask, don't touch.
5468   if (isSETCCOp(Cond.getOpcode())) {
5469     EVT SetCCOpVT = getSETCCOperandType(Cond);
5470     while (TLI.getTypeAction(Ctx, SetCCOpVT) != TargetLowering::TypeLegal)
5471       SetCCOpVT = TLI.getTypeToTransformTo(Ctx, SetCCOpVT);
5472     EVT SetCCResVT = getSetCCResultType(SetCCOpVT);
5473     if (SetCCResVT.getScalarSizeInBits() == 1)
5474       return SDValue();
5475   } else if (CondVT.getScalarType() == MVT::i1) {
5476     // If there is support for an i1 vector mask (or only scalar i1 conditions),
5477     // don't touch.
5478     while (TLI.getTypeAction(Ctx, CondVT) != TargetLowering::TypeLegal)
5479       CondVT = TLI.getTypeToTransformTo(Ctx, CondVT);
5480 
5481     if (CondVT.getScalarType() == MVT::i1)
5482       return SDValue();
5483   }
5484 
5485   // Widen the vselect result type if needed.
5486   if (getTypeAction(VSelVT) == TargetLowering::TypeWidenVector)
5487     VSelVT = TLI.getTypeToTransformTo(Ctx, VSelVT);
5488 
5489   // The mask of the VSELECT should have integer elements.
5490   EVT ToMaskVT = VSelVT;
5491   if (!ToMaskVT.getScalarType().isInteger())
5492     ToMaskVT = ToMaskVT.changeVectorElementTypeToInteger();
5493 
5494   SDValue Mask;
5495   if (isSETCCOp(Cond->getOpcode())) {
5496     EVT MaskVT = getSetCCResultType(getSETCCOperandType(Cond));
5497     Mask = convertMask(Cond, MaskVT, ToMaskVT);
5498   } else if (isLogicalMaskOp(Cond->getOpcode()) &&
5499              isSETCCOp(Cond->getOperand(0).getOpcode()) &&
5500              isSETCCOp(Cond->getOperand(1).getOpcode())) {
5501     // Cond is (AND/OR/XOR (SETCC, SETCC))
5502     SDValue SETCC0 = Cond->getOperand(0);
5503     SDValue SETCC1 = Cond->getOperand(1);
5504     EVT VT0 = getSetCCResultType(getSETCCOperandType(SETCC0));
5505     EVT VT1 = getSetCCResultType(getSETCCOperandType(SETCC1));
5506     unsigned ScalarBits0 = VT0.getScalarSizeInBits();
5507     unsigned ScalarBits1 = VT1.getScalarSizeInBits();
5508     unsigned ScalarBits_ToMask = ToMaskVT.getScalarSizeInBits();
5509     EVT MaskVT;
5510     // If the two SETCCs have different VTs, either extend/truncate one of
5511     // them to the other "towards" ToMaskVT, or truncate one and extend the
5512     // other to ToMaskVT.
5513     if (ScalarBits0 != ScalarBits1) {
5514       EVT NarrowVT = ((ScalarBits0 < ScalarBits1) ? VT0 : VT1);
5515       EVT WideVT = ((NarrowVT == VT0) ? VT1 : VT0);
5516       if (ScalarBits_ToMask >= WideVT.getScalarSizeInBits())
5517         MaskVT = WideVT;
5518       else if (ScalarBits_ToMask <= NarrowVT.getScalarSizeInBits())
5519         MaskVT = NarrowVT;
5520       else
5521         MaskVT = ToMaskVT;
5522     } else
5523       // If the two SETCCs have the same VT, don't change it.
5524       MaskVT = VT0;
5525 
5526     // Make new SETCCs and logical nodes.
5527     SETCC0 = convertMask(SETCC0, VT0, MaskVT);
5528     SETCC1 = convertMask(SETCC1, VT1, MaskVT);
5529     Cond = DAG.getNode(Cond->getOpcode(), SDLoc(Cond), MaskVT, SETCC0, SETCC1);
5530 
5531     // Convert the logical op for VSELECT if needed.
5532     Mask = convertMask(Cond, MaskVT, ToMaskVT);
5533   } else
5534     return SDValue();
5535 
5536   return Mask;
5537 }
5538 
WidenVecRes_Select(SDNode * N)5539 SDValue DAGTypeLegalizer::WidenVecRes_Select(SDNode *N) {
5540   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5541   ElementCount WidenEC = WidenVT.getVectorElementCount();
5542 
5543   SDValue Cond1 = N->getOperand(0);
5544   EVT CondVT = Cond1.getValueType();
5545   unsigned Opcode = N->getOpcode();
5546   if (CondVT.isVector()) {
5547     if (SDValue WideCond = WidenVSELECTMask(N)) {
5548       SDValue InOp1 = GetWidenedVector(N->getOperand(1));
5549       SDValue InOp2 = GetWidenedVector(N->getOperand(2));
5550       assert(InOp1.getValueType() == WidenVT && InOp2.getValueType() == WidenVT);
5551       return DAG.getNode(Opcode, SDLoc(N), WidenVT, WideCond, InOp1, InOp2);
5552     }
5553 
5554     EVT CondEltVT = CondVT.getVectorElementType();
5555     EVT CondWidenVT = EVT::getVectorVT(*DAG.getContext(), CondEltVT, WidenEC);
5556     if (getTypeAction(CondVT) == TargetLowering::TypeWidenVector)
5557       Cond1 = GetWidenedVector(Cond1);
5558 
5559     // If we have to split the condition there is no point in widening the
5560     // select. This would result in an cycle of widening the select ->
5561     // widening the condition operand -> splitting the condition operand ->
5562     // splitting the select -> widening the select. Instead split this select
5563     // further and widen the resulting type.
5564     if (getTypeAction(CondVT) == TargetLowering::TypeSplitVector) {
5565       SDValue SplitSelect = SplitVecOp_VSELECT(N, 0);
5566       SDValue Res = ModifyToType(SplitSelect, WidenVT);
5567       return Res;
5568     }
5569 
5570     if (Cond1.getValueType() != CondWidenVT)
5571       Cond1 = ModifyToType(Cond1, CondWidenVT);
5572   }
5573 
5574   SDValue InOp1 = GetWidenedVector(N->getOperand(1));
5575   SDValue InOp2 = GetWidenedVector(N->getOperand(2));
5576   assert(InOp1.getValueType() == WidenVT && InOp2.getValueType() == WidenVT);
5577   if (Opcode == ISD::VP_SELECT || Opcode == ISD::VP_MERGE)
5578     return DAG.getNode(Opcode, SDLoc(N), WidenVT, Cond1, InOp1, InOp2,
5579                        N->getOperand(3));
5580   return DAG.getNode(Opcode, SDLoc(N), WidenVT, Cond1, InOp1, InOp2);
5581 }
5582 
WidenVecRes_SELECT_CC(SDNode * N)5583 SDValue DAGTypeLegalizer::WidenVecRes_SELECT_CC(SDNode *N) {
5584   SDValue InOp1 = GetWidenedVector(N->getOperand(2));
5585   SDValue InOp2 = GetWidenedVector(N->getOperand(3));
5586   return DAG.getNode(ISD::SELECT_CC, SDLoc(N),
5587                      InOp1.getValueType(), N->getOperand(0),
5588                      N->getOperand(1), InOp1, InOp2, N->getOperand(4));
5589 }
5590 
WidenVecRes_UNDEF(SDNode * N)5591 SDValue DAGTypeLegalizer::WidenVecRes_UNDEF(SDNode *N) {
5592  EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5593  return DAG.getUNDEF(WidenVT);
5594 }
5595 
WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode * N)5596 SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N) {
5597   EVT VT = N->getValueType(0);
5598   SDLoc dl(N);
5599 
5600   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5601   unsigned NumElts = VT.getVectorNumElements();
5602   unsigned WidenNumElts = WidenVT.getVectorNumElements();
5603 
5604   SDValue InOp1 = GetWidenedVector(N->getOperand(0));
5605   SDValue InOp2 = GetWidenedVector(N->getOperand(1));
5606 
5607   // Adjust mask based on new input vector length.
5608   SmallVector<int, 16> NewMask;
5609   for (unsigned i = 0; i != NumElts; ++i) {
5610     int Idx = N->getMaskElt(i);
5611     if (Idx < (int)NumElts)
5612       NewMask.push_back(Idx);
5613     else
5614       NewMask.push_back(Idx - NumElts + WidenNumElts);
5615   }
5616   for (unsigned i = NumElts; i != WidenNumElts; ++i)
5617     NewMask.push_back(-1);
5618   return DAG.getVectorShuffle(WidenVT, dl, InOp1, InOp2, NewMask);
5619 }
5620 
WidenVecRes_VECTOR_REVERSE(SDNode * N)5621 SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_REVERSE(SDNode *N) {
5622   EVT VT = N->getValueType(0);
5623   EVT EltVT = VT.getVectorElementType();
5624   SDLoc dl(N);
5625 
5626   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5627   SDValue OpValue = GetWidenedVector(N->getOperand(0));
5628   assert(WidenVT == OpValue.getValueType() && "Unexpected widened vector type");
5629 
5630   SDValue ReverseVal = DAG.getNode(ISD::VECTOR_REVERSE, dl, WidenVT, OpValue);
5631   unsigned WidenNumElts = WidenVT.getVectorMinNumElements();
5632   unsigned VTNumElts = VT.getVectorMinNumElements();
5633   unsigned IdxVal = WidenNumElts - VTNumElts;
5634 
5635   if (VT.isScalableVector()) {
5636     // Try to split the 'Widen ReverseVal' into smaller extracts and concat the
5637     // results together, e.g.(nxv6i64 -> nxv8i64)
5638     //    nxv8i64 vector_reverse
5639     // <->
5640     //  nxv8i64 concat(
5641     //    nxv2i64 extract_subvector(nxv8i64, 2)
5642     //    nxv2i64 extract_subvector(nxv8i64, 4)
5643     //    nxv2i64 extract_subvector(nxv8i64, 6)
5644     //    nxv2i64 undef)
5645 
5646     unsigned GCD = std::gcd(VTNumElts, WidenNumElts);
5647     EVT PartVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
5648                                   ElementCount::getScalable(GCD));
5649     assert((IdxVal % GCD) == 0 && "Expected Idx to be a multiple of the broken "
5650                                   "down type's element count");
5651     SmallVector<SDValue> Parts;
5652     unsigned i = 0;
5653     for (; i < VTNumElts / GCD; ++i)
5654       Parts.push_back(
5655           DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, PartVT, ReverseVal,
5656                       DAG.getVectorIdxConstant(IdxVal + i * GCD, dl)));
5657     for (; i < WidenNumElts / GCD; ++i)
5658       Parts.push_back(DAG.getUNDEF(PartVT));
5659 
5660     return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, Parts);
5661   }
5662 
5663   // Use VECTOR_SHUFFLE to combine new vector from 'ReverseVal' for
5664   // fixed-vectors.
5665   SmallVector<int, 16> Mask;
5666   for (unsigned i = 0; i != VTNumElts; ++i) {
5667     Mask.push_back(IdxVal + i);
5668   }
5669   for (unsigned i = VTNumElts; i != WidenNumElts; ++i)
5670     Mask.push_back(-1);
5671 
5672   return DAG.getVectorShuffle(WidenVT, dl, ReverseVal, DAG.getUNDEF(WidenVT),
5673                               Mask);
5674 }
5675 
WidenVecRes_SETCC(SDNode * N)5676 SDValue DAGTypeLegalizer::WidenVecRes_SETCC(SDNode *N) {
5677   assert(N->getValueType(0).isVector() &&
5678          N->getOperand(0).getValueType().isVector() &&
5679          "Operands must be vectors");
5680   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
5681   ElementCount WidenEC = WidenVT.getVectorElementCount();
5682 
5683   SDValue InOp1 = N->getOperand(0);
5684   EVT InVT = InOp1.getValueType();
5685   assert(InVT.isVector() && "can not widen non-vector type");
5686   EVT WidenInVT =
5687       EVT::getVectorVT(*DAG.getContext(), InVT.getVectorElementType(), WidenEC);
5688 
5689   // The input and output types often differ here, and it could be that while
5690   // we'd prefer to widen the result type, the input operands have been split.
5691   // In this case, we also need to split the result of this node as well.
5692   if (getTypeAction(InVT) == TargetLowering::TypeSplitVector) {
5693     SDValue SplitVSetCC = SplitVecOp_VSETCC(N);
5694     SDValue Res = ModifyToType(SplitVSetCC, WidenVT);
5695     return Res;
5696   }
5697 
5698   // If the inputs also widen, handle them directly. Otherwise widen by hand.
5699   SDValue InOp2 = N->getOperand(1);
5700   if (getTypeAction(InVT) == TargetLowering::TypeWidenVector) {
5701     InOp1 = GetWidenedVector(InOp1);
5702     InOp2 = GetWidenedVector(InOp2);
5703   } else {
5704     InOp1 = DAG.WidenVector(InOp1, SDLoc(N));
5705     InOp2 = DAG.WidenVector(InOp2, SDLoc(N));
5706   }
5707 
5708   // Assume that the input and output will be widen appropriately.  If not,
5709   // we will have to unroll it at some point.
5710   assert(InOp1.getValueType() == WidenInVT &&
5711          InOp2.getValueType() == WidenInVT &&
5712          "Input not widened to expected type!");
5713   (void)WidenInVT;
5714   if (N->getOpcode() == ISD::VP_SETCC) {
5715     SDValue Mask =
5716         GetWidenedMask(N->getOperand(3), WidenVT.getVectorElementCount());
5717     return DAG.getNode(ISD::VP_SETCC, SDLoc(N), WidenVT, InOp1, InOp2,
5718                        N->getOperand(2), Mask, N->getOperand(4));
5719   }
5720   return DAG.getNode(ISD::SETCC, SDLoc(N), WidenVT, InOp1, InOp2,
5721                      N->getOperand(2));
5722 }
5723 
WidenVecRes_STRICT_FSETCC(SDNode * N)5724 SDValue DAGTypeLegalizer::WidenVecRes_STRICT_FSETCC(SDNode *N) {
5725   assert(N->getValueType(0).isVector() &&
5726          N->getOperand(1).getValueType().isVector() &&
5727          "Operands must be vectors");
5728   EVT VT = N->getValueType(0);
5729   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
5730   unsigned WidenNumElts = WidenVT.getVectorNumElements();
5731   unsigned NumElts = VT.getVectorNumElements();
5732   EVT EltVT = VT.getVectorElementType();
5733 
5734   SDLoc dl(N);
5735   SDValue Chain = N->getOperand(0);
5736   SDValue LHS = N->getOperand(1);
5737   SDValue RHS = N->getOperand(2);
5738   SDValue CC = N->getOperand(3);
5739   EVT TmpEltVT = LHS.getValueType().getVectorElementType();
5740 
5741   // Fully unroll and reassemble.
5742   SmallVector<SDValue, 8> Scalars(WidenNumElts, DAG.getUNDEF(EltVT));
5743   SmallVector<SDValue, 8> Chains(NumElts);
5744   for (unsigned i = 0; i != NumElts; ++i) {
5745     SDValue LHSElem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, LHS,
5746                                   DAG.getVectorIdxConstant(i, dl));
5747     SDValue RHSElem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, RHS,
5748                                   DAG.getVectorIdxConstant(i, dl));
5749 
5750     Scalars[i] = DAG.getNode(N->getOpcode(), dl, {MVT::i1, MVT::Other},
5751                              {Chain, LHSElem, RHSElem, CC});
5752     Chains[i] = Scalars[i].getValue(1);
5753     Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
5754                                DAG.getBoolConstant(true, dl, EltVT, VT),
5755                                DAG.getBoolConstant(false, dl, EltVT, VT));
5756   }
5757 
5758   SDValue NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Chains);
5759   ReplaceValueWith(SDValue(N, 1), NewChain);
5760 
5761   return DAG.getBuildVector(WidenVT, dl, Scalars);
5762 }
5763 
5764 //===----------------------------------------------------------------------===//
5765 // Widen Vector Operand
5766 //===----------------------------------------------------------------------===//
WidenVectorOperand(SDNode * N,unsigned OpNo)5767 bool DAGTypeLegalizer::WidenVectorOperand(SDNode *N, unsigned OpNo) {
5768   LLVM_DEBUG(dbgs() << "Widen node operand " << OpNo << ": "; N->dump(&DAG);
5769              dbgs() << "\n");
5770   SDValue Res = SDValue();
5771 
5772   // See if the target wants to custom widen this node.
5773   if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
5774     return false;
5775 
5776   switch (N->getOpcode()) {
5777   default:
5778 #ifndef NDEBUG
5779     dbgs() << "WidenVectorOperand op #" << OpNo << ": ";
5780     N->dump(&DAG);
5781     dbgs() << "\n";
5782 #endif
5783     llvm_unreachable("Do not know how to widen this operator's operand!");
5784 
5785   case ISD::BITCAST:            Res = WidenVecOp_BITCAST(N); break;
5786   case ISD::CONCAT_VECTORS:     Res = WidenVecOp_CONCAT_VECTORS(N); break;
5787   case ISD::INSERT_SUBVECTOR:   Res = WidenVecOp_INSERT_SUBVECTOR(N); break;
5788   case ISD::EXTRACT_SUBVECTOR:  Res = WidenVecOp_EXTRACT_SUBVECTOR(N); break;
5789   case ISD::EXTRACT_VECTOR_ELT: Res = WidenVecOp_EXTRACT_VECTOR_ELT(N); break;
5790   case ISD::STORE:              Res = WidenVecOp_STORE(N); break;
5791   case ISD::VP_STORE:           Res = WidenVecOp_VP_STORE(N, OpNo); break;
5792   case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
5793     Res = WidenVecOp_VP_STRIDED_STORE(N, OpNo);
5794     break;
5795   case ISD::MSTORE:             Res = WidenVecOp_MSTORE(N, OpNo); break;
5796   case ISD::MGATHER:            Res = WidenVecOp_MGATHER(N, OpNo); break;
5797   case ISD::MSCATTER:           Res = WidenVecOp_MSCATTER(N, OpNo); break;
5798   case ISD::VP_SCATTER:         Res = WidenVecOp_VP_SCATTER(N, OpNo); break;
5799   case ISD::SETCC:              Res = WidenVecOp_SETCC(N); break;
5800   case ISD::STRICT_FSETCC:
5801   case ISD::STRICT_FSETCCS:     Res = WidenVecOp_STRICT_FSETCC(N); break;
5802   case ISD::VSELECT:            Res = WidenVecOp_VSELECT(N); break;
5803   case ISD::FCOPYSIGN:          Res = WidenVecOp_FCOPYSIGN(N); break;
5804   case ISD::IS_FPCLASS:         Res = WidenVecOp_IS_FPCLASS(N); break;
5805 
5806   case ISD::ANY_EXTEND:
5807   case ISD::SIGN_EXTEND:
5808   case ISD::ZERO_EXTEND:
5809     Res = WidenVecOp_EXTEND(N);
5810     break;
5811 
5812   case ISD::FP_EXTEND:
5813   case ISD::STRICT_FP_EXTEND:
5814   case ISD::FP_ROUND:
5815   case ISD::STRICT_FP_ROUND:
5816   case ISD::FP_TO_SINT:
5817   case ISD::STRICT_FP_TO_SINT:
5818   case ISD::FP_TO_UINT:
5819   case ISD::STRICT_FP_TO_UINT:
5820   case ISD::SINT_TO_FP:
5821   case ISD::STRICT_SINT_TO_FP:
5822   case ISD::UINT_TO_FP:
5823   case ISD::STRICT_UINT_TO_FP:
5824   case ISD::TRUNCATE:
5825     Res = WidenVecOp_Convert(N);
5826     break;
5827 
5828   case ISD::FP_TO_SINT_SAT:
5829   case ISD::FP_TO_UINT_SAT:
5830     Res = WidenVecOp_FP_TO_XINT_SAT(N);
5831     break;
5832 
5833   case ISD::VECREDUCE_FADD:
5834   case ISD::VECREDUCE_FMUL:
5835   case ISD::VECREDUCE_ADD:
5836   case ISD::VECREDUCE_MUL:
5837   case ISD::VECREDUCE_AND:
5838   case ISD::VECREDUCE_OR:
5839   case ISD::VECREDUCE_XOR:
5840   case ISD::VECREDUCE_SMAX:
5841   case ISD::VECREDUCE_SMIN:
5842   case ISD::VECREDUCE_UMAX:
5843   case ISD::VECREDUCE_UMIN:
5844   case ISD::VECREDUCE_FMAX:
5845   case ISD::VECREDUCE_FMIN:
5846     Res = WidenVecOp_VECREDUCE(N);
5847     break;
5848   case ISD::VECREDUCE_SEQ_FADD:
5849   case ISD::VECREDUCE_SEQ_FMUL:
5850     Res = WidenVecOp_VECREDUCE_SEQ(N);
5851     break;
5852   case ISD::VP_REDUCE_FADD:
5853   case ISD::VP_REDUCE_SEQ_FADD:
5854   case ISD::VP_REDUCE_FMUL:
5855   case ISD::VP_REDUCE_SEQ_FMUL:
5856   case ISD::VP_REDUCE_ADD:
5857   case ISD::VP_REDUCE_MUL:
5858   case ISD::VP_REDUCE_AND:
5859   case ISD::VP_REDUCE_OR:
5860   case ISD::VP_REDUCE_XOR:
5861   case ISD::VP_REDUCE_SMAX:
5862   case ISD::VP_REDUCE_SMIN:
5863   case ISD::VP_REDUCE_UMAX:
5864   case ISD::VP_REDUCE_UMIN:
5865   case ISD::VP_REDUCE_FMAX:
5866   case ISD::VP_REDUCE_FMIN:
5867     Res = WidenVecOp_VP_REDUCE(N);
5868     break;
5869   }
5870 
5871   // If Res is null, the sub-method took care of registering the result.
5872   if (!Res.getNode()) return false;
5873 
5874   // If the result is N, the sub-method updated N in place.  Tell the legalizer
5875   // core about this.
5876   if (Res.getNode() == N)
5877     return true;
5878 
5879 
5880   if (N->isStrictFPOpcode())
5881     assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 2 &&
5882            "Invalid operand expansion");
5883   else
5884     assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
5885            "Invalid operand expansion");
5886 
5887   ReplaceValueWith(SDValue(N, 0), Res);
5888   return false;
5889 }
5890 
WidenVecOp_EXTEND(SDNode * N)5891 SDValue DAGTypeLegalizer::WidenVecOp_EXTEND(SDNode *N) {
5892   SDLoc DL(N);
5893   EVT VT = N->getValueType(0);
5894 
5895   SDValue InOp = N->getOperand(0);
5896   assert(getTypeAction(InOp.getValueType()) ==
5897              TargetLowering::TypeWidenVector &&
5898          "Unexpected type action");
5899   InOp = GetWidenedVector(InOp);
5900   assert(VT.getVectorNumElements() <
5901              InOp.getValueType().getVectorNumElements() &&
5902          "Input wasn't widened!");
5903 
5904   // We may need to further widen the operand until it has the same total
5905   // vector size as the result.
5906   EVT InVT = InOp.getValueType();
5907   if (InVT.getSizeInBits() != VT.getSizeInBits()) {
5908     EVT InEltVT = InVT.getVectorElementType();
5909     for (EVT FixedVT : MVT::vector_valuetypes()) {
5910       EVT FixedEltVT = FixedVT.getVectorElementType();
5911       if (TLI.isTypeLegal(FixedVT) &&
5912           FixedVT.getSizeInBits() == VT.getSizeInBits() &&
5913           FixedEltVT == InEltVT) {
5914         assert(FixedVT.getVectorNumElements() >= VT.getVectorNumElements() &&
5915                "Not enough elements in the fixed type for the operand!");
5916         assert(FixedVT.getVectorNumElements() != InVT.getVectorNumElements() &&
5917                "We can't have the same type as we started with!");
5918         if (FixedVT.getVectorNumElements() > InVT.getVectorNumElements())
5919           InOp = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, FixedVT,
5920                              DAG.getUNDEF(FixedVT), InOp,
5921                              DAG.getVectorIdxConstant(0, DL));
5922         else
5923           InOp = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, FixedVT, InOp,
5924                              DAG.getVectorIdxConstant(0, DL));
5925         break;
5926       }
5927     }
5928     InVT = InOp.getValueType();
5929     if (InVT.getSizeInBits() != VT.getSizeInBits())
5930       // We couldn't find a legal vector type that was a widening of the input
5931       // and could be extended in-register to the result type, so we have to
5932       // scalarize.
5933       return WidenVecOp_Convert(N);
5934   }
5935 
5936   // Use special DAG nodes to represent the operation of extending the
5937   // low lanes.
5938   switch (N->getOpcode()) {
5939   default:
5940     llvm_unreachable("Extend legalization on extend operation!");
5941   case ISD::ANY_EXTEND:
5942     return DAG.getNode(ISD::ANY_EXTEND_VECTOR_INREG, DL, VT, InOp);
5943   case ISD::SIGN_EXTEND:
5944     return DAG.getNode(ISD::SIGN_EXTEND_VECTOR_INREG, DL, VT, InOp);
5945   case ISD::ZERO_EXTEND:
5946     return DAG.getNode(ISD::ZERO_EXTEND_VECTOR_INREG, DL, VT, InOp);
5947   }
5948 }
5949 
WidenVecOp_FCOPYSIGN(SDNode * N)5950 SDValue DAGTypeLegalizer::WidenVecOp_FCOPYSIGN(SDNode *N) {
5951   // The result (and first input) is legal, but the second input is illegal.
5952   // We can't do much to fix that, so just unroll and let the extracts off of
5953   // the second input be widened as needed later.
5954   return DAG.UnrollVectorOp(N);
5955 }
5956 
WidenVecOp_IS_FPCLASS(SDNode * N)5957 SDValue DAGTypeLegalizer::WidenVecOp_IS_FPCLASS(SDNode *N) {
5958   SDLoc DL(N);
5959   EVT ResultVT = N->getValueType(0);
5960   SDValue Test = N->getOperand(1);
5961   SDValue WideArg = GetWidenedVector(N->getOperand(0));
5962 
5963   // Process this node similarly to SETCC.
5964   EVT WideResultVT = getSetCCResultType(WideArg.getValueType());
5965   if (ResultVT.getScalarType() == MVT::i1)
5966     WideResultVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1,
5967                                     WideResultVT.getVectorNumElements());
5968 
5969   SDValue WideNode = DAG.getNode(ISD::IS_FPCLASS, DL, WideResultVT,
5970                                  {WideArg, Test}, N->getFlags());
5971 
5972   // Extract the needed results from the result vector.
5973   EVT ResVT =
5974       EVT::getVectorVT(*DAG.getContext(), WideResultVT.getVectorElementType(),
5975                        ResultVT.getVectorNumElements());
5976   SDValue CC = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ResVT, WideNode,
5977                            DAG.getVectorIdxConstant(0, DL));
5978 
5979   EVT OpVT = N->getOperand(0).getValueType();
5980   ISD::NodeType ExtendCode =
5981       TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT));
5982   return DAG.getNode(ExtendCode, DL, ResultVT, CC);
5983 }
5984 
WidenVecOp_Convert(SDNode * N)5985 SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) {
5986   // Since the result is legal and the input is illegal.
5987   EVT VT = N->getValueType(0);
5988   EVT EltVT = VT.getVectorElementType();
5989   SDLoc dl(N);
5990   SDValue InOp = N->getOperand(N->isStrictFPOpcode() ? 1 : 0);
5991   assert(getTypeAction(InOp.getValueType()) ==
5992              TargetLowering::TypeWidenVector &&
5993          "Unexpected type action");
5994   InOp = GetWidenedVector(InOp);
5995   EVT InVT = InOp.getValueType();
5996   unsigned Opcode = N->getOpcode();
5997 
5998   // See if a widened result type would be legal, if so widen the node.
5999   // FIXME: This isn't safe for StrictFP. Other optimization here is needed.
6000   EVT WideVT = EVT::getVectorVT(*DAG.getContext(), EltVT,
6001                                 InVT.getVectorElementCount());
6002   if (TLI.isTypeLegal(WideVT) && !N->isStrictFPOpcode()) {
6003     SDValue Res;
6004     if (N->isStrictFPOpcode()) {
6005       if (Opcode == ISD::STRICT_FP_ROUND)
6006         Res = DAG.getNode(Opcode, dl, { WideVT, MVT::Other },
6007                           { N->getOperand(0), InOp, N->getOperand(2) });
6008       else
6009         Res = DAG.getNode(Opcode, dl, { WideVT, MVT::Other },
6010                           { N->getOperand(0), InOp });
6011       // Legalize the chain result - switch anything that used the old chain to
6012       // use the new one.
6013       ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
6014     } else {
6015       if (Opcode == ISD::FP_ROUND)
6016         Res = DAG.getNode(Opcode, dl, WideVT, InOp, N->getOperand(1));
6017       else
6018         Res = DAG.getNode(Opcode, dl, WideVT, InOp);
6019     }
6020     return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, Res,
6021                        DAG.getVectorIdxConstant(0, dl));
6022   }
6023 
6024   EVT InEltVT = InVT.getVectorElementType();
6025 
6026   // Unroll the convert into some scalar code and create a nasty build vector.
6027   unsigned NumElts = VT.getVectorNumElements();
6028   SmallVector<SDValue, 16> Ops(NumElts);
6029   if (N->isStrictFPOpcode()) {
6030     SmallVector<SDValue, 4> NewOps(N->op_begin(), N->op_end());
6031     SmallVector<SDValue, 32> OpChains;
6032     for (unsigned i=0; i < NumElts; ++i) {
6033       NewOps[1] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp,
6034                               DAG.getVectorIdxConstant(i, dl));
6035       Ops[i] = DAG.getNode(Opcode, dl, { EltVT, MVT::Other }, NewOps);
6036       OpChains.push_back(Ops[i].getValue(1));
6037     }
6038     SDValue NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OpChains);
6039     ReplaceValueWith(SDValue(N, 1), NewChain);
6040   } else {
6041     for (unsigned i = 0; i < NumElts; ++i)
6042       Ops[i] = DAG.getNode(Opcode, dl, EltVT,
6043                            DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InEltVT,
6044                                        InOp, DAG.getVectorIdxConstant(i, dl)));
6045   }
6046 
6047   return DAG.getBuildVector(VT, dl, Ops);
6048 }
6049 
WidenVecOp_FP_TO_XINT_SAT(SDNode * N)6050 SDValue DAGTypeLegalizer::WidenVecOp_FP_TO_XINT_SAT(SDNode *N) {
6051   EVT DstVT = N->getValueType(0);
6052   SDValue Src = GetWidenedVector(N->getOperand(0));
6053   EVT SrcVT = Src.getValueType();
6054   ElementCount WideNumElts = SrcVT.getVectorElementCount();
6055   SDLoc dl(N);
6056 
6057   // See if a widened result type would be legal, if so widen the node.
6058   EVT WideDstVT = EVT::getVectorVT(*DAG.getContext(),
6059                                    DstVT.getVectorElementType(), WideNumElts);
6060   if (TLI.isTypeLegal(WideDstVT)) {
6061     SDValue Res =
6062         DAG.getNode(N->getOpcode(), dl, WideDstVT, Src, N->getOperand(1));
6063     return DAG.getNode(
6064         ISD::EXTRACT_SUBVECTOR, dl, DstVT, Res,
6065         DAG.getConstant(0, dl, TLI.getVectorIdxTy(DAG.getDataLayout())));
6066   }
6067 
6068   // Give up and unroll.
6069   return DAG.UnrollVectorOp(N);
6070 }
6071 
WidenVecOp_BITCAST(SDNode * N)6072 SDValue DAGTypeLegalizer::WidenVecOp_BITCAST(SDNode *N) {
6073   EVT VT = N->getValueType(0);
6074   SDValue InOp = GetWidenedVector(N->getOperand(0));
6075   EVT InWidenVT = InOp.getValueType();
6076   SDLoc dl(N);
6077 
6078   // Check if we can convert between two legal vector types and extract.
6079   TypeSize InWidenSize = InWidenVT.getSizeInBits();
6080   TypeSize Size = VT.getSizeInBits();
6081   // x86mmx is not an acceptable vector element type, so don't try.
6082   if (!VT.isVector() && VT != MVT::x86mmx &&
6083       InWidenSize.hasKnownScalarFactor(Size)) {
6084     unsigned NewNumElts = InWidenSize.getKnownScalarFactor(Size);
6085     EVT NewVT = EVT::getVectorVT(*DAG.getContext(), VT, NewNumElts);
6086     if (TLI.isTypeLegal(NewVT)) {
6087       SDValue BitOp = DAG.getNode(ISD::BITCAST, dl, NewVT, InOp);
6088       return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, BitOp,
6089                          DAG.getVectorIdxConstant(0, dl));
6090     }
6091   }
6092 
6093   // Handle a case like bitcast v12i8 -> v3i32. Normally that would get widened
6094   // to v16i8 -> v4i32, but for a target where v3i32 is legal but v12i8 is not,
6095   // we end up here. Handling the case here with EXTRACT_SUBVECTOR avoids
6096   // having to copy via memory.
6097   if (VT.isVector()) {
6098     EVT EltVT = VT.getVectorElementType();
6099     unsigned EltSize = EltVT.getFixedSizeInBits();
6100     if (InWidenSize.isKnownMultipleOf(EltSize)) {
6101       ElementCount NewNumElts =
6102           (InWidenVT.getVectorElementCount() * InWidenVT.getScalarSizeInBits())
6103               .divideCoefficientBy(EltSize);
6104       EVT NewVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NewNumElts);
6105       if (TLI.isTypeLegal(NewVT)) {
6106         SDValue BitOp = DAG.getNode(ISD::BITCAST, dl, NewVT, InOp);
6107         return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VT, BitOp,
6108                            DAG.getVectorIdxConstant(0, dl));
6109       }
6110     }
6111   }
6112 
6113   return CreateStackStoreLoad(InOp, VT);
6114 }
6115 
WidenVecOp_CONCAT_VECTORS(SDNode * N)6116 SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) {
6117   EVT VT = N->getValueType(0);
6118   EVT EltVT = VT.getVectorElementType();
6119   EVT InVT = N->getOperand(0).getValueType();
6120   SDLoc dl(N);
6121 
6122   // If the widen width for this operand is the same as the width of the concat
6123   // and all but the first operand is undef, just use the widened operand.
6124   unsigned NumOperands = N->getNumOperands();
6125   if (VT == TLI.getTypeToTransformTo(*DAG.getContext(), InVT)) {
6126     unsigned i;
6127     for (i = 1; i < NumOperands; ++i)
6128       if (!N->getOperand(i).isUndef())
6129         break;
6130 
6131     if (i == NumOperands)
6132       return GetWidenedVector(N->getOperand(0));
6133   }
6134 
6135   // Otherwise, fall back to a nasty build vector.
6136   unsigned NumElts = VT.getVectorNumElements();
6137   SmallVector<SDValue, 16> Ops(NumElts);
6138 
6139   unsigned NumInElts = InVT.getVectorNumElements();
6140 
6141   unsigned Idx = 0;
6142   for (unsigned i=0; i < NumOperands; ++i) {
6143     SDValue InOp = N->getOperand(i);
6144     assert(getTypeAction(InOp.getValueType()) ==
6145                TargetLowering::TypeWidenVector &&
6146            "Unexpected type action");
6147     InOp = GetWidenedVector(InOp);
6148     for (unsigned j = 0; j < NumInElts; ++j)
6149       Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
6150                                DAG.getVectorIdxConstant(j, dl));
6151   }
6152   return DAG.getBuildVector(VT, dl, Ops);
6153 }
6154 
WidenVecOp_INSERT_SUBVECTOR(SDNode * N)6155 SDValue DAGTypeLegalizer::WidenVecOp_INSERT_SUBVECTOR(SDNode *N) {
6156   EVT VT = N->getValueType(0);
6157   SDValue SubVec = N->getOperand(1);
6158   SDValue InVec = N->getOperand(0);
6159 
6160   if (getTypeAction(SubVec.getValueType()) == TargetLowering::TypeWidenVector)
6161     SubVec = GetWidenedVector(SubVec);
6162 
6163   if (SubVec.getValueType().knownBitsLE(VT) && InVec.isUndef() &&
6164       N->getConstantOperandVal(2) == 0)
6165     return DAG.getNode(ISD::INSERT_SUBVECTOR, SDLoc(N), VT, InVec, SubVec,
6166                        N->getOperand(2));
6167 
6168   report_fatal_error("Don't know how to widen the operands for "
6169                      "INSERT_SUBVECTOR");
6170 }
6171 
WidenVecOp_EXTRACT_SUBVECTOR(SDNode * N)6172 SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(SDNode *N) {
6173   SDValue InOp = GetWidenedVector(N->getOperand(0));
6174   return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(N),
6175                      N->getValueType(0), InOp, N->getOperand(1));
6176 }
6177 
WidenVecOp_EXTRACT_VECTOR_ELT(SDNode * N)6178 SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(SDNode *N) {
6179   SDValue InOp = GetWidenedVector(N->getOperand(0));
6180   return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N),
6181                      N->getValueType(0), InOp, N->getOperand(1));
6182 }
6183 
WidenVecOp_STORE(SDNode * N)6184 SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) {
6185   // We have to widen the value, but we want only to store the original
6186   // vector type.
6187   StoreSDNode *ST = cast<StoreSDNode>(N);
6188 
6189   if (!ST->getMemoryVT().getScalarType().isByteSized())
6190     return TLI.scalarizeVectorStore(ST, DAG);
6191 
6192   if (ST->isTruncatingStore())
6193     return TLI.scalarizeVectorStore(ST, DAG);
6194 
6195   SmallVector<SDValue, 16> StChain;
6196   if (GenWidenVectorStores(StChain, ST)) {
6197     if (StChain.size() == 1)
6198       return StChain[0];
6199 
6200     return DAG.getNode(ISD::TokenFactor, SDLoc(ST), MVT::Other, StChain);
6201   }
6202 
6203   // Generate a vector-predicated store if it is custom/legal on the target.
6204   // To avoid possible recursion, only do this if the widened mask type is
6205   // legal.
6206   // FIXME: Not all targets may support EVL in VP_STORE. These will have been
6207   // removed from the IR by the ExpandVectorPredication pass but we're
6208   // reintroducing them here.
6209   SDValue StVal = ST->getValue();
6210   EVT StVT = StVal.getValueType();
6211   EVT WideVT = TLI.getTypeToTransformTo(*DAG.getContext(), StVT);
6212   EVT WideMaskVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1,
6213                                     WideVT.getVectorElementCount());
6214   if (WideVT.isScalableVector() &&
6215       TLI.isOperationLegalOrCustom(ISD::VP_STORE, WideVT) &&
6216       TLI.isTypeLegal(WideMaskVT)) {
6217     // Widen the value.
6218     SDLoc DL(N);
6219     StVal = GetWidenedVector(StVal);
6220     SDValue Mask = DAG.getAllOnesConstant(DL, WideMaskVT);
6221     MVT EVLVT = TLI.getVPExplicitVectorLengthTy();
6222     unsigned NumVTElts = StVT.getVectorMinNumElements();
6223     SDValue EVL =
6224         DAG.getVScale(DL, EVLVT, APInt(EVLVT.getScalarSizeInBits(), NumVTElts));
6225     return DAG.getStoreVP(ST->getChain(), DL, StVal, ST->getBasePtr(),
6226                           DAG.getUNDEF(ST->getBasePtr().getValueType()), Mask,
6227                           EVL, StVal.getValueType(), ST->getMemOperand(),
6228                           ST->getAddressingMode());
6229   }
6230 
6231   report_fatal_error("Unable to widen vector store");
6232 }
6233 
WidenVecOp_VP_STORE(SDNode * N,unsigned OpNo)6234 SDValue DAGTypeLegalizer::WidenVecOp_VP_STORE(SDNode *N, unsigned OpNo) {
6235   assert((OpNo == 1 || OpNo == 3) &&
6236          "Can widen only data or mask operand of vp_store");
6237   VPStoreSDNode *ST = cast<VPStoreSDNode>(N);
6238   SDValue Mask = ST->getMask();
6239   SDValue StVal = ST->getValue();
6240   SDLoc dl(N);
6241 
6242   if (OpNo == 1) {
6243     // Widen the value.
6244     StVal = GetWidenedVector(StVal);
6245 
6246     // We only handle the case where the mask needs widening to an
6247     // identically-sized type as the vector inputs.
6248     assert(getTypeAction(Mask.getValueType()) ==
6249                TargetLowering::TypeWidenVector &&
6250            "Unable to widen VP store");
6251     Mask = GetWidenedVector(Mask);
6252   } else {
6253     Mask = GetWidenedVector(Mask);
6254 
6255     // We only handle the case where the stored value needs widening to an
6256     // identically-sized type as the mask.
6257     assert(getTypeAction(StVal.getValueType()) ==
6258                TargetLowering::TypeWidenVector &&
6259            "Unable to widen VP store");
6260     StVal = GetWidenedVector(StVal);
6261   }
6262 
6263   assert(Mask.getValueType().getVectorElementCount() ==
6264              StVal.getValueType().getVectorElementCount() &&
6265          "Mask and data vectors should have the same number of elements");
6266   return DAG.getStoreVP(ST->getChain(), dl, StVal, ST->getBasePtr(),
6267                         ST->getOffset(), Mask, ST->getVectorLength(),
6268                         ST->getMemoryVT(), ST->getMemOperand(),
6269                         ST->getAddressingMode(), ST->isTruncatingStore(),
6270                         ST->isCompressingStore());
6271 }
6272 
WidenVecOp_VP_STRIDED_STORE(SDNode * N,unsigned OpNo)6273 SDValue DAGTypeLegalizer::WidenVecOp_VP_STRIDED_STORE(SDNode *N,
6274                                                       unsigned OpNo) {
6275   assert((OpNo == 1 || OpNo == 4) &&
6276          "Can widen only data or mask operand of vp_strided_store");
6277   VPStridedStoreSDNode *SST = cast<VPStridedStoreSDNode>(N);
6278   SDValue Mask = SST->getMask();
6279   SDValue StVal = SST->getValue();
6280   SDLoc DL(N);
6281 
6282   if (OpNo == 1)
6283     assert(getTypeAction(Mask.getValueType()) ==
6284                TargetLowering::TypeWidenVector &&
6285            "Unable to widen VP strided store");
6286   else
6287     assert(getTypeAction(StVal.getValueType()) ==
6288                TargetLowering::TypeWidenVector &&
6289            "Unable to widen VP strided store");
6290 
6291   StVal = GetWidenedVector(StVal);
6292   Mask = GetWidenedVector(Mask);
6293 
6294   assert(StVal.getValueType().getVectorElementCount() ==
6295              Mask.getValueType().getVectorElementCount() &&
6296          "Data and mask vectors should have the same number of elements");
6297 
6298   return DAG.getStridedStoreVP(
6299       SST->getChain(), DL, StVal, SST->getBasePtr(), SST->getOffset(),
6300       SST->getStride(), Mask, SST->getVectorLength(), SST->getMemoryVT(),
6301       SST->getMemOperand(), SST->getAddressingMode(), SST->isTruncatingStore(),
6302       SST->isCompressingStore());
6303 }
6304 
WidenVecOp_MSTORE(SDNode * N,unsigned OpNo)6305 SDValue DAGTypeLegalizer::WidenVecOp_MSTORE(SDNode *N, unsigned OpNo) {
6306   assert((OpNo == 1 || OpNo == 3) &&
6307          "Can widen only data or mask operand of mstore");
6308   MaskedStoreSDNode *MST = cast<MaskedStoreSDNode>(N);
6309   SDValue Mask = MST->getMask();
6310   EVT MaskVT = Mask.getValueType();
6311   SDValue StVal = MST->getValue();
6312   SDLoc dl(N);
6313 
6314   if (OpNo == 1) {
6315     // Widen the value.
6316     StVal = GetWidenedVector(StVal);
6317 
6318     // The mask should be widened as well.
6319     EVT WideVT = StVal.getValueType();
6320     EVT WideMaskVT = EVT::getVectorVT(*DAG.getContext(),
6321                                       MaskVT.getVectorElementType(),
6322                                       WideVT.getVectorNumElements());
6323     Mask = ModifyToType(Mask, WideMaskVT, true);
6324   } else {
6325     // Widen the mask.
6326     EVT WideMaskVT = TLI.getTypeToTransformTo(*DAG.getContext(), MaskVT);
6327     Mask = ModifyToType(Mask, WideMaskVT, true);
6328 
6329     EVT ValueVT = StVal.getValueType();
6330     EVT WideVT = EVT::getVectorVT(*DAG.getContext(),
6331                                   ValueVT.getVectorElementType(),
6332                                   WideMaskVT.getVectorNumElements());
6333     StVal = ModifyToType(StVal, WideVT);
6334   }
6335 
6336   assert(Mask.getValueType().getVectorNumElements() ==
6337          StVal.getValueType().getVectorNumElements() &&
6338          "Mask and data vectors should have the same number of elements");
6339   return DAG.getMaskedStore(MST->getChain(), dl, StVal, MST->getBasePtr(),
6340                             MST->getOffset(), Mask, MST->getMemoryVT(),
6341                             MST->getMemOperand(), MST->getAddressingMode(),
6342                             false, MST->isCompressingStore());
6343 }
6344 
WidenVecOp_MGATHER(SDNode * N,unsigned OpNo)6345 SDValue DAGTypeLegalizer::WidenVecOp_MGATHER(SDNode *N, unsigned OpNo) {
6346   assert(OpNo == 4 && "Can widen only the index of mgather");
6347   auto *MG = cast<MaskedGatherSDNode>(N);
6348   SDValue DataOp = MG->getPassThru();
6349   SDValue Mask = MG->getMask();
6350   SDValue Scale = MG->getScale();
6351 
6352   // Just widen the index. It's allowed to have extra elements.
6353   SDValue Index = GetWidenedVector(MG->getIndex());
6354 
6355   SDLoc dl(N);
6356   SDValue Ops[] = {MG->getChain(), DataOp, Mask, MG->getBasePtr(), Index,
6357                    Scale};
6358   SDValue Res = DAG.getMaskedGather(MG->getVTList(), MG->getMemoryVT(), dl, Ops,
6359                                     MG->getMemOperand(), MG->getIndexType(),
6360                                     MG->getExtensionType());
6361   ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
6362   ReplaceValueWith(SDValue(N, 0), Res.getValue(0));
6363   return SDValue();
6364 }
6365 
WidenVecOp_MSCATTER(SDNode * N,unsigned OpNo)6366 SDValue DAGTypeLegalizer::WidenVecOp_MSCATTER(SDNode *N, unsigned OpNo) {
6367   MaskedScatterSDNode *MSC = cast<MaskedScatterSDNode>(N);
6368   SDValue DataOp = MSC->getValue();
6369   SDValue Mask = MSC->getMask();
6370   SDValue Index = MSC->getIndex();
6371   SDValue Scale = MSC->getScale();
6372   EVT WideMemVT = MSC->getMemoryVT();
6373 
6374   if (OpNo == 1) {
6375     DataOp = GetWidenedVector(DataOp);
6376     unsigned NumElts = DataOp.getValueType().getVectorNumElements();
6377 
6378     // Widen index.
6379     EVT IndexVT = Index.getValueType();
6380     EVT WideIndexVT = EVT::getVectorVT(*DAG.getContext(),
6381                                        IndexVT.getVectorElementType(), NumElts);
6382     Index = ModifyToType(Index, WideIndexVT);
6383 
6384     // The mask should be widened as well.
6385     EVT MaskVT = Mask.getValueType();
6386     EVT WideMaskVT = EVT::getVectorVT(*DAG.getContext(),
6387                                       MaskVT.getVectorElementType(), NumElts);
6388     Mask = ModifyToType(Mask, WideMaskVT, true);
6389 
6390     // Widen the MemoryType
6391     WideMemVT = EVT::getVectorVT(*DAG.getContext(),
6392                                  MSC->getMemoryVT().getScalarType(), NumElts);
6393   } else if (OpNo == 4) {
6394     // Just widen the index. It's allowed to have extra elements.
6395     Index = GetWidenedVector(Index);
6396   } else
6397     llvm_unreachable("Can't widen this operand of mscatter");
6398 
6399   SDValue Ops[] = {MSC->getChain(), DataOp, Mask, MSC->getBasePtr(), Index,
6400                    Scale};
6401   return DAG.getMaskedScatter(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(N),
6402                               Ops, MSC->getMemOperand(), MSC->getIndexType(),
6403                               MSC->isTruncatingStore());
6404 }
6405 
WidenVecOp_VP_SCATTER(SDNode * N,unsigned OpNo)6406 SDValue DAGTypeLegalizer::WidenVecOp_VP_SCATTER(SDNode *N, unsigned OpNo) {
6407   VPScatterSDNode *VPSC = cast<VPScatterSDNode>(N);
6408   SDValue DataOp = VPSC->getValue();
6409   SDValue Mask = VPSC->getMask();
6410   SDValue Index = VPSC->getIndex();
6411   SDValue Scale = VPSC->getScale();
6412   EVT WideMemVT = VPSC->getMemoryVT();
6413 
6414   if (OpNo == 1) {
6415     DataOp = GetWidenedVector(DataOp);
6416     Index = GetWidenedVector(Index);
6417     const auto WideEC = DataOp.getValueType().getVectorElementCount();
6418     Mask = GetWidenedMask(Mask, WideEC);
6419     WideMemVT = EVT::getVectorVT(*DAG.getContext(),
6420                                  VPSC->getMemoryVT().getScalarType(), WideEC);
6421   } else if (OpNo == 3) {
6422     // Just widen the index. It's allowed to have extra elements.
6423     Index = GetWidenedVector(Index);
6424   } else
6425     llvm_unreachable("Can't widen this operand of VP_SCATTER");
6426 
6427   SDValue Ops[] = {
6428       VPSC->getChain(),       DataOp, VPSC->getBasePtr(), Index, Scale, Mask,
6429       VPSC->getVectorLength()};
6430   return DAG.getScatterVP(DAG.getVTList(MVT::Other), WideMemVT, SDLoc(N), Ops,
6431                           VPSC->getMemOperand(), VPSC->getIndexType());
6432 }
6433 
WidenVecOp_SETCC(SDNode * N)6434 SDValue DAGTypeLegalizer::WidenVecOp_SETCC(SDNode *N) {
6435   SDValue InOp0 = GetWidenedVector(N->getOperand(0));
6436   SDValue InOp1 = GetWidenedVector(N->getOperand(1));
6437   SDLoc dl(N);
6438   EVT VT = N->getValueType(0);
6439 
6440   // WARNING: In this code we widen the compare instruction with garbage.
6441   // This garbage may contain denormal floats which may be slow. Is this a real
6442   // concern ? Should we zero the unused lanes if this is a float compare ?
6443 
6444   // Get a new SETCC node to compare the newly widened operands.
6445   // Only some of the compared elements are legal.
6446   EVT SVT = getSetCCResultType(InOp0.getValueType());
6447   // The result type is legal, if its vXi1, keep vXi1 for the new SETCC.
6448   if (VT.getScalarType() == MVT::i1)
6449     SVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1,
6450                            SVT.getVectorElementCount());
6451 
6452   SDValue WideSETCC = DAG.getNode(ISD::SETCC, SDLoc(N),
6453                                   SVT, InOp0, InOp1, N->getOperand(2));
6454 
6455   // Extract the needed results from the result vector.
6456   EVT ResVT = EVT::getVectorVT(*DAG.getContext(),
6457                                SVT.getVectorElementType(),
6458                                VT.getVectorElementCount());
6459   SDValue CC = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, ResVT, WideSETCC,
6460                            DAG.getVectorIdxConstant(0, dl));
6461 
6462   EVT OpVT = N->getOperand(0).getValueType();
6463   ISD::NodeType ExtendCode =
6464       TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT));
6465   return DAG.getNode(ExtendCode, dl, VT, CC);
6466 }
6467 
WidenVecOp_STRICT_FSETCC(SDNode * N)6468 SDValue DAGTypeLegalizer::WidenVecOp_STRICT_FSETCC(SDNode *N) {
6469   SDValue Chain = N->getOperand(0);
6470   SDValue LHS = GetWidenedVector(N->getOperand(1));
6471   SDValue RHS = GetWidenedVector(N->getOperand(2));
6472   SDValue CC = N->getOperand(3);
6473   SDLoc dl(N);
6474 
6475   EVT VT = N->getValueType(0);
6476   EVT EltVT = VT.getVectorElementType();
6477   EVT TmpEltVT = LHS.getValueType().getVectorElementType();
6478   unsigned NumElts = VT.getVectorNumElements();
6479 
6480   // Unroll into a build vector.
6481   SmallVector<SDValue, 8> Scalars(NumElts);
6482   SmallVector<SDValue, 8> Chains(NumElts);
6483 
6484   for (unsigned i = 0; i != NumElts; ++i) {
6485     SDValue LHSElem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, LHS,
6486                                   DAG.getVectorIdxConstant(i, dl));
6487     SDValue RHSElem = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, RHS,
6488                                   DAG.getVectorIdxConstant(i, dl));
6489 
6490     Scalars[i] = DAG.getNode(N->getOpcode(), dl, {MVT::i1, MVT::Other},
6491                              {Chain, LHSElem, RHSElem, CC});
6492     Chains[i] = Scalars[i].getValue(1);
6493     Scalars[i] = DAG.getSelect(dl, EltVT, Scalars[i],
6494                                DAG.getBoolConstant(true, dl, EltVT, VT),
6495                                DAG.getBoolConstant(false, dl, EltVT, VT));
6496   }
6497 
6498   SDValue NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Chains);
6499   ReplaceValueWith(SDValue(N, 1), NewChain);
6500 
6501   return DAG.getBuildVector(VT, dl, Scalars);
6502 }
6503 
WidenVecOp_VECREDUCE(SDNode * N)6504 SDValue DAGTypeLegalizer::WidenVecOp_VECREDUCE(SDNode *N) {
6505   SDLoc dl(N);
6506   SDValue Op = GetWidenedVector(N->getOperand(0));
6507   EVT OrigVT = N->getOperand(0).getValueType();
6508   EVT WideVT = Op.getValueType();
6509   EVT ElemVT = OrigVT.getVectorElementType();
6510   SDNodeFlags Flags = N->getFlags();
6511 
6512   unsigned Opc = N->getOpcode();
6513   unsigned BaseOpc = ISD::getVecReduceBaseOpcode(Opc);
6514   SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
6515   assert(NeutralElem && "Neutral element must exist");
6516 
6517   // Pad the vector with the neutral element.
6518   unsigned OrigElts = OrigVT.getVectorMinNumElements();
6519   unsigned WideElts = WideVT.getVectorMinNumElements();
6520 
6521   if (WideVT.isScalableVector()) {
6522     unsigned GCD = std::gcd(OrigElts, WideElts);
6523     EVT SplatVT = EVT::getVectorVT(*DAG.getContext(), ElemVT,
6524                                    ElementCount::getScalable(GCD));
6525     SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
6526     for (unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
6527       Op = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, WideVT, Op, SplatNeutral,
6528                        DAG.getVectorIdxConstant(Idx, dl));
6529     return DAG.getNode(Opc, dl, N->getValueType(0), Op, Flags);
6530   }
6531 
6532   for (unsigned Idx = OrigElts; Idx < WideElts; Idx++)
6533     Op = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, WideVT, Op, NeutralElem,
6534                      DAG.getVectorIdxConstant(Idx, dl));
6535 
6536   return DAG.getNode(Opc, dl, N->getValueType(0), Op, Flags);
6537 }
6538 
WidenVecOp_VECREDUCE_SEQ(SDNode * N)6539 SDValue DAGTypeLegalizer::WidenVecOp_VECREDUCE_SEQ(SDNode *N) {
6540   SDLoc dl(N);
6541   SDValue AccOp = N->getOperand(0);
6542   SDValue VecOp = N->getOperand(1);
6543   SDValue Op = GetWidenedVector(VecOp);
6544 
6545   EVT OrigVT = VecOp.getValueType();
6546   EVT WideVT = Op.getValueType();
6547   EVT ElemVT = OrigVT.getVectorElementType();
6548   SDNodeFlags Flags = N->getFlags();
6549 
6550   unsigned Opc = N->getOpcode();
6551   unsigned BaseOpc = ISD::getVecReduceBaseOpcode(Opc);
6552   SDValue NeutralElem = DAG.getNeutralElement(BaseOpc, dl, ElemVT, Flags);
6553 
6554   // Pad the vector with the neutral element.
6555   unsigned OrigElts = OrigVT.getVectorMinNumElements();
6556   unsigned WideElts = WideVT.getVectorMinNumElements();
6557 
6558   if (WideVT.isScalableVector()) {
6559     unsigned GCD = std::gcd(OrigElts, WideElts);
6560     EVT SplatVT = EVT::getVectorVT(*DAG.getContext(), ElemVT,
6561                                    ElementCount::getScalable(GCD));
6562     SDValue SplatNeutral = DAG.getSplatVector(SplatVT, dl, NeutralElem);
6563     for (unsigned Idx = OrigElts; Idx < WideElts; Idx = Idx + GCD)
6564       Op = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, WideVT, Op, SplatNeutral,
6565                        DAG.getVectorIdxConstant(Idx, dl));
6566     return DAG.getNode(Opc, dl, N->getValueType(0), AccOp, Op, Flags);
6567   }
6568 
6569   for (unsigned Idx = OrigElts; Idx < WideElts; Idx++)
6570     Op = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, WideVT, Op, NeutralElem,
6571                      DAG.getVectorIdxConstant(Idx, dl));
6572 
6573   return DAG.getNode(Opc, dl, N->getValueType(0), AccOp, Op, Flags);
6574 }
6575 
WidenVecOp_VP_REDUCE(SDNode * N)6576 SDValue DAGTypeLegalizer::WidenVecOp_VP_REDUCE(SDNode *N) {
6577   assert(N->isVPOpcode() && "Expected VP opcode");
6578 
6579   SDLoc dl(N);
6580   SDValue Op = GetWidenedVector(N->getOperand(1));
6581   SDValue Mask = GetWidenedMask(N->getOperand(2),
6582                                 Op.getValueType().getVectorElementCount());
6583 
6584   return DAG.getNode(N->getOpcode(), dl, N->getValueType(0),
6585                      {N->getOperand(0), Op, Mask, N->getOperand(3)},
6586                      N->getFlags());
6587 }
6588 
WidenVecOp_VSELECT(SDNode * N)6589 SDValue DAGTypeLegalizer::WidenVecOp_VSELECT(SDNode *N) {
6590   // This only gets called in the case that the left and right inputs and
6591   // result are of a legal odd vector type, and the condition is illegal i1 of
6592   // the same odd width that needs widening.
6593   EVT VT = N->getValueType(0);
6594   assert(VT.isVector() && !VT.isPow2VectorType() && isTypeLegal(VT));
6595 
6596   SDValue Cond = GetWidenedVector(N->getOperand(0));
6597   SDValue LeftIn = DAG.WidenVector(N->getOperand(1), SDLoc(N));
6598   SDValue RightIn = DAG.WidenVector(N->getOperand(2), SDLoc(N));
6599   SDLoc DL(N);
6600 
6601   SDValue Select = DAG.getNode(N->getOpcode(), DL, LeftIn.getValueType(), Cond,
6602                                LeftIn, RightIn);
6603   return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Select,
6604                      DAG.getVectorIdxConstant(0, DL));
6605 }
6606 
6607 //===----------------------------------------------------------------------===//
6608 // Vector Widening Utilities
6609 //===----------------------------------------------------------------------===//
6610 
6611 // Utility function to find the type to chop up a widen vector for load/store
6612 //  TLI:       Target lowering used to determine legal types.
6613 //  Width:     Width left need to load/store.
6614 //  WidenVT:   The widen vector type to load to/store from
6615 //  Align:     If 0, don't allow use of a wider type
6616 //  WidenEx:   If Align is not 0, the amount additional we can load/store from.
6617 
findMemType(SelectionDAG & DAG,const TargetLowering & TLI,unsigned Width,EVT WidenVT,unsigned Align=0,unsigned WidenEx=0)6618 static std::optional<EVT> findMemType(SelectionDAG &DAG,
6619                                       const TargetLowering &TLI, unsigned Width,
6620                                       EVT WidenVT, unsigned Align = 0,
6621                                       unsigned WidenEx = 0) {
6622   EVT WidenEltVT = WidenVT.getVectorElementType();
6623   const bool Scalable = WidenVT.isScalableVector();
6624   unsigned WidenWidth = WidenVT.getSizeInBits().getKnownMinValue();
6625   unsigned WidenEltWidth = WidenEltVT.getSizeInBits();
6626   unsigned AlignInBits = Align*8;
6627 
6628   // If we have one element to load/store, return it.
6629   EVT RetVT = WidenEltVT;
6630   if (!Scalable && Width == WidenEltWidth)
6631     return RetVT;
6632 
6633   // Don't bother looking for an integer type if the vector is scalable, skip
6634   // to vector types.
6635   if (!Scalable) {
6636     // See if there is larger legal integer than the element type to load/store.
6637     for (EVT MemVT : reverse(MVT::integer_valuetypes())) {
6638       unsigned MemVTWidth = MemVT.getSizeInBits();
6639       if (MemVT.getSizeInBits() <= WidenEltWidth)
6640         break;
6641       auto Action = TLI.getTypeAction(*DAG.getContext(), MemVT);
6642       if ((Action == TargetLowering::TypeLegal ||
6643            Action == TargetLowering::TypePromoteInteger) &&
6644           (WidenWidth % MemVTWidth) == 0 &&
6645           isPowerOf2_32(WidenWidth / MemVTWidth) &&
6646           (MemVTWidth <= Width ||
6647            (Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
6648         if (MemVTWidth == WidenWidth)
6649           return MemVT;
6650         RetVT = MemVT;
6651         break;
6652       }
6653     }
6654   }
6655 
6656   // See if there is a larger vector type to load/store that has the same vector
6657   // element type and is evenly divisible with the WidenVT.
6658   for (EVT MemVT : reverse(MVT::vector_valuetypes())) {
6659     // Skip vector MVTs which don't match the scalable property of WidenVT.
6660     if (Scalable != MemVT.isScalableVector())
6661       continue;
6662     unsigned MemVTWidth = MemVT.getSizeInBits().getKnownMinValue();
6663     auto Action = TLI.getTypeAction(*DAG.getContext(), MemVT);
6664     if ((Action == TargetLowering::TypeLegal ||
6665          Action == TargetLowering::TypePromoteInteger) &&
6666         WidenEltVT == MemVT.getVectorElementType() &&
6667         (WidenWidth % MemVTWidth) == 0 &&
6668         isPowerOf2_32(WidenWidth / MemVTWidth) &&
6669         (MemVTWidth <= Width ||
6670          (Align!=0 && MemVTWidth<=AlignInBits && MemVTWidth<=Width+WidenEx))) {
6671       if (RetVT.getFixedSizeInBits() < MemVTWidth || MemVT == WidenVT)
6672         return MemVT;
6673     }
6674   }
6675 
6676   // Using element-wise loads and stores for widening operations is not
6677   // supported for scalable vectors
6678   if (Scalable)
6679     return std::nullopt;
6680 
6681   return RetVT;
6682 }
6683 
6684 // Builds a vector type from scalar loads
6685 //  VecTy: Resulting Vector type
6686 //  LDOps: Load operators to build a vector type
6687 //  [Start,End) the list of loads to use.
BuildVectorFromScalar(SelectionDAG & DAG,EVT VecTy,SmallVectorImpl<SDValue> & LdOps,unsigned Start,unsigned End)6688 static SDValue BuildVectorFromScalar(SelectionDAG& DAG, EVT VecTy,
6689                                      SmallVectorImpl<SDValue> &LdOps,
6690                                      unsigned Start, unsigned End) {
6691   SDLoc dl(LdOps[Start]);
6692   EVT LdTy = LdOps[Start].getValueType();
6693   unsigned Width = VecTy.getSizeInBits();
6694   unsigned NumElts = Width / LdTy.getSizeInBits();
6695   EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), LdTy, NumElts);
6696 
6697   unsigned Idx = 1;
6698   SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT,LdOps[Start]);
6699 
6700   for (unsigned i = Start + 1; i != End; ++i) {
6701     EVT NewLdTy = LdOps[i].getValueType();
6702     if (NewLdTy != LdTy) {
6703       NumElts = Width / NewLdTy.getSizeInBits();
6704       NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewLdTy, NumElts);
6705       VecOp = DAG.getNode(ISD::BITCAST, dl, NewVecVT, VecOp);
6706       // Readjust position and vector position based on new load type.
6707       Idx = Idx * LdTy.getSizeInBits() / NewLdTy.getSizeInBits();
6708       LdTy = NewLdTy;
6709     }
6710     VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, VecOp, LdOps[i],
6711                         DAG.getVectorIdxConstant(Idx++, dl));
6712   }
6713   return DAG.getNode(ISD::BITCAST, dl, VecTy, VecOp);
6714 }
6715 
GenWidenVectorLoads(SmallVectorImpl<SDValue> & LdChain,LoadSDNode * LD)6716 SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl<SDValue> &LdChain,
6717                                               LoadSDNode *LD) {
6718   // The strategy assumes that we can efficiently load power-of-two widths.
6719   // The routine chops the vector into the largest vector loads with the same
6720   // element type or scalar loads and then recombines it to the widen vector
6721   // type.
6722   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),LD->getValueType(0));
6723   EVT LdVT    = LD->getMemoryVT();
6724   SDLoc dl(LD);
6725   assert(LdVT.isVector() && WidenVT.isVector());
6726   assert(LdVT.isScalableVector() == WidenVT.isScalableVector());
6727   assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType());
6728 
6729   // Load information
6730   SDValue Chain = LD->getChain();
6731   SDValue BasePtr = LD->getBasePtr();
6732   MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
6733   AAMDNodes AAInfo = LD->getAAInfo();
6734 
6735   TypeSize LdWidth = LdVT.getSizeInBits();
6736   TypeSize WidenWidth = WidenVT.getSizeInBits();
6737   TypeSize WidthDiff = WidenWidth - LdWidth;
6738   // Allow wider loads if they are sufficiently aligned to avoid memory faults
6739   // and if the original load is simple.
6740   unsigned LdAlign =
6741       (!LD->isSimple() || LdVT.isScalableVector()) ? 0 : LD->getAlign().value();
6742 
6743   // Find the vector type that can load from.
6744   std::optional<EVT> FirstVT =
6745       findMemType(DAG, TLI, LdWidth.getKnownMinValue(), WidenVT, LdAlign,
6746                   WidthDiff.getKnownMinValue());
6747 
6748   if (!FirstVT)
6749     return SDValue();
6750 
6751   SmallVector<EVT, 8> MemVTs;
6752   TypeSize FirstVTWidth = FirstVT->getSizeInBits();
6753 
6754   // Unless we're able to load in one instruction we must work out how to load
6755   // the remainder.
6756   if (!TypeSize::isKnownLE(LdWidth, FirstVTWidth)) {
6757     std::optional<EVT> NewVT = FirstVT;
6758     TypeSize RemainingWidth = LdWidth;
6759     TypeSize NewVTWidth = FirstVTWidth;
6760     do {
6761       RemainingWidth -= NewVTWidth;
6762       if (TypeSize::isKnownLT(RemainingWidth, NewVTWidth)) {
6763         // The current type we are using is too large. Find a better size.
6764         NewVT = findMemType(DAG, TLI, RemainingWidth.getKnownMinValue(),
6765                             WidenVT, LdAlign, WidthDiff.getKnownMinValue());
6766         if (!NewVT)
6767           return SDValue();
6768         NewVTWidth = NewVT->getSizeInBits();
6769       }
6770       MemVTs.push_back(*NewVT);
6771     } while (TypeSize::isKnownGT(RemainingWidth, NewVTWidth));
6772   }
6773 
6774   SDValue LdOp = DAG.getLoad(*FirstVT, dl, Chain, BasePtr, LD->getPointerInfo(),
6775                              LD->getOriginalAlign(), MMOFlags, AAInfo);
6776   LdChain.push_back(LdOp.getValue(1));
6777 
6778   // Check if we can load the element with one instruction.
6779   if (MemVTs.empty()) {
6780     assert(TypeSize::isKnownLE(LdWidth, FirstVTWidth));
6781     if (!FirstVT->isVector()) {
6782       unsigned NumElts =
6783           WidenWidth.getFixedValue() / FirstVTWidth.getFixedValue();
6784       EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), *FirstVT, NumElts);
6785       SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp);
6786       return DAG.getNode(ISD::BITCAST, dl, WidenVT, VecOp);
6787     }
6788     if (FirstVT == WidenVT)
6789       return LdOp;
6790 
6791     // TODO: We don't currently have any tests that exercise this code path.
6792     assert(WidenWidth.getFixedValue() % FirstVTWidth.getFixedValue() == 0);
6793     unsigned NumConcat =
6794         WidenWidth.getFixedValue() / FirstVTWidth.getFixedValue();
6795     SmallVector<SDValue, 16> ConcatOps(NumConcat);
6796     SDValue UndefVal = DAG.getUNDEF(*FirstVT);
6797     ConcatOps[0] = LdOp;
6798     for (unsigned i = 1; i != NumConcat; ++i)
6799       ConcatOps[i] = UndefVal;
6800     return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, ConcatOps);
6801   }
6802 
6803   // Load vector by using multiple loads from largest vector to scalar.
6804   SmallVector<SDValue, 16> LdOps;
6805   LdOps.push_back(LdOp);
6806 
6807   uint64_t ScaledOffset = 0;
6808   MachinePointerInfo MPI = LD->getPointerInfo();
6809 
6810   // First incremement past the first load.
6811   IncrementPointer(cast<LoadSDNode>(LdOp), *FirstVT, MPI, BasePtr,
6812                    &ScaledOffset);
6813 
6814   for (EVT MemVT : MemVTs) {
6815     Align NewAlign = ScaledOffset == 0
6816                          ? LD->getOriginalAlign()
6817                          : commonAlignment(LD->getAlign(), ScaledOffset);
6818     SDValue L =
6819         DAG.getLoad(MemVT, dl, Chain, BasePtr, MPI, NewAlign, MMOFlags, AAInfo);
6820 
6821     LdOps.push_back(L);
6822     LdChain.push_back(L.getValue(1));
6823     IncrementPointer(cast<LoadSDNode>(L), MemVT, MPI, BasePtr, &ScaledOffset);
6824   }
6825 
6826   // Build the vector from the load operations.
6827   unsigned End = LdOps.size();
6828   if (!LdOps[0].getValueType().isVector())
6829     // All the loads are scalar loads.
6830     return BuildVectorFromScalar(DAG, WidenVT, LdOps, 0, End);
6831 
6832   // If the load contains vectors, build the vector using concat vector.
6833   // All of the vectors used to load are power-of-2, and the scalar loads can be
6834   // combined to make a power-of-2 vector.
6835   SmallVector<SDValue, 16> ConcatOps(End);
6836   int i = End - 1;
6837   int Idx = End;
6838   EVT LdTy = LdOps[i].getValueType();
6839   // First, combine the scalar loads to a vector.
6840   if (!LdTy.isVector())  {
6841     for (--i; i >= 0; --i) {
6842       LdTy = LdOps[i].getValueType();
6843       if (LdTy.isVector())
6844         break;
6845     }
6846     ConcatOps[--Idx] = BuildVectorFromScalar(DAG, LdTy, LdOps, i + 1, End);
6847   }
6848 
6849   ConcatOps[--Idx] = LdOps[i];
6850   for (--i; i >= 0; --i) {
6851     EVT NewLdTy = LdOps[i].getValueType();
6852     if (NewLdTy != LdTy) {
6853       // Create a larger vector.
6854       TypeSize LdTySize = LdTy.getSizeInBits();
6855       TypeSize NewLdTySize = NewLdTy.getSizeInBits();
6856       assert(NewLdTySize.isScalable() == LdTySize.isScalable() &&
6857              NewLdTySize.isKnownMultipleOf(LdTySize.getKnownMinValue()));
6858       unsigned NumOps =
6859           NewLdTySize.getKnownMinValue() / LdTySize.getKnownMinValue();
6860       SmallVector<SDValue, 16> WidenOps(NumOps);
6861       unsigned j = 0;
6862       for (; j != End-Idx; ++j)
6863         WidenOps[j] = ConcatOps[Idx+j];
6864       for (; j != NumOps; ++j)
6865         WidenOps[j] = DAG.getUNDEF(LdTy);
6866 
6867       ConcatOps[End-1] = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewLdTy,
6868                                      WidenOps);
6869       Idx = End - 1;
6870       LdTy = NewLdTy;
6871     }
6872     ConcatOps[--Idx] = LdOps[i];
6873   }
6874 
6875   if (WidenWidth == LdTy.getSizeInBits() * (End - Idx))
6876     return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT,
6877                        ArrayRef(&ConcatOps[Idx], End - Idx));
6878 
6879   // We need to fill the rest with undefs to build the vector.
6880   unsigned NumOps =
6881       WidenWidth.getKnownMinValue() / LdTy.getSizeInBits().getKnownMinValue();
6882   SmallVector<SDValue, 16> WidenOps(NumOps);
6883   SDValue UndefVal = DAG.getUNDEF(LdTy);
6884   {
6885     unsigned i = 0;
6886     for (; i != End-Idx; ++i)
6887       WidenOps[i] = ConcatOps[Idx+i];
6888     for (; i != NumOps; ++i)
6889       WidenOps[i] = UndefVal;
6890   }
6891   return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, WidenOps);
6892 }
6893 
6894 SDValue
GenWidenVectorExtLoads(SmallVectorImpl<SDValue> & LdChain,LoadSDNode * LD,ISD::LoadExtType ExtType)6895 DAGTypeLegalizer::GenWidenVectorExtLoads(SmallVectorImpl<SDValue> &LdChain,
6896                                          LoadSDNode *LD,
6897                                          ISD::LoadExtType ExtType) {
6898   // For extension loads, it may not be more efficient to chop up the vector
6899   // and then extend it. Instead, we unroll the load and build a new vector.
6900   EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(),LD->getValueType(0));
6901   EVT LdVT    = LD->getMemoryVT();
6902   SDLoc dl(LD);
6903   assert(LdVT.isVector() && WidenVT.isVector());
6904   assert(LdVT.isScalableVector() == WidenVT.isScalableVector());
6905 
6906   // Load information
6907   SDValue Chain = LD->getChain();
6908   SDValue BasePtr = LD->getBasePtr();
6909   MachineMemOperand::Flags MMOFlags = LD->getMemOperand()->getFlags();
6910   AAMDNodes AAInfo = LD->getAAInfo();
6911 
6912   if (LdVT.isScalableVector())
6913     report_fatal_error("Generating widen scalable extending vector loads is "
6914                        "not yet supported");
6915 
6916   EVT EltVT = WidenVT.getVectorElementType();
6917   EVT LdEltVT = LdVT.getVectorElementType();
6918   unsigned NumElts = LdVT.getVectorNumElements();
6919 
6920   // Load each element and widen.
6921   unsigned WidenNumElts = WidenVT.getVectorNumElements();
6922   SmallVector<SDValue, 16> Ops(WidenNumElts);
6923   unsigned Increment = LdEltVT.getSizeInBits() / 8;
6924   Ops[0] =
6925       DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr, LD->getPointerInfo(),
6926                      LdEltVT, LD->getOriginalAlign(), MMOFlags, AAInfo);
6927   LdChain.push_back(Ops[0].getValue(1));
6928   unsigned i = 0, Offset = Increment;
6929   for (i=1; i < NumElts; ++i, Offset += Increment) {
6930     SDValue NewBasePtr =
6931         DAG.getObjectPtrOffset(dl, BasePtr, TypeSize::Fixed(Offset));
6932     Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr,
6933                             LD->getPointerInfo().getWithOffset(Offset), LdEltVT,
6934                             LD->getOriginalAlign(), MMOFlags, AAInfo);
6935     LdChain.push_back(Ops[i].getValue(1));
6936   }
6937 
6938   // Fill the rest with undefs.
6939   SDValue UndefVal = DAG.getUNDEF(EltVT);
6940   for (; i != WidenNumElts; ++i)
6941     Ops[i] = UndefVal;
6942 
6943   return DAG.getBuildVector(WidenVT, dl, Ops);
6944 }
6945 
GenWidenVectorStores(SmallVectorImpl<SDValue> & StChain,StoreSDNode * ST)6946 bool DAGTypeLegalizer::GenWidenVectorStores(SmallVectorImpl<SDValue> &StChain,
6947                                             StoreSDNode *ST) {
6948   // The strategy assumes that we can efficiently store power-of-two widths.
6949   // The routine chops the vector into the largest vector stores with the same
6950   // element type or scalar stores.
6951   SDValue  Chain = ST->getChain();
6952   SDValue  BasePtr = ST->getBasePtr();
6953   MachineMemOperand::Flags MMOFlags = ST->getMemOperand()->getFlags();
6954   AAMDNodes AAInfo = ST->getAAInfo();
6955   SDValue  ValOp = GetWidenedVector(ST->getValue());
6956   SDLoc dl(ST);
6957 
6958   EVT StVT = ST->getMemoryVT();
6959   TypeSize StWidth = StVT.getSizeInBits();
6960   EVT ValVT = ValOp.getValueType();
6961   TypeSize ValWidth = ValVT.getSizeInBits();
6962   EVT ValEltVT = ValVT.getVectorElementType();
6963   unsigned ValEltWidth = ValEltVT.getFixedSizeInBits();
6964   assert(StVT.getVectorElementType() == ValEltVT);
6965   assert(StVT.isScalableVector() == ValVT.isScalableVector() &&
6966          "Mismatch between store and value types");
6967 
6968   int Idx = 0;          // current index to store
6969 
6970   MachinePointerInfo MPI = ST->getPointerInfo();
6971   uint64_t ScaledOffset = 0;
6972 
6973   // A breakdown of how to widen this vector store. Each element of the vector
6974   // is a memory VT combined with the number of times it is to be stored to,
6975   // e,g., v5i32 -> {{v2i32,2},{i32,1}}
6976   SmallVector<std::pair<EVT, unsigned>, 4> MemVTs;
6977 
6978   while (StWidth.isNonZero()) {
6979     // Find the largest vector type we can store with.
6980     std::optional<EVT> NewVT =
6981         findMemType(DAG, TLI, StWidth.getKnownMinValue(), ValVT);
6982     if (!NewVT)
6983       return false;
6984     MemVTs.push_back({*NewVT, 0});
6985     TypeSize NewVTWidth = NewVT->getSizeInBits();
6986 
6987     do {
6988       StWidth -= NewVTWidth;
6989       MemVTs.back().second++;
6990     } while (StWidth.isNonZero() && TypeSize::isKnownGE(StWidth, NewVTWidth));
6991   }
6992 
6993   for (const auto &Pair : MemVTs) {
6994     EVT NewVT = Pair.first;
6995     unsigned Count = Pair.second;
6996     TypeSize NewVTWidth = NewVT.getSizeInBits();
6997 
6998     if (NewVT.isVector()) {
6999       unsigned NumVTElts = NewVT.getVectorMinNumElements();
7000       do {
7001         Align NewAlign = ScaledOffset == 0
7002                              ? ST->getOriginalAlign()
7003                              : commonAlignment(ST->getAlign(), ScaledOffset);
7004         SDValue EOp = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NewVT, ValOp,
7005                                   DAG.getVectorIdxConstant(Idx, dl));
7006         SDValue PartStore = DAG.getStore(Chain, dl, EOp, BasePtr, MPI, NewAlign,
7007                                          MMOFlags, AAInfo);
7008         StChain.push_back(PartStore);
7009 
7010         Idx += NumVTElts;
7011         IncrementPointer(cast<StoreSDNode>(PartStore), NewVT, MPI, BasePtr,
7012                          &ScaledOffset);
7013       } while (--Count);
7014     } else {
7015       // Cast the vector to the scalar type we can store.
7016       unsigned NumElts = ValWidth.getFixedValue() / NewVTWidth.getFixedValue();
7017       EVT NewVecVT = EVT::getVectorVT(*DAG.getContext(), NewVT, NumElts);
7018       SDValue VecOp = DAG.getNode(ISD::BITCAST, dl, NewVecVT, ValOp);
7019       // Readjust index position based on new vector type.
7020       Idx = Idx * ValEltWidth / NewVTWidth.getFixedValue();
7021       do {
7022         SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, VecOp,
7023                                   DAG.getVectorIdxConstant(Idx++, dl));
7024         SDValue PartStore =
7025             DAG.getStore(Chain, dl, EOp, BasePtr, MPI, ST->getOriginalAlign(),
7026                          MMOFlags, AAInfo);
7027         StChain.push_back(PartStore);
7028 
7029         IncrementPointer(cast<StoreSDNode>(PartStore), NewVT, MPI, BasePtr);
7030       } while (--Count);
7031       // Restore index back to be relative to the original widen element type.
7032       Idx = Idx * NewVTWidth.getFixedValue() / ValEltWidth;
7033     }
7034   }
7035 
7036   return true;
7037 }
7038 
7039 /// Modifies a vector input (widen or narrows) to a vector of NVT.  The
7040 /// input vector must have the same element type as NVT.
7041 /// FillWithZeroes specifies that the vector should be widened with zeroes.
ModifyToType(SDValue InOp,EVT NVT,bool FillWithZeroes)7042 SDValue DAGTypeLegalizer::ModifyToType(SDValue InOp, EVT NVT,
7043                                        bool FillWithZeroes) {
7044   // Note that InOp might have been widened so it might already have
7045   // the right width or it might need be narrowed.
7046   EVT InVT = InOp.getValueType();
7047   assert(InVT.getVectorElementType() == NVT.getVectorElementType() &&
7048          "input and widen element type must match");
7049   assert(InVT.isScalableVector() == NVT.isScalableVector() &&
7050          "cannot modify scalable vectors in this way");
7051   SDLoc dl(InOp);
7052 
7053   // Check if InOp already has the right width.
7054   if (InVT == NVT)
7055     return InOp;
7056 
7057   ElementCount InEC = InVT.getVectorElementCount();
7058   ElementCount WidenEC = NVT.getVectorElementCount();
7059   if (WidenEC.hasKnownScalarFactor(InEC)) {
7060     unsigned NumConcat = WidenEC.getKnownScalarFactor(InEC);
7061     SmallVector<SDValue, 16> Ops(NumConcat);
7062     SDValue FillVal = FillWithZeroes ? DAG.getConstant(0, dl, InVT) :
7063       DAG.getUNDEF(InVT);
7064     Ops[0] = InOp;
7065     for (unsigned i = 1; i != NumConcat; ++i)
7066       Ops[i] = FillVal;
7067 
7068     return DAG.getNode(ISD::CONCAT_VECTORS, dl, NVT, Ops);
7069   }
7070 
7071   if (InEC.hasKnownScalarFactor(WidenEC))
7072     return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NVT, InOp,
7073                        DAG.getVectorIdxConstant(0, dl));
7074 
7075   assert(!InVT.isScalableVector() && !NVT.isScalableVector() &&
7076          "Scalable vectors should have been handled already.");
7077 
7078   unsigned InNumElts = InEC.getFixedValue();
7079   unsigned WidenNumElts = WidenEC.getFixedValue();
7080 
7081   // Fall back to extract and build (+ mask, if padding with zeros).
7082   SmallVector<SDValue, 16> Ops(WidenNumElts);
7083   EVT EltVT = NVT.getVectorElementType();
7084   unsigned MinNumElts = std::min(WidenNumElts, InNumElts);
7085   unsigned Idx;
7086   for (Idx = 0; Idx < MinNumElts; ++Idx)
7087     Ops[Idx] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp,
7088                            DAG.getVectorIdxConstant(Idx, dl));
7089 
7090   SDValue UndefVal = DAG.getUNDEF(EltVT);
7091   for (; Idx < WidenNumElts; ++Idx)
7092     Ops[Idx] = UndefVal;
7093 
7094   SDValue Widened = DAG.getBuildVector(NVT, dl, Ops);
7095   if (!FillWithZeroes)
7096     return Widened;
7097 
7098   assert(NVT.isInteger() &&
7099          "We expect to never want to FillWithZeroes for non-integral types.");
7100 
7101   SmallVector<SDValue, 16> MaskOps;
7102   MaskOps.append(MinNumElts, DAG.getAllOnesConstant(dl, EltVT));
7103   MaskOps.append(WidenNumElts - MinNumElts, DAG.getConstant(0, dl, EltVT));
7104 
7105   return DAG.getNode(ISD::AND, dl, NVT, Widened,
7106                      DAG.getBuildVector(NVT, dl, MaskOps));
7107 }
7108