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