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::FP_ROUND_INREG
: R
= ScalarizeVecRes_InregOp(N
); break;
56 case ISD::FPOWI
: R
= ScalarizeVecRes_FPOWI(N
); break;
57 case ISD::INSERT_VECTOR_ELT
: R
= ScalarizeVecRes_INSERT_VECTOR_ELT(N
); break;
58 case ISD::LOAD
: R
= ScalarizeVecRes_LOAD(cast
<LoadSDNode
>(N
));break;
59 case ISD::SCALAR_TO_VECTOR
: R
= ScalarizeVecRes_SCALAR_TO_VECTOR(N
); break;
60 case ISD::SIGN_EXTEND_INREG
: R
= ScalarizeVecRes_InregOp(N
); break;
61 case ISD::VSELECT
: R
= ScalarizeVecRes_VSELECT(N
); break;
62 case ISD::SELECT
: R
= ScalarizeVecRes_SELECT(N
); break;
63 case ISD::SELECT_CC
: R
= ScalarizeVecRes_SELECT_CC(N
); break;
64 case ISD::SETCC
: R
= ScalarizeVecRes_SETCC(N
); break;
65 case ISD::UNDEF
: R
= ScalarizeVecRes_UNDEF(N
); break;
66 case ISD::VECTOR_SHUFFLE
: R
= ScalarizeVecRes_VECTOR_SHUFFLE(N
); break;
67 case ISD::ANY_EXTEND_VECTOR_INREG
:
68 case ISD::SIGN_EXTEND_VECTOR_INREG
:
69 case ISD::ZERO_EXTEND_VECTOR_INREG
:
70 R
= ScalarizeVecRes_VecInregOp(N
);
77 case ISD::CTLZ_ZERO_UNDEF
:
80 case ISD::CTTZ_ZERO_UNDEF
:
100 case ISD::SIGN_EXTEND
:
101 case ISD::SINT_TO_FP
:
103 case ISD::UINT_TO_FP
:
104 case ISD::ZERO_EXTEND
:
105 case ISD::FCANONICALIZE
:
106 R
= ScalarizeVecRes_UnaryOp(N
);
117 case ISD::FMINNUM_IEEE
:
118 case ISD::FMAXNUM_IEEE
:
145 R
= ScalarizeVecRes_BinOp(N
);
148 R
= ScalarizeVecRes_TernaryOp(N
);
150 case ISD::STRICT_FADD
:
151 case ISD::STRICT_FSUB
:
152 case ISD::STRICT_FMUL
:
153 case ISD::STRICT_FDIV
:
154 case ISD::STRICT_FREM
:
155 case ISD::STRICT_FSQRT
:
156 case ISD::STRICT_FMA
:
157 case ISD::STRICT_FPOW
:
158 case ISD::STRICT_FPOWI
:
159 case ISD::STRICT_FSIN
:
160 case ISD::STRICT_FCOS
:
161 case ISD::STRICT_FEXP
:
162 case ISD::STRICT_FEXP2
:
163 case ISD::STRICT_FLOG
:
164 case ISD::STRICT_FLOG10
:
165 case ISD::STRICT_FLOG2
:
166 case ISD::STRICT_FRINT
:
167 case ISD::STRICT_FNEARBYINT
:
168 case ISD::STRICT_FMAXNUM
:
169 case ISD::STRICT_FMINNUM
:
170 case ISD::STRICT_FCEIL
:
171 case ISD::STRICT_FFLOOR
:
172 case ISD::STRICT_FROUND
:
173 case ISD::STRICT_FTRUNC
:
174 case ISD::STRICT_FP_EXTEND
:
175 R
= ScalarizeVecRes_StrictFPOp(N
);
183 R
= ScalarizeVecRes_OverflowOp(N
, ResNo
);
186 case ISD::SMULFIXSAT
:
188 R
= ScalarizeVecRes_MULFIX(N
);
192 // If R is null, the sub-method took care of registering the result.
194 SetScalarizedVector(SDValue(N
, ResNo
), R
);
197 SDValue
DAGTypeLegalizer::ScalarizeVecRes_BinOp(SDNode
*N
) {
198 SDValue LHS
= GetScalarizedVector(N
->getOperand(0));
199 SDValue RHS
= GetScalarizedVector(N
->getOperand(1));
200 return DAG
.getNode(N
->getOpcode(), SDLoc(N
),
201 LHS
.getValueType(), LHS
, RHS
, N
->getFlags());
204 SDValue
DAGTypeLegalizer::ScalarizeVecRes_TernaryOp(SDNode
*N
) {
205 SDValue Op0
= GetScalarizedVector(N
->getOperand(0));
206 SDValue Op1
= GetScalarizedVector(N
->getOperand(1));
207 SDValue Op2
= GetScalarizedVector(N
->getOperand(2));
208 return DAG
.getNode(N
->getOpcode(), SDLoc(N
),
209 Op0
.getValueType(), Op0
, Op1
, Op2
);
212 SDValue
DAGTypeLegalizer::ScalarizeVecRes_MULFIX(SDNode
*N
) {
213 SDValue Op0
= GetScalarizedVector(N
->getOperand(0));
214 SDValue Op1
= GetScalarizedVector(N
->getOperand(1));
215 SDValue Op2
= N
->getOperand(2);
216 return DAG
.getNode(N
->getOpcode(), SDLoc(N
), Op0
.getValueType(), Op0
, Op1
,
220 SDValue
DAGTypeLegalizer::ScalarizeVecRes_StrictFPOp(SDNode
*N
) {
221 EVT VT
= N
->getValueType(0).getVectorElementType();
222 unsigned NumOpers
= N
->getNumOperands();
223 SDValue Chain
= N
->getOperand(0);
224 EVT ValueVTs
[] = {VT
, MVT::Other
};
227 SmallVector
<SDValue
, 4> Opers
;
229 // The Chain is the first operand.
230 Opers
.push_back(Chain
);
232 // Now process the remaining operands.
233 for (unsigned i
= 1; i
< NumOpers
; ++i
) {
234 SDValue Oper
= N
->getOperand(i
);
236 if (Oper
.getValueType().isVector())
237 Oper
= GetScalarizedVector(Oper
);
239 Opers
.push_back(Oper
);
242 SDValue Result
= DAG
.getNode(N
->getOpcode(), dl
, ValueVTs
, Opers
);
244 // Legalize the chain result - switch anything that used the old chain to
246 ReplaceValueWith(SDValue(N
, 1), Result
.getValue(1));
250 SDValue
DAGTypeLegalizer::ScalarizeVecRes_OverflowOp(SDNode
*N
,
253 EVT ResVT
= N
->getValueType(0);
254 EVT OvVT
= N
->getValueType(1);
256 SDValue ScalarLHS
, ScalarRHS
;
257 if (getTypeAction(ResVT
) == TargetLowering::TypeScalarizeVector
) {
258 ScalarLHS
= GetScalarizedVector(N
->getOperand(0));
259 ScalarRHS
= GetScalarizedVector(N
->getOperand(1));
261 SmallVector
<SDValue
, 1> ElemsLHS
, ElemsRHS
;
262 DAG
.ExtractVectorElements(N
->getOperand(0), ElemsLHS
);
263 DAG
.ExtractVectorElements(N
->getOperand(1), ElemsRHS
);
264 ScalarLHS
= ElemsLHS
[0];
265 ScalarRHS
= ElemsRHS
[0];
268 SDVTList ScalarVTs
= DAG
.getVTList(
269 ResVT
.getVectorElementType(), OvVT
.getVectorElementType());
270 SDNode
*ScalarNode
= DAG
.getNode(
271 N
->getOpcode(), DL
, ScalarVTs
, ScalarLHS
, ScalarRHS
).getNode();
273 // Replace the other vector result not being explicitly scalarized here.
274 unsigned OtherNo
= 1 - ResNo
;
275 EVT OtherVT
= N
->getValueType(OtherNo
);
276 if (getTypeAction(OtherVT
) == TargetLowering::TypeScalarizeVector
) {
277 SetScalarizedVector(SDValue(N
, OtherNo
), SDValue(ScalarNode
, OtherNo
));
279 SDValue OtherVal
= DAG
.getNode(
280 ISD::SCALAR_TO_VECTOR
, DL
, OtherVT
, SDValue(ScalarNode
, OtherNo
));
281 ReplaceValueWith(SDValue(N
, OtherNo
), OtherVal
);
284 return SDValue(ScalarNode
, ResNo
);
287 SDValue
DAGTypeLegalizer::ScalarizeVecRes_MERGE_VALUES(SDNode
*N
,
289 SDValue Op
= DisintegrateMERGE_VALUES(N
, ResNo
);
290 return GetScalarizedVector(Op
);
293 SDValue
DAGTypeLegalizer::ScalarizeVecRes_BITCAST(SDNode
*N
) {
294 SDValue Op
= N
->getOperand(0);
295 if (Op
.getValueType().isVector()
296 && Op
.getValueType().getVectorNumElements() == 1
297 && !isSimpleLegalType(Op
.getValueType()))
298 Op
= GetScalarizedVector(Op
);
299 EVT NewVT
= N
->getValueType(0).getVectorElementType();
300 return DAG
.getNode(ISD::BITCAST
, SDLoc(N
),
304 SDValue
DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(SDNode
*N
) {
305 EVT EltVT
= N
->getValueType(0).getVectorElementType();
306 SDValue InOp
= N
->getOperand(0);
307 // The BUILD_VECTOR operands may be of wider element types and
308 // we may need to truncate them back to the requested return type.
309 if (EltVT
.isInteger())
310 return DAG
.getNode(ISD::TRUNCATE
, SDLoc(N
), EltVT
, InOp
);
314 SDValue
DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode
*N
) {
315 return DAG
.getNode(ISD::EXTRACT_VECTOR_ELT
, SDLoc(N
),
316 N
->getValueType(0).getVectorElementType(),
317 N
->getOperand(0), N
->getOperand(1));
320 SDValue
DAGTypeLegalizer::ScalarizeVecRes_FP_ROUND(SDNode
*N
) {
321 EVT NewVT
= N
->getValueType(0).getVectorElementType();
322 SDValue Op
= GetScalarizedVector(N
->getOperand(0));
323 return DAG
.getNode(ISD::FP_ROUND
, SDLoc(N
),
324 NewVT
, Op
, N
->getOperand(1));
327 SDValue
DAGTypeLegalizer::ScalarizeVecRes_STRICT_FP_ROUND(SDNode
*N
) {
328 EVT NewVT
= N
->getValueType(0).getVectorElementType();
329 SDValue Op
= GetScalarizedVector(N
->getOperand(1));
330 SDValue Res
= DAG
.getNode(ISD::STRICT_FP_ROUND
, SDLoc(N
),
331 { NewVT
, MVT::Other
},
332 { N
->getOperand(0), Op
, N
->getOperand(2) });
333 // Legalize the chain result - switch anything that used the old chain to
335 ReplaceValueWith(SDValue(N
, 1), Res
.getValue(1));
339 SDValue
DAGTypeLegalizer::ScalarizeVecRes_FPOWI(SDNode
*N
) {
340 SDValue Op
= GetScalarizedVector(N
->getOperand(0));
341 return DAG
.getNode(ISD::FPOWI
, SDLoc(N
),
342 Op
.getValueType(), Op
, N
->getOperand(1));
345 SDValue
DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode
*N
) {
346 // The value to insert may have a wider type than the vector element type,
347 // so be sure to truncate it to the element type if necessary.
348 SDValue Op
= N
->getOperand(1);
349 EVT EltVT
= N
->getValueType(0).getVectorElementType();
350 if (Op
.getValueType() != EltVT
)
351 // FIXME: Can this happen for floating point types?
352 Op
= DAG
.getNode(ISD::TRUNCATE
, SDLoc(N
), EltVT
, Op
);
356 SDValue
DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode
*N
) {
357 assert(N
->isUnindexed() && "Indexed vector load?");
359 SDValue Result
= DAG
.getLoad(
360 ISD::UNINDEXED
, N
->getExtensionType(),
361 N
->getValueType(0).getVectorElementType(), SDLoc(N
), N
->getChain(),
362 N
->getBasePtr(), DAG
.getUNDEF(N
->getBasePtr().getValueType()),
363 N
->getPointerInfo(), N
->getMemoryVT().getVectorElementType(),
364 N
->getOriginalAlignment(), N
->getMemOperand()->getFlags(),
367 // Legalize the chain result - switch anything that used the old chain to
369 ReplaceValueWith(SDValue(N
, 1), Result
.getValue(1));
373 SDValue
DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(SDNode
*N
) {
374 // Get the dest type - it doesn't always match the input type, e.g. int_to_fp.
375 EVT DestVT
= N
->getValueType(0).getVectorElementType();
376 SDValue Op
= N
->getOperand(0);
377 EVT OpVT
= Op
.getValueType();
379 // The result needs scalarizing, but it's not a given that the source does.
380 // This is a workaround for targets where it's impossible to scalarize the
381 // result of a conversion, because the source type is legal.
382 // For instance, this happens on AArch64: v1i1 is illegal but v1i{8,16,32}
383 // are widened to v8i8, v4i16, and v2i32, which is legal, because v1i64 is
384 // legal and was not scalarized.
385 // See the similar logic in ScalarizeVecRes_SETCC
386 if (getTypeAction(OpVT
) == TargetLowering::TypeScalarizeVector
) {
387 Op
= GetScalarizedVector(Op
);
389 EVT VT
= OpVT
.getVectorElementType();
391 ISD::EXTRACT_VECTOR_ELT
, DL
, VT
, Op
,
392 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
394 return DAG
.getNode(N
->getOpcode(), SDLoc(N
), DestVT
, Op
);
397 SDValue
DAGTypeLegalizer::ScalarizeVecRes_InregOp(SDNode
*N
) {
398 EVT EltVT
= N
->getValueType(0).getVectorElementType();
399 EVT ExtVT
= cast
<VTSDNode
>(N
->getOperand(1))->getVT().getVectorElementType();
400 SDValue LHS
= GetScalarizedVector(N
->getOperand(0));
401 return DAG
.getNode(N
->getOpcode(), SDLoc(N
), EltVT
,
402 LHS
, DAG
.getValueType(ExtVT
));
405 SDValue
DAGTypeLegalizer::ScalarizeVecRes_VecInregOp(SDNode
*N
) {
407 SDValue Op
= N
->getOperand(0);
409 EVT OpVT
= Op
.getValueType();
410 EVT OpEltVT
= OpVT
.getVectorElementType();
411 EVT EltVT
= N
->getValueType(0).getVectorElementType();
413 if (getTypeAction(OpVT
) == TargetLowering::TypeScalarizeVector
) {
414 Op
= GetScalarizedVector(Op
);
417 ISD::EXTRACT_VECTOR_ELT
, DL
, OpEltVT
, Op
,
418 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
421 switch (N
->getOpcode()) {
422 case ISD::ANY_EXTEND_VECTOR_INREG
:
423 return DAG
.getNode(ISD::ANY_EXTEND
, DL
, EltVT
, Op
);
424 case ISD::SIGN_EXTEND_VECTOR_INREG
:
425 return DAG
.getNode(ISD::SIGN_EXTEND
, DL
, EltVT
, Op
);
426 case ISD::ZERO_EXTEND_VECTOR_INREG
:
427 return DAG
.getNode(ISD::ZERO_EXTEND
, DL
, EltVT
, Op
);
430 llvm_unreachable("Illegal extend_vector_inreg opcode");
433 SDValue
DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode
*N
) {
434 // If the operand is wider than the vector element type then it is implicitly
435 // truncated. Make that explicit here.
436 EVT EltVT
= N
->getValueType(0).getVectorElementType();
437 SDValue InOp
= N
->getOperand(0);
438 if (InOp
.getValueType() != EltVT
)
439 return DAG
.getNode(ISD::TRUNCATE
, SDLoc(N
), EltVT
, InOp
);
443 SDValue
DAGTypeLegalizer::ScalarizeVecRes_VSELECT(SDNode
*N
) {
444 SDValue Cond
= N
->getOperand(0);
445 EVT OpVT
= Cond
.getValueType();
447 // The vselect result and true/value operands needs scalarizing, but it's
448 // not a given that the Cond does. For instance, in AVX512 v1i1 is legal.
449 // See the similar logic in ScalarizeVecRes_SETCC
450 if (getTypeAction(OpVT
) == TargetLowering::TypeScalarizeVector
) {
451 Cond
= GetScalarizedVector(Cond
);
453 EVT VT
= OpVT
.getVectorElementType();
455 ISD::EXTRACT_VECTOR_ELT
, DL
, VT
, Cond
,
456 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
459 SDValue LHS
= GetScalarizedVector(N
->getOperand(1));
460 TargetLowering::BooleanContent ScalarBool
=
461 TLI
.getBooleanContents(false, false);
462 TargetLowering::BooleanContent VecBool
= TLI
.getBooleanContents(true, false);
464 // If integer and float booleans have different contents then we can't
465 // reliably optimize in all cases. There is a full explanation for this in
466 // DAGCombiner::visitSELECT() where the same issue affects folding
467 // (select C, 0, 1) to (xor C, 1).
468 if (TLI
.getBooleanContents(false, false) !=
469 TLI
.getBooleanContents(false, true)) {
470 // At least try the common case where the boolean is generated by a
472 if (Cond
->getOpcode() == ISD::SETCC
) {
473 EVT OpVT
= Cond
->getOperand(0).getValueType();
474 ScalarBool
= TLI
.getBooleanContents(OpVT
.getScalarType());
475 VecBool
= TLI
.getBooleanContents(OpVT
);
477 ScalarBool
= TargetLowering::UndefinedBooleanContent
;
480 EVT CondVT
= Cond
.getValueType();
481 if (ScalarBool
!= VecBool
) {
482 switch (ScalarBool
) {
483 case TargetLowering::UndefinedBooleanContent
:
485 case TargetLowering::ZeroOrOneBooleanContent
:
486 assert(VecBool
== TargetLowering::UndefinedBooleanContent
||
487 VecBool
== TargetLowering::ZeroOrNegativeOneBooleanContent
);
488 // Vector read from all ones, scalar expects a single 1 so mask.
489 Cond
= DAG
.getNode(ISD::AND
, SDLoc(N
), CondVT
,
490 Cond
, DAG
.getConstant(1, SDLoc(N
), CondVT
));
492 case TargetLowering::ZeroOrNegativeOneBooleanContent
:
493 assert(VecBool
== TargetLowering::UndefinedBooleanContent
||
494 VecBool
== TargetLowering::ZeroOrOneBooleanContent
);
495 // Vector reads from a one, scalar from all ones so sign extend.
496 Cond
= DAG
.getNode(ISD::SIGN_EXTEND_INREG
, SDLoc(N
), CondVT
,
497 Cond
, DAG
.getValueType(MVT::i1
));
502 // Truncate the condition if needed
503 auto BoolVT
= getSetCCResultType(CondVT
);
504 if (BoolVT
.bitsLT(CondVT
))
505 Cond
= DAG
.getNode(ISD::TRUNCATE
, SDLoc(N
), BoolVT
, Cond
);
507 return DAG
.getSelect(SDLoc(N
),
508 LHS
.getValueType(), Cond
, LHS
,
509 GetScalarizedVector(N
->getOperand(2)));
512 SDValue
DAGTypeLegalizer::ScalarizeVecRes_SELECT(SDNode
*N
) {
513 SDValue LHS
= GetScalarizedVector(N
->getOperand(1));
514 return DAG
.getSelect(SDLoc(N
),
515 LHS
.getValueType(), N
->getOperand(0), LHS
,
516 GetScalarizedVector(N
->getOperand(2)));
519 SDValue
DAGTypeLegalizer::ScalarizeVecRes_SELECT_CC(SDNode
*N
) {
520 SDValue LHS
= GetScalarizedVector(N
->getOperand(2));
521 return DAG
.getNode(ISD::SELECT_CC
, SDLoc(N
), LHS
.getValueType(),
522 N
->getOperand(0), N
->getOperand(1),
523 LHS
, GetScalarizedVector(N
->getOperand(3)),
527 SDValue
DAGTypeLegalizer::ScalarizeVecRes_UNDEF(SDNode
*N
) {
528 return DAG
.getUNDEF(N
->getValueType(0).getVectorElementType());
531 SDValue
DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(SDNode
*N
) {
532 // Figure out if the scalar is the LHS or RHS and return it.
533 SDValue Arg
= N
->getOperand(2).getOperand(0);
535 return DAG
.getUNDEF(N
->getValueType(0).getVectorElementType());
536 unsigned Op
= !cast
<ConstantSDNode
>(Arg
)->isNullValue();
537 return GetScalarizedVector(N
->getOperand(Op
));
540 SDValue
DAGTypeLegalizer::ScalarizeVecRes_SETCC(SDNode
*N
) {
541 assert(N
->getValueType(0).isVector() &&
542 N
->getOperand(0).getValueType().isVector() &&
543 "Operand types must be vectors");
544 SDValue LHS
= N
->getOperand(0);
545 SDValue RHS
= N
->getOperand(1);
546 EVT OpVT
= LHS
.getValueType();
547 EVT NVT
= N
->getValueType(0).getVectorElementType();
550 // The result needs scalarizing, but it's not a given that the source does.
551 if (getTypeAction(OpVT
) == TargetLowering::TypeScalarizeVector
) {
552 LHS
= GetScalarizedVector(LHS
);
553 RHS
= GetScalarizedVector(RHS
);
555 EVT VT
= OpVT
.getVectorElementType();
557 ISD::EXTRACT_VECTOR_ELT
, DL
, VT
, LHS
,
558 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
560 ISD::EXTRACT_VECTOR_ELT
, DL
, VT
, RHS
,
561 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
564 // Turn it into a scalar SETCC.
565 SDValue Res
= DAG
.getNode(ISD::SETCC
, DL
, MVT::i1
, LHS
, RHS
,
567 // Vectors may have a different boolean contents to scalars. Promote the
568 // value appropriately.
569 ISD::NodeType ExtendCode
=
570 TargetLowering::getExtendForContent(TLI
.getBooleanContents(OpVT
));
571 return DAG
.getNode(ExtendCode
, DL
, NVT
, Res
);
575 //===----------------------------------------------------------------------===//
576 // Operand Vector Scalarization <1 x ty> -> ty.
577 //===----------------------------------------------------------------------===//
579 bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode
*N
, unsigned OpNo
) {
580 LLVM_DEBUG(dbgs() << "Scalarize node operand " << OpNo
<< ": "; N
->dump(&DAG
);
582 SDValue Res
= SDValue();
584 if (!Res
.getNode()) {
585 switch (N
->getOpcode()) {
588 dbgs() << "ScalarizeVectorOperand Op #" << OpNo
<< ": ";
592 report_fatal_error("Do not know how to scalarize this operator's "
595 Res
= ScalarizeVecOp_BITCAST(N
);
597 case ISD::ANY_EXTEND
:
598 case ISD::ZERO_EXTEND
:
599 case ISD::SIGN_EXTEND
:
601 case ISD::FP_TO_SINT
:
602 case ISD::FP_TO_UINT
:
603 case ISD::SINT_TO_FP
:
604 case ISD::UINT_TO_FP
:
605 Res
= ScalarizeVecOp_UnaryOp(N
);
607 case ISD::CONCAT_VECTORS
:
608 Res
= ScalarizeVecOp_CONCAT_VECTORS(N
);
610 case ISD::EXTRACT_VECTOR_ELT
:
611 Res
= ScalarizeVecOp_EXTRACT_VECTOR_ELT(N
);
614 Res
= ScalarizeVecOp_VSELECT(N
);
617 Res
= ScalarizeVecOp_VSETCC(N
);
620 Res
= ScalarizeVecOp_STORE(cast
<StoreSDNode
>(N
), OpNo
);
622 case ISD::STRICT_FP_ROUND
:
623 Res
= ScalarizeVecOp_STRICT_FP_ROUND(N
, OpNo
);
626 Res
= ScalarizeVecOp_FP_ROUND(N
, OpNo
);
628 case ISD::VECREDUCE_FADD
:
629 case ISD::VECREDUCE_FMUL
:
630 case ISD::VECREDUCE_ADD
:
631 case ISD::VECREDUCE_MUL
:
632 case ISD::VECREDUCE_AND
:
633 case ISD::VECREDUCE_OR
:
634 case ISD::VECREDUCE_XOR
:
635 case ISD::VECREDUCE_SMAX
:
636 case ISD::VECREDUCE_SMIN
:
637 case ISD::VECREDUCE_UMAX
:
638 case ISD::VECREDUCE_UMIN
:
639 case ISD::VECREDUCE_FMAX
:
640 case ISD::VECREDUCE_FMIN
:
641 Res
= ScalarizeVecOp_VECREDUCE(N
);
646 // If the result is null, the sub-method took care of registering results etc.
647 if (!Res
.getNode()) return false;
649 // If the result is N, the sub-method updated N in place. Tell the legalizer
651 if (Res
.getNode() == N
)
654 assert(Res
.getValueType() == N
->getValueType(0) && N
->getNumValues() == 1 &&
655 "Invalid operand expansion");
657 ReplaceValueWith(SDValue(N
, 0), Res
);
661 /// If the value to convert is a vector that needs to be scalarized, it must be
662 /// <1 x ty>. Convert the element instead.
663 SDValue
DAGTypeLegalizer::ScalarizeVecOp_BITCAST(SDNode
*N
) {
664 SDValue Elt
= GetScalarizedVector(N
->getOperand(0));
665 return DAG
.getNode(ISD::BITCAST
, SDLoc(N
),
666 N
->getValueType(0), Elt
);
669 /// If the input is a vector that needs to be scalarized, it must be <1 x ty>.
670 /// Do the operation on the element instead.
671 SDValue
DAGTypeLegalizer::ScalarizeVecOp_UnaryOp(SDNode
*N
) {
672 assert(N
->getValueType(0).getVectorNumElements() == 1 &&
673 "Unexpected vector type!");
674 SDValue Elt
= GetScalarizedVector(N
->getOperand(0));
675 SDValue Op
= DAG
.getNode(N
->getOpcode(), SDLoc(N
),
676 N
->getValueType(0).getScalarType(), Elt
);
677 // Revectorize the result so the types line up with what the uses of this
678 // expression expect.
679 return DAG
.getNode(ISD::SCALAR_TO_VECTOR
, SDLoc(N
), N
->getValueType(0), Op
);
682 /// The vectors to concatenate have length one - use a BUILD_VECTOR instead.
683 SDValue
DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(SDNode
*N
) {
684 SmallVector
<SDValue
, 8> Ops(N
->getNumOperands());
685 for (unsigned i
= 0, e
= N
->getNumOperands(); i
< e
; ++i
)
686 Ops
[i
] = GetScalarizedVector(N
->getOperand(i
));
687 return DAG
.getBuildVector(N
->getValueType(0), SDLoc(N
), Ops
);
690 /// If the input is a vector that needs to be scalarized, it must be <1 x ty>,
691 /// so just return the element, ignoring the index.
692 SDValue
DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode
*N
) {
693 EVT VT
= N
->getValueType(0);
694 SDValue Res
= GetScalarizedVector(N
->getOperand(0));
695 if (Res
.getValueType() != VT
)
696 Res
= VT
.isFloatingPoint()
697 ? DAG
.getNode(ISD::FP_EXTEND
, SDLoc(N
), VT
, Res
)
698 : DAG
.getNode(ISD::ANY_EXTEND
, SDLoc(N
), VT
, Res
);
702 /// If the input condition is a vector that needs to be scalarized, it must be
703 /// <1 x i1>, so just convert to a normal ISD::SELECT
704 /// (still with vector output type since that was acceptable if we got here).
705 SDValue
DAGTypeLegalizer::ScalarizeVecOp_VSELECT(SDNode
*N
) {
706 SDValue ScalarCond
= GetScalarizedVector(N
->getOperand(0));
707 EVT VT
= N
->getValueType(0);
709 return DAG
.getNode(ISD::SELECT
, SDLoc(N
), VT
, ScalarCond
, N
->getOperand(1),
713 /// If the operand is a vector that needs to be scalarized then the
714 /// result must be v1i1, so just convert to a scalar SETCC and wrap
715 /// with a scalar_to_vector since the res type is legal if we got here
716 SDValue
DAGTypeLegalizer::ScalarizeVecOp_VSETCC(SDNode
*N
) {
717 assert(N
->getValueType(0).isVector() &&
718 N
->getOperand(0).getValueType().isVector() &&
719 "Operand types must be vectors");
720 assert(N
->getValueType(0) == MVT::v1i1
&& "Expected v1i1 type");
722 EVT VT
= N
->getValueType(0);
723 SDValue LHS
= GetScalarizedVector(N
->getOperand(0));
724 SDValue RHS
= GetScalarizedVector(N
->getOperand(1));
726 EVT OpVT
= N
->getOperand(0).getValueType();
727 EVT NVT
= VT
.getVectorElementType();
729 // Turn it into a scalar SETCC.
730 SDValue Res
= DAG
.getNode(ISD::SETCC
, DL
, MVT::i1
, LHS
, RHS
,
733 // Vectors may have a different boolean contents to scalars. Promote the
734 // value appropriately.
735 ISD::NodeType ExtendCode
=
736 TargetLowering::getExtendForContent(TLI
.getBooleanContents(OpVT
));
738 Res
= DAG
.getNode(ExtendCode
, DL
, NVT
, Res
);
740 return DAG
.getNode(ISD::SCALAR_TO_VECTOR
, DL
, VT
, Res
);
743 /// If the value to store is a vector that needs to be scalarized, it must be
744 /// <1 x ty>. Just store the element.
745 SDValue
DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode
*N
, unsigned OpNo
){
746 assert(N
->isUnindexed() && "Indexed store of one-element vector?");
747 assert(OpNo
== 1 && "Do not know how to scalarize this operand!");
750 if (N
->isTruncatingStore())
751 return DAG
.getTruncStore(
752 N
->getChain(), dl
, GetScalarizedVector(N
->getOperand(1)),
753 N
->getBasePtr(), N
->getPointerInfo(),
754 N
->getMemoryVT().getVectorElementType(), N
->getAlignment(),
755 N
->getMemOperand()->getFlags(), N
->getAAInfo());
757 return DAG
.getStore(N
->getChain(), dl
, GetScalarizedVector(N
->getOperand(1)),
758 N
->getBasePtr(), N
->getPointerInfo(),
759 N
->getOriginalAlignment(), N
->getMemOperand()->getFlags(),
763 /// If the value to round is a vector that needs to be scalarized, it must be
764 /// <1 x ty>. Convert the element instead.
765 SDValue
DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(SDNode
*N
, unsigned OpNo
) {
766 SDValue Elt
= GetScalarizedVector(N
->getOperand(0));
767 SDValue Res
= DAG
.getNode(ISD::FP_ROUND
, SDLoc(N
),
768 N
->getValueType(0).getVectorElementType(), Elt
,
770 return DAG
.getNode(ISD::SCALAR_TO_VECTOR
, SDLoc(N
), N
->getValueType(0), Res
);
773 SDValue
DAGTypeLegalizer::ScalarizeVecOp_STRICT_FP_ROUND(SDNode
*N
,
775 assert(OpNo
== 1 && "Wrong operand for scalarization!");
776 SDValue Elt
= GetScalarizedVector(N
->getOperand(1));
777 SDValue Res
= DAG
.getNode(ISD::STRICT_FP_ROUND
, SDLoc(N
),
778 { N
->getValueType(0).getVectorElementType(),
780 { N
->getOperand(0), Elt
, N
->getOperand(2) });
781 // Legalize the chain result - switch anything that used the old chain to
783 ReplaceValueWith(SDValue(N
, 1), Res
.getValue(1));
784 return DAG
.getNode(ISD::SCALAR_TO_VECTOR
, SDLoc(N
), N
->getValueType(0), Res
);
787 SDValue
DAGTypeLegalizer::ScalarizeVecOp_VECREDUCE(SDNode
*N
) {
788 SDValue Res
= GetScalarizedVector(N
->getOperand(0));
789 // Result type may be wider than element type.
790 if (Res
.getValueType() != N
->getValueType(0))
791 Res
= DAG
.getNode(ISD::ANY_EXTEND
, SDLoc(N
), N
->getValueType(0), Res
);
795 //===----------------------------------------------------------------------===//
796 // Result Vector Splitting
797 //===----------------------------------------------------------------------===//
799 /// This method is called when the specified result of the specified node is
800 /// found to need vector splitting. At this point, the node may also have
801 /// invalid operands or may have other results that need legalization, we just
802 /// know that (at least) one result needs vector splitting.
803 void DAGTypeLegalizer::SplitVectorResult(SDNode
*N
, unsigned ResNo
) {
804 LLVM_DEBUG(dbgs() << "Split node result: "; N
->dump(&DAG
); dbgs() << "\n");
807 // See if the target wants to custom expand this node.
808 if (CustomLowerNode(N
, N
->getValueType(ResNo
), true))
811 switch (N
->getOpcode()) {
814 dbgs() << "SplitVectorResult #" << ResNo
<< ": ";
818 report_fatal_error("Do not know how to split the result of this "
821 case ISD::MERGE_VALUES
: SplitRes_MERGE_VALUES(N
, ResNo
, Lo
, Hi
); break;
823 case ISD::SELECT
: SplitRes_SELECT(N
, Lo
, Hi
); break;
824 case ISD::SELECT_CC
: SplitRes_SELECT_CC(N
, Lo
, Hi
); break;
825 case ISD::UNDEF
: SplitRes_UNDEF(N
, Lo
, Hi
); break;
826 case ISD::BITCAST
: SplitVecRes_BITCAST(N
, Lo
, Hi
); break;
827 case ISD::BUILD_VECTOR
: SplitVecRes_BUILD_VECTOR(N
, Lo
, Hi
); break;
828 case ISD::CONCAT_VECTORS
: SplitVecRes_CONCAT_VECTORS(N
, Lo
, Hi
); break;
829 case ISD::EXTRACT_SUBVECTOR
: SplitVecRes_EXTRACT_SUBVECTOR(N
, Lo
, Hi
); break;
830 case ISD::INSERT_SUBVECTOR
: SplitVecRes_INSERT_SUBVECTOR(N
, Lo
, Hi
); break;
831 case ISD::FP_ROUND_INREG
: SplitVecRes_InregOp(N
, Lo
, Hi
); break;
832 case ISD::FPOWI
: SplitVecRes_FPOWI(N
, Lo
, Hi
); break;
833 case ISD::FCOPYSIGN
: SplitVecRes_FCOPYSIGN(N
, Lo
, Hi
); break;
834 case ISD::INSERT_VECTOR_ELT
: SplitVecRes_INSERT_VECTOR_ELT(N
, Lo
, Hi
); break;
835 case ISD::SCALAR_TO_VECTOR
: SplitVecRes_SCALAR_TO_VECTOR(N
, Lo
, Hi
); break;
836 case ISD::SIGN_EXTEND_INREG
: SplitVecRes_InregOp(N
, Lo
, Hi
); break;
838 SplitVecRes_LOAD(cast
<LoadSDNode
>(N
), Lo
, Hi
);
841 SplitVecRes_MLOAD(cast
<MaskedLoadSDNode
>(N
), Lo
, Hi
);
844 SplitVecRes_MGATHER(cast
<MaskedGatherSDNode
>(N
), Lo
, Hi
);
847 SplitVecRes_SETCC(N
, Lo
, Hi
);
849 case ISD::VECTOR_SHUFFLE
:
850 SplitVecRes_VECTOR_SHUFFLE(cast
<ShuffleVectorSDNode
>(N
), Lo
, Hi
);
853 SplitVecRes_VAARG(N
, Lo
, Hi
);
856 case ISD::ANY_EXTEND_VECTOR_INREG
:
857 case ISD::SIGN_EXTEND_VECTOR_INREG
:
858 case ISD::ZERO_EXTEND_VECTOR_INREG
:
859 SplitVecRes_ExtVecInRegOp(N
, Lo
, Hi
);
863 case ISD::BITREVERSE
:
867 case ISD::CTLZ_ZERO_UNDEF
:
868 case ISD::CTTZ_ZERO_UNDEF
:
879 case ISD::FNEARBYINT
:
882 case ISD::STRICT_FP_EXTEND
:
884 case ISD::STRICT_FP_ROUND
:
885 case ISD::FP_TO_SINT
:
886 case ISD::FP_TO_UINT
:
892 case ISD::SINT_TO_FP
:
894 case ISD::UINT_TO_FP
:
895 case ISD::FCANONICALIZE
:
896 SplitVecRes_UnaryOp(N
, Lo
, Hi
);
899 case ISD::ANY_EXTEND
:
900 case ISD::SIGN_EXTEND
:
901 case ISD::ZERO_EXTEND
:
902 SplitVecRes_ExtendOp(N
, Lo
, Hi
);
938 SplitVecRes_BinOp(N
, Lo
, Hi
);
941 SplitVecRes_TernaryOp(N
, Lo
, Hi
);
943 case ISD::STRICT_FADD
:
944 case ISD::STRICT_FSUB
:
945 case ISD::STRICT_FMUL
:
946 case ISD::STRICT_FDIV
:
947 case ISD::STRICT_FREM
:
948 case ISD::STRICT_FSQRT
:
949 case ISD::STRICT_FMA
:
950 case ISD::STRICT_FPOW
:
951 case ISD::STRICT_FPOWI
:
952 case ISD::STRICT_FSIN
:
953 case ISD::STRICT_FCOS
:
954 case ISD::STRICT_FEXP
:
955 case ISD::STRICT_FEXP2
:
956 case ISD::STRICT_FLOG
:
957 case ISD::STRICT_FLOG10
:
958 case ISD::STRICT_FLOG2
:
959 case ISD::STRICT_FRINT
:
960 case ISD::STRICT_FNEARBYINT
:
961 case ISD::STRICT_FMAXNUM
:
962 case ISD::STRICT_FMINNUM
:
963 case ISD::STRICT_FCEIL
:
964 case ISD::STRICT_FFLOOR
:
965 case ISD::STRICT_FROUND
:
966 case ISD::STRICT_FTRUNC
:
967 SplitVecRes_StrictFPOp(N
, Lo
, Hi
);
975 SplitVecRes_OverflowOp(N
, ResNo
, Lo
, Hi
);
978 case ISD::SMULFIXSAT
:
980 SplitVecRes_MULFIX(N
, Lo
, Hi
);
984 // If Lo/Hi is null, the sub-method took care of registering results etc.
986 SetSplitVector(SDValue(N
, ResNo
), Lo
, Hi
);
989 void DAGTypeLegalizer::SplitVecRes_BinOp(SDNode
*N
, SDValue
&Lo
,
991 SDValue LHSLo
, LHSHi
;
992 GetSplitVector(N
->getOperand(0), LHSLo
, LHSHi
);
993 SDValue RHSLo
, RHSHi
;
994 GetSplitVector(N
->getOperand(1), RHSLo
, RHSHi
);
997 const SDNodeFlags Flags
= N
->getFlags();
998 unsigned Opcode
= N
->getOpcode();
999 Lo
= DAG
.getNode(Opcode
, dl
, LHSLo
.getValueType(), LHSLo
, RHSLo
, Flags
);
1000 Hi
= DAG
.getNode(Opcode
, dl
, LHSHi
.getValueType(), LHSHi
, RHSHi
, Flags
);
1003 void DAGTypeLegalizer::SplitVecRes_TernaryOp(SDNode
*N
, SDValue
&Lo
,
1005 SDValue Op0Lo
, Op0Hi
;
1006 GetSplitVector(N
->getOperand(0), Op0Lo
, Op0Hi
);
1007 SDValue Op1Lo
, Op1Hi
;
1008 GetSplitVector(N
->getOperand(1), Op1Lo
, Op1Hi
);
1009 SDValue Op2Lo
, Op2Hi
;
1010 GetSplitVector(N
->getOperand(2), Op2Lo
, Op2Hi
);
1013 Lo
= DAG
.getNode(N
->getOpcode(), dl
, Op0Lo
.getValueType(),
1014 Op0Lo
, Op1Lo
, Op2Lo
);
1015 Hi
= DAG
.getNode(N
->getOpcode(), dl
, Op0Hi
.getValueType(),
1016 Op0Hi
, Op1Hi
, Op2Hi
);
1019 void DAGTypeLegalizer::SplitVecRes_MULFIX(SDNode
*N
, SDValue
&Lo
, SDValue
&Hi
) {
1020 SDValue LHSLo
, LHSHi
;
1021 GetSplitVector(N
->getOperand(0), LHSLo
, LHSHi
);
1022 SDValue RHSLo
, RHSHi
;
1023 GetSplitVector(N
->getOperand(1), RHSLo
, RHSHi
);
1025 SDValue Op2
= N
->getOperand(2);
1027 unsigned Opcode
= N
->getOpcode();
1028 Lo
= DAG
.getNode(Opcode
, dl
, LHSLo
.getValueType(), LHSLo
, RHSLo
, Op2
);
1029 Hi
= DAG
.getNode(Opcode
, dl
, LHSHi
.getValueType(), LHSHi
, RHSHi
, Op2
);
1032 void DAGTypeLegalizer::SplitVecRes_BITCAST(SDNode
*N
, SDValue
&Lo
,
1034 // We know the result is a vector. The input may be either a vector or a
1037 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1040 SDValue InOp
= N
->getOperand(0);
1041 EVT InVT
= InOp
.getValueType();
1043 // Handle some special cases efficiently.
1044 switch (getTypeAction(InVT
)) {
1045 case TargetLowering::TypeLegal
:
1046 case TargetLowering::TypePromoteInteger
:
1047 case TargetLowering::TypePromoteFloat
:
1048 case TargetLowering::TypeSoftenFloat
:
1049 case TargetLowering::TypeScalarizeVector
:
1050 case TargetLowering::TypeWidenVector
:
1052 case TargetLowering::TypeExpandInteger
:
1053 case TargetLowering::TypeExpandFloat
:
1054 // A scalar to vector conversion, where the scalar needs expansion.
1055 // If the vector is being split in two then we can just convert the
1058 GetExpandedOp(InOp
, Lo
, Hi
);
1059 if (DAG
.getDataLayout().isBigEndian())
1061 Lo
= DAG
.getNode(ISD::BITCAST
, dl
, LoVT
, Lo
);
1062 Hi
= DAG
.getNode(ISD::BITCAST
, dl
, HiVT
, Hi
);
1066 case TargetLowering::TypeSplitVector
:
1067 // If the input is a vector that needs to be split, convert each split
1068 // piece of the input now.
1069 GetSplitVector(InOp
, Lo
, Hi
);
1070 Lo
= DAG
.getNode(ISD::BITCAST
, dl
, LoVT
, Lo
);
1071 Hi
= DAG
.getNode(ISD::BITCAST
, dl
, HiVT
, Hi
);
1075 // In the general case, convert the input to an integer and split it by hand.
1076 EVT LoIntVT
= EVT::getIntegerVT(*DAG
.getContext(), LoVT
.getSizeInBits());
1077 EVT HiIntVT
= EVT::getIntegerVT(*DAG
.getContext(), HiVT
.getSizeInBits());
1078 if (DAG
.getDataLayout().isBigEndian())
1079 std::swap(LoIntVT
, HiIntVT
);
1081 SplitInteger(BitConvertToInteger(InOp
), LoIntVT
, HiIntVT
, Lo
, Hi
);
1083 if (DAG
.getDataLayout().isBigEndian())
1085 Lo
= DAG
.getNode(ISD::BITCAST
, dl
, LoVT
, Lo
);
1086 Hi
= DAG
.getNode(ISD::BITCAST
, dl
, HiVT
, Hi
);
1089 void DAGTypeLegalizer::SplitVecRes_BUILD_VECTOR(SDNode
*N
, SDValue
&Lo
,
1093 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1094 unsigned LoNumElts
= LoVT
.getVectorNumElements();
1095 SmallVector
<SDValue
, 8> LoOps(N
->op_begin(), N
->op_begin()+LoNumElts
);
1096 Lo
= DAG
.getBuildVector(LoVT
, dl
, LoOps
);
1098 SmallVector
<SDValue
, 8> HiOps(N
->op_begin()+LoNumElts
, N
->op_end());
1099 Hi
= DAG
.getBuildVector(HiVT
, dl
, HiOps
);
1102 void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode
*N
, SDValue
&Lo
,
1104 assert(!(N
->getNumOperands() & 1) && "Unsupported CONCAT_VECTORS");
1106 unsigned NumSubvectors
= N
->getNumOperands() / 2;
1107 if (NumSubvectors
== 1) {
1108 Lo
= N
->getOperand(0);
1109 Hi
= N
->getOperand(1);
1114 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1116 SmallVector
<SDValue
, 8> LoOps(N
->op_begin(), N
->op_begin()+NumSubvectors
);
1117 Lo
= DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, LoVT
, LoOps
);
1119 SmallVector
<SDValue
, 8> HiOps(N
->op_begin()+NumSubvectors
, N
->op_end());
1120 Hi
= DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, HiVT
, HiOps
);
1123 void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(SDNode
*N
, SDValue
&Lo
,
1125 SDValue Vec
= N
->getOperand(0);
1126 SDValue Idx
= N
->getOperand(1);
1130 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1132 Lo
= DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, dl
, LoVT
, Vec
, Idx
);
1133 uint64_t IdxVal
= cast
<ConstantSDNode
>(Idx
)->getZExtValue();
1134 Hi
= DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, dl
, HiVT
, Vec
,
1135 DAG
.getConstant(IdxVal
+ LoVT
.getVectorNumElements(), dl
,
1136 TLI
.getVectorIdxTy(DAG
.getDataLayout())));
1139 void DAGTypeLegalizer::SplitVecRes_INSERT_SUBVECTOR(SDNode
*N
, SDValue
&Lo
,
1141 SDValue Vec
= N
->getOperand(0);
1142 SDValue SubVec
= N
->getOperand(1);
1143 SDValue Idx
= N
->getOperand(2);
1145 GetSplitVector(Vec
, Lo
, Hi
);
1147 EVT VecVT
= Vec
.getValueType();
1148 unsigned VecElems
= VecVT
.getVectorNumElements();
1149 unsigned SubElems
= SubVec
.getValueType().getVectorNumElements();
1151 // If we know the index is 0, and we know the subvector doesn't cross the
1152 // boundary between the halves, we can avoid spilling the vector, and insert
1153 // into the lower half of the split vector directly.
1154 // TODO: The IdxVal == 0 constraint is artificial, we could do this whenever
1155 // the index is constant and there is no boundary crossing. But those cases
1156 // don't seem to get hit in practice.
1157 if (ConstantSDNode
*ConstIdx
= dyn_cast
<ConstantSDNode
>(Idx
)) {
1158 unsigned IdxVal
= ConstIdx
->getZExtValue();
1159 if ((IdxVal
== 0) && (IdxVal
+ SubElems
<= VecElems
/ 2)) {
1161 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1162 Lo
= DAG
.getNode(ISD::INSERT_SUBVECTOR
, dl
, LoVT
, Lo
, SubVec
, Idx
);
1167 // Spill the vector to the stack.
1168 SDValue StackPtr
= DAG
.CreateStackTemporary(VecVT
);
1170 DAG
.getStore(DAG
.getEntryNode(), dl
, Vec
, StackPtr
, MachinePointerInfo());
1172 // Store the new subvector into the specified index.
1173 SDValue SubVecPtr
= TLI
.getVectorElementPointer(DAG
, StackPtr
, VecVT
, Idx
);
1174 Type
*VecType
= VecVT
.getTypeForEVT(*DAG
.getContext());
1175 unsigned Alignment
= DAG
.getDataLayout().getPrefTypeAlignment(VecType
);
1176 Store
= DAG
.getStore(Store
, dl
, SubVec
, SubVecPtr
, MachinePointerInfo());
1178 // Load the Lo part from the stack slot.
1180 DAG
.getLoad(Lo
.getValueType(), dl
, Store
, StackPtr
, MachinePointerInfo());
1182 // Increment the pointer to the other part.
1183 unsigned IncrementSize
= Lo
.getValueSizeInBits() / 8;
1185 DAG
.getNode(ISD::ADD
, dl
, StackPtr
.getValueType(), StackPtr
,
1186 DAG
.getConstant(IncrementSize
, dl
, StackPtr
.getValueType()));
1188 // Load the Hi part from the stack slot.
1189 Hi
= DAG
.getLoad(Hi
.getValueType(), dl
, Store
, StackPtr
, MachinePointerInfo(),
1190 MinAlign(Alignment
, IncrementSize
));
1193 void DAGTypeLegalizer::SplitVecRes_FPOWI(SDNode
*N
, SDValue
&Lo
,
1196 GetSplitVector(N
->getOperand(0), Lo
, Hi
);
1197 Lo
= DAG
.getNode(ISD::FPOWI
, dl
, Lo
.getValueType(), Lo
, N
->getOperand(1));
1198 Hi
= DAG
.getNode(ISD::FPOWI
, dl
, Hi
.getValueType(), Hi
, N
->getOperand(1));
1201 void DAGTypeLegalizer::SplitVecRes_FCOPYSIGN(SDNode
*N
, SDValue
&Lo
,
1203 SDValue LHSLo
, LHSHi
;
1204 GetSplitVector(N
->getOperand(0), LHSLo
, LHSHi
);
1207 SDValue RHSLo
, RHSHi
;
1208 SDValue RHS
= N
->getOperand(1);
1209 EVT RHSVT
= RHS
.getValueType();
1210 if (getTypeAction(RHSVT
) == TargetLowering::TypeSplitVector
)
1211 GetSplitVector(RHS
, RHSLo
, RHSHi
);
1213 std::tie(RHSLo
, RHSHi
) = DAG
.SplitVector(RHS
, SDLoc(RHS
));
1216 Lo
= DAG
.getNode(ISD::FCOPYSIGN
, DL
, LHSLo
.getValueType(), LHSLo
, RHSLo
);
1217 Hi
= DAG
.getNode(ISD::FCOPYSIGN
, DL
, LHSHi
.getValueType(), LHSHi
, RHSHi
);
1220 void DAGTypeLegalizer::SplitVecRes_InregOp(SDNode
*N
, SDValue
&Lo
,
1222 SDValue LHSLo
, LHSHi
;
1223 GetSplitVector(N
->getOperand(0), LHSLo
, LHSHi
);
1227 std::tie(LoVT
, HiVT
) =
1228 DAG
.GetSplitDestVTs(cast
<VTSDNode
>(N
->getOperand(1))->getVT());
1230 Lo
= DAG
.getNode(N
->getOpcode(), dl
, LHSLo
.getValueType(), LHSLo
,
1231 DAG
.getValueType(LoVT
));
1232 Hi
= DAG
.getNode(N
->getOpcode(), dl
, LHSHi
.getValueType(), LHSHi
,
1233 DAG
.getValueType(HiVT
));
1236 void DAGTypeLegalizer::SplitVecRes_ExtVecInRegOp(SDNode
*N
, SDValue
&Lo
,
1238 unsigned Opcode
= N
->getOpcode();
1239 SDValue N0
= N
->getOperand(0);
1244 if (getTypeAction(N0
.getValueType()) == TargetLowering::TypeSplitVector
)
1245 GetSplitVector(N0
, InLo
, InHi
);
1247 std::tie(InLo
, InHi
) = DAG
.SplitVectorOperand(N
, 0);
1249 EVT InLoVT
= InLo
.getValueType();
1250 unsigned InNumElements
= InLoVT
.getVectorNumElements();
1252 EVT OutLoVT
, OutHiVT
;
1253 std::tie(OutLoVT
, OutHiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1254 unsigned OutNumElements
= OutLoVT
.getVectorNumElements();
1255 assert((2 * OutNumElements
) <= InNumElements
&&
1256 "Illegal extend vector in reg split");
1258 // *_EXTEND_VECTOR_INREG instructions extend the lowest elements of the
1259 // input vector (i.e. we only use InLo):
1260 // OutLo will extend the first OutNumElements from InLo.
1261 // OutHi will extend the next OutNumElements from InLo.
1263 // Shuffle the elements from InLo for OutHi into the bottom elements to
1264 // create a 'fake' InHi.
1265 SmallVector
<int, 8> SplitHi(InNumElements
, -1);
1266 for (unsigned i
= 0; i
!= OutNumElements
; ++i
)
1267 SplitHi
[i
] = i
+ OutNumElements
;
1268 InHi
= DAG
.getVectorShuffle(InLoVT
, dl
, InLo
, DAG
.getUNDEF(InLoVT
), SplitHi
);
1270 Lo
= DAG
.getNode(Opcode
, dl
, OutLoVT
, InLo
);
1271 Hi
= DAG
.getNode(Opcode
, dl
, OutHiVT
, InHi
);
1274 void DAGTypeLegalizer::SplitVecRes_StrictFPOp(SDNode
*N
, SDValue
&Lo
,
1276 unsigned NumOps
= N
->getNumOperands();
1277 SDValue Chain
= N
->getOperand(0);
1280 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1282 SmallVector
<SDValue
, 4> OpsLo
;
1283 SmallVector
<SDValue
, 4> OpsHi
;
1285 // The Chain is the first operand.
1286 OpsLo
.push_back(Chain
);
1287 OpsHi
.push_back(Chain
);
1289 // Now process the remaining operands.
1290 for (unsigned i
= 1; i
< NumOps
; ++i
) {
1291 SDValue Op
= N
->getOperand(i
);
1295 EVT InVT
= Op
.getValueType();
1296 if (InVT
.isVector()) {
1297 // If the input also splits, handle it directly for a
1298 // compile time speedup. Otherwise split it by hand.
1299 if (getTypeAction(InVT
) == TargetLowering::TypeSplitVector
)
1300 GetSplitVector(Op
, OpLo
, OpHi
);
1302 std::tie(OpLo
, OpHi
) = DAG
.SplitVectorOperand(N
, i
);
1305 OpsLo
.push_back(OpLo
);
1306 OpsHi
.push_back(OpHi
);
1309 EVT LoValueVTs
[] = {LoVT
, MVT::Other
};
1310 EVT HiValueVTs
[] = {HiVT
, MVT::Other
};
1311 Lo
= DAG
.getNode(N
->getOpcode(), dl
, LoValueVTs
, OpsLo
);
1312 Hi
= DAG
.getNode(N
->getOpcode(), dl
, HiValueVTs
, OpsHi
);
1314 // Build a factor node to remember that this Op is independent of the
1316 Chain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
,
1317 Lo
.getValue(1), Hi
.getValue(1));
1319 // Legalize the chain result - switch anything that used the old chain to
1321 ReplaceValueWith(SDValue(N
, 1), Chain
);
1324 SDValue
DAGTypeLegalizer::UnrollVectorOp_StrictFP(SDNode
*N
, unsigned ResNE
) {
1325 SDValue Chain
= N
->getOperand(0);
1326 EVT VT
= N
->getValueType(0);
1327 unsigned NE
= VT
.getVectorNumElements();
1328 EVT EltVT
= VT
.getVectorElementType();
1331 SmallVector
<SDValue
, 8> Scalars
;
1332 SmallVector
<SDValue
, 4> Operands(N
->getNumOperands());
1334 // If ResNE is 0, fully unroll the vector op.
1337 else if (NE
> ResNE
)
1340 //The results of each unrolled operation, including the chain.
1341 EVT ChainVTs
[] = {EltVT
, MVT::Other
};
1342 SmallVector
<SDValue
, 8> Chains
;
1345 for (i
= 0; i
!= NE
; ++i
) {
1346 Operands
[0] = Chain
;
1347 for (unsigned j
= 1, e
= N
->getNumOperands(); j
!= e
; ++j
) {
1348 SDValue Operand
= N
->getOperand(j
);
1349 EVT OperandVT
= Operand
.getValueType();
1350 if (OperandVT
.isVector()) {
1351 EVT OperandEltVT
= OperandVT
.getVectorElementType();
1353 DAG
.getNode(ISD::EXTRACT_VECTOR_ELT
, dl
, OperandEltVT
, Operand
,
1354 DAG
.getConstant(i
, dl
, TLI
.getVectorIdxTy(
1355 DAG
.getDataLayout())));
1357 Operands
[j
] = Operand
;
1360 SDValue Scalar
= DAG
.getNode(N
->getOpcode(), dl
, ChainVTs
, Operands
);
1361 Scalar
.getNode()->setFlags(N
->getFlags());
1363 //Add in the scalar as well as its chain value to the
1365 Scalars
.push_back(Scalar
);
1366 Chains
.push_back(Scalar
.getValue(1));
1369 for (; i
< ResNE
; ++i
)
1370 Scalars
.push_back(DAG
.getUNDEF(EltVT
));
1372 // Build a new factor node to connect the chain back together.
1373 Chain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, Chains
);
1374 ReplaceValueWith(SDValue(N
, 1), Chain
);
1376 // Create a new BUILD_VECTOR node
1377 EVT VecVT
= EVT::getVectorVT(*DAG
.getContext(), EltVT
, ResNE
);
1378 return DAG
.getBuildVector(VecVT
, dl
, Scalars
);
1381 void DAGTypeLegalizer::SplitVecRes_OverflowOp(SDNode
*N
, unsigned ResNo
,
1382 SDValue
&Lo
, SDValue
&Hi
) {
1384 EVT ResVT
= N
->getValueType(0);
1385 EVT OvVT
= N
->getValueType(1);
1386 EVT LoResVT
, HiResVT
, LoOvVT
, HiOvVT
;
1387 std::tie(LoResVT
, HiResVT
) = DAG
.GetSplitDestVTs(ResVT
);
1388 std::tie(LoOvVT
, HiOvVT
) = DAG
.GetSplitDestVTs(OvVT
);
1390 SDValue LoLHS
, HiLHS
, LoRHS
, HiRHS
;
1391 if (getTypeAction(ResVT
) == TargetLowering::TypeSplitVector
) {
1392 GetSplitVector(N
->getOperand(0), LoLHS
, HiLHS
);
1393 GetSplitVector(N
->getOperand(1), LoRHS
, HiRHS
);
1395 std::tie(LoLHS
, HiLHS
) = DAG
.SplitVectorOperand(N
, 0);
1396 std::tie(LoRHS
, HiRHS
) = DAG
.SplitVectorOperand(N
, 1);
1399 unsigned Opcode
= N
->getOpcode();
1400 SDVTList LoVTs
= DAG
.getVTList(LoResVT
, LoOvVT
);
1401 SDVTList HiVTs
= DAG
.getVTList(HiResVT
, HiOvVT
);
1402 SDNode
*LoNode
= DAG
.getNode(Opcode
, dl
, LoVTs
, LoLHS
, LoRHS
).getNode();
1403 SDNode
*HiNode
= DAG
.getNode(Opcode
, dl
, HiVTs
, HiLHS
, HiRHS
).getNode();
1405 Lo
= SDValue(LoNode
, ResNo
);
1406 Hi
= SDValue(HiNode
, ResNo
);
1408 // Replace the other vector result not being explicitly split here.
1409 unsigned OtherNo
= 1 - ResNo
;
1410 EVT OtherVT
= N
->getValueType(OtherNo
);
1411 if (getTypeAction(OtherVT
) == TargetLowering::TypeSplitVector
) {
1412 SetSplitVector(SDValue(N
, OtherNo
),
1413 SDValue(LoNode
, OtherNo
), SDValue(HiNode
, OtherNo
));
1415 SDValue OtherVal
= DAG
.getNode(
1416 ISD::CONCAT_VECTORS
, dl
, OtherVT
,
1417 SDValue(LoNode
, OtherNo
), SDValue(HiNode
, OtherNo
));
1418 ReplaceValueWith(SDValue(N
, OtherNo
), OtherVal
);
1422 void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode
*N
, SDValue
&Lo
,
1424 SDValue Vec
= N
->getOperand(0);
1425 SDValue Elt
= N
->getOperand(1);
1426 SDValue Idx
= N
->getOperand(2);
1428 GetSplitVector(Vec
, Lo
, Hi
);
1430 if (ConstantSDNode
*CIdx
= dyn_cast
<ConstantSDNode
>(Idx
)) {
1431 unsigned IdxVal
= CIdx
->getZExtValue();
1432 unsigned LoNumElts
= Lo
.getValueType().getVectorNumElements();
1433 if (IdxVal
< LoNumElts
)
1434 Lo
= DAG
.getNode(ISD::INSERT_VECTOR_ELT
, dl
,
1435 Lo
.getValueType(), Lo
, Elt
, Idx
);
1438 DAG
.getNode(ISD::INSERT_VECTOR_ELT
, dl
, Hi
.getValueType(), Hi
, Elt
,
1439 DAG
.getConstant(IdxVal
- LoNumElts
, dl
,
1440 TLI
.getVectorIdxTy(DAG
.getDataLayout())));
1444 // See if the target wants to custom expand this node.
1445 if (CustomLowerNode(N
, N
->getValueType(0), true))
1448 // Make the vector elements byte-addressable if they aren't already.
1449 EVT VecVT
= Vec
.getValueType();
1450 EVT EltVT
= VecVT
.getVectorElementType();
1451 if (VecVT
.getScalarSizeInBits() < 8) {
1453 VecVT
= EVT::getVectorVT(*DAG
.getContext(), EltVT
,
1454 VecVT
.getVectorNumElements());
1455 Vec
= DAG
.getNode(ISD::ANY_EXTEND
, dl
, VecVT
, Vec
);
1456 // Extend the element type to match if needed.
1457 if (EltVT
.bitsGT(Elt
.getValueType()))
1458 Elt
= DAG
.getNode(ISD::ANY_EXTEND
, dl
, EltVT
, Elt
);
1461 // Spill the vector to the stack.
1462 SDValue StackPtr
= DAG
.CreateStackTemporary(VecVT
);
1463 auto &MF
= DAG
.getMachineFunction();
1464 auto FrameIndex
= cast
<FrameIndexSDNode
>(StackPtr
.getNode())->getIndex();
1465 auto PtrInfo
= MachinePointerInfo::getFixedStack(MF
, FrameIndex
);
1466 SDValue Store
= DAG
.getStore(DAG
.getEntryNode(), dl
, Vec
, StackPtr
, PtrInfo
);
1468 // Store the new element. This may be larger than the vector element type,
1469 // so use a truncating store.
1470 SDValue EltPtr
= TLI
.getVectorElementPointer(DAG
, StackPtr
, VecVT
, Idx
);
1471 Type
*VecType
= VecVT
.getTypeForEVT(*DAG
.getContext());
1472 unsigned Alignment
= DAG
.getDataLayout().getPrefTypeAlignment(VecType
);
1473 Store
= DAG
.getTruncStore(Store
, dl
, Elt
, EltPtr
,
1474 MachinePointerInfo::getUnknownStack(MF
), EltVT
);
1477 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(VecVT
);
1479 // Load the Lo part from the stack slot.
1480 Lo
= DAG
.getLoad(LoVT
, dl
, Store
, StackPtr
, PtrInfo
);
1482 // Increment the pointer to the other part.
1483 unsigned IncrementSize
= LoVT
.getSizeInBits() / 8;
1484 StackPtr
= DAG
.getNode(ISD::ADD
, dl
, StackPtr
.getValueType(), StackPtr
,
1485 DAG
.getConstant(IncrementSize
, dl
,
1486 StackPtr
.getValueType()));
1488 // Load the Hi part from the stack slot.
1489 Hi
= DAG
.getLoad(HiVT
, dl
, Store
, StackPtr
,
1490 PtrInfo
.getWithOffset(IncrementSize
),
1491 MinAlign(Alignment
, IncrementSize
));
1493 // If we adjusted the original type, we need to truncate the results.
1494 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1495 if (LoVT
!= Lo
.getValueType())
1496 Lo
= DAG
.getNode(ISD::TRUNCATE
, dl
, LoVT
, Lo
);
1497 if (HiVT
!= Hi
.getValueType())
1498 Hi
= DAG
.getNode(ISD::TRUNCATE
, dl
, HiVT
, Hi
);
1501 void DAGTypeLegalizer::SplitVecRes_SCALAR_TO_VECTOR(SDNode
*N
, SDValue
&Lo
,
1505 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1506 Lo
= DAG
.getNode(ISD::SCALAR_TO_VECTOR
, dl
, LoVT
, N
->getOperand(0));
1507 Hi
= DAG
.getUNDEF(HiVT
);
1510 void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode
*LD
, SDValue
&Lo
,
1512 assert(ISD::isUNINDEXEDLoad(LD
) && "Indexed load during type legalization!");
1515 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(LD
->getValueType(0));
1517 ISD::LoadExtType ExtType
= LD
->getExtensionType();
1518 SDValue Ch
= LD
->getChain();
1519 SDValue Ptr
= LD
->getBasePtr();
1520 SDValue Offset
= DAG
.getUNDEF(Ptr
.getValueType());
1521 EVT MemoryVT
= LD
->getMemoryVT();
1522 unsigned Alignment
= LD
->getOriginalAlignment();
1523 MachineMemOperand::Flags MMOFlags
= LD
->getMemOperand()->getFlags();
1524 AAMDNodes AAInfo
= LD
->getAAInfo();
1526 EVT LoMemVT
, HiMemVT
;
1527 std::tie(LoMemVT
, HiMemVT
) = DAG
.GetSplitDestVTs(MemoryVT
);
1529 Lo
= DAG
.getLoad(ISD::UNINDEXED
, ExtType
, LoVT
, dl
, Ch
, Ptr
, Offset
,
1530 LD
->getPointerInfo(), LoMemVT
, Alignment
, MMOFlags
, AAInfo
);
1532 unsigned IncrementSize
= LoMemVT
.getSizeInBits()/8;
1533 Ptr
= DAG
.getObjectPtrOffset(dl
, Ptr
, IncrementSize
);
1534 Hi
= DAG
.getLoad(ISD::UNINDEXED
, ExtType
, HiVT
, dl
, Ch
, Ptr
, Offset
,
1535 LD
->getPointerInfo().getWithOffset(IncrementSize
), HiMemVT
,
1536 Alignment
, MMOFlags
, AAInfo
);
1538 // Build a factor node to remember that this load is independent of the
1540 Ch
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, Lo
.getValue(1),
1543 // Legalize the chain result - switch anything that used the old chain to
1545 ReplaceValueWith(SDValue(LD
, 1), Ch
);
1548 void DAGTypeLegalizer::SplitVecRes_MLOAD(MaskedLoadSDNode
*MLD
,
1549 SDValue
&Lo
, SDValue
&Hi
) {
1552 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(MLD
->getValueType(0));
1554 SDValue Ch
= MLD
->getChain();
1555 SDValue Ptr
= MLD
->getBasePtr();
1556 SDValue Mask
= MLD
->getMask();
1557 SDValue PassThru
= MLD
->getPassThru();
1558 unsigned Alignment
= MLD
->getOriginalAlignment();
1559 ISD::LoadExtType ExtType
= MLD
->getExtensionType();
1561 // Split Mask operand
1562 SDValue MaskLo
, MaskHi
;
1563 if (Mask
.getOpcode() == ISD::SETCC
) {
1564 SplitVecRes_SETCC(Mask
.getNode(), MaskLo
, MaskHi
);
1566 if (getTypeAction(Mask
.getValueType()) == TargetLowering::TypeSplitVector
)
1567 GetSplitVector(Mask
, MaskLo
, MaskHi
);
1569 std::tie(MaskLo
, MaskHi
) = DAG
.SplitVector(Mask
, dl
);
1572 EVT MemoryVT
= MLD
->getMemoryVT();
1573 EVT LoMemVT
, HiMemVT
;
1574 std::tie(LoMemVT
, HiMemVT
) = DAG
.GetSplitDestVTs(MemoryVT
);
1576 SDValue PassThruLo
, PassThruHi
;
1577 if (getTypeAction(PassThru
.getValueType()) == TargetLowering::TypeSplitVector
)
1578 GetSplitVector(PassThru
, PassThruLo
, PassThruHi
);
1580 std::tie(PassThruLo
, PassThruHi
) = DAG
.SplitVector(PassThru
, dl
);
1582 MachineMemOperand
*MMO
= DAG
.getMachineFunction().
1583 getMachineMemOperand(MLD
->getPointerInfo(),
1584 MachineMemOperand::MOLoad
, LoMemVT
.getStoreSize(),
1585 Alignment
, MLD
->getAAInfo(), MLD
->getRanges());
1587 Lo
= DAG
.getMaskedLoad(LoVT
, dl
, Ch
, Ptr
, MaskLo
, PassThruLo
, LoMemVT
, MMO
,
1588 ExtType
, MLD
->isExpandingLoad());
1590 Ptr
= TLI
.IncrementMemoryAddress(Ptr
, MaskLo
, dl
, LoMemVT
, DAG
,
1591 MLD
->isExpandingLoad());
1592 unsigned HiOffset
= LoMemVT
.getStoreSize();
1594 MMO
= DAG
.getMachineFunction().getMachineMemOperand(
1595 MLD
->getPointerInfo().getWithOffset(HiOffset
), MachineMemOperand::MOLoad
,
1596 HiMemVT
.getStoreSize(), Alignment
, MLD
->getAAInfo(),
1599 Hi
= DAG
.getMaskedLoad(HiVT
, dl
, Ch
, Ptr
, MaskHi
, PassThruHi
, HiMemVT
, MMO
,
1600 ExtType
, MLD
->isExpandingLoad());
1602 // Build a factor node to remember that this load is independent of the
1604 Ch
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, Lo
.getValue(1),
1607 // Legalize the chain result - switch anything that used the old chain to
1609 ReplaceValueWith(SDValue(MLD
, 1), Ch
);
1613 void DAGTypeLegalizer::SplitVecRes_MGATHER(MaskedGatherSDNode
*MGT
,
1614 SDValue
&Lo
, SDValue
&Hi
) {
1617 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(MGT
->getValueType(0));
1619 SDValue Ch
= MGT
->getChain();
1620 SDValue Ptr
= MGT
->getBasePtr();
1621 SDValue Mask
= MGT
->getMask();
1622 SDValue PassThru
= MGT
->getPassThru();
1623 SDValue Index
= MGT
->getIndex();
1624 SDValue Scale
= MGT
->getScale();
1625 unsigned Alignment
= MGT
->getOriginalAlignment();
1627 // Split Mask operand
1628 SDValue MaskLo
, MaskHi
;
1629 if (Mask
.getOpcode() == ISD::SETCC
) {
1630 SplitVecRes_SETCC(Mask
.getNode(), MaskLo
, MaskHi
);
1632 if (getTypeAction(Mask
.getValueType()) == TargetLowering::TypeSplitVector
)
1633 GetSplitVector(Mask
, MaskLo
, MaskHi
);
1635 std::tie(MaskLo
, MaskHi
) = DAG
.SplitVector(Mask
, dl
);
1638 EVT MemoryVT
= MGT
->getMemoryVT();
1639 EVT LoMemVT
, HiMemVT
;
1641 std::tie(LoMemVT
, HiMemVT
) = DAG
.GetSplitDestVTs(MemoryVT
);
1643 SDValue PassThruLo
, PassThruHi
;
1644 if (getTypeAction(PassThru
.getValueType()) == TargetLowering::TypeSplitVector
)
1645 GetSplitVector(PassThru
, PassThruLo
, PassThruHi
);
1647 std::tie(PassThruLo
, PassThruHi
) = DAG
.SplitVector(PassThru
, dl
);
1649 SDValue IndexHi
, IndexLo
;
1650 if (getTypeAction(Index
.getValueType()) == TargetLowering::TypeSplitVector
)
1651 GetSplitVector(Index
, IndexLo
, IndexHi
);
1653 std::tie(IndexLo
, IndexHi
) = DAG
.SplitVector(Index
, dl
);
1655 MachineMemOperand
*MMO
= DAG
.getMachineFunction().
1656 getMachineMemOperand(MGT
->getPointerInfo(),
1657 MachineMemOperand::MOLoad
, LoMemVT
.getStoreSize(),
1658 Alignment
, MGT
->getAAInfo(), MGT
->getRanges());
1660 SDValue OpsLo
[] = {Ch
, PassThruLo
, MaskLo
, Ptr
, IndexLo
, Scale
};
1661 Lo
= DAG
.getMaskedGather(DAG
.getVTList(LoVT
, MVT::Other
), LoVT
, dl
, OpsLo
,
1662 MMO
, MGT
->getIndexType());
1664 SDValue OpsHi
[] = {Ch
, PassThruHi
, MaskHi
, Ptr
, IndexHi
, Scale
};
1665 Hi
= DAG
.getMaskedGather(DAG
.getVTList(HiVT
, MVT::Other
), HiVT
, dl
, OpsHi
,
1666 MMO
, MGT
->getIndexType());
1668 // Build a factor node to remember that this load is independent of the
1670 Ch
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, Lo
.getValue(1),
1673 // Legalize the chain result - switch anything that used the old chain to
1675 ReplaceValueWith(SDValue(MGT
, 1), Ch
);
1679 void DAGTypeLegalizer::SplitVecRes_SETCC(SDNode
*N
, SDValue
&Lo
, SDValue
&Hi
) {
1680 assert(N
->getValueType(0).isVector() &&
1681 N
->getOperand(0).getValueType().isVector() &&
1682 "Operand types must be vectors");
1686 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1688 // If the input also splits, handle it directly. Otherwise split it by hand.
1689 SDValue LL
, LH
, RL
, RH
;
1690 if (getTypeAction(N
->getOperand(0).getValueType()) ==
1691 TargetLowering::TypeSplitVector
)
1692 GetSplitVector(N
->getOperand(0), LL
, LH
);
1694 std::tie(LL
, LH
) = DAG
.SplitVectorOperand(N
, 0);
1696 if (getTypeAction(N
->getOperand(1).getValueType()) ==
1697 TargetLowering::TypeSplitVector
)
1698 GetSplitVector(N
->getOperand(1), RL
, RH
);
1700 std::tie(RL
, RH
) = DAG
.SplitVectorOperand(N
, 1);
1702 Lo
= DAG
.getNode(N
->getOpcode(), DL
, LoVT
, LL
, RL
, N
->getOperand(2));
1703 Hi
= DAG
.getNode(N
->getOpcode(), DL
, HiVT
, LH
, RH
, N
->getOperand(2));
1706 void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode
*N
, SDValue
&Lo
,
1708 // Get the dest types - they may not match the input types, e.g. int_to_fp.
1711 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1713 // If the input also splits, handle it directly for a compile time speedup.
1714 // Otherwise split it by hand.
1715 unsigned OpNo
= N
->isStrictFPOpcode() ? 1 : 0;
1716 EVT InVT
= N
->getOperand(OpNo
).getValueType();
1717 if (getTypeAction(InVT
) == TargetLowering::TypeSplitVector
)
1718 GetSplitVector(N
->getOperand(OpNo
), Lo
, Hi
);
1720 std::tie(Lo
, Hi
) = DAG
.SplitVectorOperand(N
, OpNo
);
1722 if (N
->getOpcode() == ISD::FP_ROUND
) {
1723 Lo
= DAG
.getNode(N
->getOpcode(), dl
, LoVT
, Lo
, N
->getOperand(1));
1724 Hi
= DAG
.getNode(N
->getOpcode(), dl
, HiVT
, Hi
, N
->getOperand(1));
1725 } else if (N
->getOpcode() == ISD::STRICT_FP_ROUND
) {
1726 Lo
= DAG
.getNode(N
->getOpcode(), dl
, { LoVT
, MVT::Other
},
1727 { N
->getOperand(0), Lo
, N
->getOperand(2) });
1728 Hi
= DAG
.getNode(N
->getOpcode(), dl
, { HiVT
, MVT::Other
},
1729 { N
->getOperand(0), Hi
, N
->getOperand(2) });
1730 SDValue NewChain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
,
1731 Lo
.getValue(1), Hi
.getValue(1));
1732 ReplaceValueWith(SDValue(N
, 1), NewChain
);
1733 } else if (N
->isStrictFPOpcode()) {
1734 Lo
= DAG
.getNode(N
->getOpcode(), dl
, { LoVT
, MVT::Other
},
1735 { N
->getOperand(0), Lo
});
1736 Hi
= DAG
.getNode(N
->getOpcode(), dl
, { HiVT
, MVT::Other
},
1737 { N
->getOperand(0), Hi
});
1738 // Legalize the chain result - switch anything that used the old chain to
1740 SDValue NewChain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
,
1741 Lo
.getValue(1), Hi
.getValue(1));
1742 ReplaceValueWith(SDValue(N
, 1), NewChain
);
1744 Lo
= DAG
.getNode(N
->getOpcode(), dl
, LoVT
, Lo
);
1745 Hi
= DAG
.getNode(N
->getOpcode(), dl
, HiVT
, Hi
);
1749 void DAGTypeLegalizer::SplitVecRes_ExtendOp(SDNode
*N
, SDValue
&Lo
,
1752 EVT SrcVT
= N
->getOperand(0).getValueType();
1753 EVT DestVT
= N
->getValueType(0);
1755 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(DestVT
);
1757 // We can do better than a generic split operation if the extend is doing
1758 // more than just doubling the width of the elements and the following are
1760 // - The number of vector elements is even,
1761 // - the source type is legal,
1762 // - the type of a split source is illegal,
1763 // - the type of an extended (by doubling element size) source is legal, and
1764 // - the type of that extended source when split is legal.
1766 // This won't necessarily completely legalize the operation, but it will
1767 // more effectively move in the right direction and prevent falling down
1768 // to scalarization in many cases due to the input vector being split too
1770 unsigned NumElements
= SrcVT
.getVectorNumElements();
1771 if ((NumElements
& 1) == 0 &&
1772 SrcVT
.getSizeInBits() * 2 < DestVT
.getSizeInBits()) {
1773 LLVMContext
&Ctx
= *DAG
.getContext();
1774 EVT NewSrcVT
= SrcVT
.widenIntegerVectorElementType(Ctx
);
1775 EVT SplitSrcVT
= SrcVT
.getHalfNumVectorElementsVT(Ctx
);
1777 EVT SplitLoVT
, SplitHiVT
;
1778 std::tie(SplitLoVT
, SplitHiVT
) = DAG
.GetSplitDestVTs(NewSrcVT
);
1779 if (TLI
.isTypeLegal(SrcVT
) && !TLI
.isTypeLegal(SplitSrcVT
) &&
1780 TLI
.isTypeLegal(NewSrcVT
) && TLI
.isTypeLegal(SplitLoVT
)) {
1781 LLVM_DEBUG(dbgs() << "Split vector extend via incremental extend:";
1782 N
->dump(&DAG
); dbgs() << "\n");
1783 // Extend the source vector by one step.
1785 DAG
.getNode(N
->getOpcode(), dl
, NewSrcVT
, N
->getOperand(0));
1786 // Get the low and high halves of the new, extended one step, vector.
1787 std::tie(Lo
, Hi
) = DAG
.SplitVector(NewSrc
, dl
);
1788 // Extend those vector halves the rest of the way.
1789 Lo
= DAG
.getNode(N
->getOpcode(), dl
, LoVT
, Lo
);
1790 Hi
= DAG
.getNode(N
->getOpcode(), dl
, HiVT
, Hi
);
1794 // Fall back to the generic unary operator splitting otherwise.
1795 SplitVecRes_UnaryOp(N
, Lo
, Hi
);
1798 void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode
*N
,
1799 SDValue
&Lo
, SDValue
&Hi
) {
1800 // The low and high parts of the original input give four input vectors.
1803 GetSplitVector(N
->getOperand(0), Inputs
[0], Inputs
[1]);
1804 GetSplitVector(N
->getOperand(1), Inputs
[2], Inputs
[3]);
1805 EVT NewVT
= Inputs
[0].getValueType();
1806 unsigned NewElts
= NewVT
.getVectorNumElements();
1808 // If Lo or Hi uses elements from at most two of the four input vectors, then
1809 // express it as a vector shuffle of those two inputs. Otherwise extract the
1810 // input elements by hand and construct the Lo/Hi output using a BUILD_VECTOR.
1811 SmallVector
<int, 16> Ops
;
1812 for (unsigned High
= 0; High
< 2; ++High
) {
1813 SDValue
&Output
= High
? Hi
: Lo
;
1815 // Build a shuffle mask for the output, discovering on the fly which
1816 // input vectors to use as shuffle operands (recorded in InputUsed).
1817 // If building a suitable shuffle vector proves too hard, then bail
1818 // out with useBuildVector set.
1819 unsigned InputUsed
[2] = { -1U, -1U }; // Not yet discovered.
1820 unsigned FirstMaskIdx
= High
* NewElts
;
1821 bool useBuildVector
= false;
1822 for (unsigned MaskOffset
= 0; MaskOffset
< NewElts
; ++MaskOffset
) {
1823 // The mask element. This indexes into the input.
1824 int Idx
= N
->getMaskElt(FirstMaskIdx
+ MaskOffset
);
1826 // The input vector this mask element indexes into.
1827 unsigned Input
= (unsigned)Idx
/ NewElts
;
1829 if (Input
>= array_lengthof(Inputs
)) {
1830 // The mask element does not index into any input vector.
1835 // Turn the index into an offset from the start of the input vector.
1836 Idx
-= Input
* NewElts
;
1838 // Find or create a shuffle vector operand to hold this input.
1840 for (OpNo
= 0; OpNo
< array_lengthof(InputUsed
); ++OpNo
) {
1841 if (InputUsed
[OpNo
] == Input
) {
1842 // This input vector is already an operand.
1844 } else if (InputUsed
[OpNo
] == -1U) {
1845 // Create a new operand for this input vector.
1846 InputUsed
[OpNo
] = Input
;
1851 if (OpNo
>= array_lengthof(InputUsed
)) {
1852 // More than two input vectors used! Give up on trying to create a
1853 // shuffle vector. Insert all elements into a BUILD_VECTOR instead.
1854 useBuildVector
= true;
1858 // Add the mask index for the new shuffle vector.
1859 Ops
.push_back(Idx
+ OpNo
* NewElts
);
1862 if (useBuildVector
) {
1863 EVT EltVT
= NewVT
.getVectorElementType();
1864 SmallVector
<SDValue
, 16> SVOps
;
1866 // Extract the input elements by hand.
1867 for (unsigned MaskOffset
= 0; MaskOffset
< NewElts
; ++MaskOffset
) {
1868 // The mask element. This indexes into the input.
1869 int Idx
= N
->getMaskElt(FirstMaskIdx
+ MaskOffset
);
1871 // The input vector this mask element indexes into.
1872 unsigned Input
= (unsigned)Idx
/ NewElts
;
1874 if (Input
>= array_lengthof(Inputs
)) {
1875 // The mask element is "undef" or indexes off the end of the input.
1876 SVOps
.push_back(DAG
.getUNDEF(EltVT
));
1880 // Turn the index into an offset from the start of the input vector.
1881 Idx
-= Input
* NewElts
;
1883 // Extract the vector element by hand.
1884 SVOps
.push_back(DAG
.getNode(
1885 ISD::EXTRACT_VECTOR_ELT
, dl
, EltVT
, Inputs
[Input
],
1886 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout()))));
1889 // Construct the Lo/Hi output using a BUILD_VECTOR.
1890 Output
= DAG
.getBuildVector(NewVT
, dl
, SVOps
);
1891 } else if (InputUsed
[0] == -1U) {
1892 // No input vectors were used! The result is undefined.
1893 Output
= DAG
.getUNDEF(NewVT
);
1895 SDValue Op0
= Inputs
[InputUsed
[0]];
1896 // If only one input was used, use an undefined vector for the other.
1897 SDValue Op1
= InputUsed
[1] == -1U ?
1898 DAG
.getUNDEF(NewVT
) : Inputs
[InputUsed
[1]];
1899 // At least one input vector was used. Create a new shuffle vector.
1900 Output
= DAG
.getVectorShuffle(NewVT
, dl
, Op0
, Op1
, Ops
);
1907 void DAGTypeLegalizer::SplitVecRes_VAARG(SDNode
*N
, SDValue
&Lo
, SDValue
&Hi
) {
1908 EVT OVT
= N
->getValueType(0);
1909 EVT NVT
= OVT
.getHalfNumVectorElementsVT(*DAG
.getContext());
1910 SDValue Chain
= N
->getOperand(0);
1911 SDValue Ptr
= N
->getOperand(1);
1912 SDValue SV
= N
->getOperand(2);
1915 const unsigned Alignment
= DAG
.getDataLayout().getABITypeAlignment(
1916 NVT
.getTypeForEVT(*DAG
.getContext()));
1918 Lo
= DAG
.getVAArg(NVT
, dl
, Chain
, Ptr
, SV
, Alignment
);
1919 Hi
= DAG
.getVAArg(NVT
, dl
, Lo
.getValue(1), Ptr
, SV
, Alignment
);
1920 Chain
= Hi
.getValue(1);
1922 // Modified the chain - switch anything that used the old chain to use
1924 ReplaceValueWith(SDValue(N
, 1), Chain
);
1928 //===----------------------------------------------------------------------===//
1929 // Operand Vector Splitting
1930 //===----------------------------------------------------------------------===//
1932 /// This method is called when the specified operand of the specified node is
1933 /// found to need vector splitting. At this point, all of the result types of
1934 /// the node are known to be legal, but other operands of the node may need
1935 /// legalization as well as the specified one.
1936 bool DAGTypeLegalizer::SplitVectorOperand(SDNode
*N
, unsigned OpNo
) {
1937 LLVM_DEBUG(dbgs() << "Split node operand: "; N
->dump(&DAG
); dbgs() << "\n");
1938 SDValue Res
= SDValue();
1940 // See if the target wants to custom split this node.
1941 if (CustomLowerNode(N
, N
->getOperand(OpNo
).getValueType(), false))
1944 if (!Res
.getNode()) {
1945 switch (N
->getOpcode()) {
1948 dbgs() << "SplitVectorOperand Op #" << OpNo
<< ": ";
1952 report_fatal_error("Do not know how to split this operator's "
1955 case ISD::SETCC
: Res
= SplitVecOp_VSETCC(N
); break;
1956 case ISD::BITCAST
: Res
= SplitVecOp_BITCAST(N
); break;
1957 case ISD::EXTRACT_SUBVECTOR
: Res
= SplitVecOp_EXTRACT_SUBVECTOR(N
); break;
1958 case ISD::EXTRACT_VECTOR_ELT
:Res
= SplitVecOp_EXTRACT_VECTOR_ELT(N
); break;
1959 case ISD::CONCAT_VECTORS
: Res
= SplitVecOp_CONCAT_VECTORS(N
); break;
1961 Res
= SplitVecOp_TruncateHelper(N
);
1963 case ISD::STRICT_FP_ROUND
:
1964 case ISD::FP_ROUND
: Res
= SplitVecOp_FP_ROUND(N
); break;
1965 case ISD::FCOPYSIGN
: Res
= SplitVecOp_FCOPYSIGN(N
); break;
1967 Res
= SplitVecOp_STORE(cast
<StoreSDNode
>(N
), OpNo
);
1970 Res
= SplitVecOp_MSTORE(cast
<MaskedStoreSDNode
>(N
), OpNo
);
1973 Res
= SplitVecOp_MSCATTER(cast
<MaskedScatterSDNode
>(N
), OpNo
);
1976 Res
= SplitVecOp_MGATHER(cast
<MaskedGatherSDNode
>(N
), OpNo
);
1979 Res
= SplitVecOp_VSELECT(N
, OpNo
);
1981 case ISD::SINT_TO_FP
:
1982 case ISD::UINT_TO_FP
:
1983 if (N
->getValueType(0).bitsLT(N
->getOperand(0).getValueType()))
1984 Res
= SplitVecOp_TruncateHelper(N
);
1986 Res
= SplitVecOp_UnaryOp(N
);
1988 case ISD::FP_TO_SINT
:
1989 case ISD::FP_TO_UINT
:
1993 case ISD::STRICT_FP_EXTEND
:
1994 case ISD::FP_EXTEND
:
1995 case ISD::SIGN_EXTEND
:
1996 case ISD::ZERO_EXTEND
:
1997 case ISD::ANY_EXTEND
:
1999 case ISD::FCANONICALIZE
:
2000 Res
= SplitVecOp_UnaryOp(N
);
2003 case ISD::ANY_EXTEND_VECTOR_INREG
:
2004 case ISD::SIGN_EXTEND_VECTOR_INREG
:
2005 case ISD::ZERO_EXTEND_VECTOR_INREG
:
2006 Res
= SplitVecOp_ExtVecInRegOp(N
);
2009 case ISD::VECREDUCE_FADD
:
2010 case ISD::VECREDUCE_FMUL
:
2011 case ISD::VECREDUCE_ADD
:
2012 case ISD::VECREDUCE_MUL
:
2013 case ISD::VECREDUCE_AND
:
2014 case ISD::VECREDUCE_OR
:
2015 case ISD::VECREDUCE_XOR
:
2016 case ISD::VECREDUCE_SMAX
:
2017 case ISD::VECREDUCE_SMIN
:
2018 case ISD::VECREDUCE_UMAX
:
2019 case ISD::VECREDUCE_UMIN
:
2020 case ISD::VECREDUCE_FMAX
:
2021 case ISD::VECREDUCE_FMIN
:
2022 Res
= SplitVecOp_VECREDUCE(N
, OpNo
);
2027 // If the result is null, the sub-method took care of registering results etc.
2028 if (!Res
.getNode()) return false;
2030 // If the result is N, the sub-method updated N in place. Tell the legalizer
2032 if (Res
.getNode() == N
)
2035 if (N
->isStrictFPOpcode())
2036 assert(Res
.getValueType() == N
->getValueType(0) && N
->getNumValues() == 2 &&
2037 "Invalid operand expansion");
2039 assert(Res
.getValueType() == N
->getValueType(0) && N
->getNumValues() == 1 &&
2040 "Invalid operand expansion");
2042 ReplaceValueWith(SDValue(N
, 0), Res
);
2046 SDValue
DAGTypeLegalizer::SplitVecOp_VSELECT(SDNode
*N
, unsigned OpNo
) {
2047 // The only possibility for an illegal operand is the mask, since result type
2048 // legalization would have handled this node already otherwise.
2049 assert(OpNo
== 0 && "Illegal operand must be mask");
2051 SDValue Mask
= N
->getOperand(0);
2052 SDValue Src0
= N
->getOperand(1);
2053 SDValue Src1
= N
->getOperand(2);
2054 EVT Src0VT
= Src0
.getValueType();
2056 assert(Mask
.getValueType().isVector() && "VSELECT without a vector mask?");
2059 GetSplitVector(N
->getOperand(0), Lo
, Hi
);
2060 assert(Lo
.getValueType() == Hi
.getValueType() &&
2061 "Lo and Hi have differing types");
2064 std::tie(LoOpVT
, HiOpVT
) = DAG
.GetSplitDestVTs(Src0VT
);
2065 assert(LoOpVT
== HiOpVT
&& "Asymmetric vector split?");
2067 SDValue LoOp0
, HiOp0
, LoOp1
, HiOp1
, LoMask
, HiMask
;
2068 std::tie(LoOp0
, HiOp0
) = DAG
.SplitVector(Src0
, DL
);
2069 std::tie(LoOp1
, HiOp1
) = DAG
.SplitVector(Src1
, DL
);
2070 std::tie(LoMask
, HiMask
) = DAG
.SplitVector(Mask
, DL
);
2073 DAG
.getNode(ISD::VSELECT
, DL
, LoOpVT
, LoMask
, LoOp0
, LoOp1
);
2075 DAG
.getNode(ISD::VSELECT
, DL
, HiOpVT
, HiMask
, HiOp0
, HiOp1
);
2077 return DAG
.getNode(ISD::CONCAT_VECTORS
, DL
, Src0VT
, LoSelect
, HiSelect
);
2080 SDValue
DAGTypeLegalizer::SplitVecOp_VECREDUCE(SDNode
*N
, unsigned OpNo
) {
2081 EVT ResVT
= N
->getValueType(0);
2085 SDValue VecOp
= N
->getOperand(OpNo
);
2086 EVT VecVT
= VecOp
.getValueType();
2087 assert(VecVT
.isVector() && "Can only split reduce vector operand");
2088 GetSplitVector(VecOp
, Lo
, Hi
);
2090 std::tie(LoOpVT
, HiOpVT
) = DAG
.GetSplitDestVTs(VecVT
);
2092 bool NoNaN
= N
->getFlags().hasNoNaNs();
2093 unsigned CombineOpc
= 0;
2094 switch (N
->getOpcode()) {
2095 case ISD::VECREDUCE_FADD
: CombineOpc
= ISD::FADD
; break;
2096 case ISD::VECREDUCE_FMUL
: CombineOpc
= ISD::FMUL
; break;
2097 case ISD::VECREDUCE_ADD
: CombineOpc
= ISD::ADD
; break;
2098 case ISD::VECREDUCE_MUL
: CombineOpc
= ISD::MUL
; break;
2099 case ISD::VECREDUCE_AND
: CombineOpc
= ISD::AND
; break;
2100 case ISD::VECREDUCE_OR
: CombineOpc
= ISD::OR
; break;
2101 case ISD::VECREDUCE_XOR
: CombineOpc
= ISD::XOR
; break;
2102 case ISD::VECREDUCE_SMAX
: CombineOpc
= ISD::SMAX
; break;
2103 case ISD::VECREDUCE_SMIN
: CombineOpc
= ISD::SMIN
; break;
2104 case ISD::VECREDUCE_UMAX
: CombineOpc
= ISD::UMAX
; break;
2105 case ISD::VECREDUCE_UMIN
: CombineOpc
= ISD::UMIN
; break;
2106 case ISD::VECREDUCE_FMAX
:
2107 CombineOpc
= NoNaN
? ISD::FMAXNUM
: ISD::FMAXIMUM
;
2109 case ISD::VECREDUCE_FMIN
:
2110 CombineOpc
= NoNaN
? ISD::FMINNUM
: ISD::FMINIMUM
;
2113 llvm_unreachable("Unexpected reduce ISD node");
2116 // Use the appropriate scalar instruction on the split subvectors before
2117 // reducing the now partially reduced smaller vector.
2118 SDValue Partial
= DAG
.getNode(CombineOpc
, dl
, LoOpVT
, Lo
, Hi
, N
->getFlags());
2119 return DAG
.getNode(N
->getOpcode(), dl
, ResVT
, Partial
, N
->getFlags());
2122 SDValue
DAGTypeLegalizer::SplitVecOp_UnaryOp(SDNode
*N
) {
2123 // The result has a legal vector type, but the input needs splitting.
2124 EVT ResVT
= N
->getValueType(0);
2127 GetSplitVector(N
->getOperand(N
->isStrictFPOpcode() ? 1 : 0), Lo
, Hi
);
2128 EVT InVT
= Lo
.getValueType();
2130 EVT OutVT
= EVT::getVectorVT(*DAG
.getContext(), ResVT
.getVectorElementType(),
2131 InVT
.getVectorNumElements());
2133 if (N
->isStrictFPOpcode()) {
2134 Lo
= DAG
.getNode(N
->getOpcode(), dl
, { OutVT
, MVT::Other
},
2135 { N
->getOperand(0), Lo
});
2136 Hi
= DAG
.getNode(N
->getOpcode(), dl
, { OutVT
, MVT::Other
},
2137 { N
->getOperand(0), Hi
});
2139 // Build a factor node to remember that this operation is independent
2140 // of the other one.
2141 SDValue Ch
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, Lo
.getValue(1),
2144 // Legalize the chain result - switch anything that used the old chain to
2146 ReplaceValueWith(SDValue(N
, 1), Ch
);
2148 Lo
= DAG
.getNode(N
->getOpcode(), dl
, OutVT
, Lo
);
2149 Hi
= DAG
.getNode(N
->getOpcode(), dl
, OutVT
, Hi
);
2152 return DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, ResVT
, Lo
, Hi
);
2155 SDValue
DAGTypeLegalizer::SplitVecOp_BITCAST(SDNode
*N
) {
2156 // For example, i64 = BITCAST v4i16 on alpha. Typically the vector will
2157 // end up being split all the way down to individual components. Convert the
2158 // split pieces into integers and reassemble.
2160 GetSplitVector(N
->getOperand(0), Lo
, Hi
);
2161 Lo
= BitConvertToInteger(Lo
);
2162 Hi
= BitConvertToInteger(Hi
);
2164 if (DAG
.getDataLayout().isBigEndian())
2167 return DAG
.getNode(ISD::BITCAST
, SDLoc(N
), N
->getValueType(0),
2168 JoinIntegers(Lo
, Hi
));
2171 SDValue
DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode
*N
) {
2172 // We know that the extracted result type is legal.
2173 EVT SubVT
= N
->getValueType(0);
2174 SDValue Idx
= N
->getOperand(1);
2177 GetSplitVector(N
->getOperand(0), Lo
, Hi
);
2179 uint64_t LoElts
= Lo
.getValueType().getVectorNumElements();
2180 uint64_t IdxVal
= cast
<ConstantSDNode
>(Idx
)->getZExtValue();
2182 if (IdxVal
< LoElts
) {
2183 assert(IdxVal
+ SubVT
.getVectorNumElements() <= LoElts
&&
2184 "Extracted subvector crosses vector split!");
2185 return DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, dl
, SubVT
, Lo
, Idx
);
2187 return DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, dl
, SubVT
, Hi
,
2188 DAG
.getConstant(IdxVal
- LoElts
, dl
,
2189 Idx
.getValueType()));
2193 SDValue
DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode
*N
) {
2194 SDValue Vec
= N
->getOperand(0);
2195 SDValue Idx
= N
->getOperand(1);
2196 EVT VecVT
= Vec
.getValueType();
2198 if (isa
<ConstantSDNode
>(Idx
)) {
2199 uint64_t IdxVal
= cast
<ConstantSDNode
>(Idx
)->getZExtValue();
2202 GetSplitVector(Vec
, Lo
, Hi
);
2204 uint64_t LoElts
= Lo
.getValueType().getVectorNumElements();
2206 if (IdxVal
< LoElts
)
2207 return SDValue(DAG
.UpdateNodeOperands(N
, Lo
, Idx
), 0);
2208 return SDValue(DAG
.UpdateNodeOperands(N
, Hi
,
2209 DAG
.getConstant(IdxVal
- LoElts
, SDLoc(N
),
2210 Idx
.getValueType())), 0);
2213 // See if the target wants to custom expand this node.
2214 if (CustomLowerNode(N
, N
->getValueType(0), true))
2217 // Make the vector elements byte-addressable if they aren't already.
2219 EVT EltVT
= VecVT
.getVectorElementType();
2220 if (VecVT
.getScalarSizeInBits() < 8) {
2222 VecVT
= EVT::getVectorVT(*DAG
.getContext(), EltVT
,
2223 VecVT
.getVectorNumElements());
2224 Vec
= DAG
.getNode(ISD::ANY_EXTEND
, dl
, VecVT
, Vec
);
2227 // Store the vector to the stack.
2228 SDValue StackPtr
= DAG
.CreateStackTemporary(VecVT
);
2229 auto &MF
= DAG
.getMachineFunction();
2230 auto FrameIndex
= cast
<FrameIndexSDNode
>(StackPtr
.getNode())->getIndex();
2231 auto PtrInfo
= MachinePointerInfo::getFixedStack(MF
, FrameIndex
);
2232 SDValue Store
= DAG
.getStore(DAG
.getEntryNode(), dl
, Vec
, StackPtr
, PtrInfo
);
2234 // Load back the required element.
2235 StackPtr
= TLI
.getVectorElementPointer(DAG
, StackPtr
, VecVT
, Idx
);
2237 // FIXME: This is to handle i1 vectors with elements promoted to i8.
2238 // i1 vector handling needs general improvement.
2239 if (N
->getValueType(0).bitsLT(EltVT
)) {
2240 SDValue Load
= DAG
.getLoad(EltVT
, dl
, Store
, StackPtr
,
2241 MachinePointerInfo::getUnknownStack(DAG
.getMachineFunction()));
2242 return DAG
.getZExtOrTrunc(Load
, dl
, N
->getValueType(0));
2245 return DAG
.getExtLoad(
2246 ISD::EXTLOAD
, dl
, N
->getValueType(0), Store
, StackPtr
,
2247 MachinePointerInfo::getUnknownStack(DAG
.getMachineFunction()), EltVT
);
2250 SDValue
DAGTypeLegalizer::SplitVecOp_ExtVecInRegOp(SDNode
*N
) {
2253 // *_EXTEND_VECTOR_INREG only reference the lower half of the input, so
2254 // splitting the result has the same effect as splitting the input operand.
2255 SplitVecRes_ExtVecInRegOp(N
, Lo
, Hi
);
2257 return DAG
.getNode(ISD::CONCAT_VECTORS
, SDLoc(N
), N
->getValueType(0), Lo
, Hi
);
2260 SDValue
DAGTypeLegalizer::SplitVecOp_MGATHER(MaskedGatherSDNode
*MGT
,
2264 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(MGT
->getValueType(0));
2266 SDValue Ch
= MGT
->getChain();
2267 SDValue Ptr
= MGT
->getBasePtr();
2268 SDValue Index
= MGT
->getIndex();
2269 SDValue Scale
= MGT
->getScale();
2270 SDValue Mask
= MGT
->getMask();
2271 SDValue PassThru
= MGT
->getPassThru();
2272 unsigned Alignment
= MGT
->getOriginalAlignment();
2274 SDValue MaskLo
, MaskHi
;
2275 if (getTypeAction(Mask
.getValueType()) == TargetLowering::TypeSplitVector
)
2276 // Split Mask operand
2277 GetSplitVector(Mask
, MaskLo
, MaskHi
);
2279 std::tie(MaskLo
, MaskHi
) = DAG
.SplitVector(Mask
, dl
);
2281 EVT MemoryVT
= MGT
->getMemoryVT();
2282 EVT LoMemVT
, HiMemVT
;
2283 std::tie(LoMemVT
, HiMemVT
) = DAG
.GetSplitDestVTs(MemoryVT
);
2285 SDValue PassThruLo
, PassThruHi
;
2286 if (getTypeAction(PassThru
.getValueType()) == TargetLowering::TypeSplitVector
)
2287 GetSplitVector(PassThru
, PassThruLo
, PassThruHi
);
2289 std::tie(PassThruLo
, PassThruHi
) = DAG
.SplitVector(PassThru
, dl
);
2291 SDValue IndexHi
, IndexLo
;
2292 if (getTypeAction(Index
.getValueType()) == TargetLowering::TypeSplitVector
)
2293 GetSplitVector(Index
, IndexLo
, IndexHi
);
2295 std::tie(IndexLo
, IndexHi
) = DAG
.SplitVector(Index
, dl
);
2297 MachineMemOperand
*MMO
= DAG
.getMachineFunction().
2298 getMachineMemOperand(MGT
->getPointerInfo(),
2299 MachineMemOperand::MOLoad
, LoMemVT
.getStoreSize(),
2300 Alignment
, MGT
->getAAInfo(), MGT
->getRanges());
2302 SDValue OpsLo
[] = {Ch
, PassThruLo
, MaskLo
, Ptr
, IndexLo
, Scale
};
2303 SDValue Lo
= DAG
.getMaskedGather(DAG
.getVTList(LoVT
, MVT::Other
), LoVT
, dl
,
2304 OpsLo
, MMO
, MGT
->getIndexType());
2306 MMO
= DAG
.getMachineFunction().
2307 getMachineMemOperand(MGT
->getPointerInfo(),
2308 MachineMemOperand::MOLoad
, HiMemVT
.getStoreSize(),
2309 Alignment
, MGT
->getAAInfo(),
2312 SDValue OpsHi
[] = {Ch
, PassThruHi
, MaskHi
, Ptr
, IndexHi
, Scale
};
2313 SDValue Hi
= DAG
.getMaskedGather(DAG
.getVTList(HiVT
, MVT::Other
), HiVT
, dl
,
2314 OpsHi
, MMO
, MGT
->getIndexType());
2316 // Build a factor node to remember that this load is independent of the
2318 Ch
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, Lo
.getValue(1),
2321 // Legalize the chain result - switch anything that used the old chain to
2323 ReplaceValueWith(SDValue(MGT
, 1), Ch
);
2325 SDValue Res
= DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, MGT
->getValueType(0), Lo
,
2327 ReplaceValueWith(SDValue(MGT
, 0), Res
);
2331 SDValue
DAGTypeLegalizer::SplitVecOp_MSTORE(MaskedStoreSDNode
*N
,
2333 SDValue Ch
= N
->getChain();
2334 SDValue Ptr
= N
->getBasePtr();
2335 SDValue Mask
= N
->getMask();
2336 SDValue Data
= N
->getValue();
2337 EVT MemoryVT
= N
->getMemoryVT();
2338 unsigned Alignment
= N
->getOriginalAlignment();
2341 EVT LoMemVT
, HiMemVT
;
2342 std::tie(LoMemVT
, HiMemVT
) = DAG
.GetSplitDestVTs(MemoryVT
);
2344 SDValue DataLo
, DataHi
;
2345 if (getTypeAction(Data
.getValueType()) == TargetLowering::TypeSplitVector
)
2346 // Split Data operand
2347 GetSplitVector(Data
, DataLo
, DataHi
);
2349 std::tie(DataLo
, DataHi
) = DAG
.SplitVector(Data
, DL
);
2351 // Split Mask operand
2352 SDValue MaskLo
, MaskHi
;
2353 if (OpNo
== 1 && Mask
.getOpcode() == ISD::SETCC
) {
2354 SplitVecRes_SETCC(Mask
.getNode(), MaskLo
, MaskHi
);
2356 if (getTypeAction(Mask
.getValueType()) == TargetLowering::TypeSplitVector
)
2357 GetSplitVector(Mask
, MaskLo
, MaskHi
);
2359 std::tie(MaskLo
, MaskHi
) = DAG
.SplitVector(Mask
, DL
);
2363 MachineMemOperand
*MMO
= DAG
.getMachineFunction().
2364 getMachineMemOperand(N
->getPointerInfo(),
2365 MachineMemOperand::MOStore
, LoMemVT
.getStoreSize(),
2366 Alignment
, N
->getAAInfo(), N
->getRanges());
2368 Lo
= DAG
.getMaskedStore(Ch
, DL
, DataLo
, Ptr
, MaskLo
, LoMemVT
, MMO
,
2369 N
->isTruncatingStore(),
2370 N
->isCompressingStore());
2372 Ptr
= TLI
.IncrementMemoryAddress(Ptr
, MaskLo
, DL
, LoMemVT
, DAG
,
2373 N
->isCompressingStore());
2374 unsigned HiOffset
= LoMemVT
.getStoreSize();
2376 MMO
= DAG
.getMachineFunction().getMachineMemOperand(
2377 N
->getPointerInfo().getWithOffset(HiOffset
), MachineMemOperand::MOStore
,
2378 HiMemVT
.getStoreSize(), Alignment
, N
->getAAInfo(),
2381 Hi
= DAG
.getMaskedStore(Ch
, DL
, DataHi
, Ptr
, MaskHi
, HiMemVT
, MMO
,
2382 N
->isTruncatingStore(), N
->isCompressingStore());
2384 // Build a factor node to remember that this store is independent of the
2386 return DAG
.getNode(ISD::TokenFactor
, DL
, MVT::Other
, Lo
, Hi
);
2389 SDValue
DAGTypeLegalizer::SplitVecOp_MSCATTER(MaskedScatterSDNode
*N
,
2391 SDValue Ch
= N
->getChain();
2392 SDValue Ptr
= N
->getBasePtr();
2393 SDValue Mask
= N
->getMask();
2394 SDValue Index
= N
->getIndex();
2395 SDValue Scale
= N
->getScale();
2396 SDValue Data
= N
->getValue();
2397 EVT MemoryVT
= N
->getMemoryVT();
2398 unsigned Alignment
= N
->getOriginalAlignment();
2401 // Split all operands
2402 EVT LoMemVT
, HiMemVT
;
2403 std::tie(LoMemVT
, HiMemVT
) = DAG
.GetSplitDestVTs(MemoryVT
);
2405 SDValue DataLo
, DataHi
;
2406 if (getTypeAction(Data
.getValueType()) == TargetLowering::TypeSplitVector
)
2407 // Split Data operand
2408 GetSplitVector(Data
, DataLo
, DataHi
);
2410 std::tie(DataLo
, DataHi
) = DAG
.SplitVector(Data
, DL
);
2412 // Split Mask operand
2413 SDValue MaskLo
, MaskHi
;
2414 if (OpNo
== 1 && Mask
.getOpcode() == ISD::SETCC
) {
2415 SplitVecRes_SETCC(Mask
.getNode(), MaskLo
, MaskHi
);
2417 if (getTypeAction(Mask
.getValueType()) == TargetLowering::TypeSplitVector
)
2418 GetSplitVector(Mask
, MaskLo
, MaskHi
);
2420 std::tie(MaskLo
, MaskHi
) = DAG
.SplitVector(Mask
, DL
);
2423 SDValue IndexHi
, IndexLo
;
2424 if (getTypeAction(Index
.getValueType()) == TargetLowering::TypeSplitVector
)
2425 GetSplitVector(Index
, IndexLo
, IndexHi
);
2427 std::tie(IndexLo
, IndexHi
) = DAG
.SplitVector(Index
, DL
);
2430 MachineMemOperand
*MMO
= DAG
.getMachineFunction().
2431 getMachineMemOperand(N
->getPointerInfo(),
2432 MachineMemOperand::MOStore
, LoMemVT
.getStoreSize(),
2433 Alignment
, N
->getAAInfo(), N
->getRanges());
2435 SDValue OpsLo
[] = {Ch
, DataLo
, MaskLo
, Ptr
, IndexLo
, Scale
};
2436 Lo
= DAG
.getMaskedScatter(DAG
.getVTList(MVT::Other
), DataLo
.getValueType(),
2437 DL
, OpsLo
, MMO
, N
->getIndexType());
2439 MMO
= DAG
.getMachineFunction().
2440 getMachineMemOperand(N
->getPointerInfo(),
2441 MachineMemOperand::MOStore
, HiMemVT
.getStoreSize(),
2442 Alignment
, N
->getAAInfo(), N
->getRanges());
2444 // The order of the Scatter operation after split is well defined. The "Hi"
2445 // part comes after the "Lo". So these two operations should be chained one
2447 SDValue OpsHi
[] = {Lo
, DataHi
, MaskHi
, Ptr
, IndexHi
, Scale
};
2448 return DAG
.getMaskedScatter(DAG
.getVTList(MVT::Other
), DataHi
.getValueType(),
2449 DL
, OpsHi
, MMO
, N
->getIndexType());
2452 SDValue
DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode
*N
, unsigned OpNo
) {
2453 assert(N
->isUnindexed() && "Indexed store of vector?");
2454 assert(OpNo
== 1 && "Can only split the stored value");
2457 bool isTruncating
= N
->isTruncatingStore();
2458 SDValue Ch
= N
->getChain();
2459 SDValue Ptr
= N
->getBasePtr();
2460 EVT MemoryVT
= N
->getMemoryVT();
2461 unsigned Alignment
= N
->getOriginalAlignment();
2462 MachineMemOperand::Flags MMOFlags
= N
->getMemOperand()->getFlags();
2463 AAMDNodes AAInfo
= N
->getAAInfo();
2465 GetSplitVector(N
->getOperand(1), Lo
, Hi
);
2467 EVT LoMemVT
, HiMemVT
;
2468 std::tie(LoMemVT
, HiMemVT
) = DAG
.GetSplitDestVTs(MemoryVT
);
2470 // Scalarize if the split halves are not byte-sized.
2471 if (!LoMemVT
.isByteSized() || !HiMemVT
.isByteSized())
2472 return TLI
.scalarizeVectorStore(N
, DAG
);
2474 unsigned IncrementSize
= LoMemVT
.getSizeInBits()/8;
2477 Lo
= DAG
.getTruncStore(Ch
, DL
, Lo
, Ptr
, N
->getPointerInfo(), LoMemVT
,
2478 Alignment
, MMOFlags
, AAInfo
);
2480 Lo
= DAG
.getStore(Ch
, DL
, Lo
, Ptr
, N
->getPointerInfo(), Alignment
, MMOFlags
,
2483 // Increment the pointer to the other half.
2484 Ptr
= DAG
.getObjectPtrOffset(DL
, Ptr
, IncrementSize
);
2487 Hi
= DAG
.getTruncStore(Ch
, DL
, Hi
, Ptr
,
2488 N
->getPointerInfo().getWithOffset(IncrementSize
),
2489 HiMemVT
, Alignment
, MMOFlags
, AAInfo
);
2491 Hi
= DAG
.getStore(Ch
, DL
, Hi
, Ptr
,
2492 N
->getPointerInfo().getWithOffset(IncrementSize
),
2493 Alignment
, MMOFlags
, AAInfo
);
2495 return DAG
.getNode(ISD::TokenFactor
, DL
, MVT::Other
, Lo
, Hi
);
2498 SDValue
DAGTypeLegalizer::SplitVecOp_CONCAT_VECTORS(SDNode
*N
) {
2501 // The input operands all must have the same type, and we know the result
2502 // type is valid. Convert this to a buildvector which extracts all the
2504 // TODO: If the input elements are power-two vectors, we could convert this to
2505 // a new CONCAT_VECTORS node with elements that are half-wide.
2506 SmallVector
<SDValue
, 32> Elts
;
2507 EVT EltVT
= N
->getValueType(0).getVectorElementType();
2508 for (const SDValue
&Op
: N
->op_values()) {
2509 for (unsigned i
= 0, e
= Op
.getValueType().getVectorNumElements();
2511 Elts
.push_back(DAG
.getNode(
2512 ISD::EXTRACT_VECTOR_ELT
, DL
, EltVT
, Op
,
2513 DAG
.getConstant(i
, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout()))));
2517 return DAG
.getBuildVector(N
->getValueType(0), DL
, Elts
);
2520 SDValue
DAGTypeLegalizer::SplitVecOp_TruncateHelper(SDNode
*N
) {
2521 // The result type is legal, but the input type is illegal. If splitting
2522 // ends up with the result type of each half still being legal, just
2523 // do that. If, however, that would result in an illegal result type,
2524 // we can try to get more clever with power-two vectors. Specifically,
2525 // split the input type, but also widen the result element size, then
2526 // concatenate the halves and truncate again. For example, consider a target
2527 // where v8i8 is legal and v8i32 is not (ARM, which doesn't have 256-bit
2528 // vectors). To perform a "%res = v8i8 trunc v8i32 %in" we do:
2529 // %inlo = v4i32 extract_subvector %in, 0
2530 // %inhi = v4i32 extract_subvector %in, 4
2531 // %lo16 = v4i16 trunc v4i32 %inlo
2532 // %hi16 = v4i16 trunc v4i32 %inhi
2533 // %in16 = v8i16 concat_vectors v4i16 %lo16, v4i16 %hi16
2534 // %res = v8i8 trunc v8i16 %in16
2536 // Without this transform, the original truncate would end up being
2537 // scalarized, which is pretty much always a last resort.
2538 SDValue InVec
= N
->getOperand(0);
2539 EVT InVT
= InVec
->getValueType(0);
2540 EVT OutVT
= N
->getValueType(0);
2541 unsigned NumElements
= OutVT
.getVectorNumElements();
2542 bool IsFloat
= OutVT
.isFloatingPoint();
2544 // Widening should have already made sure this is a power-two vector
2545 // if we're trying to split it at all. assert() that's true, just in case.
2546 assert(!(NumElements
& 1) && "Splitting vector, but not in half!");
2548 unsigned InElementSize
= InVT
.getScalarSizeInBits();
2549 unsigned OutElementSize
= OutVT
.getScalarSizeInBits();
2551 // Determine the split output VT. If its legal we can just split dirctly.
2552 EVT LoOutVT
, HiOutVT
;
2553 std::tie(LoOutVT
, HiOutVT
) = DAG
.GetSplitDestVTs(OutVT
);
2554 assert(LoOutVT
== HiOutVT
&& "Unequal split?");
2556 // If the input elements are only 1/2 the width of the result elements,
2557 // just use the normal splitting. Our trick only work if there's room
2558 // to split more than once.
2559 if (isTypeLegal(LoOutVT
) ||
2560 InElementSize
<= OutElementSize
* 2)
2561 return SplitVecOp_UnaryOp(N
);
2564 // Don't touch if this will be scalarized.
2566 while (getTypeAction(FinalVT
) == TargetLowering::TypeSplitVector
)
2567 FinalVT
= FinalVT
.getHalfNumVectorElementsVT(*DAG
.getContext());
2569 if (getTypeAction(FinalVT
) == TargetLowering::TypeScalarizeVector
)
2570 return SplitVecOp_UnaryOp(N
);
2572 // Get the split input vector.
2573 SDValue InLoVec
, InHiVec
;
2574 GetSplitVector(InVec
, InLoVec
, InHiVec
);
2576 // Truncate them to 1/2 the element size.
2577 EVT HalfElementVT
= IsFloat
?
2578 EVT::getFloatingPointVT(InElementSize
/2) :
2579 EVT::getIntegerVT(*DAG
.getContext(), InElementSize
/2);
2580 EVT HalfVT
= EVT::getVectorVT(*DAG
.getContext(), HalfElementVT
,
2582 SDValue HalfLo
= DAG
.getNode(N
->getOpcode(), DL
, HalfVT
, InLoVec
);
2583 SDValue HalfHi
= DAG
.getNode(N
->getOpcode(), DL
, HalfVT
, InHiVec
);
2584 // Concatenate them to get the full intermediate truncation result.
2585 EVT InterVT
= EVT::getVectorVT(*DAG
.getContext(), HalfElementVT
, NumElements
);
2586 SDValue InterVec
= DAG
.getNode(ISD::CONCAT_VECTORS
, DL
, InterVT
, HalfLo
,
2588 // Now finish up by truncating all the way down to the original result
2589 // type. This should normally be something that ends up being legal directly,
2590 // but in theory if a target has very wide vectors and an annoyingly
2591 // restricted set of legal types, this split can chain to build things up.
2593 ? DAG
.getNode(ISD::FP_ROUND
, DL
, OutVT
, InterVec
,
2594 DAG
.getTargetConstant(
2595 0, DL
, TLI
.getPointerTy(DAG
.getDataLayout())))
2596 : DAG
.getNode(ISD::TRUNCATE
, DL
, OutVT
, InterVec
);
2599 SDValue
DAGTypeLegalizer::SplitVecOp_VSETCC(SDNode
*N
) {
2600 assert(N
->getValueType(0).isVector() &&
2601 N
->getOperand(0).getValueType().isVector() &&
2602 "Operand types must be vectors");
2603 // The result has a legal vector type, but the input needs splitting.
2604 SDValue Lo0
, Hi0
, Lo1
, Hi1
, LoRes
, HiRes
;
2606 GetSplitVector(N
->getOperand(0), Lo0
, Hi0
);
2607 GetSplitVector(N
->getOperand(1), Lo1
, Hi1
);
2608 unsigned PartElements
= Lo0
.getValueType().getVectorNumElements();
2609 EVT PartResVT
= EVT::getVectorVT(*DAG
.getContext(), MVT::i1
, PartElements
);
2610 EVT WideResVT
= EVT::getVectorVT(*DAG
.getContext(), MVT::i1
, 2*PartElements
);
2612 LoRes
= DAG
.getNode(ISD::SETCC
, DL
, PartResVT
, Lo0
, Lo1
, N
->getOperand(2));
2613 HiRes
= DAG
.getNode(ISD::SETCC
, DL
, PartResVT
, Hi0
, Hi1
, N
->getOperand(2));
2614 SDValue Con
= DAG
.getNode(ISD::CONCAT_VECTORS
, DL
, WideResVT
, LoRes
, HiRes
);
2615 return PromoteTargetBoolean(Con
, N
->getValueType(0));
2619 SDValue
DAGTypeLegalizer::SplitVecOp_FP_ROUND(SDNode
*N
) {
2620 // The result has a legal vector type, but the input needs splitting.
2621 EVT ResVT
= N
->getValueType(0);
2624 GetSplitVector(N
->getOperand(N
->isStrictFPOpcode() ? 1 : 0), Lo
, Hi
);
2625 EVT InVT
= Lo
.getValueType();
2627 EVT OutVT
= EVT::getVectorVT(*DAG
.getContext(), ResVT
.getVectorElementType(),
2628 InVT
.getVectorNumElements());
2630 if (N
->isStrictFPOpcode()) {
2631 Lo
= DAG
.getNode(N
->getOpcode(), DL
, { OutVT
, MVT::Other
},
2632 { N
->getOperand(0), Lo
, N
->getOperand(2) });
2633 Hi
= DAG
.getNode(N
->getOpcode(), DL
, { OutVT
, MVT::Other
},
2634 { N
->getOperand(0), Hi
, N
->getOperand(2) });
2635 // Legalize the chain result - switch anything that used the old chain to
2637 SDValue NewChain
= DAG
.getNode(ISD::TokenFactor
, DL
, MVT::Other
,
2638 Lo
.getValue(1), Hi
.getValue(1));
2639 ReplaceValueWith(SDValue(N
, 1), NewChain
);
2641 Lo
= DAG
.getNode(ISD::FP_ROUND
, DL
, OutVT
, Lo
, N
->getOperand(1));
2642 Hi
= DAG
.getNode(ISD::FP_ROUND
, DL
, OutVT
, Hi
, N
->getOperand(1));
2645 return DAG
.getNode(ISD::CONCAT_VECTORS
, DL
, ResVT
, Lo
, Hi
);
2648 SDValue
DAGTypeLegalizer::SplitVecOp_FCOPYSIGN(SDNode
*N
) {
2649 // The result (and the first input) has a legal vector type, but the second
2650 // input needs splitting.
2651 return DAG
.UnrollVectorOp(N
, N
->getValueType(0).getVectorNumElements());
2655 //===----------------------------------------------------------------------===//
2656 // Result Vector Widening
2657 //===----------------------------------------------------------------------===//
2659 void DAGTypeLegalizer::WidenVectorResult(SDNode
*N
, unsigned ResNo
) {
2660 LLVM_DEBUG(dbgs() << "Widen node result " << ResNo
<< ": "; N
->dump(&DAG
);
2663 // See if the target wants to custom widen this node.
2664 if (CustomWidenLowerNode(N
, N
->getValueType(ResNo
)))
2667 SDValue Res
= SDValue();
2668 switch (N
->getOpcode()) {
2671 dbgs() << "WidenVectorResult #" << ResNo
<< ": ";
2675 llvm_unreachable("Do not know how to widen the result of this operator!");
2677 case ISD::MERGE_VALUES
: Res
= WidenVecRes_MERGE_VALUES(N
, ResNo
); break;
2678 case ISD::BITCAST
: Res
= WidenVecRes_BITCAST(N
); break;
2679 case ISD::BUILD_VECTOR
: Res
= WidenVecRes_BUILD_VECTOR(N
); break;
2680 case ISD::CONCAT_VECTORS
: Res
= WidenVecRes_CONCAT_VECTORS(N
); break;
2681 case ISD::EXTRACT_SUBVECTOR
: Res
= WidenVecRes_EXTRACT_SUBVECTOR(N
); break;
2682 case ISD::FP_ROUND_INREG
: Res
= WidenVecRes_InregOp(N
); break;
2683 case ISD::INSERT_VECTOR_ELT
: Res
= WidenVecRes_INSERT_VECTOR_ELT(N
); break;
2684 case ISD::LOAD
: Res
= WidenVecRes_LOAD(N
); break;
2685 case ISD::SCALAR_TO_VECTOR
: Res
= WidenVecRes_SCALAR_TO_VECTOR(N
); break;
2686 case ISD::SIGN_EXTEND_INREG
: Res
= WidenVecRes_InregOp(N
); break;
2688 case ISD::SELECT
: Res
= WidenVecRes_SELECT(N
); break;
2689 case ISD::SELECT_CC
: Res
= WidenVecRes_SELECT_CC(N
); break;
2690 case ISD::SETCC
: Res
= WidenVecRes_SETCC(N
); break;
2691 case ISD::UNDEF
: Res
= WidenVecRes_UNDEF(N
); break;
2692 case ISD::VECTOR_SHUFFLE
:
2693 Res
= WidenVecRes_VECTOR_SHUFFLE(cast
<ShuffleVectorSDNode
>(N
));
2696 Res
= WidenVecRes_MLOAD(cast
<MaskedLoadSDNode
>(N
));
2699 Res
= WidenVecRes_MGATHER(cast
<MaskedGatherSDNode
>(N
));
2722 Res
= WidenVecRes_Binary(N
);
2735 Res
= WidenVecRes_BinaryCanTrap(N
);
2739 case ISD::SMULFIXSAT
:
2741 // These are binary operations, but with an extra operand that shouldn't
2742 // be widened (the scale).
2743 Res
= WidenVecRes_BinaryWithExtraScalarOp(N
);
2746 case ISD::STRICT_FADD
:
2747 case ISD::STRICT_FSUB
:
2748 case ISD::STRICT_FMUL
:
2749 case ISD::STRICT_FDIV
:
2750 case ISD::STRICT_FREM
:
2751 case ISD::STRICT_FSQRT
:
2752 case ISD::STRICT_FMA
:
2753 case ISD::STRICT_FPOW
:
2754 case ISD::STRICT_FPOWI
:
2755 case ISD::STRICT_FSIN
:
2756 case ISD::STRICT_FCOS
:
2757 case ISD::STRICT_FEXP
:
2758 case ISD::STRICT_FEXP2
:
2759 case ISD::STRICT_FLOG
:
2760 case ISD::STRICT_FLOG10
:
2761 case ISD::STRICT_FLOG2
:
2762 case ISD::STRICT_FRINT
:
2763 case ISD::STRICT_FNEARBYINT
:
2764 case ISD::STRICT_FMAXNUM
:
2765 case ISD::STRICT_FMINNUM
:
2766 case ISD::STRICT_FCEIL
:
2767 case ISD::STRICT_FFLOOR
:
2768 case ISD::STRICT_FROUND
:
2769 case ISD::STRICT_FTRUNC
:
2770 Res
= WidenVecRes_StrictFP(N
);
2779 Res
= WidenVecRes_OverflowOp(N
, ResNo
);
2782 case ISD::FCOPYSIGN
:
2783 Res
= WidenVecRes_FCOPYSIGN(N
);
2787 Res
= WidenVecRes_POWI(N
);
2793 Res
= WidenVecRes_Shift(N
);
2796 case ISD::ANY_EXTEND_VECTOR_INREG
:
2797 case ISD::SIGN_EXTEND_VECTOR_INREG
:
2798 case ISD::ZERO_EXTEND_VECTOR_INREG
:
2799 Res
= WidenVecRes_EXTEND_VECTOR_INREG(N
);
2802 case ISD::ANY_EXTEND
:
2803 case ISD::FP_EXTEND
:
2805 case ISD::FP_TO_SINT
:
2806 case ISD::FP_TO_UINT
:
2807 case ISD::SIGN_EXTEND
:
2808 case ISD::SINT_TO_FP
:
2810 case ISD::UINT_TO_FP
:
2811 case ISD::ZERO_EXTEND
:
2812 Res
= WidenVecRes_Convert(N
);
2815 case ISD::STRICT_FP_EXTEND
:
2816 case ISD::STRICT_FP_ROUND
:
2817 Res
= WidenVecRes_Convert_StrictFP(N
);
2829 case ISD::FNEARBYINT
:
2835 // We're going to widen this vector op to a legal type by padding with undef
2836 // elements. If the wide vector op is eventually going to be expanded to
2837 // scalar libcalls, then unroll into scalar ops now to avoid unnecessary
2838 // libcalls on the undef elements.
2839 EVT VT
= N
->getValueType(0);
2840 EVT WideVecVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
2841 if (!TLI
.isOperationLegalOrCustom(N
->getOpcode(), WideVecVT
) &&
2842 TLI
.isOperationExpand(N
->getOpcode(), VT
.getScalarType())) {
2843 Res
= DAG
.UnrollVectorOp(N
, WideVecVT
.getVectorNumElements());
2847 // If the target has custom/legal support for the scalar FP intrinsic ops
2848 // (they are probably not destined to become libcalls), then widen those like
2849 // any other unary ops.
2853 case ISD::BITREVERSE
:
2856 case ISD::CTLZ_ZERO_UNDEF
:
2859 case ISD::CTTZ_ZERO_UNDEF
:
2861 case ISD::FCANONICALIZE
:
2862 Res
= WidenVecRes_Unary(N
);
2865 Res
= WidenVecRes_Ternary(N
);
2869 // If Res is null, the sub-method took care of registering the result.
2871 SetWidenedVector(SDValue(N
, ResNo
), Res
);
2874 SDValue
DAGTypeLegalizer::WidenVecRes_Ternary(SDNode
*N
) {
2875 // Ternary op widening.
2877 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
2878 SDValue InOp1
= GetWidenedVector(N
->getOperand(0));
2879 SDValue InOp2
= GetWidenedVector(N
->getOperand(1));
2880 SDValue InOp3
= GetWidenedVector(N
->getOperand(2));
2881 return DAG
.getNode(N
->getOpcode(), dl
, WidenVT
, InOp1
, InOp2
, InOp3
);
2884 SDValue
DAGTypeLegalizer::WidenVecRes_Binary(SDNode
*N
) {
2885 // Binary op widening.
2887 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
2888 SDValue InOp1
= GetWidenedVector(N
->getOperand(0));
2889 SDValue InOp2
= GetWidenedVector(N
->getOperand(1));
2890 return DAG
.getNode(N
->getOpcode(), dl
, WidenVT
, InOp1
, InOp2
, N
->getFlags());
2893 SDValue
DAGTypeLegalizer::WidenVecRes_BinaryWithExtraScalarOp(SDNode
*N
) {
2894 // Binary op widening, but with an extra operand that shouldn't be widened.
2896 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
2897 SDValue InOp1
= GetWidenedVector(N
->getOperand(0));
2898 SDValue InOp2
= GetWidenedVector(N
->getOperand(1));
2899 SDValue InOp3
= N
->getOperand(2);
2900 return DAG
.getNode(N
->getOpcode(), dl
, WidenVT
, InOp1
, InOp2
, InOp3
,
2904 // Given a vector of operations that have been broken up to widen, see
2905 // if we can collect them together into the next widest legal VT. This
2906 // implementation is trap-safe.
2907 static SDValue
CollectOpsToWiden(SelectionDAG
&DAG
, const TargetLowering
&TLI
,
2908 SmallVectorImpl
<SDValue
> &ConcatOps
,
2909 unsigned ConcatEnd
, EVT VT
, EVT MaxVT
,
2911 // Check to see if we have a single operation with the widen type.
2912 if (ConcatEnd
== 1) {
2913 VT
= ConcatOps
[0].getValueType();
2915 return ConcatOps
[0];
2918 SDLoc
dl(ConcatOps
[0]);
2919 EVT WidenEltVT
= WidenVT
.getVectorElementType();
2921 // while (Some element of ConcatOps is not of type MaxVT) {
2922 // From the end of ConcatOps, collect elements of the same type and put
2923 // them into an op of the next larger supported type
2925 while (ConcatOps
[ConcatEnd
-1].getValueType() != MaxVT
) {
2926 int Idx
= ConcatEnd
- 1;
2927 VT
= ConcatOps
[Idx
--].getValueType();
2928 while (Idx
>= 0 && ConcatOps
[Idx
].getValueType() == VT
)
2931 int NextSize
= VT
.isVector() ? VT
.getVectorNumElements() : 1;
2935 NextVT
= EVT::getVectorVT(*DAG
.getContext(), WidenEltVT
, NextSize
);
2936 } while (!TLI
.isTypeLegal(NextVT
));
2938 if (!VT
.isVector()) {
2939 // Scalar type, create an INSERT_VECTOR_ELEMENT of type NextVT
2940 SDValue VecOp
= DAG
.getUNDEF(NextVT
);
2941 unsigned NumToInsert
= ConcatEnd
- Idx
- 1;
2942 for (unsigned i
= 0, OpIdx
= Idx
+1; i
< NumToInsert
; i
++, OpIdx
++) {
2943 VecOp
= DAG
.getNode(
2944 ISD::INSERT_VECTOR_ELT
, dl
, NextVT
, VecOp
, ConcatOps
[OpIdx
],
2945 DAG
.getConstant(i
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
2947 ConcatOps
[Idx
+1] = VecOp
;
2948 ConcatEnd
= Idx
+ 2;
2950 // Vector type, create a CONCAT_VECTORS of type NextVT
2951 SDValue undefVec
= DAG
.getUNDEF(VT
);
2952 unsigned OpsToConcat
= NextSize
/VT
.getVectorNumElements();
2953 SmallVector
<SDValue
, 16> SubConcatOps(OpsToConcat
);
2954 unsigned RealVals
= ConcatEnd
- Idx
- 1;
2955 unsigned SubConcatEnd
= 0;
2956 unsigned SubConcatIdx
= Idx
+ 1;
2957 while (SubConcatEnd
< RealVals
)
2958 SubConcatOps
[SubConcatEnd
++] = ConcatOps
[++Idx
];
2959 while (SubConcatEnd
< OpsToConcat
)
2960 SubConcatOps
[SubConcatEnd
++] = undefVec
;
2961 ConcatOps
[SubConcatIdx
] = DAG
.getNode(ISD::CONCAT_VECTORS
, dl
,
2962 NextVT
, SubConcatOps
);
2963 ConcatEnd
= SubConcatIdx
+ 1;
2967 // Check to see if we have a single operation with the widen type.
2968 if (ConcatEnd
== 1) {
2969 VT
= ConcatOps
[0].getValueType();
2971 return ConcatOps
[0];
2974 // add undefs of size MaxVT until ConcatOps grows to length of WidenVT
2975 unsigned NumOps
= WidenVT
.getVectorNumElements()/MaxVT
.getVectorNumElements();
2976 if (NumOps
!= ConcatEnd
) {
2977 SDValue UndefVal
= DAG
.getUNDEF(MaxVT
);
2978 for (unsigned j
= ConcatEnd
; j
< NumOps
; ++j
)
2979 ConcatOps
[j
] = UndefVal
;
2981 return DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, WidenVT
,
2982 makeArrayRef(ConcatOps
.data(), NumOps
));
2985 SDValue
DAGTypeLegalizer::WidenVecRes_BinaryCanTrap(SDNode
*N
) {
2986 // Binary op widening for operations that can trap.
2987 unsigned Opcode
= N
->getOpcode();
2989 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
2990 EVT WidenEltVT
= WidenVT
.getVectorElementType();
2992 unsigned NumElts
= VT
.getVectorNumElements();
2993 const SDNodeFlags Flags
= N
->getFlags();
2994 while (!TLI
.isTypeLegal(VT
) && NumElts
!= 1) {
2995 NumElts
= NumElts
/ 2;
2996 VT
= EVT::getVectorVT(*DAG
.getContext(), WidenEltVT
, NumElts
);
2999 if (NumElts
!= 1 && !TLI
.canOpTrap(N
->getOpcode(), VT
)) {
3000 // Operation doesn't trap so just widen as normal.
3001 SDValue InOp1
= GetWidenedVector(N
->getOperand(0));
3002 SDValue InOp2
= GetWidenedVector(N
->getOperand(1));
3003 return DAG
.getNode(N
->getOpcode(), dl
, WidenVT
, InOp1
, InOp2
, Flags
);
3006 // No legal vector version so unroll the vector operation and then widen.
3008 return DAG
.UnrollVectorOp(N
, WidenVT
.getVectorNumElements());
3010 // Since the operation can trap, apply operation on the original vector.
3012 SDValue InOp1
= GetWidenedVector(N
->getOperand(0));
3013 SDValue InOp2
= GetWidenedVector(N
->getOperand(1));
3014 unsigned CurNumElts
= N
->getValueType(0).getVectorNumElements();
3016 SmallVector
<SDValue
, 16> ConcatOps(CurNumElts
);
3017 unsigned ConcatEnd
= 0; // Current ConcatOps index.
3018 int Idx
= 0; // Current Idx into input vectors.
3020 // NumElts := greatest legal vector size (at most WidenVT)
3021 // while (orig. vector has unhandled elements) {
3022 // take munches of size NumElts from the beginning and add to ConcatOps
3023 // NumElts := next smaller supported vector size or 1
3025 while (CurNumElts
!= 0) {
3026 while (CurNumElts
>= NumElts
) {
3027 SDValue EOp1
= DAG
.getNode(
3028 ISD::EXTRACT_SUBVECTOR
, dl
, VT
, InOp1
,
3029 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3030 SDValue EOp2
= DAG
.getNode(
3031 ISD::EXTRACT_SUBVECTOR
, dl
, VT
, InOp2
,
3032 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3033 ConcatOps
[ConcatEnd
++] = DAG
.getNode(Opcode
, dl
, VT
, EOp1
, EOp2
, Flags
);
3035 CurNumElts
-= NumElts
;
3038 NumElts
= NumElts
/ 2;
3039 VT
= EVT::getVectorVT(*DAG
.getContext(), WidenEltVT
, NumElts
);
3040 } while (!TLI
.isTypeLegal(VT
) && NumElts
!= 1);
3043 for (unsigned i
= 0; i
!= CurNumElts
; ++i
, ++Idx
) {
3044 SDValue EOp1
= DAG
.getNode(
3045 ISD::EXTRACT_VECTOR_ELT
, dl
, WidenEltVT
, InOp1
,
3046 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3047 SDValue EOp2
= DAG
.getNode(
3048 ISD::EXTRACT_VECTOR_ELT
, dl
, WidenEltVT
, InOp2
,
3049 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3050 ConcatOps
[ConcatEnd
++] = DAG
.getNode(Opcode
, dl
, WidenEltVT
,
3057 return CollectOpsToWiden(DAG
, TLI
, ConcatOps
, ConcatEnd
, VT
, MaxVT
, WidenVT
);
3060 SDValue
DAGTypeLegalizer::WidenVecRes_StrictFP(SDNode
*N
) {
3061 // StrictFP op widening for operations that can trap.
3062 unsigned NumOpers
= N
->getNumOperands();
3063 unsigned Opcode
= N
->getOpcode();
3065 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3066 EVT WidenEltVT
= WidenVT
.getVectorElementType();
3068 unsigned NumElts
= VT
.getVectorNumElements();
3069 while (!TLI
.isTypeLegal(VT
) && NumElts
!= 1) {
3070 NumElts
= NumElts
/ 2;
3071 VT
= EVT::getVectorVT(*DAG
.getContext(), WidenEltVT
, NumElts
);
3074 // No legal vector version so unroll the vector operation and then widen.
3076 return UnrollVectorOp_StrictFP(N
, WidenVT
.getVectorNumElements());
3078 // Since the operation can trap, apply operation on the original vector.
3080 SmallVector
<SDValue
, 4> InOps
;
3081 unsigned CurNumElts
= N
->getValueType(0).getVectorNumElements();
3083 SmallVector
<SDValue
, 16> ConcatOps(CurNumElts
);
3084 SmallVector
<SDValue
, 16> Chains
;
3085 unsigned ConcatEnd
= 0; // Current ConcatOps index.
3086 int Idx
= 0; // Current Idx into input vectors.
3088 // The Chain is the first operand.
3089 InOps
.push_back(N
->getOperand(0));
3091 // Now process the remaining operands.
3092 for (unsigned i
= 1; i
< NumOpers
; ++i
) {
3093 SDValue Oper
= N
->getOperand(i
);
3095 if (Oper
.getValueType().isVector()) {
3096 assert(Oper
.getValueType() == N
->getValueType(0) &&
3097 "Invalid operand type to widen!");
3098 Oper
= GetWidenedVector(Oper
);
3101 InOps
.push_back(Oper
);
3104 // NumElts := greatest legal vector size (at most WidenVT)
3105 // while (orig. vector has unhandled elements) {
3106 // take munches of size NumElts from the beginning and add to ConcatOps
3107 // NumElts := next smaller supported vector size or 1
3109 while (CurNumElts
!= 0) {
3110 while (CurNumElts
>= NumElts
) {
3111 SmallVector
<SDValue
, 4> EOps
;
3113 for (unsigned i
= 0; i
< NumOpers
; ++i
) {
3114 SDValue Op
= InOps
[i
];
3116 if (Op
.getValueType().isVector())
3118 ISD::EXTRACT_SUBVECTOR
, dl
, VT
, Op
,
3119 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3124 EVT OperVT
[] = {VT
, MVT::Other
};
3125 SDValue Oper
= DAG
.getNode(Opcode
, dl
, OperVT
, EOps
);
3126 ConcatOps
[ConcatEnd
++] = Oper
;
3127 Chains
.push_back(Oper
.getValue(1));
3129 CurNumElts
-= NumElts
;
3132 NumElts
= NumElts
/ 2;
3133 VT
= EVT::getVectorVT(*DAG
.getContext(), WidenEltVT
, NumElts
);
3134 } while (!TLI
.isTypeLegal(VT
) && NumElts
!= 1);
3137 for (unsigned i
= 0; i
!= CurNumElts
; ++i
, ++Idx
) {
3138 SmallVector
<SDValue
, 4> EOps
;
3140 for (unsigned i
= 0; i
< NumOpers
; ++i
) {
3141 SDValue Op
= InOps
[i
];
3143 if (Op
.getValueType().isVector())
3145 ISD::EXTRACT_VECTOR_ELT
, dl
, WidenEltVT
, Op
,
3146 DAG
.getConstant(Idx
, dl
,
3147 TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3152 EVT WidenVT
[] = {WidenEltVT
, MVT::Other
};
3153 SDValue Oper
= DAG
.getNode(Opcode
, dl
, WidenVT
, EOps
);
3154 ConcatOps
[ConcatEnd
++] = Oper
;
3155 Chains
.push_back(Oper
.getValue(1));
3161 // Build a factor node to remember all the Ops that have been created.
3163 if (Chains
.size() == 1)
3164 NewChain
= Chains
[0];
3166 NewChain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, Chains
);
3167 ReplaceValueWith(SDValue(N
, 1), NewChain
);
3169 return CollectOpsToWiden(DAG
, TLI
, ConcatOps
, ConcatEnd
, VT
, MaxVT
, WidenVT
);
3172 SDValue
DAGTypeLegalizer::WidenVecRes_OverflowOp(SDNode
*N
, unsigned ResNo
) {
3174 EVT ResVT
= N
->getValueType(0);
3175 EVT OvVT
= N
->getValueType(1);
3176 EVT WideResVT
, WideOvVT
;
3177 SDValue WideLHS
, WideRHS
;
3179 // TODO: This might result in a widen/split loop.
3181 WideResVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), ResVT
);
3182 WideOvVT
= EVT::getVectorVT(
3183 *DAG
.getContext(), OvVT
.getVectorElementType(),
3184 WideResVT
.getVectorNumElements());
3186 WideLHS
= GetWidenedVector(N
->getOperand(0));
3187 WideRHS
= GetWidenedVector(N
->getOperand(1));
3189 WideOvVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), OvVT
);
3190 WideResVT
= EVT::getVectorVT(
3191 *DAG
.getContext(), ResVT
.getVectorElementType(),
3192 WideOvVT
.getVectorNumElements());
3194 SDValue Zero
= DAG
.getConstant(
3195 0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout()));
3196 WideLHS
= DAG
.getNode(
3197 ISD::INSERT_SUBVECTOR
, DL
, WideResVT
, DAG
.getUNDEF(WideResVT
),
3198 N
->getOperand(0), Zero
);
3199 WideRHS
= DAG
.getNode(
3200 ISD::INSERT_SUBVECTOR
, DL
, WideResVT
, DAG
.getUNDEF(WideResVT
),
3201 N
->getOperand(1), Zero
);
3204 SDVTList WideVTs
= DAG
.getVTList(WideResVT
, WideOvVT
);
3205 SDNode
*WideNode
= DAG
.getNode(
3206 N
->getOpcode(), DL
, WideVTs
, WideLHS
, WideRHS
).getNode();
3208 // Replace the other vector result not being explicitly widened here.
3209 unsigned OtherNo
= 1 - ResNo
;
3210 EVT OtherVT
= N
->getValueType(OtherNo
);
3211 if (getTypeAction(OtherVT
) == TargetLowering::TypeWidenVector
) {
3212 SetWidenedVector(SDValue(N
, OtherNo
), SDValue(WideNode
, OtherNo
));
3214 SDValue Zero
= DAG
.getConstant(
3215 0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout()));
3216 SDValue OtherVal
= DAG
.getNode(
3217 ISD::EXTRACT_SUBVECTOR
, DL
, OtherVT
, SDValue(WideNode
, OtherNo
), Zero
);
3218 ReplaceValueWith(SDValue(N
, OtherNo
), OtherVal
);
3221 return SDValue(WideNode
, ResNo
);
3224 SDValue
DAGTypeLegalizer::WidenVecRes_Convert(SDNode
*N
) {
3225 SDValue InOp
= N
->getOperand(0);
3228 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3229 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
3231 EVT InVT
= InOp
.getValueType();
3232 EVT InEltVT
= InVT
.getVectorElementType();
3233 EVT InWidenVT
= EVT::getVectorVT(*DAG
.getContext(), InEltVT
, WidenNumElts
);
3235 unsigned Opcode
= N
->getOpcode();
3236 unsigned InVTNumElts
= InVT
.getVectorNumElements();
3237 const SDNodeFlags Flags
= N
->getFlags();
3238 if (getTypeAction(InVT
) == TargetLowering::TypeWidenVector
) {
3239 InOp
= GetWidenedVector(N
->getOperand(0));
3240 InVT
= InOp
.getValueType();
3241 InVTNumElts
= InVT
.getVectorNumElements();
3242 if (InVTNumElts
== WidenNumElts
) {
3243 if (N
->getNumOperands() == 1)
3244 return DAG
.getNode(Opcode
, DL
, WidenVT
, InOp
);
3245 return DAG
.getNode(Opcode
, DL
, WidenVT
, InOp
, N
->getOperand(1), Flags
);
3247 if (WidenVT
.getSizeInBits() == InVT
.getSizeInBits()) {
3248 // If both input and result vector types are of same width, extend
3249 // operations should be done with SIGN/ZERO_EXTEND_VECTOR_INREG, which
3250 // accepts fewer elements in the result than in the input.
3251 if (Opcode
== ISD::ANY_EXTEND
)
3252 return DAG
.getNode(ISD::ANY_EXTEND_VECTOR_INREG
, DL
, WidenVT
, InOp
);
3253 if (Opcode
== ISD::SIGN_EXTEND
)
3254 return DAG
.getNode(ISD::SIGN_EXTEND_VECTOR_INREG
, DL
, WidenVT
, InOp
);
3255 if (Opcode
== ISD::ZERO_EXTEND
)
3256 return DAG
.getNode(ISD::ZERO_EXTEND_VECTOR_INREG
, DL
, WidenVT
, InOp
);
3260 if (TLI
.isTypeLegal(InWidenVT
)) {
3261 // Because the result and the input are different vector types, widening
3262 // the result could create a legal type but widening the input might make
3263 // it an illegal type that might lead to repeatedly splitting the input
3264 // and then widening it. To avoid this, we widen the input only if
3265 // it results in a legal type.
3266 if (WidenNumElts
% InVTNumElts
== 0) {
3267 // Widen the input and call convert on the widened input vector.
3268 unsigned NumConcat
= WidenNumElts
/InVTNumElts
;
3269 SmallVector
<SDValue
, 16> Ops(NumConcat
, DAG
.getUNDEF(InVT
));
3271 SDValue InVec
= DAG
.getNode(ISD::CONCAT_VECTORS
, DL
, InWidenVT
, Ops
);
3272 if (N
->getNumOperands() == 1)
3273 return DAG
.getNode(Opcode
, DL
, WidenVT
, InVec
);
3274 return DAG
.getNode(Opcode
, DL
, WidenVT
, InVec
, N
->getOperand(1), Flags
);
3277 if (InVTNumElts
% WidenNumElts
== 0) {
3278 SDValue InVal
= DAG
.getNode(
3279 ISD::EXTRACT_SUBVECTOR
, DL
, InWidenVT
, InOp
,
3280 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3281 // Extract the input and convert the shorten input vector.
3282 if (N
->getNumOperands() == 1)
3283 return DAG
.getNode(Opcode
, DL
, WidenVT
, InVal
);
3284 return DAG
.getNode(Opcode
, DL
, WidenVT
, InVal
, N
->getOperand(1), Flags
);
3288 // Otherwise unroll into some nasty scalar code and rebuild the vector.
3289 EVT EltVT
= WidenVT
.getVectorElementType();
3290 SmallVector
<SDValue
, 16> Ops(WidenNumElts
, DAG
.getUNDEF(EltVT
));
3291 // Use the original element count so we don't do more scalar opts than
3293 unsigned MinElts
= N
->getValueType(0).getVectorNumElements();
3294 for (unsigned i
=0; i
< MinElts
; ++i
) {
3295 SDValue Val
= DAG
.getNode(
3296 ISD::EXTRACT_VECTOR_ELT
, DL
, InEltVT
, InOp
,
3297 DAG
.getConstant(i
, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3298 if (N
->getNumOperands() == 1)
3299 Ops
[i
] = DAG
.getNode(Opcode
, DL
, EltVT
, Val
);
3301 Ops
[i
] = DAG
.getNode(Opcode
, DL
, EltVT
, Val
, N
->getOperand(1), Flags
);
3304 return DAG
.getBuildVector(WidenVT
, DL
, Ops
);
3307 SDValue
DAGTypeLegalizer::WidenVecRes_Convert_StrictFP(SDNode
*N
) {
3308 SDValue InOp
= N
->getOperand(1);
3310 SmallVector
<SDValue
, 4> NewOps(N
->op_begin(), N
->op_end());
3312 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3313 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
3314 SmallVector
<EVT
, 2> WidenVTs
= { WidenVT
, MVT::Other
};
3316 EVT InVT
= InOp
.getValueType();
3317 EVT InEltVT
= InVT
.getVectorElementType();
3319 unsigned Opcode
= N
->getOpcode();
3321 // FIXME: Optimizations need to be implemented here.
3323 // Otherwise unroll into some nasty scalar code and rebuild the vector.
3324 EVT EltVT
= WidenVT
.getVectorElementType();
3325 SmallVector
<EVT
, 2> EltVTs
= { EltVT
, MVT::Other
};
3326 SmallVector
<SDValue
, 16> Ops(WidenNumElts
, DAG
.getUNDEF(EltVT
));
3327 SmallVector
<SDValue
, 32> OpChains
;
3328 // Use the original element count so we don't do more scalar opts than
3330 unsigned MinElts
= N
->getValueType(0).getVectorNumElements();
3331 for (unsigned i
=0; i
< MinElts
; ++i
) {
3332 NewOps
[1] = DAG
.getNode(
3333 ISD::EXTRACT_VECTOR_ELT
, DL
, InEltVT
, InOp
,
3334 DAG
.getConstant(i
, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3335 Ops
[i
] = DAG
.getNode(Opcode
, DL
, EltVTs
, NewOps
);
3336 OpChains
.push_back(Ops
[i
].getValue(1));
3338 SDValue NewChain
= DAG
.getNode(ISD::TokenFactor
, DL
, MVT::Other
, OpChains
);
3339 ReplaceValueWith(SDValue(N
, 1), NewChain
);
3341 return DAG
.getBuildVector(WidenVT
, DL
, Ops
);
3344 SDValue
DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(SDNode
*N
) {
3345 unsigned Opcode
= N
->getOpcode();
3346 SDValue InOp
= N
->getOperand(0);
3349 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3350 EVT WidenSVT
= WidenVT
.getVectorElementType();
3351 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
3353 EVT InVT
= InOp
.getValueType();
3354 EVT InSVT
= InVT
.getVectorElementType();
3355 unsigned InVTNumElts
= InVT
.getVectorNumElements();
3357 if (getTypeAction(InVT
) == TargetLowering::TypeWidenVector
) {
3358 InOp
= GetWidenedVector(InOp
);
3359 InVT
= InOp
.getValueType();
3360 if (InVT
.getSizeInBits() == WidenVT
.getSizeInBits()) {
3362 case ISD::ANY_EXTEND_VECTOR_INREG
:
3363 case ISD::SIGN_EXTEND_VECTOR_INREG
:
3364 case ISD::ZERO_EXTEND_VECTOR_INREG
:
3365 return DAG
.getNode(Opcode
, DL
, WidenVT
, InOp
);
3370 // Unroll, extend the scalars and rebuild the vector.
3371 SmallVector
<SDValue
, 16> Ops
;
3372 for (unsigned i
= 0, e
= std::min(InVTNumElts
, WidenNumElts
); i
!= e
; ++i
) {
3373 SDValue Val
= DAG
.getNode(ISD::EXTRACT_VECTOR_ELT
, DL
, InSVT
, InOp
,
3374 DAG
.getConstant(i
, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3376 case ISD::ANY_EXTEND_VECTOR_INREG
:
3377 Val
= DAG
.getNode(ISD::ANY_EXTEND
, DL
, WidenSVT
, Val
);
3379 case ISD::SIGN_EXTEND_VECTOR_INREG
:
3380 Val
= DAG
.getNode(ISD::SIGN_EXTEND
, DL
, WidenSVT
, Val
);
3382 case ISD::ZERO_EXTEND_VECTOR_INREG
:
3383 Val
= DAG
.getNode(ISD::ZERO_EXTEND
, DL
, WidenSVT
, Val
);
3386 llvm_unreachable("A *_EXTEND_VECTOR_INREG node was expected");
3391 while (Ops
.size() != WidenNumElts
)
3392 Ops
.push_back(DAG
.getUNDEF(WidenSVT
));
3394 return DAG
.getBuildVector(WidenVT
, DL
, Ops
);
3397 SDValue
DAGTypeLegalizer::WidenVecRes_FCOPYSIGN(SDNode
*N
) {
3398 // If this is an FCOPYSIGN with same input types, we can treat it as a
3399 // normal (can trap) binary op.
3400 if (N
->getOperand(0).getValueType() == N
->getOperand(1).getValueType())
3401 return WidenVecRes_BinaryCanTrap(N
);
3403 // If the types are different, fall back to unrolling.
3404 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3405 return DAG
.UnrollVectorOp(N
, WidenVT
.getVectorNumElements());
3408 SDValue
DAGTypeLegalizer::WidenVecRes_POWI(SDNode
*N
) {
3409 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3410 SDValue InOp
= GetWidenedVector(N
->getOperand(0));
3411 SDValue ShOp
= N
->getOperand(1);
3412 return DAG
.getNode(N
->getOpcode(), SDLoc(N
), WidenVT
, InOp
, ShOp
);
3415 SDValue
DAGTypeLegalizer::WidenVecRes_Shift(SDNode
*N
) {
3416 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3417 SDValue InOp
= GetWidenedVector(N
->getOperand(0));
3418 SDValue ShOp
= N
->getOperand(1);
3420 EVT ShVT
= ShOp
.getValueType();
3421 if (getTypeAction(ShVT
) == TargetLowering::TypeWidenVector
) {
3422 ShOp
= GetWidenedVector(ShOp
);
3423 ShVT
= ShOp
.getValueType();
3425 EVT ShWidenVT
= EVT::getVectorVT(*DAG
.getContext(),
3426 ShVT
.getVectorElementType(),
3427 WidenVT
.getVectorNumElements());
3428 if (ShVT
!= ShWidenVT
)
3429 ShOp
= ModifyToType(ShOp
, ShWidenVT
);
3431 return DAG
.getNode(N
->getOpcode(), SDLoc(N
), WidenVT
, InOp
, ShOp
);
3434 SDValue
DAGTypeLegalizer::WidenVecRes_Unary(SDNode
*N
) {
3435 // Unary op widening.
3436 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3437 SDValue InOp
= GetWidenedVector(N
->getOperand(0));
3438 return DAG
.getNode(N
->getOpcode(), SDLoc(N
), WidenVT
, InOp
);
3441 SDValue
DAGTypeLegalizer::WidenVecRes_InregOp(SDNode
*N
) {
3442 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3443 EVT ExtVT
= EVT::getVectorVT(*DAG
.getContext(),
3444 cast
<VTSDNode
>(N
->getOperand(1))->getVT()
3445 .getVectorElementType(),
3446 WidenVT
.getVectorNumElements());
3447 SDValue WidenLHS
= GetWidenedVector(N
->getOperand(0));
3448 return DAG
.getNode(N
->getOpcode(), SDLoc(N
),
3449 WidenVT
, WidenLHS
, DAG
.getValueType(ExtVT
));
3452 SDValue
DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(SDNode
*N
, unsigned ResNo
) {
3453 SDValue WidenVec
= DisintegrateMERGE_VALUES(N
, ResNo
);
3454 return GetWidenedVector(WidenVec
);
3457 SDValue
DAGTypeLegalizer::WidenVecRes_BITCAST(SDNode
*N
) {
3458 SDValue InOp
= N
->getOperand(0);
3459 EVT InVT
= InOp
.getValueType();
3460 EVT VT
= N
->getValueType(0);
3461 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
3464 switch (getTypeAction(InVT
)) {
3465 case TargetLowering::TypeLegal
:
3467 case TargetLowering::TypePromoteInteger
:
3468 // If the incoming type is a vector that is being promoted, then
3469 // we know that the elements are arranged differently and that we
3470 // must perform the conversion using a stack slot.
3471 if (InVT
.isVector())
3474 // If the InOp is promoted to the same size, convert it. Otherwise,
3475 // fall out of the switch and widen the promoted input.
3476 InOp
= GetPromotedInteger(InOp
);
3477 InVT
= InOp
.getValueType();
3478 if (WidenVT
.bitsEq(InVT
))
3479 return DAG
.getNode(ISD::BITCAST
, dl
, WidenVT
, InOp
);
3481 case TargetLowering::TypeSoftenFloat
:
3482 case TargetLowering::TypePromoteFloat
:
3483 case TargetLowering::TypeExpandInteger
:
3484 case TargetLowering::TypeExpandFloat
:
3485 case TargetLowering::TypeScalarizeVector
:
3486 case TargetLowering::TypeSplitVector
:
3488 case TargetLowering::TypeWidenVector
:
3489 // If the InOp is widened to the same size, convert it. Otherwise, fall
3490 // out of the switch and widen the widened input.
3491 InOp
= GetWidenedVector(InOp
);
3492 InVT
= InOp
.getValueType();
3493 if (WidenVT
.bitsEq(InVT
))
3494 // The input widens to the same size. Convert to the widen value.
3495 return DAG
.getNode(ISD::BITCAST
, dl
, WidenVT
, InOp
);
3499 unsigned WidenSize
= WidenVT
.getSizeInBits();
3500 unsigned InSize
= InVT
.getSizeInBits();
3501 // x86mmx is not an acceptable vector element type, so don't try.
3502 if (WidenSize
% InSize
== 0 && InVT
!= MVT::x86mmx
) {
3503 // Determine new input vector type. The new input vector type will use
3504 // the same element type (if its a vector) or use the input type as a
3505 // vector. It is the same size as the type to widen to.
3507 unsigned NewNumElts
= WidenSize
/ InSize
;
3508 if (InVT
.isVector()) {
3509 EVT InEltVT
= InVT
.getVectorElementType();
3510 NewInVT
= EVT::getVectorVT(*DAG
.getContext(), InEltVT
,
3511 WidenSize
/ InEltVT
.getSizeInBits());
3513 NewInVT
= EVT::getVectorVT(*DAG
.getContext(), InVT
, NewNumElts
);
3516 if (TLI
.isTypeLegal(NewInVT
)) {
3518 if (InVT
.isVector()) {
3519 // Because the result and the input are different vector types, widening
3520 // the result could create a legal type but widening the input might make
3521 // it an illegal type that might lead to repeatedly splitting the input
3522 // and then widening it. To avoid this, we widen the input only if
3523 // it results in a legal type.
3524 SmallVector
<SDValue
, 16> Ops(NewNumElts
, DAG
.getUNDEF(InVT
));
3527 NewVec
= DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, NewInVT
, Ops
);
3529 NewVec
= DAG
.getNode(ISD::SCALAR_TO_VECTOR
, dl
, NewInVT
, InOp
);
3531 return DAG
.getNode(ISD::BITCAST
, dl
, WidenVT
, NewVec
);
3535 return CreateStackStoreLoad(InOp
, WidenVT
);
3538 SDValue
DAGTypeLegalizer::WidenVecRes_BUILD_VECTOR(SDNode
*N
) {
3540 // Build a vector with undefined for the new nodes.
3541 EVT VT
= N
->getValueType(0);
3543 // Integer BUILD_VECTOR operands may be larger than the node's vector element
3544 // type. The UNDEFs need to have the same type as the existing operands.
3545 EVT EltVT
= N
->getOperand(0).getValueType();
3546 unsigned NumElts
= VT
.getVectorNumElements();
3548 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
3549 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
3551 SmallVector
<SDValue
, 16> NewOps(N
->op_begin(), N
->op_end());
3552 assert(WidenNumElts
>= NumElts
&& "Shrinking vector instead of widening!");
3553 NewOps
.append(WidenNumElts
- NumElts
, DAG
.getUNDEF(EltVT
));
3555 return DAG
.getBuildVector(WidenVT
, dl
, NewOps
);
3558 SDValue
DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode
*N
) {
3559 EVT InVT
= N
->getOperand(0).getValueType();
3560 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3562 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
3563 unsigned NumInElts
= InVT
.getVectorNumElements();
3564 unsigned NumOperands
= N
->getNumOperands();
3566 bool InputWidened
= false; // Indicates we need to widen the input.
3567 if (getTypeAction(InVT
) != TargetLowering::TypeWidenVector
) {
3568 if (WidenVT
.getVectorNumElements() % InVT
.getVectorNumElements() == 0) {
3569 // Add undef vectors to widen to correct length.
3570 unsigned NumConcat
= WidenVT
.getVectorNumElements() /
3571 InVT
.getVectorNumElements();
3572 SDValue UndefVal
= DAG
.getUNDEF(InVT
);
3573 SmallVector
<SDValue
, 16> Ops(NumConcat
);
3574 for (unsigned i
=0; i
< NumOperands
; ++i
)
3575 Ops
[i
] = N
->getOperand(i
);
3576 for (unsigned i
= NumOperands
; i
!= NumConcat
; ++i
)
3578 return DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, WidenVT
, Ops
);
3581 InputWidened
= true;
3582 if (WidenVT
== TLI
.getTypeToTransformTo(*DAG
.getContext(), InVT
)) {
3583 // The inputs and the result are widen to the same value.
3585 for (i
=1; i
< NumOperands
; ++i
)
3586 if (!N
->getOperand(i
).isUndef())
3589 if (i
== NumOperands
)
3590 // Everything but the first operand is an UNDEF so just return the
3591 // widened first operand.
3592 return GetWidenedVector(N
->getOperand(0));
3594 if (NumOperands
== 2) {
3595 // Replace concat of two operands with a shuffle.
3596 SmallVector
<int, 16> MaskOps(WidenNumElts
, -1);
3597 for (unsigned i
= 0; i
< NumInElts
; ++i
) {
3599 MaskOps
[i
+ NumInElts
] = i
+ WidenNumElts
;
3601 return DAG
.getVectorShuffle(WidenVT
, dl
,
3602 GetWidenedVector(N
->getOperand(0)),
3603 GetWidenedVector(N
->getOperand(1)),
3609 // Fall back to use extracts and build vector.
3610 EVT EltVT
= WidenVT
.getVectorElementType();
3611 SmallVector
<SDValue
, 16> Ops(WidenNumElts
);
3613 for (unsigned i
=0; i
< NumOperands
; ++i
) {
3614 SDValue InOp
= N
->getOperand(i
);
3616 InOp
= GetWidenedVector(InOp
);
3617 for (unsigned j
=0; j
< NumInElts
; ++j
)
3618 Ops
[Idx
++] = DAG
.getNode(
3619 ISD::EXTRACT_VECTOR_ELT
, dl
, EltVT
, InOp
,
3620 DAG
.getConstant(j
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3622 SDValue UndefVal
= DAG
.getUNDEF(EltVT
);
3623 for (; Idx
< WidenNumElts
; ++Idx
)
3624 Ops
[Idx
] = UndefVal
;
3625 return DAG
.getBuildVector(WidenVT
, dl
, Ops
);
3628 SDValue
DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode
*N
) {
3629 EVT VT
= N
->getValueType(0);
3630 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
3631 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
3632 SDValue InOp
= N
->getOperand(0);
3633 SDValue Idx
= N
->getOperand(1);
3636 if (getTypeAction(InOp
.getValueType()) == TargetLowering::TypeWidenVector
)
3637 InOp
= GetWidenedVector(InOp
);
3639 EVT InVT
= InOp
.getValueType();
3641 // Check if we can just return the input vector after widening.
3642 uint64_t IdxVal
= cast
<ConstantSDNode
>(Idx
)->getZExtValue();
3643 if (IdxVal
== 0 && InVT
== WidenVT
)
3646 // Check if we can extract from the vector.
3647 unsigned InNumElts
= InVT
.getVectorNumElements();
3648 if (IdxVal
% WidenNumElts
== 0 && IdxVal
+ WidenNumElts
< InNumElts
)
3649 return DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, dl
, WidenVT
, InOp
, Idx
);
3651 // We could try widening the input to the right length but for now, extract
3652 // the original elements, fill the rest with undefs and build a vector.
3653 SmallVector
<SDValue
, 16> Ops(WidenNumElts
);
3654 EVT EltVT
= VT
.getVectorElementType();
3655 unsigned NumElts
= VT
.getVectorNumElements();
3657 for (i
=0; i
< NumElts
; ++i
)
3659 DAG
.getNode(ISD::EXTRACT_VECTOR_ELT
, dl
, EltVT
, InOp
,
3660 DAG
.getConstant(IdxVal
+ i
, dl
,
3661 TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3663 SDValue UndefVal
= DAG
.getUNDEF(EltVT
);
3664 for (; i
< WidenNumElts
; ++i
)
3666 return DAG
.getBuildVector(WidenVT
, dl
, Ops
);
3669 SDValue
DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode
*N
) {
3670 SDValue InOp
= GetWidenedVector(N
->getOperand(0));
3671 return DAG
.getNode(ISD::INSERT_VECTOR_ELT
, SDLoc(N
),
3672 InOp
.getValueType(), InOp
,
3673 N
->getOperand(1), N
->getOperand(2));
3676 SDValue
DAGTypeLegalizer::WidenVecRes_LOAD(SDNode
*N
) {
3677 LoadSDNode
*LD
= cast
<LoadSDNode
>(N
);
3678 ISD::LoadExtType ExtType
= LD
->getExtensionType();
3681 SmallVector
<SDValue
, 16> LdChain
; // Chain for the series of load
3682 if (ExtType
!= ISD::NON_EXTLOAD
)
3683 Result
= GenWidenVectorExtLoads(LdChain
, LD
, ExtType
);
3685 Result
= GenWidenVectorLoads(LdChain
, LD
);
3687 // If we generate a single load, we can use that for the chain. Otherwise,
3688 // build a factor node to remember the multiple loads are independent and
3691 if (LdChain
.size() == 1)
3692 NewChain
= LdChain
[0];
3694 NewChain
= DAG
.getNode(ISD::TokenFactor
, SDLoc(LD
), MVT::Other
, LdChain
);
3696 // Modified the chain - switch anything that used the old chain to use
3698 ReplaceValueWith(SDValue(N
, 1), NewChain
);
3703 SDValue
DAGTypeLegalizer::WidenVecRes_MLOAD(MaskedLoadSDNode
*N
) {
3705 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(),N
->getValueType(0));
3706 SDValue Mask
= N
->getMask();
3707 EVT MaskVT
= Mask
.getValueType();
3708 SDValue PassThru
= GetWidenedVector(N
->getPassThru());
3709 ISD::LoadExtType ExtType
= N
->getExtensionType();
3712 // The mask should be widened as well
3713 EVT WideMaskVT
= EVT::getVectorVT(*DAG
.getContext(),
3714 MaskVT
.getVectorElementType(),
3715 WidenVT
.getVectorNumElements());
3716 Mask
= ModifyToType(Mask
, WideMaskVT
, true);
3718 SDValue Res
= DAG
.getMaskedLoad(WidenVT
, dl
, N
->getChain(), N
->getBasePtr(),
3719 Mask
, PassThru
, N
->getMemoryVT(),
3720 N
->getMemOperand(), ExtType
,
3721 N
->isExpandingLoad());
3722 // Legalize the chain result - switch anything that used the old chain to
3724 ReplaceValueWith(SDValue(N
, 1), Res
.getValue(1));
3728 SDValue
DAGTypeLegalizer::WidenVecRes_MGATHER(MaskedGatherSDNode
*N
) {
3730 EVT WideVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3731 SDValue Mask
= N
->getMask();
3732 EVT MaskVT
= Mask
.getValueType();
3733 SDValue PassThru
= GetWidenedVector(N
->getPassThru());
3734 SDValue Scale
= N
->getScale();
3735 unsigned NumElts
= WideVT
.getVectorNumElements();
3738 // The mask should be widened as well
3739 EVT WideMaskVT
= EVT::getVectorVT(*DAG
.getContext(),
3740 MaskVT
.getVectorElementType(),
3741 WideVT
.getVectorNumElements());
3742 Mask
= ModifyToType(Mask
, WideMaskVT
, true);
3744 // Widen the Index operand
3745 SDValue Index
= N
->getIndex();
3746 EVT WideIndexVT
= EVT::getVectorVT(*DAG
.getContext(),
3747 Index
.getValueType().getScalarType(),
3749 Index
= ModifyToType(Index
, WideIndexVT
);
3750 SDValue Ops
[] = { N
->getChain(), PassThru
, Mask
, N
->getBasePtr(), Index
,
3752 SDValue Res
= DAG
.getMaskedGather(DAG
.getVTList(WideVT
, MVT::Other
),
3753 N
->getMemoryVT(), dl
, Ops
,
3754 N
->getMemOperand(), N
->getIndexType());
3756 // Legalize the chain result - switch anything that used the old chain to
3758 ReplaceValueWith(SDValue(N
, 1), Res
.getValue(1));
3762 SDValue
DAGTypeLegalizer::WidenVecRes_SCALAR_TO_VECTOR(SDNode
*N
) {
3763 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3764 return DAG
.getNode(ISD::SCALAR_TO_VECTOR
, SDLoc(N
),
3765 WidenVT
, N
->getOperand(0));
3768 // Return true if this is a node that could have two SETCCs as operands.
3769 static inline bool isLogicalMaskOp(unsigned Opcode
) {
3779 // This is used just for the assert in convertMask(). Check that this either
3780 // a SETCC or a previously handled SETCC by convertMask().
3782 static inline bool isSETCCorConvertedSETCC(SDValue N
) {
3783 if (N
.getOpcode() == ISD::EXTRACT_SUBVECTOR
)
3784 N
= N
.getOperand(0);
3785 else if (N
.getOpcode() == ISD::CONCAT_VECTORS
) {
3786 for (unsigned i
= 1; i
< N
->getNumOperands(); ++i
)
3787 if (!N
->getOperand(i
)->isUndef())
3789 N
= N
.getOperand(0);
3792 if (N
.getOpcode() == ISD::TRUNCATE
)
3793 N
= N
.getOperand(0);
3794 else if (N
.getOpcode() == ISD::SIGN_EXTEND
)
3795 N
= N
.getOperand(0);
3797 if (isLogicalMaskOp(N
.getOpcode()))
3798 return isSETCCorConvertedSETCC(N
.getOperand(0)) &&
3799 isSETCCorConvertedSETCC(N
.getOperand(1));
3801 return (N
.getOpcode() == ISD::SETCC
||
3802 ISD::isBuildVectorOfConstantSDNodes(N
.getNode()));
3806 // Return a mask of vector type MaskVT to replace InMask. Also adjust MaskVT
3807 // to ToMaskVT if needed with vector extension or truncation.
3808 SDValue
DAGTypeLegalizer::convertMask(SDValue InMask
, EVT MaskVT
,
3810 // Currently a SETCC or a AND/OR/XOR with two SETCCs are handled.
3811 // FIXME: This code seems to be too restrictive, we might consider
3812 // generalizing it or dropping it.
3813 assert(isSETCCorConvertedSETCC(InMask
) && "Unexpected mask argument.");
3815 // Make a new Mask node, with a legal result VT.
3816 SmallVector
<SDValue
, 4> Ops
;
3817 for (unsigned i
= 0, e
= InMask
->getNumOperands(); i
< e
; ++i
)
3818 Ops
.push_back(InMask
->getOperand(i
));
3819 SDValue Mask
= DAG
.getNode(InMask
->getOpcode(), SDLoc(InMask
), MaskVT
, Ops
);
3821 // If MaskVT has smaller or bigger elements than ToMaskVT, a vector sign
3822 // extend or truncate is needed.
3823 LLVMContext
&Ctx
= *DAG
.getContext();
3824 unsigned MaskScalarBits
= MaskVT
.getScalarSizeInBits();
3825 unsigned ToMaskScalBits
= ToMaskVT
.getScalarSizeInBits();
3826 if (MaskScalarBits
< ToMaskScalBits
) {
3827 EVT ExtVT
= EVT::getVectorVT(Ctx
, ToMaskVT
.getVectorElementType(),
3828 MaskVT
.getVectorNumElements());
3829 Mask
= DAG
.getNode(ISD::SIGN_EXTEND
, SDLoc(Mask
), ExtVT
, Mask
);
3830 } else if (MaskScalarBits
> ToMaskScalBits
) {
3831 EVT TruncVT
= EVT::getVectorVT(Ctx
, ToMaskVT
.getVectorElementType(),
3832 MaskVT
.getVectorNumElements());
3833 Mask
= DAG
.getNode(ISD::TRUNCATE
, SDLoc(Mask
), TruncVT
, Mask
);
3836 assert(Mask
->getValueType(0).getScalarSizeInBits() ==
3837 ToMaskVT
.getScalarSizeInBits() &&
3838 "Mask should have the right element size by now.");
3840 // Adjust Mask to the right number of elements.
3841 unsigned CurrMaskNumEls
= Mask
->getValueType(0).getVectorNumElements();
3842 if (CurrMaskNumEls
> ToMaskVT
.getVectorNumElements()) {
3843 MVT IdxTy
= TLI
.getVectorIdxTy(DAG
.getDataLayout());
3844 SDValue ZeroIdx
= DAG
.getConstant(0, SDLoc(Mask
), IdxTy
);
3845 Mask
= DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, SDLoc(Mask
), ToMaskVT
, Mask
,
3847 } else if (CurrMaskNumEls
< ToMaskVT
.getVectorNumElements()) {
3848 unsigned NumSubVecs
= (ToMaskVT
.getVectorNumElements() / CurrMaskNumEls
);
3849 EVT SubVT
= Mask
->getValueType(0);
3850 SmallVector
<SDValue
, 16> SubOps(NumSubVecs
, DAG
.getUNDEF(SubVT
));
3852 Mask
= DAG
.getNode(ISD::CONCAT_VECTORS
, SDLoc(Mask
), ToMaskVT
, SubOps
);
3855 assert((Mask
->getValueType(0) == ToMaskVT
) &&
3856 "A mask of ToMaskVT should have been produced by now.");
3861 // This method tries to handle VSELECT and its mask by legalizing operands
3862 // (which may require widening) and if needed adjusting the mask vector type
3863 // to match that of the VSELECT. Without it, many cases end up with
3864 // scalarization of the SETCC, with many unnecessary instructions.
3865 SDValue
DAGTypeLegalizer::WidenVSELECTAndMask(SDNode
*N
) {
3866 LLVMContext
&Ctx
= *DAG
.getContext();
3867 SDValue Cond
= N
->getOperand(0);
3869 if (N
->getOpcode() != ISD::VSELECT
)
3872 if (Cond
->getOpcode() != ISD::SETCC
&& !isLogicalMaskOp(Cond
->getOpcode()))
3875 // If this is a splitted VSELECT that was previously already handled, do
3877 EVT CondVT
= Cond
->getValueType(0);
3878 if (CondVT
.getScalarSizeInBits() != 1)
3881 EVT VSelVT
= N
->getValueType(0);
3882 // Only handle vector types which are a power of 2.
3883 if (!isPowerOf2_64(VSelVT
.getSizeInBits()))
3886 // Don't touch if this will be scalarized.
3887 EVT FinalVT
= VSelVT
;
3888 while (getTypeAction(FinalVT
) == TargetLowering::TypeSplitVector
)
3889 FinalVT
= FinalVT
.getHalfNumVectorElementsVT(Ctx
);
3891 if (FinalVT
.getVectorNumElements() == 1)
3894 // If there is support for an i1 vector mask, don't touch.
3895 if (Cond
.getOpcode() == ISD::SETCC
) {
3896 EVT SetCCOpVT
= Cond
->getOperand(0).getValueType();
3897 while (TLI
.getTypeAction(Ctx
, SetCCOpVT
) != TargetLowering::TypeLegal
)
3898 SetCCOpVT
= TLI
.getTypeToTransformTo(Ctx
, SetCCOpVT
);
3899 EVT SetCCResVT
= getSetCCResultType(SetCCOpVT
);
3900 if (SetCCResVT
.getScalarSizeInBits() == 1)
3902 } else if (CondVT
.getScalarType() == MVT::i1
) {
3903 // If there is support for an i1 vector mask (or only scalar i1 conditions),
3905 while (TLI
.getTypeAction(Ctx
, CondVT
) != TargetLowering::TypeLegal
)
3906 CondVT
= TLI
.getTypeToTransformTo(Ctx
, CondVT
);
3908 if (CondVT
.getScalarType() == MVT::i1
)
3912 // Get the VT and operands for VSELECT, and widen if needed.
3913 SDValue VSelOp1
= N
->getOperand(1);
3914 SDValue VSelOp2
= N
->getOperand(2);
3915 if (getTypeAction(VSelVT
) == TargetLowering::TypeWidenVector
) {
3916 VSelVT
= TLI
.getTypeToTransformTo(Ctx
, VSelVT
);
3917 VSelOp1
= GetWidenedVector(VSelOp1
);
3918 VSelOp2
= GetWidenedVector(VSelOp2
);
3921 // The mask of the VSELECT should have integer elements.
3922 EVT ToMaskVT
= VSelVT
;
3923 if (!ToMaskVT
.getScalarType().isInteger())
3924 ToMaskVT
= ToMaskVT
.changeVectorElementTypeToInteger();
3927 if (Cond
->getOpcode() == ISD::SETCC
) {
3928 EVT MaskVT
= getSetCCResultType(Cond
.getOperand(0).getValueType());
3929 Mask
= convertMask(Cond
, MaskVT
, ToMaskVT
);
3930 } else if (isLogicalMaskOp(Cond
->getOpcode()) &&
3931 Cond
->getOperand(0).getOpcode() == ISD::SETCC
&&
3932 Cond
->getOperand(1).getOpcode() == ISD::SETCC
) {
3933 // Cond is (AND/OR/XOR (SETCC, SETCC))
3934 SDValue SETCC0
= Cond
->getOperand(0);
3935 SDValue SETCC1
= Cond
->getOperand(1);
3936 EVT VT0
= getSetCCResultType(SETCC0
.getOperand(0).getValueType());
3937 EVT VT1
= getSetCCResultType(SETCC1
.getOperand(0).getValueType());
3938 unsigned ScalarBits0
= VT0
.getScalarSizeInBits();
3939 unsigned ScalarBits1
= VT1
.getScalarSizeInBits();
3940 unsigned ScalarBits_ToMask
= ToMaskVT
.getScalarSizeInBits();
3942 // If the two SETCCs have different VTs, either extend/truncate one of
3943 // them to the other "towards" ToMaskVT, or truncate one and extend the
3944 // other to ToMaskVT.
3945 if (ScalarBits0
!= ScalarBits1
) {
3946 EVT NarrowVT
= ((ScalarBits0
< ScalarBits1
) ? VT0
: VT1
);
3947 EVT WideVT
= ((NarrowVT
== VT0
) ? VT1
: VT0
);
3948 if (ScalarBits_ToMask
>= WideVT
.getScalarSizeInBits())
3950 else if (ScalarBits_ToMask
<= NarrowVT
.getScalarSizeInBits())
3955 // If the two SETCCs have the same VT, don't change it.
3958 // Make new SETCCs and logical nodes.
3959 SETCC0
= convertMask(SETCC0
, VT0
, MaskVT
);
3960 SETCC1
= convertMask(SETCC1
, VT1
, MaskVT
);
3961 Cond
= DAG
.getNode(Cond
->getOpcode(), SDLoc(Cond
), MaskVT
, SETCC0
, SETCC1
);
3963 // Convert the logical op for VSELECT if needed.
3964 Mask
= convertMask(Cond
, MaskVT
, ToMaskVT
);
3968 return DAG
.getNode(ISD::VSELECT
, SDLoc(N
), VSelVT
, Mask
, VSelOp1
, VSelOp2
);
3971 SDValue
DAGTypeLegalizer::WidenVecRes_SELECT(SDNode
*N
) {
3972 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3973 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
3975 SDValue Cond1
= N
->getOperand(0);
3976 EVT CondVT
= Cond1
.getValueType();
3977 if (CondVT
.isVector()) {
3978 if (SDValue Res
= WidenVSELECTAndMask(N
))
3981 EVT CondEltVT
= CondVT
.getVectorElementType();
3982 EVT CondWidenVT
= EVT::getVectorVT(*DAG
.getContext(),
3983 CondEltVT
, WidenNumElts
);
3984 if (getTypeAction(CondVT
) == TargetLowering::TypeWidenVector
)
3985 Cond1
= GetWidenedVector(Cond1
);
3987 // If we have to split the condition there is no point in widening the
3988 // select. This would result in an cycle of widening the select ->
3989 // widening the condition operand -> splitting the condition operand ->
3990 // splitting the select -> widening the select. Instead split this select
3991 // further and widen the resulting type.
3992 if (getTypeAction(CondVT
) == TargetLowering::TypeSplitVector
) {
3993 SDValue SplitSelect
= SplitVecOp_VSELECT(N
, 0);
3994 SDValue Res
= ModifyToType(SplitSelect
, WidenVT
);
3998 if (Cond1
.getValueType() != CondWidenVT
)
3999 Cond1
= ModifyToType(Cond1
, CondWidenVT
);
4002 SDValue InOp1
= GetWidenedVector(N
->getOperand(1));
4003 SDValue InOp2
= GetWidenedVector(N
->getOperand(2));
4004 assert(InOp1
.getValueType() == WidenVT
&& InOp2
.getValueType() == WidenVT
);
4005 return DAG
.getNode(N
->getOpcode(), SDLoc(N
),
4006 WidenVT
, Cond1
, InOp1
, InOp2
);
4009 SDValue
DAGTypeLegalizer::WidenVecRes_SELECT_CC(SDNode
*N
) {
4010 SDValue InOp1
= GetWidenedVector(N
->getOperand(2));
4011 SDValue InOp2
= GetWidenedVector(N
->getOperand(3));
4012 return DAG
.getNode(ISD::SELECT_CC
, SDLoc(N
),
4013 InOp1
.getValueType(), N
->getOperand(0),
4014 N
->getOperand(1), InOp1
, InOp2
, N
->getOperand(4));
4017 SDValue
DAGTypeLegalizer::WidenVecRes_UNDEF(SDNode
*N
) {
4018 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
4019 return DAG
.getUNDEF(WidenVT
);
4022 SDValue
DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode
*N
) {
4023 EVT VT
= N
->getValueType(0);
4026 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
4027 unsigned NumElts
= VT
.getVectorNumElements();
4028 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
4030 SDValue InOp1
= GetWidenedVector(N
->getOperand(0));
4031 SDValue InOp2
= GetWidenedVector(N
->getOperand(1));
4033 // Adjust mask based on new input vector length.
4034 SmallVector
<int, 16> NewMask
;
4035 for (unsigned i
= 0; i
!= NumElts
; ++i
) {
4036 int Idx
= N
->getMaskElt(i
);
4037 if (Idx
< (int)NumElts
)
4038 NewMask
.push_back(Idx
);
4040 NewMask
.push_back(Idx
- NumElts
+ WidenNumElts
);
4042 for (unsigned i
= NumElts
; i
!= WidenNumElts
; ++i
)
4043 NewMask
.push_back(-1);
4044 return DAG
.getVectorShuffle(WidenVT
, dl
, InOp1
, InOp2
, NewMask
);
4047 SDValue
DAGTypeLegalizer::WidenVecRes_SETCC(SDNode
*N
) {
4048 assert(N
->getValueType(0).isVector() &&
4049 N
->getOperand(0).getValueType().isVector() &&
4050 "Operands must be vectors");
4051 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
4052 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
4054 SDValue InOp1
= N
->getOperand(0);
4055 EVT InVT
= InOp1
.getValueType();
4056 assert(InVT
.isVector() && "can not widen non-vector type");
4057 EVT WidenInVT
= EVT::getVectorVT(*DAG
.getContext(),
4058 InVT
.getVectorElementType(), WidenNumElts
);
4060 // The input and output types often differ here, and it could be that while
4061 // we'd prefer to widen the result type, the input operands have been split.
4062 // In this case, we also need to split the result of this node as well.
4063 if (getTypeAction(InVT
) == TargetLowering::TypeSplitVector
) {
4064 SDValue SplitVSetCC
= SplitVecOp_VSETCC(N
);
4065 SDValue Res
= ModifyToType(SplitVSetCC
, WidenVT
);
4069 // If the inputs also widen, handle them directly. Otherwise widen by hand.
4070 SDValue InOp2
= N
->getOperand(1);
4071 if (getTypeAction(InVT
) == TargetLowering::TypeWidenVector
) {
4072 InOp1
= GetWidenedVector(InOp1
);
4073 InOp2
= GetWidenedVector(InOp2
);
4075 InOp1
= DAG
.WidenVector(InOp1
, SDLoc(N
));
4076 InOp2
= DAG
.WidenVector(InOp2
, SDLoc(N
));
4079 // Assume that the input and output will be widen appropriately. If not,
4080 // we will have to unroll it at some point.
4081 assert(InOp1
.getValueType() == WidenInVT
&&
4082 InOp2
.getValueType() == WidenInVT
&&
4083 "Input not widened to expected type!");
4085 return DAG
.getNode(ISD::SETCC
, SDLoc(N
),
4086 WidenVT
, InOp1
, InOp2
, N
->getOperand(2));
4090 //===----------------------------------------------------------------------===//
4091 // Widen Vector Operand
4092 //===----------------------------------------------------------------------===//
4093 bool DAGTypeLegalizer::WidenVectorOperand(SDNode
*N
, unsigned OpNo
) {
4094 LLVM_DEBUG(dbgs() << "Widen node operand " << OpNo
<< ": "; N
->dump(&DAG
);
4096 SDValue Res
= SDValue();
4098 // See if the target wants to custom widen this node.
4099 if (CustomLowerNode(N
, N
->getOperand(OpNo
).getValueType(), false))
4102 switch (N
->getOpcode()) {
4105 dbgs() << "WidenVectorOperand op #" << OpNo
<< ": ";
4109 llvm_unreachable("Do not know how to widen this operator's operand!");
4111 case ISD::BITCAST
: Res
= WidenVecOp_BITCAST(N
); break;
4112 case ISD::CONCAT_VECTORS
: Res
= WidenVecOp_CONCAT_VECTORS(N
); break;
4113 case ISD::EXTRACT_SUBVECTOR
: Res
= WidenVecOp_EXTRACT_SUBVECTOR(N
); break;
4114 case ISD::EXTRACT_VECTOR_ELT
: Res
= WidenVecOp_EXTRACT_VECTOR_ELT(N
); break;
4115 case ISD::STORE
: Res
= WidenVecOp_STORE(N
); break;
4116 case ISD::MSTORE
: Res
= WidenVecOp_MSTORE(N
, OpNo
); break;
4117 case ISD::MGATHER
: Res
= WidenVecOp_MGATHER(N
, OpNo
); break;
4118 case ISD::MSCATTER
: Res
= WidenVecOp_MSCATTER(N
, OpNo
); break;
4119 case ISD::SETCC
: Res
= WidenVecOp_SETCC(N
); break;
4120 case ISD::VSELECT
: Res
= WidenVecOp_VSELECT(N
); break;
4121 case ISD::FCOPYSIGN
: Res
= WidenVecOp_FCOPYSIGN(N
); break;
4123 case ISD::ANY_EXTEND
:
4124 case ISD::SIGN_EXTEND
:
4125 case ISD::ZERO_EXTEND
:
4126 Res
= WidenVecOp_EXTEND(N
);
4129 case ISD::FP_EXTEND
:
4130 case ISD::STRICT_FP_EXTEND
:
4131 case ISD::FP_TO_SINT
:
4132 case ISD::FP_TO_UINT
:
4133 case ISD::SINT_TO_FP
:
4134 case ISD::UINT_TO_FP
:
4136 Res
= WidenVecOp_Convert(N
);
4139 case ISD::VECREDUCE_FADD
:
4140 case ISD::VECREDUCE_FMUL
:
4141 case ISD::VECREDUCE_ADD
:
4142 case ISD::VECREDUCE_MUL
:
4143 case ISD::VECREDUCE_AND
:
4144 case ISD::VECREDUCE_OR
:
4145 case ISD::VECREDUCE_XOR
:
4146 case ISD::VECREDUCE_SMAX
:
4147 case ISD::VECREDUCE_SMIN
:
4148 case ISD::VECREDUCE_UMAX
:
4149 case ISD::VECREDUCE_UMIN
:
4150 case ISD::VECREDUCE_FMAX
:
4151 case ISD::VECREDUCE_FMIN
:
4152 Res
= WidenVecOp_VECREDUCE(N
);
4156 // If Res is null, the sub-method took care of registering the result.
4157 if (!Res
.getNode()) return false;
4159 // If the result is N, the sub-method updated N in place. Tell the legalizer
4161 if (Res
.getNode() == N
)
4165 if (N
->isStrictFPOpcode())
4166 assert(Res
.getValueType() == N
->getValueType(0) && N
->getNumValues() == 2 &&
4167 "Invalid operand expansion");
4169 assert(Res
.getValueType() == N
->getValueType(0) && N
->getNumValues() == 1 &&
4170 "Invalid operand expansion");
4172 ReplaceValueWith(SDValue(N
, 0), Res
);
4176 SDValue
DAGTypeLegalizer::WidenVecOp_EXTEND(SDNode
*N
) {
4178 EVT VT
= N
->getValueType(0);
4180 SDValue InOp
= N
->getOperand(0);
4181 assert(getTypeAction(InOp
.getValueType()) ==
4182 TargetLowering::TypeWidenVector
&&
4183 "Unexpected type action");
4184 InOp
= GetWidenedVector(InOp
);
4185 assert(VT
.getVectorNumElements() <
4186 InOp
.getValueType().getVectorNumElements() &&
4187 "Input wasn't widened!");
4189 // We may need to further widen the operand until it has the same total
4190 // vector size as the result.
4191 EVT InVT
= InOp
.getValueType();
4192 if (InVT
.getSizeInBits() != VT
.getSizeInBits()) {
4193 EVT InEltVT
= InVT
.getVectorElementType();
4194 for (int i
= MVT::FIRST_VECTOR_VALUETYPE
, e
= MVT::LAST_VECTOR_VALUETYPE
; i
< e
; ++i
) {
4195 EVT FixedVT
= (MVT::SimpleValueType
)i
;
4196 EVT FixedEltVT
= FixedVT
.getVectorElementType();
4197 if (TLI
.isTypeLegal(FixedVT
) &&
4198 FixedVT
.getSizeInBits() == VT
.getSizeInBits() &&
4199 FixedEltVT
== InEltVT
) {
4200 assert(FixedVT
.getVectorNumElements() >= VT
.getVectorNumElements() &&
4201 "Not enough elements in the fixed type for the operand!");
4202 assert(FixedVT
.getVectorNumElements() != InVT
.getVectorNumElements() &&
4203 "We can't have the same type as we started with!");
4204 if (FixedVT
.getVectorNumElements() > InVT
.getVectorNumElements())
4206 ISD::INSERT_SUBVECTOR
, DL
, FixedVT
, DAG
.getUNDEF(FixedVT
), InOp
,
4207 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4210 ISD::EXTRACT_SUBVECTOR
, DL
, FixedVT
, InOp
,
4211 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4215 InVT
= InOp
.getValueType();
4216 if (InVT
.getSizeInBits() != VT
.getSizeInBits())
4217 // We couldn't find a legal vector type that was a widening of the input
4218 // and could be extended in-register to the result type, so we have to
4220 return WidenVecOp_Convert(N
);
4223 // Use special DAG nodes to represent the operation of extending the
4225 switch (N
->getOpcode()) {
4227 llvm_unreachable("Extend legalization on extend operation!");
4228 case ISD::ANY_EXTEND
:
4229 return DAG
.getNode(ISD::ANY_EXTEND_VECTOR_INREG
, DL
, VT
, InOp
);
4230 case ISD::SIGN_EXTEND
:
4231 return DAG
.getNode(ISD::SIGN_EXTEND_VECTOR_INREG
, DL
, VT
, InOp
);
4232 case ISD::ZERO_EXTEND
:
4233 return DAG
.getNode(ISD::ZERO_EXTEND_VECTOR_INREG
, DL
, VT
, InOp
);
4237 SDValue
DAGTypeLegalizer::WidenVecOp_FCOPYSIGN(SDNode
*N
) {
4238 // The result (and first input) is legal, but the second input is illegal.
4239 // We can't do much to fix that, so just unroll and let the extracts off of
4240 // the second input be widened as needed later.
4241 return DAG
.UnrollVectorOp(N
);
4244 SDValue
DAGTypeLegalizer::WidenVecOp_Convert(SDNode
*N
) {
4245 // Since the result is legal and the input is illegal.
4246 EVT VT
= N
->getValueType(0);
4247 EVT EltVT
= VT
.getVectorElementType();
4249 unsigned NumElts
= VT
.getVectorNumElements();
4250 SDValue InOp
= N
->getOperand(N
->isStrictFPOpcode() ? 1 : 0);
4251 assert(getTypeAction(InOp
.getValueType()) ==
4252 TargetLowering::TypeWidenVector
&&
4253 "Unexpected type action");
4254 InOp
= GetWidenedVector(InOp
);
4255 EVT InVT
= InOp
.getValueType();
4256 unsigned Opcode
= N
->getOpcode();
4258 // See if a widened result type would be legal, if so widen the node.
4259 // FIXME: This isn't safe for StrictFP. Other optimization here is needed.
4260 EVT WideVT
= EVT::getVectorVT(*DAG
.getContext(), EltVT
,
4261 InVT
.getVectorNumElements());
4262 if (TLI
.isTypeLegal(WideVT
) && !N
->isStrictFPOpcode()) {
4264 if (N
->isStrictFPOpcode()) {
4265 Res
= DAG
.getNode(Opcode
, dl
, { WideVT
, MVT::Other
},
4266 { N
->getOperand(0), InOp
});
4267 // Legalize the chain result - switch anything that used the old chain to
4269 ReplaceValueWith(SDValue(N
, 1), Res
.getValue(1));
4271 Res
= DAG
.getNode(Opcode
, dl
, WideVT
, InOp
);
4273 ISD::EXTRACT_SUBVECTOR
, dl
, VT
, Res
,
4274 DAG
.getConstant(0, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4277 EVT InEltVT
= InVT
.getVectorElementType();
4279 // Unroll the convert into some scalar code and create a nasty build vector.
4280 SmallVector
<SDValue
, 16> Ops(NumElts
);
4281 if (N
->isStrictFPOpcode()) {
4282 SmallVector
<SDValue
, 4> NewOps(N
->op_begin(), N
->op_end());
4283 SmallVector
<SDValue
, 32> OpChains
;
4284 for (unsigned i
=0; i
< NumElts
; ++i
) {
4285 NewOps
[1] = DAG
.getNode(
4286 ISD::EXTRACT_VECTOR_ELT
, dl
, InEltVT
, InOp
,
4287 DAG
.getConstant(i
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4288 Ops
[i
] = DAG
.getNode(Opcode
, dl
, { EltVT
, MVT::Other
}, NewOps
);
4289 OpChains
.push_back(Ops
[i
].getValue(1));
4291 SDValue NewChain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, OpChains
);
4292 ReplaceValueWith(SDValue(N
, 1), NewChain
);
4294 for (unsigned i
= 0; i
< NumElts
; ++i
)
4295 Ops
[i
] = DAG
.getNode(
4298 ISD::EXTRACT_VECTOR_ELT
, dl
, InEltVT
, InOp
,
4299 DAG
.getConstant(i
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout()))));
4302 return DAG
.getBuildVector(VT
, dl
, Ops
);
4305 SDValue
DAGTypeLegalizer::WidenVecOp_BITCAST(SDNode
*N
) {
4306 EVT VT
= N
->getValueType(0);
4307 SDValue InOp
= GetWidenedVector(N
->getOperand(0));
4308 EVT InWidenVT
= InOp
.getValueType();
4311 // Check if we can convert between two legal vector types and extract.
4312 unsigned InWidenSize
= InWidenVT
.getSizeInBits();
4313 unsigned Size
= VT
.getSizeInBits();
4314 // x86mmx is not an acceptable vector element type, so don't try.
4315 if (InWidenSize
% Size
== 0 && !VT
.isVector() && VT
!= MVT::x86mmx
) {
4316 unsigned NewNumElts
= InWidenSize
/ Size
;
4317 EVT NewVT
= EVT::getVectorVT(*DAG
.getContext(), VT
, NewNumElts
);
4318 if (TLI
.isTypeLegal(NewVT
)) {
4319 SDValue BitOp
= DAG
.getNode(ISD::BITCAST
, dl
, NewVT
, InOp
);
4321 ISD::EXTRACT_VECTOR_ELT
, dl
, VT
, BitOp
,
4322 DAG
.getConstant(0, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4326 // Handle a case like bitcast v12i8 -> v3i32. Normally that would get widened
4327 // to v16i8 -> v4i32, but for a target where v3i32 is legal but v12i8 is not,
4328 // we end up here. Handling the case here with EXTRACT_SUBVECTOR avoids
4329 // having to copy via memory.
4330 if (VT
.isVector()) {
4331 EVT EltVT
= VT
.getVectorElementType();
4332 unsigned EltSize
= EltVT
.getSizeInBits();
4333 if (InWidenSize
% EltSize
== 0) {
4334 unsigned NewNumElts
= InWidenSize
/ EltSize
;
4335 EVT NewVT
= EVT::getVectorVT(*DAG
.getContext(), EltVT
, NewNumElts
);
4336 if (TLI
.isTypeLegal(NewVT
)) {
4337 SDValue BitOp
= DAG
.getNode(ISD::BITCAST
, dl
, NewVT
, InOp
);
4338 return DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, dl
, VT
, BitOp
,
4339 DAG
.getConstant(0, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4344 return CreateStackStoreLoad(InOp
, VT
);
4347 SDValue
DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode
*N
) {
4348 EVT VT
= N
->getValueType(0);
4349 EVT EltVT
= VT
.getVectorElementType();
4350 EVT InVT
= N
->getOperand(0).getValueType();
4353 // If the widen width for this operand is the same as the width of the concat
4354 // and all but the first operand is undef, just use the widened operand.
4355 unsigned NumOperands
= N
->getNumOperands();
4356 if (VT
== TLI
.getTypeToTransformTo(*DAG
.getContext(), InVT
)) {
4358 for (i
= 1; i
< NumOperands
; ++i
)
4359 if (!N
->getOperand(i
).isUndef())
4362 if (i
== NumOperands
)
4363 return GetWidenedVector(N
->getOperand(0));
4366 // Otherwise, fall back to a nasty build vector.
4367 unsigned NumElts
= VT
.getVectorNumElements();
4368 SmallVector
<SDValue
, 16> Ops(NumElts
);
4370 unsigned NumInElts
= InVT
.getVectorNumElements();
4373 for (unsigned i
=0; i
< NumOperands
; ++i
) {
4374 SDValue InOp
= N
->getOperand(i
);
4375 assert(getTypeAction(InOp
.getValueType()) ==
4376 TargetLowering::TypeWidenVector
&&
4377 "Unexpected type action");
4378 InOp
= GetWidenedVector(InOp
);
4379 for (unsigned j
=0; j
< NumInElts
; ++j
)
4380 Ops
[Idx
++] = DAG
.getNode(
4381 ISD::EXTRACT_VECTOR_ELT
, dl
, EltVT
, InOp
,
4382 DAG
.getConstant(j
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4384 return DAG
.getBuildVector(VT
, dl
, Ops
);
4387 SDValue
DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(SDNode
*N
) {
4388 SDValue InOp
= GetWidenedVector(N
->getOperand(0));
4389 return DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, SDLoc(N
),
4390 N
->getValueType(0), InOp
, N
->getOperand(1));
4393 SDValue
DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(SDNode
*N
) {
4394 SDValue InOp
= GetWidenedVector(N
->getOperand(0));
4395 return DAG
.getNode(ISD::EXTRACT_VECTOR_ELT
, SDLoc(N
),
4396 N
->getValueType(0), InOp
, N
->getOperand(1));
4399 SDValue
DAGTypeLegalizer::WidenVecOp_STORE(SDNode
*N
) {
4400 // We have to widen the value, but we want only to store the original
4402 StoreSDNode
*ST
= cast
<StoreSDNode
>(N
);
4404 if (!ST
->getMemoryVT().getScalarType().isByteSized())
4405 return TLI
.scalarizeVectorStore(ST
, DAG
);
4407 SmallVector
<SDValue
, 16> StChain
;
4408 if (ST
->isTruncatingStore())
4409 GenWidenVectorTruncStores(StChain
, ST
);
4411 GenWidenVectorStores(StChain
, ST
);
4413 if (StChain
.size() == 1)
4416 return DAG
.getNode(ISD::TokenFactor
, SDLoc(ST
), MVT::Other
, StChain
);
4419 SDValue
DAGTypeLegalizer::WidenVecOp_MSTORE(SDNode
*N
, unsigned OpNo
) {
4420 assert((OpNo
== 1 || OpNo
== 3) &&
4421 "Can widen only data or mask operand of mstore");
4422 MaskedStoreSDNode
*MST
= cast
<MaskedStoreSDNode
>(N
);
4423 SDValue Mask
= MST
->getMask();
4424 EVT MaskVT
= Mask
.getValueType();
4425 SDValue StVal
= MST
->getValue();
4430 StVal
= GetWidenedVector(StVal
);
4432 // The mask should be widened as well.
4433 EVT WideVT
= StVal
.getValueType();
4434 EVT WideMaskVT
= EVT::getVectorVT(*DAG
.getContext(),
4435 MaskVT
.getVectorElementType(),
4436 WideVT
.getVectorNumElements());
4437 Mask
= ModifyToType(Mask
, WideMaskVT
, true);
4440 EVT WideMaskVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), MaskVT
);
4441 Mask
= ModifyToType(Mask
, WideMaskVT
, true);
4443 EVT ValueVT
= StVal
.getValueType();
4444 EVT WideVT
= EVT::getVectorVT(*DAG
.getContext(),
4445 ValueVT
.getVectorElementType(),
4446 WideMaskVT
.getVectorNumElements());
4447 StVal
= ModifyToType(StVal
, WideVT
);
4450 assert(Mask
.getValueType().getVectorNumElements() ==
4451 StVal
.getValueType().getVectorNumElements() &&
4452 "Mask and data vectors should have the same number of elements");
4453 return DAG
.getMaskedStore(MST
->getChain(), dl
, StVal
, MST
->getBasePtr(),
4454 Mask
, MST
->getMemoryVT(), MST
->getMemOperand(),
4455 false, MST
->isCompressingStore());
4458 SDValue
DAGTypeLegalizer::WidenVecOp_MGATHER(SDNode
*N
, unsigned OpNo
) {
4459 assert(OpNo
== 4 && "Can widen only the index of mgather");
4460 auto *MG
= cast
<MaskedGatherSDNode
>(N
);
4461 SDValue DataOp
= MG
->getPassThru();
4462 SDValue Mask
= MG
->getMask();
4463 SDValue Scale
= MG
->getScale();
4465 // Just widen the index. It's allowed to have extra elements.
4466 SDValue Index
= GetWidenedVector(MG
->getIndex());
4469 SDValue Ops
[] = {MG
->getChain(), DataOp
, Mask
, MG
->getBasePtr(), Index
,
4471 SDValue Res
= DAG
.getMaskedGather(MG
->getVTList(), MG
->getMemoryVT(), dl
, Ops
,
4472 MG
->getMemOperand(), MG
->getIndexType());
4473 ReplaceValueWith(SDValue(N
, 1), Res
.getValue(1));
4474 ReplaceValueWith(SDValue(N
, 0), Res
.getValue(0));
4478 SDValue
DAGTypeLegalizer::WidenVecOp_MSCATTER(SDNode
*N
, unsigned OpNo
) {
4479 MaskedScatterSDNode
*MSC
= cast
<MaskedScatterSDNode
>(N
);
4480 SDValue DataOp
= MSC
->getValue();
4481 SDValue Mask
= MSC
->getMask();
4482 SDValue Index
= MSC
->getIndex();
4483 SDValue Scale
= MSC
->getScale();
4486 DataOp
= GetWidenedVector(DataOp
);
4487 unsigned NumElts
= DataOp
.getValueType().getVectorNumElements();
4490 EVT IndexVT
= Index
.getValueType();
4491 EVT WideIndexVT
= EVT::getVectorVT(*DAG
.getContext(),
4492 IndexVT
.getVectorElementType(), NumElts
);
4493 Index
= ModifyToType(Index
, WideIndexVT
);
4495 // The mask should be widened as well.
4496 EVT MaskVT
= Mask
.getValueType();
4497 EVT WideMaskVT
= EVT::getVectorVT(*DAG
.getContext(),
4498 MaskVT
.getVectorElementType(), NumElts
);
4499 Mask
= ModifyToType(Mask
, WideMaskVT
, true);
4500 } else if (OpNo
== 4) {
4501 // Just widen the index. It's allowed to have extra elements.
4502 Index
= GetWidenedVector(Index
);
4504 llvm_unreachable("Can't widen this operand of mscatter");
4506 SDValue Ops
[] = {MSC
->getChain(), DataOp
, Mask
, MSC
->getBasePtr(), Index
,
4508 return DAG
.getMaskedScatter(DAG
.getVTList(MVT::Other
),
4509 MSC
->getMemoryVT(), SDLoc(N
), Ops
,
4510 MSC
->getMemOperand(), MSC
->getIndexType());
4513 SDValue
DAGTypeLegalizer::WidenVecOp_SETCC(SDNode
*N
) {
4514 SDValue InOp0
= GetWidenedVector(N
->getOperand(0));
4515 SDValue InOp1
= GetWidenedVector(N
->getOperand(1));
4517 EVT VT
= N
->getValueType(0);
4519 // WARNING: In this code we widen the compare instruction with garbage.
4520 // This garbage may contain denormal floats which may be slow. Is this a real
4521 // concern ? Should we zero the unused lanes if this is a float compare ?
4523 // Get a new SETCC node to compare the newly widened operands.
4524 // Only some of the compared elements are legal.
4525 EVT SVT
= getSetCCResultType(InOp0
.getValueType());
4526 // The result type is legal, if its vXi1, keep vXi1 for the new SETCC.
4527 if (VT
.getScalarType() == MVT::i1
)
4528 SVT
= EVT::getVectorVT(*DAG
.getContext(), MVT::i1
,
4529 SVT
.getVectorNumElements());
4531 SDValue WideSETCC
= DAG
.getNode(ISD::SETCC
, SDLoc(N
),
4532 SVT
, InOp0
, InOp1
, N
->getOperand(2));
4534 // Extract the needed results from the result vector.
4535 EVT ResVT
= EVT::getVectorVT(*DAG
.getContext(),
4536 SVT
.getVectorElementType(),
4537 VT
.getVectorNumElements());
4538 SDValue CC
= DAG
.getNode(
4539 ISD::EXTRACT_SUBVECTOR
, dl
, ResVT
, WideSETCC
,
4540 DAG
.getConstant(0, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4542 return PromoteTargetBoolean(CC
, VT
);
4545 SDValue
DAGTypeLegalizer::WidenVecOp_VECREDUCE(SDNode
*N
) {
4547 SDValue Op
= GetWidenedVector(N
->getOperand(0));
4548 EVT OrigVT
= N
->getOperand(0).getValueType();
4549 EVT WideVT
= Op
.getValueType();
4550 EVT ElemVT
= OrigVT
.getVectorElementType();
4552 SDValue NeutralElem
;
4553 switch (N
->getOpcode()) {
4554 case ISD::VECREDUCE_ADD
:
4555 case ISD::VECREDUCE_OR
:
4556 case ISD::VECREDUCE_XOR
:
4557 case ISD::VECREDUCE_UMAX
:
4558 NeutralElem
= DAG
.getConstant(0, dl
, ElemVT
);
4560 case ISD::VECREDUCE_MUL
:
4561 NeutralElem
= DAG
.getConstant(1, dl
, ElemVT
);
4563 case ISD::VECREDUCE_AND
:
4564 case ISD::VECREDUCE_UMIN
:
4565 NeutralElem
= DAG
.getAllOnesConstant(dl
, ElemVT
);
4567 case ISD::VECREDUCE_SMAX
:
4568 NeutralElem
= DAG
.getConstant(
4569 APInt::getSignedMinValue(ElemVT
.getSizeInBits()), dl
, ElemVT
);
4571 case ISD::VECREDUCE_SMIN
:
4572 NeutralElem
= DAG
.getConstant(
4573 APInt::getSignedMaxValue(ElemVT
.getSizeInBits()), dl
, ElemVT
);
4575 case ISD::VECREDUCE_FADD
:
4576 NeutralElem
= DAG
.getConstantFP(0.0, dl
, ElemVT
);
4578 case ISD::VECREDUCE_FMUL
:
4579 NeutralElem
= DAG
.getConstantFP(1.0, dl
, ElemVT
);
4581 case ISD::VECREDUCE_FMAX
:
4582 NeutralElem
= DAG
.getConstantFP(
4583 std::numeric_limits
<double>::infinity(), dl
, ElemVT
);
4585 case ISD::VECREDUCE_FMIN
:
4586 NeutralElem
= DAG
.getConstantFP(
4587 -std::numeric_limits
<double>::infinity(), dl
, ElemVT
);
4591 // Pad the vector with the neutral element.
4592 unsigned OrigElts
= OrigVT
.getVectorNumElements();
4593 unsigned WideElts
= WideVT
.getVectorNumElements();
4594 for (unsigned Idx
= OrigElts
; Idx
< WideElts
; Idx
++)
4595 Op
= DAG
.getNode(ISD::INSERT_VECTOR_ELT
, dl
, WideVT
, Op
, NeutralElem
,
4596 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4598 return DAG
.getNode(N
->getOpcode(), dl
, N
->getValueType(0), Op
, N
->getFlags());
4601 SDValue
DAGTypeLegalizer::WidenVecOp_VSELECT(SDNode
*N
) {
4602 // This only gets called in the case that the left and right inputs and
4603 // result are of a legal odd vector type, and the condition is illegal i1 of
4604 // the same odd width that needs widening.
4605 EVT VT
= N
->getValueType(0);
4606 assert(VT
.isVector() && !VT
.isPow2VectorType() && isTypeLegal(VT
));
4608 SDValue Cond
= GetWidenedVector(N
->getOperand(0));
4609 SDValue LeftIn
= DAG
.WidenVector(N
->getOperand(1), SDLoc(N
));
4610 SDValue RightIn
= DAG
.WidenVector(N
->getOperand(2), SDLoc(N
));
4613 SDValue Select
= DAG
.getNode(N
->getOpcode(), DL
, LeftIn
.getValueType(), Cond
,
4616 ISD::EXTRACT_SUBVECTOR
, DL
, VT
, Select
,
4617 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4620 //===----------------------------------------------------------------------===//
4621 // Vector Widening Utilities
4622 //===----------------------------------------------------------------------===//
4624 // Utility function to find the type to chop up a widen vector for load/store
4625 // TLI: Target lowering used to determine legal types.
4626 // Width: Width left need to load/store.
4627 // WidenVT: The widen vector type to load to/store from
4628 // Align: If 0, don't allow use of a wider type
4629 // WidenEx: If Align is not 0, the amount additional we can load/store from.
4631 static EVT
FindMemType(SelectionDAG
& DAG
, const TargetLowering
&TLI
,
4632 unsigned Width
, EVT WidenVT
,
4633 unsigned Align
= 0, unsigned WidenEx
= 0) {
4634 EVT WidenEltVT
= WidenVT
.getVectorElementType();
4635 unsigned WidenWidth
= WidenVT
.getSizeInBits();
4636 unsigned WidenEltWidth
= WidenEltVT
.getSizeInBits();
4637 unsigned AlignInBits
= Align
*8;
4639 // If we have one element to load/store, return it.
4640 EVT RetVT
= WidenEltVT
;
4641 if (Width
== WidenEltWidth
)
4644 // See if there is larger legal integer than the element type to load/store.
4646 for (VT
= (unsigned)MVT::LAST_INTEGER_VALUETYPE
;
4647 VT
>= (unsigned)MVT::FIRST_INTEGER_VALUETYPE
; --VT
) {
4648 EVT
MemVT((MVT::SimpleValueType
) VT
);
4649 unsigned MemVTWidth
= MemVT
.getSizeInBits();
4650 if (MemVT
.getSizeInBits() <= WidenEltWidth
)
4652 auto Action
= TLI
.getTypeAction(*DAG
.getContext(), MemVT
);
4653 if ((Action
== TargetLowering::TypeLegal
||
4654 Action
== TargetLowering::TypePromoteInteger
) &&
4655 (WidenWidth
% MemVTWidth
) == 0 &&
4656 isPowerOf2_32(WidenWidth
/ MemVTWidth
) &&
4657 (MemVTWidth
<= Width
||
4658 (Align
!=0 && MemVTWidth
<=AlignInBits
&& MemVTWidth
<=Width
+WidenEx
))) {
4659 if (MemVTWidth
== WidenWidth
)
4666 // See if there is a larger vector type to load/store that has the same vector
4667 // element type and is evenly divisible with the WidenVT.
4668 for (VT
= (unsigned)MVT::LAST_VECTOR_VALUETYPE
;
4669 VT
>= (unsigned)MVT::FIRST_VECTOR_VALUETYPE
; --VT
) {
4670 EVT MemVT
= (MVT::SimpleValueType
) VT
;
4671 unsigned MemVTWidth
= MemVT
.getSizeInBits();
4672 auto Action
= TLI
.getTypeAction(*DAG
.getContext(), MemVT
);
4673 if ((Action
== TargetLowering::TypeLegal
||
4674 Action
== TargetLowering::TypePromoteInteger
) &&
4675 WidenEltVT
== MemVT
.getVectorElementType() &&
4676 (WidenWidth
% MemVTWidth
) == 0 &&
4677 isPowerOf2_32(WidenWidth
/ MemVTWidth
) &&
4678 (MemVTWidth
<= Width
||
4679 (Align
!=0 && MemVTWidth
<=AlignInBits
&& MemVTWidth
<=Width
+WidenEx
))) {
4680 if (RetVT
.getSizeInBits() < MemVTWidth
|| MemVT
== WidenVT
)
4688 // Builds a vector type from scalar loads
4689 // VecTy: Resulting Vector type
4690 // LDOps: Load operators to build a vector type
4691 // [Start,End) the list of loads to use.
4692 static SDValue
BuildVectorFromScalar(SelectionDAG
& DAG
, EVT VecTy
,
4693 SmallVectorImpl
<SDValue
> &LdOps
,
4694 unsigned Start
, unsigned End
) {
4695 const TargetLowering
&TLI
= DAG
.getTargetLoweringInfo();
4696 SDLoc
dl(LdOps
[Start
]);
4697 EVT LdTy
= LdOps
[Start
].getValueType();
4698 unsigned Width
= VecTy
.getSizeInBits();
4699 unsigned NumElts
= Width
/ LdTy
.getSizeInBits();
4700 EVT NewVecVT
= EVT::getVectorVT(*DAG
.getContext(), LdTy
, NumElts
);
4703 SDValue VecOp
= DAG
.getNode(ISD::SCALAR_TO_VECTOR
, dl
, NewVecVT
,LdOps
[Start
]);
4705 for (unsigned i
= Start
+ 1; i
!= End
; ++i
) {
4706 EVT NewLdTy
= LdOps
[i
].getValueType();
4707 if (NewLdTy
!= LdTy
) {
4708 NumElts
= Width
/ NewLdTy
.getSizeInBits();
4709 NewVecVT
= EVT::getVectorVT(*DAG
.getContext(), NewLdTy
, NumElts
);
4710 VecOp
= DAG
.getNode(ISD::BITCAST
, dl
, NewVecVT
, VecOp
);
4711 // Readjust position and vector position based on new load type.
4712 Idx
= Idx
* LdTy
.getSizeInBits() / NewLdTy
.getSizeInBits();
4715 VecOp
= DAG
.getNode(
4716 ISD::INSERT_VECTOR_ELT
, dl
, NewVecVT
, VecOp
, LdOps
[i
],
4717 DAG
.getConstant(Idx
++, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4719 return DAG
.getNode(ISD::BITCAST
, dl
, VecTy
, VecOp
);
4722 SDValue
DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl
<SDValue
> &LdChain
,
4724 // The strategy assumes that we can efficiently load power-of-two widths.
4725 // The routine chops the vector into the largest vector loads with the same
4726 // element type or scalar loads and then recombines it to the widen vector
4728 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(),LD
->getValueType(0));
4729 unsigned WidenWidth
= WidenVT
.getSizeInBits();
4730 EVT LdVT
= LD
->getMemoryVT();
4732 assert(LdVT
.isVector() && WidenVT
.isVector());
4733 assert(LdVT
.getVectorElementType() == WidenVT
.getVectorElementType());
4736 SDValue Chain
= LD
->getChain();
4737 SDValue BasePtr
= LD
->getBasePtr();
4738 unsigned Align
= LD
->getAlignment();
4739 MachineMemOperand::Flags MMOFlags
= LD
->getMemOperand()->getFlags();
4740 AAMDNodes AAInfo
= LD
->getAAInfo();
4742 int LdWidth
= LdVT
.getSizeInBits();
4743 int WidthDiff
= WidenWidth
- LdWidth
;
4744 unsigned LdAlign
= LD
->isVolatile() ? 0 : Align
; // Allow wider loads.
4746 // Find the vector type that can load from.
4747 EVT NewVT
= FindMemType(DAG
, TLI
, LdWidth
, WidenVT
, LdAlign
, WidthDiff
);
4748 int NewVTWidth
= NewVT
.getSizeInBits();
4749 SDValue LdOp
= DAG
.getLoad(NewVT
, dl
, Chain
, BasePtr
, LD
->getPointerInfo(),
4750 Align
, MMOFlags
, AAInfo
);
4751 LdChain
.push_back(LdOp
.getValue(1));
4753 // Check if we can load the element with one instruction.
4754 if (LdWidth
<= NewVTWidth
) {
4755 if (!NewVT
.isVector()) {
4756 unsigned NumElts
= WidenWidth
/ NewVTWidth
;
4757 EVT NewVecVT
= EVT::getVectorVT(*DAG
.getContext(), NewVT
, NumElts
);
4758 SDValue VecOp
= DAG
.getNode(ISD::SCALAR_TO_VECTOR
, dl
, NewVecVT
, LdOp
);
4759 return DAG
.getNode(ISD::BITCAST
, dl
, WidenVT
, VecOp
);
4761 if (NewVT
== WidenVT
)
4764 assert(WidenWidth
% NewVTWidth
== 0);
4765 unsigned NumConcat
= WidenWidth
/ NewVTWidth
;
4766 SmallVector
<SDValue
, 16> ConcatOps(NumConcat
);
4767 SDValue UndefVal
= DAG
.getUNDEF(NewVT
);
4768 ConcatOps
[0] = LdOp
;
4769 for (unsigned i
= 1; i
!= NumConcat
; ++i
)
4770 ConcatOps
[i
] = UndefVal
;
4771 return DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, WidenVT
, ConcatOps
);
4774 // Load vector by using multiple loads from largest vector to scalar.
4775 SmallVector
<SDValue
, 16> LdOps
;
4776 LdOps
.push_back(LdOp
);
4778 LdWidth
-= NewVTWidth
;
4779 unsigned Offset
= 0;
4781 while (LdWidth
> 0) {
4782 unsigned Increment
= NewVTWidth
/ 8;
4783 Offset
+= Increment
;
4784 BasePtr
= DAG
.getObjectPtrOffset(dl
, BasePtr
, Increment
);
4787 if (LdWidth
< NewVTWidth
) {
4788 // The current type we are using is too large. Find a better size.
4789 NewVT
= FindMemType(DAG
, TLI
, LdWidth
, WidenVT
, LdAlign
, WidthDiff
);
4790 NewVTWidth
= NewVT
.getSizeInBits();
4791 L
= DAG
.getLoad(NewVT
, dl
, Chain
, BasePtr
,
4792 LD
->getPointerInfo().getWithOffset(Offset
),
4793 MinAlign(Align
, Increment
), MMOFlags
, AAInfo
);
4794 LdChain
.push_back(L
.getValue(1));
4795 if (L
->getValueType(0).isVector() && NewVTWidth
>= LdWidth
) {
4796 // Later code assumes the vector loads produced will be mergeable, so we
4797 // must pad the final entry up to the previous width. Scalars are
4798 // combined separately.
4799 SmallVector
<SDValue
, 16> Loads
;
4801 unsigned size
= L
->getValueSizeInBits(0);
4802 while (size
< LdOp
->getValueSizeInBits(0)) {
4803 Loads
.push_back(DAG
.getUNDEF(L
->getValueType(0)));
4804 size
+= L
->getValueSizeInBits(0);
4806 L
= DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, LdOp
->getValueType(0), Loads
);
4809 L
= DAG
.getLoad(NewVT
, dl
, Chain
, BasePtr
,
4810 LD
->getPointerInfo().getWithOffset(Offset
),
4811 MinAlign(Align
, Increment
), MMOFlags
, AAInfo
);
4812 LdChain
.push_back(L
.getValue(1));
4818 LdWidth
-= NewVTWidth
;
4821 // Build the vector from the load operations.
4822 unsigned End
= LdOps
.size();
4823 if (!LdOps
[0].getValueType().isVector())
4824 // All the loads are scalar loads.
4825 return BuildVectorFromScalar(DAG
, WidenVT
, LdOps
, 0, End
);
4827 // If the load contains vectors, build the vector using concat vector.
4828 // All of the vectors used to load are power-of-2, and the scalar loads can be
4829 // combined to make a power-of-2 vector.
4830 SmallVector
<SDValue
, 16> ConcatOps(End
);
4833 EVT LdTy
= LdOps
[i
].getValueType();
4834 // First, combine the scalar loads to a vector.
4835 if (!LdTy
.isVector()) {
4836 for (--i
; i
>= 0; --i
) {
4837 LdTy
= LdOps
[i
].getValueType();
4838 if (LdTy
.isVector())
4841 ConcatOps
[--Idx
] = BuildVectorFromScalar(DAG
, LdTy
, LdOps
, i
+ 1, End
);
4843 ConcatOps
[--Idx
] = LdOps
[i
];
4844 for (--i
; i
>= 0; --i
) {
4845 EVT NewLdTy
= LdOps
[i
].getValueType();
4846 if (NewLdTy
!= LdTy
) {
4847 // Create a larger vector.
4848 ConcatOps
[End
-1] = DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, NewLdTy
,
4849 makeArrayRef(&ConcatOps
[Idx
], End
- Idx
));
4853 ConcatOps
[--Idx
] = LdOps
[i
];
4856 if (WidenWidth
== LdTy
.getSizeInBits() * (End
- Idx
))
4857 return DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, WidenVT
,
4858 makeArrayRef(&ConcatOps
[Idx
], End
- Idx
));
4860 // We need to fill the rest with undefs to build the vector.
4861 unsigned NumOps
= WidenWidth
/ LdTy
.getSizeInBits();
4862 SmallVector
<SDValue
, 16> WidenOps(NumOps
);
4863 SDValue UndefVal
= DAG
.getUNDEF(LdTy
);
4866 for (; i
!= End
-Idx
; ++i
)
4867 WidenOps
[i
] = ConcatOps
[Idx
+i
];
4868 for (; i
!= NumOps
; ++i
)
4869 WidenOps
[i
] = UndefVal
;
4871 return DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, WidenVT
, WidenOps
);
4875 DAGTypeLegalizer::GenWidenVectorExtLoads(SmallVectorImpl
<SDValue
> &LdChain
,
4877 ISD::LoadExtType ExtType
) {
4878 // For extension loads, it may not be more efficient to chop up the vector
4879 // and then extend it. Instead, we unroll the load and build a new vector.
4880 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(),LD
->getValueType(0));
4881 EVT LdVT
= LD
->getMemoryVT();
4883 assert(LdVT
.isVector() && WidenVT
.isVector());
4886 SDValue Chain
= LD
->getChain();
4887 SDValue BasePtr
= LD
->getBasePtr();
4888 unsigned Align
= LD
->getAlignment();
4889 MachineMemOperand::Flags MMOFlags
= LD
->getMemOperand()->getFlags();
4890 AAMDNodes AAInfo
= LD
->getAAInfo();
4892 EVT EltVT
= WidenVT
.getVectorElementType();
4893 EVT LdEltVT
= LdVT
.getVectorElementType();
4894 unsigned NumElts
= LdVT
.getVectorNumElements();
4896 // Load each element and widen.
4897 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
4898 SmallVector
<SDValue
, 16> Ops(WidenNumElts
);
4899 unsigned Increment
= LdEltVT
.getSizeInBits() / 8;
4901 DAG
.getExtLoad(ExtType
, dl
, EltVT
, Chain
, BasePtr
, LD
->getPointerInfo(),
4902 LdEltVT
, Align
, MMOFlags
, AAInfo
);
4903 LdChain
.push_back(Ops
[0].getValue(1));
4904 unsigned i
= 0, Offset
= Increment
;
4905 for (i
=1; i
< NumElts
; ++i
, Offset
+= Increment
) {
4906 SDValue NewBasePtr
= DAG
.getObjectPtrOffset(dl
, BasePtr
, Offset
);
4907 Ops
[i
] = DAG
.getExtLoad(ExtType
, dl
, EltVT
, Chain
, NewBasePtr
,
4908 LD
->getPointerInfo().getWithOffset(Offset
), LdEltVT
,
4909 Align
, MMOFlags
, AAInfo
);
4910 LdChain
.push_back(Ops
[i
].getValue(1));
4913 // Fill the rest with undefs.
4914 SDValue UndefVal
= DAG
.getUNDEF(EltVT
);
4915 for (; i
!= WidenNumElts
; ++i
)
4918 return DAG
.getBuildVector(WidenVT
, dl
, Ops
);
4921 void DAGTypeLegalizer::GenWidenVectorStores(SmallVectorImpl
<SDValue
> &StChain
,
4923 // The strategy assumes that we can efficiently store power-of-two widths.
4924 // The routine chops the vector into the largest vector stores with the same
4925 // element type or scalar stores.
4926 SDValue Chain
= ST
->getChain();
4927 SDValue BasePtr
= ST
->getBasePtr();
4928 unsigned Align
= ST
->getAlignment();
4929 MachineMemOperand::Flags MMOFlags
= ST
->getMemOperand()->getFlags();
4930 AAMDNodes AAInfo
= ST
->getAAInfo();
4931 SDValue ValOp
= GetWidenedVector(ST
->getValue());
4934 EVT StVT
= ST
->getMemoryVT();
4935 unsigned StWidth
= StVT
.getSizeInBits();
4936 EVT ValVT
= ValOp
.getValueType();
4937 unsigned ValWidth
= ValVT
.getSizeInBits();
4938 EVT ValEltVT
= ValVT
.getVectorElementType();
4939 unsigned ValEltWidth
= ValEltVT
.getSizeInBits();
4940 assert(StVT
.getVectorElementType() == ValEltVT
);
4942 int Idx
= 0; // current index to store
4943 unsigned Offset
= 0; // offset from base to store
4944 while (StWidth
!= 0) {
4945 // Find the largest vector type we can store with.
4946 EVT NewVT
= FindMemType(DAG
, TLI
, StWidth
, ValVT
);
4947 unsigned NewVTWidth
= NewVT
.getSizeInBits();
4948 unsigned Increment
= NewVTWidth
/ 8;
4949 if (NewVT
.isVector()) {
4950 unsigned NumVTElts
= NewVT
.getVectorNumElements();
4952 SDValue EOp
= DAG
.getNode(
4953 ISD::EXTRACT_SUBVECTOR
, dl
, NewVT
, ValOp
,
4954 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4955 StChain
.push_back(DAG
.getStore(
4956 Chain
, dl
, EOp
, BasePtr
, ST
->getPointerInfo().getWithOffset(Offset
),
4957 MinAlign(Align
, Offset
), MMOFlags
, AAInfo
));
4958 StWidth
-= NewVTWidth
;
4959 Offset
+= Increment
;
4962 BasePtr
= DAG
.getObjectPtrOffset(dl
, BasePtr
, Increment
);
4963 } while (StWidth
!= 0 && StWidth
>= NewVTWidth
);
4965 // Cast the vector to the scalar type we can store.
4966 unsigned NumElts
= ValWidth
/ NewVTWidth
;
4967 EVT NewVecVT
= EVT::getVectorVT(*DAG
.getContext(), NewVT
, NumElts
);
4968 SDValue VecOp
= DAG
.getNode(ISD::BITCAST
, dl
, NewVecVT
, ValOp
);
4969 // Readjust index position based on new vector type.
4970 Idx
= Idx
* ValEltWidth
/ NewVTWidth
;
4972 SDValue EOp
= DAG
.getNode(
4973 ISD::EXTRACT_VECTOR_ELT
, dl
, NewVT
, VecOp
,
4974 DAG
.getConstant(Idx
++, dl
,
4975 TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4976 StChain
.push_back(DAG
.getStore(
4977 Chain
, dl
, EOp
, BasePtr
, ST
->getPointerInfo().getWithOffset(Offset
),
4978 MinAlign(Align
, Offset
), MMOFlags
, AAInfo
));
4979 StWidth
-= NewVTWidth
;
4980 Offset
+= Increment
;
4981 BasePtr
= DAG
.getObjectPtrOffset(dl
, BasePtr
, Increment
);
4982 } while (StWidth
!= 0 && StWidth
>= NewVTWidth
);
4983 // Restore index back to be relative to the original widen element type.
4984 Idx
= Idx
* NewVTWidth
/ ValEltWidth
;
4990 DAGTypeLegalizer::GenWidenVectorTruncStores(SmallVectorImpl
<SDValue
> &StChain
,
4992 // For extension loads, it may not be more efficient to truncate the vector
4993 // and then store it. Instead, we extract each element and then store it.
4994 SDValue Chain
= ST
->getChain();
4995 SDValue BasePtr
= ST
->getBasePtr();
4996 unsigned Align
= ST
->getAlignment();
4997 MachineMemOperand::Flags MMOFlags
= ST
->getMemOperand()->getFlags();
4998 AAMDNodes AAInfo
= ST
->getAAInfo();
4999 SDValue ValOp
= GetWidenedVector(ST
->getValue());
5002 EVT StVT
= ST
->getMemoryVT();
5003 EVT ValVT
= ValOp
.getValueType();
5005 // It must be true that the wide vector type is bigger than where we need to
5007 assert(StVT
.isVector() && ValOp
.getValueType().isVector());
5008 assert(StVT
.bitsLT(ValOp
.getValueType()));
5010 // For truncating stores, we can not play the tricks of chopping legal vector
5011 // types and bitcast it to the right type. Instead, we unroll the store.
5012 EVT StEltVT
= StVT
.getVectorElementType();
5013 EVT ValEltVT
= ValVT
.getVectorElementType();
5014 unsigned Increment
= ValEltVT
.getSizeInBits() / 8;
5015 unsigned NumElts
= StVT
.getVectorNumElements();
5016 SDValue EOp
= DAG
.getNode(
5017 ISD::EXTRACT_VECTOR_ELT
, dl
, ValEltVT
, ValOp
,
5018 DAG
.getConstant(0, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
5019 StChain
.push_back(DAG
.getTruncStore(Chain
, dl
, EOp
, BasePtr
,
5020 ST
->getPointerInfo(), StEltVT
, Align
,
5022 unsigned Offset
= Increment
;
5023 for (unsigned i
=1; i
< NumElts
; ++i
, Offset
+= Increment
) {
5024 SDValue NewBasePtr
= DAG
.getObjectPtrOffset(dl
, BasePtr
, Offset
);
5025 SDValue EOp
= DAG
.getNode(
5026 ISD::EXTRACT_VECTOR_ELT
, dl
, ValEltVT
, ValOp
,
5027 DAG
.getConstant(0, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
5028 StChain
.push_back(DAG
.getTruncStore(
5029 Chain
, dl
, EOp
, NewBasePtr
, ST
->getPointerInfo().getWithOffset(Offset
),
5030 StEltVT
, MinAlign(Align
, Offset
), MMOFlags
, AAInfo
));
5034 /// Modifies a vector input (widen or narrows) to a vector of NVT. The
5035 /// input vector must have the same element type as NVT.
5036 /// FillWithZeroes specifies that the vector should be widened with zeroes.
5037 SDValue
DAGTypeLegalizer::ModifyToType(SDValue InOp
, EVT NVT
,
5038 bool FillWithZeroes
) {
5039 // Note that InOp might have been widened so it might already have
5040 // the right width or it might need be narrowed.
5041 EVT InVT
= InOp
.getValueType();
5042 assert(InVT
.getVectorElementType() == NVT
.getVectorElementType() &&
5043 "input and widen element type must match");
5046 // Check if InOp already has the right width.
5050 unsigned InNumElts
= InVT
.getVectorNumElements();
5051 unsigned WidenNumElts
= NVT
.getVectorNumElements();
5052 if (WidenNumElts
> InNumElts
&& WidenNumElts
% InNumElts
== 0) {
5053 unsigned NumConcat
= WidenNumElts
/ InNumElts
;
5054 SmallVector
<SDValue
, 16> Ops(NumConcat
);
5055 SDValue FillVal
= FillWithZeroes
? DAG
.getConstant(0, dl
, InVT
) :
5058 for (unsigned i
= 1; i
!= NumConcat
; ++i
)
5061 return DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, NVT
, Ops
);
5064 if (WidenNumElts
< InNumElts
&& InNumElts
% WidenNumElts
)
5066 ISD::EXTRACT_SUBVECTOR
, dl
, NVT
, InOp
,
5067 DAG
.getConstant(0, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
5069 // Fall back to extract and build.
5070 SmallVector
<SDValue
, 16> Ops(WidenNumElts
);
5071 EVT EltVT
= NVT
.getVectorElementType();
5072 unsigned MinNumElts
= std::min(WidenNumElts
, InNumElts
);
5074 for (Idx
= 0; Idx
< MinNumElts
; ++Idx
)
5075 Ops
[Idx
] = DAG
.getNode(
5076 ISD::EXTRACT_VECTOR_ELT
, dl
, EltVT
, InOp
,
5077 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
5079 SDValue FillVal
= FillWithZeroes
? DAG
.getConstant(0, dl
, EltVT
) :
5080 DAG
.getUNDEF(EltVT
);
5081 for ( ; Idx
< WidenNumElts
; ++Idx
)
5083 return DAG
.getBuildVector(NVT
, dl
, Ops
);