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::FP_ROUND
: R
= ScalarizeVecRes_FP_ROUND(N
); break;
54 case ISD::FP_ROUND_INREG
: R
= ScalarizeVecRes_InregOp(N
); break;
55 case ISD::FPOWI
: R
= ScalarizeVecRes_FPOWI(N
); break;
56 case ISD::INSERT_VECTOR_ELT
: R
= ScalarizeVecRes_INSERT_VECTOR_ELT(N
); break;
57 case ISD::LOAD
: R
= ScalarizeVecRes_LOAD(cast
<LoadSDNode
>(N
));break;
58 case ISD::SCALAR_TO_VECTOR
: R
= ScalarizeVecRes_SCALAR_TO_VECTOR(N
); break;
59 case ISD::SIGN_EXTEND_INREG
: R
= ScalarizeVecRes_InregOp(N
); break;
60 case ISD::VSELECT
: R
= ScalarizeVecRes_VSELECT(N
); break;
61 case ISD::SELECT
: R
= ScalarizeVecRes_SELECT(N
); break;
62 case ISD::SELECT_CC
: R
= ScalarizeVecRes_SELECT_CC(N
); break;
63 case ISD::SETCC
: R
= ScalarizeVecRes_SETCC(N
); break;
64 case ISD::UNDEF
: R
= ScalarizeVecRes_UNDEF(N
); break;
65 case ISD::VECTOR_SHUFFLE
: R
= ScalarizeVecRes_VECTOR_SHUFFLE(N
); break;
66 case ISD::ANY_EXTEND_VECTOR_INREG
:
67 case ISD::SIGN_EXTEND_VECTOR_INREG
:
68 case ISD::ZERO_EXTEND_VECTOR_INREG
:
69 R
= ScalarizeVecRes_VecInregOp(N
);
75 case ISD::CTLZ_ZERO_UNDEF
:
78 case ISD::CTTZ_ZERO_UNDEF
:
98 case ISD::SIGN_EXTEND
:
101 case ISD::UINT_TO_FP
:
102 case ISD::ZERO_EXTEND
:
103 case ISD::FCANONICALIZE
:
104 R
= ScalarizeVecRes_UnaryOp(N
);
115 case ISD::FMINNUM_IEEE
:
116 case ISD::FMAXNUM_IEEE
:
143 R
= ScalarizeVecRes_BinOp(N
);
146 R
= ScalarizeVecRes_TernaryOp(N
);
148 case ISD::STRICT_FADD
:
149 case ISD::STRICT_FSUB
:
150 case ISD::STRICT_FMUL
:
151 case ISD::STRICT_FDIV
:
152 case ISD::STRICT_FREM
:
153 case ISD::STRICT_FSQRT
:
154 case ISD::STRICT_FMA
:
155 case ISD::STRICT_FPOW
:
156 case ISD::STRICT_FPOWI
:
157 case ISD::STRICT_FSIN
:
158 case ISD::STRICT_FCOS
:
159 case ISD::STRICT_FEXP
:
160 case ISD::STRICT_FEXP2
:
161 case ISD::STRICT_FLOG
:
162 case ISD::STRICT_FLOG10
:
163 case ISD::STRICT_FLOG2
:
164 case ISD::STRICT_FRINT
:
165 case ISD::STRICT_FNEARBYINT
:
166 case ISD::STRICT_FMAXNUM
:
167 case ISD::STRICT_FMINNUM
:
168 case ISD::STRICT_FCEIL
:
169 case ISD::STRICT_FFLOOR
:
170 case ISD::STRICT_FROUND
:
171 case ISD::STRICT_FTRUNC
:
172 R
= ScalarizeVecRes_StrictFPOp(N
);
180 R
= ScalarizeVecRes_OverflowOp(N
, ResNo
);
184 R
= ScalarizeVecRes_MULFIX(N
);
188 // If R is null, the sub-method took care of registering the result.
190 SetScalarizedVector(SDValue(N
, ResNo
), R
);
193 SDValue
DAGTypeLegalizer::ScalarizeVecRes_BinOp(SDNode
*N
) {
194 SDValue LHS
= GetScalarizedVector(N
->getOperand(0));
195 SDValue RHS
= GetScalarizedVector(N
->getOperand(1));
196 return DAG
.getNode(N
->getOpcode(), SDLoc(N
),
197 LHS
.getValueType(), LHS
, RHS
, N
->getFlags());
200 SDValue
DAGTypeLegalizer::ScalarizeVecRes_TernaryOp(SDNode
*N
) {
201 SDValue Op0
= GetScalarizedVector(N
->getOperand(0));
202 SDValue Op1
= GetScalarizedVector(N
->getOperand(1));
203 SDValue Op2
= GetScalarizedVector(N
->getOperand(2));
204 return DAG
.getNode(N
->getOpcode(), SDLoc(N
),
205 Op0
.getValueType(), Op0
, Op1
, Op2
);
208 SDValue
DAGTypeLegalizer::ScalarizeVecRes_MULFIX(SDNode
*N
) {
209 SDValue Op0
= GetScalarizedVector(N
->getOperand(0));
210 SDValue Op1
= GetScalarizedVector(N
->getOperand(1));
211 SDValue Op2
= N
->getOperand(2);
212 return DAG
.getNode(N
->getOpcode(), SDLoc(N
), Op0
.getValueType(), Op0
, Op1
,
216 SDValue
DAGTypeLegalizer::ScalarizeVecRes_StrictFPOp(SDNode
*N
) {
217 EVT VT
= N
->getValueType(0).getVectorElementType();
218 unsigned NumOpers
= N
->getNumOperands();
219 SDValue Chain
= N
->getOperand(0);
220 EVT ValueVTs
[] = {VT
, MVT::Other
};
223 SmallVector
<SDValue
, 4> Opers
;
225 // The Chain is the first operand.
226 Opers
.push_back(Chain
);
228 // Now process the remaining operands.
229 for (unsigned i
= 1; i
< NumOpers
; ++i
) {
230 SDValue Oper
= N
->getOperand(i
);
232 if (Oper
.getValueType().isVector())
233 Oper
= GetScalarizedVector(Oper
);
235 Opers
.push_back(Oper
);
238 SDValue Result
= DAG
.getNode(N
->getOpcode(), dl
, ValueVTs
, Opers
);
240 // Legalize the chain result - switch anything that used the old chain to
242 ReplaceValueWith(SDValue(N
, 1), Result
.getValue(1));
246 SDValue
DAGTypeLegalizer::ScalarizeVecRes_OverflowOp(SDNode
*N
,
249 EVT ResVT
= N
->getValueType(0);
250 EVT OvVT
= N
->getValueType(1);
252 SDValue ScalarLHS
, ScalarRHS
;
253 if (getTypeAction(ResVT
) == TargetLowering::TypeScalarizeVector
) {
254 ScalarLHS
= GetScalarizedVector(N
->getOperand(0));
255 ScalarRHS
= GetScalarizedVector(N
->getOperand(1));
257 SmallVector
<SDValue
, 1> ElemsLHS
, ElemsRHS
;
258 DAG
.ExtractVectorElements(N
->getOperand(0), ElemsLHS
);
259 DAG
.ExtractVectorElements(N
->getOperand(1), ElemsRHS
);
260 ScalarLHS
= ElemsLHS
[0];
261 ScalarRHS
= ElemsRHS
[0];
264 SDVTList ScalarVTs
= DAG
.getVTList(
265 ResVT
.getVectorElementType(), OvVT
.getVectorElementType());
266 SDNode
*ScalarNode
= DAG
.getNode(
267 N
->getOpcode(), DL
, ScalarVTs
, ScalarLHS
, ScalarRHS
).getNode();
269 // Replace the other vector result not being explicitly scalarized here.
270 unsigned OtherNo
= 1 - ResNo
;
271 EVT OtherVT
= N
->getValueType(OtherNo
);
272 if (getTypeAction(OtherVT
) == TargetLowering::TypeScalarizeVector
) {
273 SetScalarizedVector(SDValue(N
, OtherNo
), SDValue(ScalarNode
, OtherNo
));
275 SDValue OtherVal
= DAG
.getNode(
276 ISD::SCALAR_TO_VECTOR
, DL
, OtherVT
, SDValue(ScalarNode
, OtherNo
));
277 ReplaceValueWith(SDValue(N
, OtherNo
), OtherVal
);
280 return SDValue(ScalarNode
, ResNo
);
283 SDValue
DAGTypeLegalizer::ScalarizeVecRes_MERGE_VALUES(SDNode
*N
,
285 SDValue Op
= DisintegrateMERGE_VALUES(N
, ResNo
);
286 return GetScalarizedVector(Op
);
289 SDValue
DAGTypeLegalizer::ScalarizeVecRes_BITCAST(SDNode
*N
) {
290 SDValue Op
= N
->getOperand(0);
291 if (Op
.getValueType().isVector()
292 && Op
.getValueType().getVectorNumElements() == 1
293 && !isSimpleLegalType(Op
.getValueType()))
294 Op
= GetScalarizedVector(Op
);
295 EVT NewVT
= N
->getValueType(0).getVectorElementType();
296 return DAG
.getNode(ISD::BITCAST
, SDLoc(N
),
300 SDValue
DAGTypeLegalizer::ScalarizeVecRes_BUILD_VECTOR(SDNode
*N
) {
301 EVT EltVT
= N
->getValueType(0).getVectorElementType();
302 SDValue InOp
= N
->getOperand(0);
303 // The BUILD_VECTOR operands may be of wider element types and
304 // we may need to truncate them back to the requested return type.
305 if (EltVT
.isInteger())
306 return DAG
.getNode(ISD::TRUNCATE
, SDLoc(N
), EltVT
, InOp
);
310 SDValue
DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode
*N
) {
311 return DAG
.getNode(ISD::EXTRACT_VECTOR_ELT
, SDLoc(N
),
312 N
->getValueType(0).getVectorElementType(),
313 N
->getOperand(0), N
->getOperand(1));
316 SDValue
DAGTypeLegalizer::ScalarizeVecRes_FP_ROUND(SDNode
*N
) {
317 EVT NewVT
= N
->getValueType(0).getVectorElementType();
318 SDValue Op
= GetScalarizedVector(N
->getOperand(0));
319 return DAG
.getNode(ISD::FP_ROUND
, SDLoc(N
),
320 NewVT
, Op
, N
->getOperand(1));
323 SDValue
DAGTypeLegalizer::ScalarizeVecRes_FPOWI(SDNode
*N
) {
324 SDValue Op
= GetScalarizedVector(N
->getOperand(0));
325 return DAG
.getNode(ISD::FPOWI
, SDLoc(N
),
326 Op
.getValueType(), Op
, N
->getOperand(1));
329 SDValue
DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode
*N
) {
330 // The value to insert may have a wider type than the vector element type,
331 // so be sure to truncate it to the element type if necessary.
332 SDValue Op
= N
->getOperand(1);
333 EVT EltVT
= N
->getValueType(0).getVectorElementType();
334 if (Op
.getValueType() != EltVT
)
335 // FIXME: Can this happen for floating point types?
336 Op
= DAG
.getNode(ISD::TRUNCATE
, SDLoc(N
), EltVT
, Op
);
340 SDValue
DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode
*N
) {
341 assert(N
->isUnindexed() && "Indexed vector load?");
343 SDValue Result
= DAG
.getLoad(
344 ISD::UNINDEXED
, N
->getExtensionType(),
345 N
->getValueType(0).getVectorElementType(), SDLoc(N
), N
->getChain(),
346 N
->getBasePtr(), DAG
.getUNDEF(N
->getBasePtr().getValueType()),
347 N
->getPointerInfo(), N
->getMemoryVT().getVectorElementType(),
348 N
->getOriginalAlignment(), N
->getMemOperand()->getFlags(),
351 // Legalize the chain result - switch anything that used the old chain to
353 ReplaceValueWith(SDValue(N
, 1), Result
.getValue(1));
357 SDValue
DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(SDNode
*N
) {
358 // Get the dest type - it doesn't always match the input type, e.g. int_to_fp.
359 EVT DestVT
= N
->getValueType(0).getVectorElementType();
360 SDValue Op
= N
->getOperand(0);
361 EVT OpVT
= Op
.getValueType();
363 // The result needs scalarizing, but it's not a given that the source does.
364 // This is a workaround for targets where it's impossible to scalarize the
365 // result of a conversion, because the source type is legal.
366 // For instance, this happens on AArch64: v1i1 is illegal but v1i{8,16,32}
367 // are widened to v8i8, v4i16, and v2i32, which is legal, because v1i64 is
368 // legal and was not scalarized.
369 // See the similar logic in ScalarizeVecRes_SETCC
370 if (getTypeAction(OpVT
) == TargetLowering::TypeScalarizeVector
) {
371 Op
= GetScalarizedVector(Op
);
373 EVT VT
= OpVT
.getVectorElementType();
375 ISD::EXTRACT_VECTOR_ELT
, DL
, VT
, Op
,
376 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
378 return DAG
.getNode(N
->getOpcode(), SDLoc(N
), DestVT
, Op
);
381 SDValue
DAGTypeLegalizer::ScalarizeVecRes_InregOp(SDNode
*N
) {
382 EVT EltVT
= N
->getValueType(0).getVectorElementType();
383 EVT ExtVT
= cast
<VTSDNode
>(N
->getOperand(1))->getVT().getVectorElementType();
384 SDValue LHS
= GetScalarizedVector(N
->getOperand(0));
385 return DAG
.getNode(N
->getOpcode(), SDLoc(N
), EltVT
,
386 LHS
, DAG
.getValueType(ExtVT
));
389 SDValue
DAGTypeLegalizer::ScalarizeVecRes_VecInregOp(SDNode
*N
) {
391 SDValue Op
= N
->getOperand(0);
393 EVT OpVT
= Op
.getValueType();
394 EVT OpEltVT
= OpVT
.getVectorElementType();
395 EVT EltVT
= N
->getValueType(0).getVectorElementType();
397 if (getTypeAction(OpVT
) == TargetLowering::TypeScalarizeVector
) {
398 Op
= GetScalarizedVector(Op
);
401 ISD::EXTRACT_VECTOR_ELT
, DL
, OpEltVT
, Op
,
402 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
405 switch (N
->getOpcode()) {
406 case ISD::ANY_EXTEND_VECTOR_INREG
:
407 return DAG
.getNode(ISD::ANY_EXTEND
, DL
, EltVT
, Op
);
408 case ISD::SIGN_EXTEND_VECTOR_INREG
:
409 return DAG
.getNode(ISD::SIGN_EXTEND
, DL
, EltVT
, Op
);
410 case ISD::ZERO_EXTEND_VECTOR_INREG
:
411 return DAG
.getNode(ISD::ZERO_EXTEND
, DL
, EltVT
, Op
);
414 llvm_unreachable("Illegal extend_vector_inreg opcode");
417 SDValue
DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode
*N
) {
418 // If the operand is wider than the vector element type then it is implicitly
419 // truncated. Make that explicit here.
420 EVT EltVT
= N
->getValueType(0).getVectorElementType();
421 SDValue InOp
= N
->getOperand(0);
422 if (InOp
.getValueType() != EltVT
)
423 return DAG
.getNode(ISD::TRUNCATE
, SDLoc(N
), EltVT
, InOp
);
427 SDValue
DAGTypeLegalizer::ScalarizeVecRes_VSELECT(SDNode
*N
) {
428 SDValue Cond
= N
->getOperand(0);
429 EVT OpVT
= Cond
.getValueType();
431 // The vselect result and true/value operands needs scalarizing, but it's
432 // not a given that the Cond does. For instance, in AVX512 v1i1 is legal.
433 // See the similar logic in ScalarizeVecRes_SETCC
434 if (getTypeAction(OpVT
) == TargetLowering::TypeScalarizeVector
) {
435 Cond
= GetScalarizedVector(Cond
);
437 EVT VT
= OpVT
.getVectorElementType();
439 ISD::EXTRACT_VECTOR_ELT
, DL
, VT
, Cond
,
440 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
443 SDValue LHS
= GetScalarizedVector(N
->getOperand(1));
444 TargetLowering::BooleanContent ScalarBool
=
445 TLI
.getBooleanContents(false, false);
446 TargetLowering::BooleanContent VecBool
= TLI
.getBooleanContents(true, false);
448 // If integer and float booleans have different contents then we can't
449 // reliably optimize in all cases. There is a full explanation for this in
450 // DAGCombiner::visitSELECT() where the same issue affects folding
451 // (select C, 0, 1) to (xor C, 1).
452 if (TLI
.getBooleanContents(false, false) !=
453 TLI
.getBooleanContents(false, true)) {
454 // At least try the common case where the boolean is generated by a
456 if (Cond
->getOpcode() == ISD::SETCC
) {
457 EVT OpVT
= Cond
->getOperand(0).getValueType();
458 ScalarBool
= TLI
.getBooleanContents(OpVT
.getScalarType());
459 VecBool
= TLI
.getBooleanContents(OpVT
);
461 ScalarBool
= TargetLowering::UndefinedBooleanContent
;
464 EVT CondVT
= Cond
.getValueType();
465 if (ScalarBool
!= VecBool
) {
466 switch (ScalarBool
) {
467 case TargetLowering::UndefinedBooleanContent
:
469 case TargetLowering::ZeroOrOneBooleanContent
:
470 assert(VecBool
== TargetLowering::UndefinedBooleanContent
||
471 VecBool
== TargetLowering::ZeroOrNegativeOneBooleanContent
);
472 // Vector read from all ones, scalar expects a single 1 so mask.
473 Cond
= DAG
.getNode(ISD::AND
, SDLoc(N
), CondVT
,
474 Cond
, DAG
.getConstant(1, SDLoc(N
), CondVT
));
476 case TargetLowering::ZeroOrNegativeOneBooleanContent
:
477 assert(VecBool
== TargetLowering::UndefinedBooleanContent
||
478 VecBool
== TargetLowering::ZeroOrOneBooleanContent
);
479 // Vector reads from a one, scalar from all ones so sign extend.
480 Cond
= DAG
.getNode(ISD::SIGN_EXTEND_INREG
, SDLoc(N
), CondVT
,
481 Cond
, DAG
.getValueType(MVT::i1
));
486 // Truncate the condition if needed
487 auto BoolVT
= getSetCCResultType(CondVT
);
488 if (BoolVT
.bitsLT(CondVT
))
489 Cond
= DAG
.getNode(ISD::TRUNCATE
, SDLoc(N
), BoolVT
, Cond
);
491 return DAG
.getSelect(SDLoc(N
),
492 LHS
.getValueType(), Cond
, LHS
,
493 GetScalarizedVector(N
->getOperand(2)));
496 SDValue
DAGTypeLegalizer::ScalarizeVecRes_SELECT(SDNode
*N
) {
497 SDValue LHS
= GetScalarizedVector(N
->getOperand(1));
498 return DAG
.getSelect(SDLoc(N
),
499 LHS
.getValueType(), N
->getOperand(0), LHS
,
500 GetScalarizedVector(N
->getOperand(2)));
503 SDValue
DAGTypeLegalizer::ScalarizeVecRes_SELECT_CC(SDNode
*N
) {
504 SDValue LHS
= GetScalarizedVector(N
->getOperand(2));
505 return DAG
.getNode(ISD::SELECT_CC
, SDLoc(N
), LHS
.getValueType(),
506 N
->getOperand(0), N
->getOperand(1),
507 LHS
, GetScalarizedVector(N
->getOperand(3)),
511 SDValue
DAGTypeLegalizer::ScalarizeVecRes_UNDEF(SDNode
*N
) {
512 return DAG
.getUNDEF(N
->getValueType(0).getVectorElementType());
515 SDValue
DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(SDNode
*N
) {
516 // Figure out if the scalar is the LHS or RHS and return it.
517 SDValue Arg
= N
->getOperand(2).getOperand(0);
519 return DAG
.getUNDEF(N
->getValueType(0).getVectorElementType());
520 unsigned Op
= !cast
<ConstantSDNode
>(Arg
)->isNullValue();
521 return GetScalarizedVector(N
->getOperand(Op
));
524 SDValue
DAGTypeLegalizer::ScalarizeVecRes_SETCC(SDNode
*N
) {
525 assert(N
->getValueType(0).isVector() &&
526 N
->getOperand(0).getValueType().isVector() &&
527 "Operand types must be vectors");
528 SDValue LHS
= N
->getOperand(0);
529 SDValue RHS
= N
->getOperand(1);
530 EVT OpVT
= LHS
.getValueType();
531 EVT NVT
= N
->getValueType(0).getVectorElementType();
534 // The result needs scalarizing, but it's not a given that the source does.
535 if (getTypeAction(OpVT
) == TargetLowering::TypeScalarizeVector
) {
536 LHS
= GetScalarizedVector(LHS
);
537 RHS
= GetScalarizedVector(RHS
);
539 EVT VT
= OpVT
.getVectorElementType();
541 ISD::EXTRACT_VECTOR_ELT
, DL
, VT
, LHS
,
542 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
544 ISD::EXTRACT_VECTOR_ELT
, DL
, VT
, RHS
,
545 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
548 // Turn it into a scalar SETCC.
549 SDValue Res
= DAG
.getNode(ISD::SETCC
, DL
, MVT::i1
, LHS
, RHS
,
551 // Vectors may have a different boolean contents to scalars. Promote the
552 // value appropriately.
553 ISD::NodeType ExtendCode
=
554 TargetLowering::getExtendForContent(TLI
.getBooleanContents(OpVT
));
555 return DAG
.getNode(ExtendCode
, DL
, NVT
, Res
);
559 //===----------------------------------------------------------------------===//
560 // Operand Vector Scalarization <1 x ty> -> ty.
561 //===----------------------------------------------------------------------===//
563 bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode
*N
, unsigned OpNo
) {
564 LLVM_DEBUG(dbgs() << "Scalarize node operand " << OpNo
<< ": "; N
->dump(&DAG
);
566 SDValue Res
= SDValue();
568 if (!Res
.getNode()) {
569 switch (N
->getOpcode()) {
572 dbgs() << "ScalarizeVectorOperand Op #" << OpNo
<< ": ";
576 report_fatal_error("Do not know how to scalarize this operator's "
579 Res
= ScalarizeVecOp_BITCAST(N
);
581 case ISD::ANY_EXTEND
:
582 case ISD::ZERO_EXTEND
:
583 case ISD::SIGN_EXTEND
:
585 case ISD::FP_TO_SINT
:
586 case ISD::FP_TO_UINT
:
587 case ISD::SINT_TO_FP
:
588 case ISD::UINT_TO_FP
:
589 Res
= ScalarizeVecOp_UnaryOp(N
);
591 case ISD::CONCAT_VECTORS
:
592 Res
= ScalarizeVecOp_CONCAT_VECTORS(N
);
594 case ISD::EXTRACT_VECTOR_ELT
:
595 Res
= ScalarizeVecOp_EXTRACT_VECTOR_ELT(N
);
598 Res
= ScalarizeVecOp_VSELECT(N
);
601 Res
= ScalarizeVecOp_VSETCC(N
);
604 Res
= ScalarizeVecOp_STORE(cast
<StoreSDNode
>(N
), OpNo
);
607 Res
= ScalarizeVecOp_FP_ROUND(N
, OpNo
);
612 // If the result is null, the sub-method took care of registering results etc.
613 if (!Res
.getNode()) return false;
615 // If the result is N, the sub-method updated N in place. Tell the legalizer
617 if (Res
.getNode() == N
)
620 assert(Res
.getValueType() == N
->getValueType(0) && N
->getNumValues() == 1 &&
621 "Invalid operand expansion");
623 ReplaceValueWith(SDValue(N
, 0), Res
);
627 /// If the value to convert is a vector that needs to be scalarized, it must be
628 /// <1 x ty>. Convert the element instead.
629 SDValue
DAGTypeLegalizer::ScalarizeVecOp_BITCAST(SDNode
*N
) {
630 SDValue Elt
= GetScalarizedVector(N
->getOperand(0));
631 return DAG
.getNode(ISD::BITCAST
, SDLoc(N
),
632 N
->getValueType(0), Elt
);
635 /// If the input is a vector that needs to be scalarized, it must be <1 x ty>.
636 /// Do the operation on the element instead.
637 SDValue
DAGTypeLegalizer::ScalarizeVecOp_UnaryOp(SDNode
*N
) {
638 assert(N
->getValueType(0).getVectorNumElements() == 1 &&
639 "Unexpected vector type!");
640 SDValue Elt
= GetScalarizedVector(N
->getOperand(0));
641 SDValue Op
= DAG
.getNode(N
->getOpcode(), SDLoc(N
),
642 N
->getValueType(0).getScalarType(), Elt
);
643 // Revectorize the result so the types line up with what the uses of this
644 // expression expect.
645 return DAG
.getNode(ISD::SCALAR_TO_VECTOR
, SDLoc(N
), N
->getValueType(0), Op
);
648 /// The vectors to concatenate have length one - use a BUILD_VECTOR instead.
649 SDValue
DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(SDNode
*N
) {
650 SmallVector
<SDValue
, 8> Ops(N
->getNumOperands());
651 for (unsigned i
= 0, e
= N
->getNumOperands(); i
< e
; ++i
)
652 Ops
[i
] = GetScalarizedVector(N
->getOperand(i
));
653 return DAG
.getBuildVector(N
->getValueType(0), SDLoc(N
), Ops
);
656 /// If the input is a vector that needs to be scalarized, it must be <1 x ty>,
657 /// so just return the element, ignoring the index.
658 SDValue
DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode
*N
) {
659 EVT VT
= N
->getValueType(0);
660 SDValue Res
= GetScalarizedVector(N
->getOperand(0));
661 if (Res
.getValueType() != VT
)
662 Res
= VT
.isFloatingPoint()
663 ? DAG
.getNode(ISD::FP_EXTEND
, SDLoc(N
), VT
, Res
)
664 : DAG
.getNode(ISD::ANY_EXTEND
, SDLoc(N
), VT
, Res
);
668 /// If the input condition is a vector that needs to be scalarized, it must be
669 /// <1 x i1>, so just convert to a normal ISD::SELECT
670 /// (still with vector output type since that was acceptable if we got here).
671 SDValue
DAGTypeLegalizer::ScalarizeVecOp_VSELECT(SDNode
*N
) {
672 SDValue ScalarCond
= GetScalarizedVector(N
->getOperand(0));
673 EVT VT
= N
->getValueType(0);
675 return DAG
.getNode(ISD::SELECT
, SDLoc(N
), VT
, ScalarCond
, N
->getOperand(1),
679 /// If the operand is a vector that needs to be scalarized then the
680 /// result must be v1i1, so just convert to a scalar SETCC and wrap
681 /// with a scalar_to_vector since the res type is legal if we got here
682 SDValue
DAGTypeLegalizer::ScalarizeVecOp_VSETCC(SDNode
*N
) {
683 assert(N
->getValueType(0).isVector() &&
684 N
->getOperand(0).getValueType().isVector() &&
685 "Operand types must be vectors");
686 assert(N
->getValueType(0) == MVT::v1i1
&& "Expected v1i1 type");
688 EVT VT
= N
->getValueType(0);
689 SDValue LHS
= GetScalarizedVector(N
->getOperand(0));
690 SDValue RHS
= GetScalarizedVector(N
->getOperand(1));
692 EVT OpVT
= N
->getOperand(0).getValueType();
693 EVT NVT
= VT
.getVectorElementType();
695 // Turn it into a scalar SETCC.
696 SDValue Res
= DAG
.getNode(ISD::SETCC
, DL
, MVT::i1
, LHS
, RHS
,
699 // Vectors may have a different boolean contents to scalars. Promote the
700 // value appropriately.
701 ISD::NodeType ExtendCode
=
702 TargetLowering::getExtendForContent(TLI
.getBooleanContents(OpVT
));
704 Res
= DAG
.getNode(ExtendCode
, DL
, NVT
, Res
);
706 return DAG
.getNode(ISD::SCALAR_TO_VECTOR
, DL
, VT
, Res
);
709 /// If the value to store is a vector that needs to be scalarized, it must be
710 /// <1 x ty>. Just store the element.
711 SDValue
DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode
*N
, unsigned OpNo
){
712 assert(N
->isUnindexed() && "Indexed store of one-element vector?");
713 assert(OpNo
== 1 && "Do not know how to scalarize this operand!");
716 if (N
->isTruncatingStore())
717 return DAG
.getTruncStore(
718 N
->getChain(), dl
, GetScalarizedVector(N
->getOperand(1)),
719 N
->getBasePtr(), N
->getPointerInfo(),
720 N
->getMemoryVT().getVectorElementType(), N
->getAlignment(),
721 N
->getMemOperand()->getFlags(), N
->getAAInfo());
723 return DAG
.getStore(N
->getChain(), dl
, GetScalarizedVector(N
->getOperand(1)),
724 N
->getBasePtr(), N
->getPointerInfo(),
725 N
->getOriginalAlignment(), N
->getMemOperand()->getFlags(),
729 /// If the value to round is a vector that needs to be scalarized, it must be
730 /// <1 x ty>. Convert the element instead.
731 SDValue
DAGTypeLegalizer::ScalarizeVecOp_FP_ROUND(SDNode
*N
, unsigned OpNo
) {
732 SDValue Elt
= GetScalarizedVector(N
->getOperand(0));
733 SDValue Res
= DAG
.getNode(ISD::FP_ROUND
, SDLoc(N
),
734 N
->getValueType(0).getVectorElementType(), Elt
,
736 return DAG
.getNode(ISD::SCALAR_TO_VECTOR
, SDLoc(N
), N
->getValueType(0), Res
);
739 //===----------------------------------------------------------------------===//
740 // Result Vector Splitting
741 //===----------------------------------------------------------------------===//
743 /// This method is called when the specified result of the specified node is
744 /// found to need vector splitting. At this point, the node may also have
745 /// invalid operands or may have other results that need legalization, we just
746 /// know that (at least) one result needs vector splitting.
747 void DAGTypeLegalizer::SplitVectorResult(SDNode
*N
, unsigned ResNo
) {
748 LLVM_DEBUG(dbgs() << "Split node result: "; N
->dump(&DAG
); dbgs() << "\n");
751 // See if the target wants to custom expand this node.
752 if (CustomLowerNode(N
, N
->getValueType(ResNo
), true))
755 switch (N
->getOpcode()) {
758 dbgs() << "SplitVectorResult #" << ResNo
<< ": ";
762 report_fatal_error("Do not know how to split the result of this "
765 case ISD::MERGE_VALUES
: SplitRes_MERGE_VALUES(N
, ResNo
, Lo
, Hi
); break;
767 case ISD::SELECT
: SplitRes_SELECT(N
, Lo
, Hi
); break;
768 case ISD::SELECT_CC
: SplitRes_SELECT_CC(N
, Lo
, Hi
); break;
769 case ISD::UNDEF
: SplitRes_UNDEF(N
, Lo
, Hi
); break;
770 case ISD::BITCAST
: SplitVecRes_BITCAST(N
, Lo
, Hi
); break;
771 case ISD::BUILD_VECTOR
: SplitVecRes_BUILD_VECTOR(N
, Lo
, Hi
); break;
772 case ISD::CONCAT_VECTORS
: SplitVecRes_CONCAT_VECTORS(N
, Lo
, Hi
); break;
773 case ISD::EXTRACT_SUBVECTOR
: SplitVecRes_EXTRACT_SUBVECTOR(N
, Lo
, Hi
); break;
774 case ISD::INSERT_SUBVECTOR
: SplitVecRes_INSERT_SUBVECTOR(N
, Lo
, Hi
); break;
775 case ISD::FP_ROUND_INREG
: SplitVecRes_InregOp(N
, Lo
, Hi
); break;
776 case ISD::FPOWI
: SplitVecRes_FPOWI(N
, Lo
, Hi
); break;
777 case ISD::FCOPYSIGN
: SplitVecRes_FCOPYSIGN(N
, Lo
, Hi
); break;
778 case ISD::INSERT_VECTOR_ELT
: SplitVecRes_INSERT_VECTOR_ELT(N
, Lo
, Hi
); break;
779 case ISD::SCALAR_TO_VECTOR
: SplitVecRes_SCALAR_TO_VECTOR(N
, Lo
, Hi
); break;
780 case ISD::SIGN_EXTEND_INREG
: SplitVecRes_InregOp(N
, Lo
, Hi
); break;
782 SplitVecRes_LOAD(cast
<LoadSDNode
>(N
), Lo
, Hi
);
785 SplitVecRes_MLOAD(cast
<MaskedLoadSDNode
>(N
), Lo
, Hi
);
788 SplitVecRes_MGATHER(cast
<MaskedGatherSDNode
>(N
), Lo
, Hi
);
791 SplitVecRes_SETCC(N
, Lo
, Hi
);
793 case ISD::VECTOR_SHUFFLE
:
794 SplitVecRes_VECTOR_SHUFFLE(cast
<ShuffleVectorSDNode
>(N
), Lo
, Hi
);
797 case ISD::ANY_EXTEND_VECTOR_INREG
:
798 case ISD::SIGN_EXTEND_VECTOR_INREG
:
799 case ISD::ZERO_EXTEND_VECTOR_INREG
:
800 SplitVecRes_ExtVecInRegOp(N
, Lo
, Hi
);
803 case ISD::BITREVERSE
:
807 case ISD::CTLZ_ZERO_UNDEF
:
808 case ISD::CTTZ_ZERO_UNDEF
:
819 case ISD::FNEARBYINT
:
823 case ISD::FP_TO_SINT
:
824 case ISD::FP_TO_UINT
:
830 case ISD::SINT_TO_FP
:
832 case ISD::UINT_TO_FP
:
833 case ISD::FCANONICALIZE
:
834 SplitVecRes_UnaryOp(N
, Lo
, Hi
);
837 case ISD::ANY_EXTEND
:
838 case ISD::SIGN_EXTEND
:
839 case ISD::ZERO_EXTEND
:
840 SplitVecRes_ExtendOp(N
, Lo
, Hi
);
876 SplitVecRes_BinOp(N
, Lo
, Hi
);
879 SplitVecRes_TernaryOp(N
, Lo
, Hi
);
881 case ISD::STRICT_FADD
:
882 case ISD::STRICT_FSUB
:
883 case ISD::STRICT_FMUL
:
884 case ISD::STRICT_FDIV
:
885 case ISD::STRICT_FREM
:
886 case ISD::STRICT_FSQRT
:
887 case ISD::STRICT_FMA
:
888 case ISD::STRICT_FPOW
:
889 case ISD::STRICT_FPOWI
:
890 case ISD::STRICT_FSIN
:
891 case ISD::STRICT_FCOS
:
892 case ISD::STRICT_FEXP
:
893 case ISD::STRICT_FEXP2
:
894 case ISD::STRICT_FLOG
:
895 case ISD::STRICT_FLOG10
:
896 case ISD::STRICT_FLOG2
:
897 case ISD::STRICT_FRINT
:
898 case ISD::STRICT_FNEARBYINT
:
899 case ISD::STRICT_FMAXNUM
:
900 case ISD::STRICT_FMINNUM
:
901 case ISD::STRICT_FCEIL
:
902 case ISD::STRICT_FFLOOR
:
903 case ISD::STRICT_FROUND
:
904 case ISD::STRICT_FTRUNC
:
905 SplitVecRes_StrictFPOp(N
, Lo
, Hi
);
913 SplitVecRes_OverflowOp(N
, ResNo
, Lo
, Hi
);
917 SplitVecRes_MULFIX(N
, Lo
, Hi
);
921 // If Lo/Hi is null, the sub-method took care of registering results etc.
923 SetSplitVector(SDValue(N
, ResNo
), Lo
, Hi
);
926 void DAGTypeLegalizer::SplitVecRes_BinOp(SDNode
*N
, SDValue
&Lo
,
928 SDValue LHSLo
, LHSHi
;
929 GetSplitVector(N
->getOperand(0), LHSLo
, LHSHi
);
930 SDValue RHSLo
, RHSHi
;
931 GetSplitVector(N
->getOperand(1), RHSLo
, RHSHi
);
934 const SDNodeFlags Flags
= N
->getFlags();
935 unsigned Opcode
= N
->getOpcode();
936 Lo
= DAG
.getNode(Opcode
, dl
, LHSLo
.getValueType(), LHSLo
, RHSLo
, Flags
);
937 Hi
= DAG
.getNode(Opcode
, dl
, LHSHi
.getValueType(), LHSHi
, RHSHi
, Flags
);
940 void DAGTypeLegalizer::SplitVecRes_TernaryOp(SDNode
*N
, SDValue
&Lo
,
942 SDValue Op0Lo
, Op0Hi
;
943 GetSplitVector(N
->getOperand(0), Op0Lo
, Op0Hi
);
944 SDValue Op1Lo
, Op1Hi
;
945 GetSplitVector(N
->getOperand(1), Op1Lo
, Op1Hi
);
946 SDValue Op2Lo
, Op2Hi
;
947 GetSplitVector(N
->getOperand(2), Op2Lo
, Op2Hi
);
950 Lo
= DAG
.getNode(N
->getOpcode(), dl
, Op0Lo
.getValueType(),
951 Op0Lo
, Op1Lo
, Op2Lo
);
952 Hi
= DAG
.getNode(N
->getOpcode(), dl
, Op0Hi
.getValueType(),
953 Op0Hi
, Op1Hi
, Op2Hi
);
956 void DAGTypeLegalizer::SplitVecRes_MULFIX(SDNode
*N
, SDValue
&Lo
, SDValue
&Hi
) {
957 SDValue LHSLo
, LHSHi
;
958 GetSplitVector(N
->getOperand(0), LHSLo
, LHSHi
);
959 SDValue RHSLo
, RHSHi
;
960 GetSplitVector(N
->getOperand(1), RHSLo
, RHSHi
);
962 SDValue Op2
= N
->getOperand(2);
964 unsigned Opcode
= N
->getOpcode();
965 Lo
= DAG
.getNode(Opcode
, dl
, LHSLo
.getValueType(), LHSLo
, RHSLo
, Op2
);
966 Hi
= DAG
.getNode(Opcode
, dl
, LHSHi
.getValueType(), LHSHi
, RHSHi
, Op2
);
969 void DAGTypeLegalizer::SplitVecRes_BITCAST(SDNode
*N
, SDValue
&Lo
,
971 // We know the result is a vector. The input may be either a vector or a
974 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
977 SDValue InOp
= N
->getOperand(0);
978 EVT InVT
= InOp
.getValueType();
980 // Handle some special cases efficiently.
981 switch (getTypeAction(InVT
)) {
982 case TargetLowering::TypeLegal
:
983 case TargetLowering::TypePromoteInteger
:
984 case TargetLowering::TypePromoteFloat
:
985 case TargetLowering::TypeSoftenFloat
:
986 case TargetLowering::TypeScalarizeVector
:
987 case TargetLowering::TypeWidenVector
:
989 case TargetLowering::TypeExpandInteger
:
990 case TargetLowering::TypeExpandFloat
:
991 // A scalar to vector conversion, where the scalar needs expansion.
992 // If the vector is being split in two then we can just convert the
995 GetExpandedOp(InOp
, Lo
, Hi
);
996 if (DAG
.getDataLayout().isBigEndian())
998 Lo
= DAG
.getNode(ISD::BITCAST
, dl
, LoVT
, Lo
);
999 Hi
= DAG
.getNode(ISD::BITCAST
, dl
, HiVT
, Hi
);
1003 case TargetLowering::TypeSplitVector
:
1004 // If the input is a vector that needs to be split, convert each split
1005 // piece of the input now.
1006 GetSplitVector(InOp
, Lo
, Hi
);
1007 Lo
= DAG
.getNode(ISD::BITCAST
, dl
, LoVT
, Lo
);
1008 Hi
= DAG
.getNode(ISD::BITCAST
, dl
, HiVT
, Hi
);
1012 // In the general case, convert the input to an integer and split it by hand.
1013 EVT LoIntVT
= EVT::getIntegerVT(*DAG
.getContext(), LoVT
.getSizeInBits());
1014 EVT HiIntVT
= EVT::getIntegerVT(*DAG
.getContext(), HiVT
.getSizeInBits());
1015 if (DAG
.getDataLayout().isBigEndian())
1016 std::swap(LoIntVT
, HiIntVT
);
1018 SplitInteger(BitConvertToInteger(InOp
), LoIntVT
, HiIntVT
, Lo
, Hi
);
1020 if (DAG
.getDataLayout().isBigEndian())
1022 Lo
= DAG
.getNode(ISD::BITCAST
, dl
, LoVT
, Lo
);
1023 Hi
= DAG
.getNode(ISD::BITCAST
, dl
, HiVT
, Hi
);
1026 void DAGTypeLegalizer::SplitVecRes_BUILD_VECTOR(SDNode
*N
, SDValue
&Lo
,
1030 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1031 unsigned LoNumElts
= LoVT
.getVectorNumElements();
1032 SmallVector
<SDValue
, 8> LoOps(N
->op_begin(), N
->op_begin()+LoNumElts
);
1033 Lo
= DAG
.getBuildVector(LoVT
, dl
, LoOps
);
1035 SmallVector
<SDValue
, 8> HiOps(N
->op_begin()+LoNumElts
, N
->op_end());
1036 Hi
= DAG
.getBuildVector(HiVT
, dl
, HiOps
);
1039 void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode
*N
, SDValue
&Lo
,
1041 assert(!(N
->getNumOperands() & 1) && "Unsupported CONCAT_VECTORS");
1043 unsigned NumSubvectors
= N
->getNumOperands() / 2;
1044 if (NumSubvectors
== 1) {
1045 Lo
= N
->getOperand(0);
1046 Hi
= N
->getOperand(1);
1051 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1053 SmallVector
<SDValue
, 8> LoOps(N
->op_begin(), N
->op_begin()+NumSubvectors
);
1054 Lo
= DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, LoVT
, LoOps
);
1056 SmallVector
<SDValue
, 8> HiOps(N
->op_begin()+NumSubvectors
, N
->op_end());
1057 Hi
= DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, HiVT
, HiOps
);
1060 void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(SDNode
*N
, SDValue
&Lo
,
1062 SDValue Vec
= N
->getOperand(0);
1063 SDValue Idx
= N
->getOperand(1);
1067 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1069 Lo
= DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, dl
, LoVT
, Vec
, Idx
);
1070 uint64_t IdxVal
= cast
<ConstantSDNode
>(Idx
)->getZExtValue();
1071 Hi
= DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, dl
, HiVT
, Vec
,
1072 DAG
.getConstant(IdxVal
+ LoVT
.getVectorNumElements(), dl
,
1073 TLI
.getVectorIdxTy(DAG
.getDataLayout())));
1076 void DAGTypeLegalizer::SplitVecRes_INSERT_SUBVECTOR(SDNode
*N
, SDValue
&Lo
,
1078 SDValue Vec
= N
->getOperand(0);
1079 SDValue SubVec
= N
->getOperand(1);
1080 SDValue Idx
= N
->getOperand(2);
1082 GetSplitVector(Vec
, Lo
, Hi
);
1084 EVT VecVT
= Vec
.getValueType();
1085 unsigned VecElems
= VecVT
.getVectorNumElements();
1086 unsigned SubElems
= SubVec
.getValueType().getVectorNumElements();
1088 // If we know the index is 0, and we know the subvector doesn't cross the
1089 // boundary between the halves, we can avoid spilling the vector, and insert
1090 // into the lower half of the split vector directly.
1091 // TODO: The IdxVal == 0 constraint is artificial, we could do this whenever
1092 // the index is constant and there is no boundary crossing. But those cases
1093 // don't seem to get hit in practice.
1094 if (ConstantSDNode
*ConstIdx
= dyn_cast
<ConstantSDNode
>(Idx
)) {
1095 unsigned IdxVal
= ConstIdx
->getZExtValue();
1096 if ((IdxVal
== 0) && (IdxVal
+ SubElems
<= VecElems
/ 2)) {
1098 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1099 Lo
= DAG
.getNode(ISD::INSERT_SUBVECTOR
, dl
, LoVT
, Lo
, SubVec
, Idx
);
1104 // Spill the vector to the stack.
1105 SDValue StackPtr
= DAG
.CreateStackTemporary(VecVT
);
1107 DAG
.getStore(DAG
.getEntryNode(), dl
, Vec
, StackPtr
, MachinePointerInfo());
1109 // Store the new subvector into the specified index.
1110 SDValue SubVecPtr
= TLI
.getVectorElementPointer(DAG
, StackPtr
, VecVT
, Idx
);
1111 Type
*VecType
= VecVT
.getTypeForEVT(*DAG
.getContext());
1112 unsigned Alignment
= DAG
.getDataLayout().getPrefTypeAlignment(VecType
);
1113 Store
= DAG
.getStore(Store
, dl
, SubVec
, SubVecPtr
, MachinePointerInfo());
1115 // Load the Lo part from the stack slot.
1117 DAG
.getLoad(Lo
.getValueType(), dl
, Store
, StackPtr
, MachinePointerInfo());
1119 // Increment the pointer to the other part.
1120 unsigned IncrementSize
= Lo
.getValueSizeInBits() / 8;
1122 DAG
.getNode(ISD::ADD
, dl
, StackPtr
.getValueType(), StackPtr
,
1123 DAG
.getConstant(IncrementSize
, dl
, StackPtr
.getValueType()));
1125 // Load the Hi part from the stack slot.
1126 Hi
= DAG
.getLoad(Hi
.getValueType(), dl
, Store
, StackPtr
, MachinePointerInfo(),
1127 MinAlign(Alignment
, IncrementSize
));
1130 void DAGTypeLegalizer::SplitVecRes_FPOWI(SDNode
*N
, SDValue
&Lo
,
1133 GetSplitVector(N
->getOperand(0), Lo
, Hi
);
1134 Lo
= DAG
.getNode(ISD::FPOWI
, dl
, Lo
.getValueType(), Lo
, N
->getOperand(1));
1135 Hi
= DAG
.getNode(ISD::FPOWI
, dl
, Hi
.getValueType(), Hi
, N
->getOperand(1));
1138 void DAGTypeLegalizer::SplitVecRes_FCOPYSIGN(SDNode
*N
, SDValue
&Lo
,
1140 SDValue LHSLo
, LHSHi
;
1141 GetSplitVector(N
->getOperand(0), LHSLo
, LHSHi
);
1144 SDValue RHSLo
, RHSHi
;
1145 SDValue RHS
= N
->getOperand(1);
1146 EVT RHSVT
= RHS
.getValueType();
1147 if (getTypeAction(RHSVT
) == TargetLowering::TypeSplitVector
)
1148 GetSplitVector(RHS
, RHSLo
, RHSHi
);
1150 std::tie(RHSLo
, RHSHi
) = DAG
.SplitVector(RHS
, SDLoc(RHS
));
1153 Lo
= DAG
.getNode(ISD::FCOPYSIGN
, DL
, LHSLo
.getValueType(), LHSLo
, RHSLo
);
1154 Hi
= DAG
.getNode(ISD::FCOPYSIGN
, DL
, LHSHi
.getValueType(), LHSHi
, RHSHi
);
1157 void DAGTypeLegalizer::SplitVecRes_InregOp(SDNode
*N
, SDValue
&Lo
,
1159 SDValue LHSLo
, LHSHi
;
1160 GetSplitVector(N
->getOperand(0), LHSLo
, LHSHi
);
1164 std::tie(LoVT
, HiVT
) =
1165 DAG
.GetSplitDestVTs(cast
<VTSDNode
>(N
->getOperand(1))->getVT());
1167 Lo
= DAG
.getNode(N
->getOpcode(), dl
, LHSLo
.getValueType(), LHSLo
,
1168 DAG
.getValueType(LoVT
));
1169 Hi
= DAG
.getNode(N
->getOpcode(), dl
, LHSHi
.getValueType(), LHSHi
,
1170 DAG
.getValueType(HiVT
));
1173 void DAGTypeLegalizer::SplitVecRes_ExtVecInRegOp(SDNode
*N
, SDValue
&Lo
,
1175 unsigned Opcode
= N
->getOpcode();
1176 SDValue N0
= N
->getOperand(0);
1181 if (getTypeAction(N0
.getValueType()) == TargetLowering::TypeSplitVector
)
1182 GetSplitVector(N0
, InLo
, InHi
);
1184 std::tie(InLo
, InHi
) = DAG
.SplitVectorOperand(N
, 0);
1186 EVT InLoVT
= InLo
.getValueType();
1187 unsigned InNumElements
= InLoVT
.getVectorNumElements();
1189 EVT OutLoVT
, OutHiVT
;
1190 std::tie(OutLoVT
, OutHiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1191 unsigned OutNumElements
= OutLoVT
.getVectorNumElements();
1192 assert((2 * OutNumElements
) <= InNumElements
&&
1193 "Illegal extend vector in reg split");
1195 // *_EXTEND_VECTOR_INREG instructions extend the lowest elements of the
1196 // input vector (i.e. we only use InLo):
1197 // OutLo will extend the first OutNumElements from InLo.
1198 // OutHi will extend the next OutNumElements from InLo.
1200 // Shuffle the elements from InLo for OutHi into the bottom elements to
1201 // create a 'fake' InHi.
1202 SmallVector
<int, 8> SplitHi(InNumElements
, -1);
1203 for (unsigned i
= 0; i
!= OutNumElements
; ++i
)
1204 SplitHi
[i
] = i
+ OutNumElements
;
1205 InHi
= DAG
.getVectorShuffle(InLoVT
, dl
, InLo
, DAG
.getUNDEF(InLoVT
), SplitHi
);
1207 Lo
= DAG
.getNode(Opcode
, dl
, OutLoVT
, InLo
);
1208 Hi
= DAG
.getNode(Opcode
, dl
, OutHiVT
, InHi
);
1211 void DAGTypeLegalizer::SplitVecRes_StrictFPOp(SDNode
*N
, SDValue
&Lo
,
1213 unsigned NumOps
= N
->getNumOperands();
1214 SDValue Chain
= N
->getOperand(0);
1217 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1219 SmallVector
<SDValue
, 4> OpsLo
;
1220 SmallVector
<SDValue
, 4> OpsHi
;
1222 // The Chain is the first operand.
1223 OpsLo
.push_back(Chain
);
1224 OpsHi
.push_back(Chain
);
1226 // Now process the remaining operands.
1227 for (unsigned i
= 1; i
< NumOps
; ++i
) {
1228 SDValue Op
= N
->getOperand(i
);
1232 EVT InVT
= Op
.getValueType();
1233 if (InVT
.isVector()) {
1234 // If the input also splits, handle it directly for a
1235 // compile time speedup. Otherwise split it by hand.
1236 if (getTypeAction(InVT
) == TargetLowering::TypeSplitVector
)
1237 GetSplitVector(Op
, OpLo
, OpHi
);
1239 std::tie(OpLo
, OpHi
) = DAG
.SplitVectorOperand(N
, i
);
1242 OpsLo
.push_back(OpLo
);
1243 OpsHi
.push_back(OpHi
);
1246 EVT LoValueVTs
[] = {LoVT
, MVT::Other
};
1247 EVT HiValueVTs
[] = {HiVT
, MVT::Other
};
1248 Lo
= DAG
.getNode(N
->getOpcode(), dl
, LoValueVTs
, OpsLo
);
1249 Hi
= DAG
.getNode(N
->getOpcode(), dl
, HiValueVTs
, OpsHi
);
1251 // Build a factor node to remember that this Op is independent of the
1253 Chain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
,
1254 Lo
.getValue(1), Hi
.getValue(1));
1256 // Legalize the chain result - switch anything that used the old chain to
1258 ReplaceValueWith(SDValue(N
, 1), Chain
);
1261 void DAGTypeLegalizer::SplitVecRes_OverflowOp(SDNode
*N
, unsigned ResNo
,
1262 SDValue
&Lo
, SDValue
&Hi
) {
1264 EVT ResVT
= N
->getValueType(0);
1265 EVT OvVT
= N
->getValueType(1);
1266 EVT LoResVT
, HiResVT
, LoOvVT
, HiOvVT
;
1267 std::tie(LoResVT
, HiResVT
) = DAG
.GetSplitDestVTs(ResVT
);
1268 std::tie(LoOvVT
, HiOvVT
) = DAG
.GetSplitDestVTs(OvVT
);
1270 SDValue LoLHS
, HiLHS
, LoRHS
, HiRHS
;
1271 if (getTypeAction(ResVT
) == TargetLowering::TypeSplitVector
) {
1272 GetSplitVector(N
->getOperand(0), LoLHS
, HiLHS
);
1273 GetSplitVector(N
->getOperand(1), LoRHS
, HiRHS
);
1275 std::tie(LoLHS
, HiLHS
) = DAG
.SplitVectorOperand(N
, 0);
1276 std::tie(LoRHS
, HiRHS
) = DAG
.SplitVectorOperand(N
, 1);
1279 unsigned Opcode
= N
->getOpcode();
1280 SDVTList LoVTs
= DAG
.getVTList(LoResVT
, LoOvVT
);
1281 SDVTList HiVTs
= DAG
.getVTList(HiResVT
, HiOvVT
);
1282 SDNode
*LoNode
= DAG
.getNode(Opcode
, dl
, LoVTs
, LoLHS
, LoRHS
).getNode();
1283 SDNode
*HiNode
= DAG
.getNode(Opcode
, dl
, HiVTs
, HiLHS
, HiRHS
).getNode();
1285 Lo
= SDValue(LoNode
, ResNo
);
1286 Hi
= SDValue(HiNode
, ResNo
);
1288 // Replace the other vector result not being explicitly split here.
1289 unsigned OtherNo
= 1 - ResNo
;
1290 EVT OtherVT
= N
->getValueType(OtherNo
);
1291 if (getTypeAction(OtherVT
) == TargetLowering::TypeSplitVector
) {
1292 SetSplitVector(SDValue(N
, OtherNo
),
1293 SDValue(LoNode
, OtherNo
), SDValue(HiNode
, OtherNo
));
1295 SDValue OtherVal
= DAG
.getNode(
1296 ISD::CONCAT_VECTORS
, dl
, OtherVT
,
1297 SDValue(LoNode
, OtherNo
), SDValue(HiNode
, OtherNo
));
1298 ReplaceValueWith(SDValue(N
, OtherNo
), OtherVal
);
1302 void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode
*N
, SDValue
&Lo
,
1304 SDValue Vec
= N
->getOperand(0);
1305 SDValue Elt
= N
->getOperand(1);
1306 SDValue Idx
= N
->getOperand(2);
1308 GetSplitVector(Vec
, Lo
, Hi
);
1310 if (ConstantSDNode
*CIdx
= dyn_cast
<ConstantSDNode
>(Idx
)) {
1311 unsigned IdxVal
= CIdx
->getZExtValue();
1312 unsigned LoNumElts
= Lo
.getValueType().getVectorNumElements();
1313 if (IdxVal
< LoNumElts
)
1314 Lo
= DAG
.getNode(ISD::INSERT_VECTOR_ELT
, dl
,
1315 Lo
.getValueType(), Lo
, Elt
, Idx
);
1318 DAG
.getNode(ISD::INSERT_VECTOR_ELT
, dl
, Hi
.getValueType(), Hi
, Elt
,
1319 DAG
.getConstant(IdxVal
- LoNumElts
, dl
,
1320 TLI
.getVectorIdxTy(DAG
.getDataLayout())));
1324 // See if the target wants to custom expand this node.
1325 if (CustomLowerNode(N
, N
->getValueType(0), true))
1328 // Make the vector elements byte-addressable if they aren't already.
1329 EVT VecVT
= Vec
.getValueType();
1330 EVT EltVT
= VecVT
.getVectorElementType();
1331 if (VecVT
.getScalarSizeInBits() < 8) {
1333 VecVT
= EVT::getVectorVT(*DAG
.getContext(), EltVT
,
1334 VecVT
.getVectorNumElements());
1335 Vec
= DAG
.getNode(ISD::ANY_EXTEND
, dl
, VecVT
, Vec
);
1336 // Extend the element type to match if needed.
1337 if (EltVT
.bitsGT(Elt
.getValueType()))
1338 Elt
= DAG
.getNode(ISD::ANY_EXTEND
, dl
, EltVT
, Elt
);
1341 // Spill the vector to the stack.
1342 SDValue StackPtr
= DAG
.CreateStackTemporary(VecVT
);
1343 auto &MF
= DAG
.getMachineFunction();
1344 auto FrameIndex
= cast
<FrameIndexSDNode
>(StackPtr
.getNode())->getIndex();
1345 auto PtrInfo
= MachinePointerInfo::getFixedStack(MF
, FrameIndex
);
1346 SDValue Store
= DAG
.getStore(DAG
.getEntryNode(), dl
, Vec
, StackPtr
, PtrInfo
);
1348 // Store the new element. This may be larger than the vector element type,
1349 // so use a truncating store.
1350 SDValue EltPtr
= TLI
.getVectorElementPointer(DAG
, StackPtr
, VecVT
, Idx
);
1351 Type
*VecType
= VecVT
.getTypeForEVT(*DAG
.getContext());
1352 unsigned Alignment
= DAG
.getDataLayout().getPrefTypeAlignment(VecType
);
1353 Store
= DAG
.getTruncStore(Store
, dl
, Elt
, EltPtr
,
1354 MachinePointerInfo::getUnknownStack(MF
), EltVT
);
1357 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(VecVT
);
1359 // Load the Lo part from the stack slot.
1360 Lo
= DAG
.getLoad(LoVT
, dl
, Store
, StackPtr
, PtrInfo
);
1362 // Increment the pointer to the other part.
1363 unsigned IncrementSize
= LoVT
.getSizeInBits() / 8;
1364 StackPtr
= DAG
.getNode(ISD::ADD
, dl
, StackPtr
.getValueType(), StackPtr
,
1365 DAG
.getConstant(IncrementSize
, dl
,
1366 StackPtr
.getValueType()));
1368 // Load the Hi part from the stack slot.
1369 Hi
= DAG
.getLoad(HiVT
, dl
, Store
, StackPtr
,
1370 PtrInfo
.getWithOffset(IncrementSize
),
1371 MinAlign(Alignment
, IncrementSize
));
1373 // If we adjusted the original type, we need to truncate the results.
1374 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1375 if (LoVT
!= Lo
.getValueType())
1376 Lo
= DAG
.getNode(ISD::TRUNCATE
, dl
, LoVT
, Lo
);
1377 if (HiVT
!= Hi
.getValueType())
1378 Hi
= DAG
.getNode(ISD::TRUNCATE
, dl
, HiVT
, Hi
);
1381 void DAGTypeLegalizer::SplitVecRes_SCALAR_TO_VECTOR(SDNode
*N
, SDValue
&Lo
,
1385 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1386 Lo
= DAG
.getNode(ISD::SCALAR_TO_VECTOR
, dl
, LoVT
, N
->getOperand(0));
1387 Hi
= DAG
.getUNDEF(HiVT
);
1390 void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode
*LD
, SDValue
&Lo
,
1392 assert(ISD::isUNINDEXEDLoad(LD
) && "Indexed load during type legalization!");
1395 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(LD
->getValueType(0));
1397 ISD::LoadExtType ExtType
= LD
->getExtensionType();
1398 SDValue Ch
= LD
->getChain();
1399 SDValue Ptr
= LD
->getBasePtr();
1400 SDValue Offset
= DAG
.getUNDEF(Ptr
.getValueType());
1401 EVT MemoryVT
= LD
->getMemoryVT();
1402 unsigned Alignment
= LD
->getOriginalAlignment();
1403 MachineMemOperand::Flags MMOFlags
= LD
->getMemOperand()->getFlags();
1404 AAMDNodes AAInfo
= LD
->getAAInfo();
1406 EVT LoMemVT
, HiMemVT
;
1407 std::tie(LoMemVT
, HiMemVT
) = DAG
.GetSplitDestVTs(MemoryVT
);
1409 Lo
= DAG
.getLoad(ISD::UNINDEXED
, ExtType
, LoVT
, dl
, Ch
, Ptr
, Offset
,
1410 LD
->getPointerInfo(), LoMemVT
, Alignment
, MMOFlags
, AAInfo
);
1412 unsigned IncrementSize
= LoMemVT
.getSizeInBits()/8;
1413 Ptr
= DAG
.getObjectPtrOffset(dl
, Ptr
, IncrementSize
);
1414 Hi
= DAG
.getLoad(ISD::UNINDEXED
, ExtType
, HiVT
, dl
, Ch
, Ptr
, Offset
,
1415 LD
->getPointerInfo().getWithOffset(IncrementSize
), HiMemVT
,
1416 Alignment
, MMOFlags
, AAInfo
);
1418 // Build a factor node to remember that this load is independent of the
1420 Ch
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, Lo
.getValue(1),
1423 // Legalize the chain result - switch anything that used the old chain to
1425 ReplaceValueWith(SDValue(LD
, 1), Ch
);
1428 void DAGTypeLegalizer::SplitVecRes_MLOAD(MaskedLoadSDNode
*MLD
,
1429 SDValue
&Lo
, SDValue
&Hi
) {
1432 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(MLD
->getValueType(0));
1434 SDValue Ch
= MLD
->getChain();
1435 SDValue Ptr
= MLD
->getBasePtr();
1436 SDValue Mask
= MLD
->getMask();
1437 SDValue PassThru
= MLD
->getPassThru();
1438 unsigned Alignment
= MLD
->getOriginalAlignment();
1439 ISD::LoadExtType ExtType
= MLD
->getExtensionType();
1441 // if Alignment is equal to the vector size,
1442 // take the half of it for the second part
1443 unsigned SecondHalfAlignment
=
1444 (Alignment
== MLD
->getValueType(0).getSizeInBits()/8) ?
1445 Alignment
/2 : Alignment
;
1447 // Split Mask operand
1448 SDValue MaskLo
, MaskHi
;
1449 if (getTypeAction(Mask
.getValueType()) == TargetLowering::TypeSplitVector
)
1450 GetSplitVector(Mask
, MaskLo
, MaskHi
);
1452 std::tie(MaskLo
, MaskHi
) = DAG
.SplitVector(Mask
, dl
);
1454 EVT MemoryVT
= MLD
->getMemoryVT();
1455 EVT LoMemVT
, HiMemVT
;
1456 std::tie(LoMemVT
, HiMemVT
) = DAG
.GetSplitDestVTs(MemoryVT
);
1458 SDValue PassThruLo
, PassThruHi
;
1459 if (getTypeAction(PassThru
.getValueType()) == TargetLowering::TypeSplitVector
)
1460 GetSplitVector(PassThru
, PassThruLo
, PassThruHi
);
1462 std::tie(PassThruLo
, PassThruHi
) = DAG
.SplitVector(PassThru
, dl
);
1464 MachineMemOperand
*MMO
= DAG
.getMachineFunction().
1465 getMachineMemOperand(MLD
->getPointerInfo(),
1466 MachineMemOperand::MOLoad
, LoMemVT
.getStoreSize(),
1467 Alignment
, MLD
->getAAInfo(), MLD
->getRanges());
1469 Lo
= DAG
.getMaskedLoad(LoVT
, dl
, Ch
, Ptr
, MaskLo
, PassThruLo
, LoMemVT
, MMO
,
1470 ExtType
, MLD
->isExpandingLoad());
1472 Ptr
= TLI
.IncrementMemoryAddress(Ptr
, MaskLo
, dl
, LoMemVT
, DAG
,
1473 MLD
->isExpandingLoad());
1474 unsigned HiOffset
= LoMemVT
.getStoreSize();
1476 MMO
= DAG
.getMachineFunction().getMachineMemOperand(
1477 MLD
->getPointerInfo().getWithOffset(HiOffset
), MachineMemOperand::MOLoad
,
1478 HiMemVT
.getStoreSize(), SecondHalfAlignment
, MLD
->getAAInfo(),
1481 Hi
= DAG
.getMaskedLoad(HiVT
, dl
, Ch
, Ptr
, MaskHi
, PassThruHi
, HiMemVT
, MMO
,
1482 ExtType
, MLD
->isExpandingLoad());
1484 // Build a factor node to remember that this load is independent of the
1486 Ch
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, Lo
.getValue(1),
1489 // Legalize the chain result - switch anything that used the old chain to
1491 ReplaceValueWith(SDValue(MLD
, 1), Ch
);
1495 void DAGTypeLegalizer::SplitVecRes_MGATHER(MaskedGatherSDNode
*MGT
,
1496 SDValue
&Lo
, SDValue
&Hi
) {
1499 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(MGT
->getValueType(0));
1501 SDValue Ch
= MGT
->getChain();
1502 SDValue Ptr
= MGT
->getBasePtr();
1503 SDValue Mask
= MGT
->getMask();
1504 SDValue PassThru
= MGT
->getPassThru();
1505 SDValue Index
= MGT
->getIndex();
1506 SDValue Scale
= MGT
->getScale();
1507 unsigned Alignment
= MGT
->getOriginalAlignment();
1509 // Split Mask operand
1510 SDValue MaskLo
, MaskHi
;
1511 if (getTypeAction(Mask
.getValueType()) == TargetLowering::TypeSplitVector
)
1512 GetSplitVector(Mask
, MaskLo
, MaskHi
);
1514 std::tie(MaskLo
, MaskHi
) = DAG
.SplitVector(Mask
, dl
);
1516 EVT MemoryVT
= MGT
->getMemoryVT();
1517 EVT LoMemVT
, HiMemVT
;
1519 std::tie(LoMemVT
, HiMemVT
) = DAG
.GetSplitDestVTs(MemoryVT
);
1521 SDValue PassThruLo
, PassThruHi
;
1522 if (getTypeAction(PassThru
.getValueType()) == TargetLowering::TypeSplitVector
)
1523 GetSplitVector(PassThru
, PassThruLo
, PassThruHi
);
1525 std::tie(PassThruLo
, PassThruHi
) = DAG
.SplitVector(PassThru
, dl
);
1527 SDValue IndexHi
, IndexLo
;
1528 if (getTypeAction(Index
.getValueType()) == TargetLowering::TypeSplitVector
)
1529 GetSplitVector(Index
, IndexLo
, IndexHi
);
1531 std::tie(IndexLo
, IndexHi
) = DAG
.SplitVector(Index
, dl
);
1533 MachineMemOperand
*MMO
= DAG
.getMachineFunction().
1534 getMachineMemOperand(MGT
->getPointerInfo(),
1535 MachineMemOperand::MOLoad
, LoMemVT
.getStoreSize(),
1536 Alignment
, MGT
->getAAInfo(), MGT
->getRanges());
1538 SDValue OpsLo
[] = {Ch
, PassThruLo
, MaskLo
, Ptr
, IndexLo
, Scale
};
1539 Lo
= DAG
.getMaskedGather(DAG
.getVTList(LoVT
, MVT::Other
), LoVT
, dl
, OpsLo
,
1542 SDValue OpsHi
[] = {Ch
, PassThruHi
, MaskHi
, Ptr
, IndexHi
, Scale
};
1543 Hi
= DAG
.getMaskedGather(DAG
.getVTList(HiVT
, MVT::Other
), HiVT
, dl
, OpsHi
,
1546 // Build a factor node to remember that this load is independent of the
1548 Ch
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, Lo
.getValue(1),
1551 // Legalize the chain result - switch anything that used the old chain to
1553 ReplaceValueWith(SDValue(MGT
, 1), Ch
);
1557 void DAGTypeLegalizer::SplitVecRes_SETCC(SDNode
*N
, SDValue
&Lo
, SDValue
&Hi
) {
1558 assert(N
->getValueType(0).isVector() &&
1559 N
->getOperand(0).getValueType().isVector() &&
1560 "Operand types must be vectors");
1564 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1566 // If the input also splits, handle it directly. Otherwise split it by hand.
1567 SDValue LL
, LH
, RL
, RH
;
1568 if (getTypeAction(N
->getOperand(0).getValueType()) ==
1569 TargetLowering::TypeSplitVector
)
1570 GetSplitVector(N
->getOperand(0), LL
, LH
);
1572 std::tie(LL
, LH
) = DAG
.SplitVectorOperand(N
, 0);
1574 if (getTypeAction(N
->getOperand(1).getValueType()) ==
1575 TargetLowering::TypeSplitVector
)
1576 GetSplitVector(N
->getOperand(1), RL
, RH
);
1578 std::tie(RL
, RH
) = DAG
.SplitVectorOperand(N
, 1);
1580 Lo
= DAG
.getNode(N
->getOpcode(), DL
, LoVT
, LL
, RL
, N
->getOperand(2));
1581 Hi
= DAG
.getNode(N
->getOpcode(), DL
, HiVT
, LH
, RH
, N
->getOperand(2));
1584 void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode
*N
, SDValue
&Lo
,
1586 // Get the dest types - they may not match the input types, e.g. int_to_fp.
1589 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(N
->getValueType(0));
1591 // If the input also splits, handle it directly for a compile time speedup.
1592 // Otherwise split it by hand.
1593 EVT InVT
= N
->getOperand(0).getValueType();
1594 if (getTypeAction(InVT
) == TargetLowering::TypeSplitVector
)
1595 GetSplitVector(N
->getOperand(0), Lo
, Hi
);
1597 std::tie(Lo
, Hi
) = DAG
.SplitVectorOperand(N
, 0);
1599 if (N
->getOpcode() == ISD::FP_ROUND
) {
1600 Lo
= DAG
.getNode(N
->getOpcode(), dl
, LoVT
, Lo
, N
->getOperand(1));
1601 Hi
= DAG
.getNode(N
->getOpcode(), dl
, HiVT
, Hi
, N
->getOperand(1));
1603 Lo
= DAG
.getNode(N
->getOpcode(), dl
, LoVT
, Lo
);
1604 Hi
= DAG
.getNode(N
->getOpcode(), dl
, HiVT
, Hi
);
1608 void DAGTypeLegalizer::SplitVecRes_ExtendOp(SDNode
*N
, SDValue
&Lo
,
1611 EVT SrcVT
= N
->getOperand(0).getValueType();
1612 EVT DestVT
= N
->getValueType(0);
1614 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(DestVT
);
1616 // We can do better than a generic split operation if the extend is doing
1617 // more than just doubling the width of the elements and the following are
1619 // - The number of vector elements is even,
1620 // - the source type is legal,
1621 // - the type of a split source is illegal,
1622 // - the type of an extended (by doubling element size) source is legal, and
1623 // - the type of that extended source when split is legal.
1625 // This won't necessarily completely legalize the operation, but it will
1626 // more effectively move in the right direction and prevent falling down
1627 // to scalarization in many cases due to the input vector being split too
1629 unsigned NumElements
= SrcVT
.getVectorNumElements();
1630 if ((NumElements
& 1) == 0 &&
1631 SrcVT
.getSizeInBits() * 2 < DestVT
.getSizeInBits()) {
1632 LLVMContext
&Ctx
= *DAG
.getContext();
1633 EVT NewSrcVT
= SrcVT
.widenIntegerVectorElementType(Ctx
);
1634 EVT SplitSrcVT
= SrcVT
.getHalfNumVectorElementsVT(Ctx
);
1636 EVT SplitLoVT
, SplitHiVT
;
1637 std::tie(SplitLoVT
, SplitHiVT
) = DAG
.GetSplitDestVTs(NewSrcVT
);
1638 if (TLI
.isTypeLegal(SrcVT
) && !TLI
.isTypeLegal(SplitSrcVT
) &&
1639 TLI
.isTypeLegal(NewSrcVT
) && TLI
.isTypeLegal(SplitLoVT
)) {
1640 LLVM_DEBUG(dbgs() << "Split vector extend via incremental extend:";
1641 N
->dump(&DAG
); dbgs() << "\n");
1642 // Extend the source vector by one step.
1644 DAG
.getNode(N
->getOpcode(), dl
, NewSrcVT
, N
->getOperand(0));
1645 // Get the low and high halves of the new, extended one step, vector.
1646 std::tie(Lo
, Hi
) = DAG
.SplitVector(NewSrc
, dl
);
1647 // Extend those vector halves the rest of the way.
1648 Lo
= DAG
.getNode(N
->getOpcode(), dl
, LoVT
, Lo
);
1649 Hi
= DAG
.getNode(N
->getOpcode(), dl
, HiVT
, Hi
);
1653 // Fall back to the generic unary operator splitting otherwise.
1654 SplitVecRes_UnaryOp(N
, Lo
, Hi
);
1657 void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode
*N
,
1658 SDValue
&Lo
, SDValue
&Hi
) {
1659 // The low and high parts of the original input give four input vectors.
1662 GetSplitVector(N
->getOperand(0), Inputs
[0], Inputs
[1]);
1663 GetSplitVector(N
->getOperand(1), Inputs
[2], Inputs
[3]);
1664 EVT NewVT
= Inputs
[0].getValueType();
1665 unsigned NewElts
= NewVT
.getVectorNumElements();
1667 // If Lo or Hi uses elements from at most two of the four input vectors, then
1668 // express it as a vector shuffle of those two inputs. Otherwise extract the
1669 // input elements by hand and construct the Lo/Hi output using a BUILD_VECTOR.
1670 SmallVector
<int, 16> Ops
;
1671 for (unsigned High
= 0; High
< 2; ++High
) {
1672 SDValue
&Output
= High
? Hi
: Lo
;
1674 // Build a shuffle mask for the output, discovering on the fly which
1675 // input vectors to use as shuffle operands (recorded in InputUsed).
1676 // If building a suitable shuffle vector proves too hard, then bail
1677 // out with useBuildVector set.
1678 unsigned InputUsed
[2] = { -1U, -1U }; // Not yet discovered.
1679 unsigned FirstMaskIdx
= High
* NewElts
;
1680 bool useBuildVector
= false;
1681 for (unsigned MaskOffset
= 0; MaskOffset
< NewElts
; ++MaskOffset
) {
1682 // The mask element. This indexes into the input.
1683 int Idx
= N
->getMaskElt(FirstMaskIdx
+ MaskOffset
);
1685 // The input vector this mask element indexes into.
1686 unsigned Input
= (unsigned)Idx
/ NewElts
;
1688 if (Input
>= array_lengthof(Inputs
)) {
1689 // The mask element does not index into any input vector.
1694 // Turn the index into an offset from the start of the input vector.
1695 Idx
-= Input
* NewElts
;
1697 // Find or create a shuffle vector operand to hold this input.
1699 for (OpNo
= 0; OpNo
< array_lengthof(InputUsed
); ++OpNo
) {
1700 if (InputUsed
[OpNo
] == Input
) {
1701 // This input vector is already an operand.
1703 } else if (InputUsed
[OpNo
] == -1U) {
1704 // Create a new operand for this input vector.
1705 InputUsed
[OpNo
] = Input
;
1710 if (OpNo
>= array_lengthof(InputUsed
)) {
1711 // More than two input vectors used! Give up on trying to create a
1712 // shuffle vector. Insert all elements into a BUILD_VECTOR instead.
1713 useBuildVector
= true;
1717 // Add the mask index for the new shuffle vector.
1718 Ops
.push_back(Idx
+ OpNo
* NewElts
);
1721 if (useBuildVector
) {
1722 EVT EltVT
= NewVT
.getVectorElementType();
1723 SmallVector
<SDValue
, 16> SVOps
;
1725 // Extract the input elements by hand.
1726 for (unsigned MaskOffset
= 0; MaskOffset
< NewElts
; ++MaskOffset
) {
1727 // The mask element. This indexes into the input.
1728 int Idx
= N
->getMaskElt(FirstMaskIdx
+ MaskOffset
);
1730 // The input vector this mask element indexes into.
1731 unsigned Input
= (unsigned)Idx
/ NewElts
;
1733 if (Input
>= array_lengthof(Inputs
)) {
1734 // The mask element is "undef" or indexes off the end of the input.
1735 SVOps
.push_back(DAG
.getUNDEF(EltVT
));
1739 // Turn the index into an offset from the start of the input vector.
1740 Idx
-= Input
* NewElts
;
1742 // Extract the vector element by hand.
1743 SVOps
.push_back(DAG
.getNode(
1744 ISD::EXTRACT_VECTOR_ELT
, dl
, EltVT
, Inputs
[Input
],
1745 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout()))));
1748 // Construct the Lo/Hi output using a BUILD_VECTOR.
1749 Output
= DAG
.getBuildVector(NewVT
, dl
, SVOps
);
1750 } else if (InputUsed
[0] == -1U) {
1751 // No input vectors were used! The result is undefined.
1752 Output
= DAG
.getUNDEF(NewVT
);
1754 SDValue Op0
= Inputs
[InputUsed
[0]];
1755 // If only one input was used, use an undefined vector for the other.
1756 SDValue Op1
= InputUsed
[1] == -1U ?
1757 DAG
.getUNDEF(NewVT
) : Inputs
[InputUsed
[1]];
1758 // At least one input vector was used. Create a new shuffle vector.
1759 Output
= DAG
.getVectorShuffle(NewVT
, dl
, Op0
, Op1
, Ops
);
1767 //===----------------------------------------------------------------------===//
1768 // Operand Vector Splitting
1769 //===----------------------------------------------------------------------===//
1771 /// This method is called when the specified operand of the specified node is
1772 /// found to need vector splitting. At this point, all of the result types of
1773 /// the node are known to be legal, but other operands of the node may need
1774 /// legalization as well as the specified one.
1775 bool DAGTypeLegalizer::SplitVectorOperand(SDNode
*N
, unsigned OpNo
) {
1776 LLVM_DEBUG(dbgs() << "Split node operand: "; N
->dump(&DAG
); dbgs() << "\n");
1777 SDValue Res
= SDValue();
1779 // See if the target wants to custom split this node.
1780 if (CustomLowerNode(N
, N
->getOperand(OpNo
).getValueType(), false))
1783 if (!Res
.getNode()) {
1784 switch (N
->getOpcode()) {
1787 dbgs() << "SplitVectorOperand Op #" << OpNo
<< ": ";
1791 report_fatal_error("Do not know how to split this operator's "
1794 case ISD::SETCC
: Res
= SplitVecOp_VSETCC(N
); break;
1795 case ISD::BITCAST
: Res
= SplitVecOp_BITCAST(N
); break;
1796 case ISD::EXTRACT_SUBVECTOR
: Res
= SplitVecOp_EXTRACT_SUBVECTOR(N
); break;
1797 case ISD::EXTRACT_VECTOR_ELT
:Res
= SplitVecOp_EXTRACT_VECTOR_ELT(N
); break;
1798 case ISD::CONCAT_VECTORS
: Res
= SplitVecOp_CONCAT_VECTORS(N
); break;
1800 Res
= SplitVecOp_TruncateHelper(N
);
1802 case ISD::FP_ROUND
: Res
= SplitVecOp_FP_ROUND(N
); break;
1803 case ISD::FCOPYSIGN
: Res
= SplitVecOp_FCOPYSIGN(N
); break;
1805 Res
= SplitVecOp_STORE(cast
<StoreSDNode
>(N
), OpNo
);
1808 Res
= SplitVecOp_MSTORE(cast
<MaskedStoreSDNode
>(N
), OpNo
);
1811 Res
= SplitVecOp_MSCATTER(cast
<MaskedScatterSDNode
>(N
), OpNo
);
1814 Res
= SplitVecOp_MGATHER(cast
<MaskedGatherSDNode
>(N
), OpNo
);
1817 Res
= SplitVecOp_VSELECT(N
, OpNo
);
1819 case ISD::SINT_TO_FP
:
1820 case ISD::UINT_TO_FP
:
1821 if (N
->getValueType(0).bitsLT(N
->getOperand(0).getValueType()))
1822 Res
= SplitVecOp_TruncateHelper(N
);
1824 Res
= SplitVecOp_UnaryOp(N
);
1826 case ISD::FP_TO_SINT
:
1827 case ISD::FP_TO_UINT
:
1831 case ISD::FP_EXTEND
:
1832 case ISD::SIGN_EXTEND
:
1833 case ISD::ZERO_EXTEND
:
1834 case ISD::ANY_EXTEND
:
1836 case ISD::FCANONICALIZE
:
1837 Res
= SplitVecOp_UnaryOp(N
);
1840 case ISD::ANY_EXTEND_VECTOR_INREG
:
1841 case ISD::SIGN_EXTEND_VECTOR_INREG
:
1842 case ISD::ZERO_EXTEND_VECTOR_INREG
:
1843 Res
= SplitVecOp_ExtVecInRegOp(N
);
1846 case ISD::VECREDUCE_FADD
:
1847 case ISD::VECREDUCE_FMUL
:
1848 case ISD::VECREDUCE_ADD
:
1849 case ISD::VECREDUCE_MUL
:
1850 case ISD::VECREDUCE_AND
:
1851 case ISD::VECREDUCE_OR
:
1852 case ISD::VECREDUCE_XOR
:
1853 case ISD::VECREDUCE_SMAX
:
1854 case ISD::VECREDUCE_SMIN
:
1855 case ISD::VECREDUCE_UMAX
:
1856 case ISD::VECREDUCE_UMIN
:
1857 case ISD::VECREDUCE_FMAX
:
1858 case ISD::VECREDUCE_FMIN
:
1859 Res
= SplitVecOp_VECREDUCE(N
, OpNo
);
1864 // If the result is null, the sub-method took care of registering results etc.
1865 if (!Res
.getNode()) return false;
1867 // If the result is N, the sub-method updated N in place. Tell the legalizer
1869 if (Res
.getNode() == N
)
1872 assert(Res
.getValueType() == N
->getValueType(0) && N
->getNumValues() == 1 &&
1873 "Invalid operand expansion");
1875 ReplaceValueWith(SDValue(N
, 0), Res
);
1879 SDValue
DAGTypeLegalizer::SplitVecOp_VSELECT(SDNode
*N
, unsigned OpNo
) {
1880 // The only possibility for an illegal operand is the mask, since result type
1881 // legalization would have handled this node already otherwise.
1882 assert(OpNo
== 0 && "Illegal operand must be mask");
1884 SDValue Mask
= N
->getOperand(0);
1885 SDValue Src0
= N
->getOperand(1);
1886 SDValue Src1
= N
->getOperand(2);
1887 EVT Src0VT
= Src0
.getValueType();
1889 assert(Mask
.getValueType().isVector() && "VSELECT without a vector mask?");
1892 GetSplitVector(N
->getOperand(0), Lo
, Hi
);
1893 assert(Lo
.getValueType() == Hi
.getValueType() &&
1894 "Lo and Hi have differing types");
1897 std::tie(LoOpVT
, HiOpVT
) = DAG
.GetSplitDestVTs(Src0VT
);
1898 assert(LoOpVT
== HiOpVT
&& "Asymmetric vector split?");
1900 SDValue LoOp0
, HiOp0
, LoOp1
, HiOp1
, LoMask
, HiMask
;
1901 std::tie(LoOp0
, HiOp0
) = DAG
.SplitVector(Src0
, DL
);
1902 std::tie(LoOp1
, HiOp1
) = DAG
.SplitVector(Src1
, DL
);
1903 std::tie(LoMask
, HiMask
) = DAG
.SplitVector(Mask
, DL
);
1906 DAG
.getNode(ISD::VSELECT
, DL
, LoOpVT
, LoMask
, LoOp0
, LoOp1
);
1908 DAG
.getNode(ISD::VSELECT
, DL
, HiOpVT
, HiMask
, HiOp0
, HiOp1
);
1910 return DAG
.getNode(ISD::CONCAT_VECTORS
, DL
, Src0VT
, LoSelect
, HiSelect
);
1913 SDValue
DAGTypeLegalizer::SplitVecOp_VECREDUCE(SDNode
*N
, unsigned OpNo
) {
1914 EVT ResVT
= N
->getValueType(0);
1918 SDValue VecOp
= N
->getOperand(OpNo
);
1919 EVT VecVT
= VecOp
.getValueType();
1920 assert(VecVT
.isVector() && "Can only split reduce vector operand");
1921 GetSplitVector(VecOp
, Lo
, Hi
);
1923 std::tie(LoOpVT
, HiOpVT
) = DAG
.GetSplitDestVTs(VecVT
);
1925 bool NoNaN
= N
->getFlags().hasNoNaNs();
1926 unsigned CombineOpc
= 0;
1927 switch (N
->getOpcode()) {
1928 case ISD::VECREDUCE_FADD
: CombineOpc
= ISD::FADD
; break;
1929 case ISD::VECREDUCE_FMUL
: CombineOpc
= ISD::FMUL
; break;
1930 case ISD::VECREDUCE_ADD
: CombineOpc
= ISD::ADD
; break;
1931 case ISD::VECREDUCE_MUL
: CombineOpc
= ISD::MUL
; break;
1932 case ISD::VECREDUCE_AND
: CombineOpc
= ISD::AND
; break;
1933 case ISD::VECREDUCE_OR
: CombineOpc
= ISD::OR
; break;
1934 case ISD::VECREDUCE_XOR
: CombineOpc
= ISD::XOR
; break;
1935 case ISD::VECREDUCE_SMAX
: CombineOpc
= ISD::SMAX
; break;
1936 case ISD::VECREDUCE_SMIN
: CombineOpc
= ISD::SMIN
; break;
1937 case ISD::VECREDUCE_UMAX
: CombineOpc
= ISD::UMAX
; break;
1938 case ISD::VECREDUCE_UMIN
: CombineOpc
= ISD::UMIN
; break;
1939 case ISD::VECREDUCE_FMAX
:
1940 CombineOpc
= NoNaN
? ISD::FMAXNUM
: ISD::FMAXIMUM
;
1942 case ISD::VECREDUCE_FMIN
:
1943 CombineOpc
= NoNaN
? ISD::FMINNUM
: ISD::FMINIMUM
;
1946 llvm_unreachable("Unexpected reduce ISD node");
1949 // Use the appropriate scalar instruction on the split subvectors before
1950 // reducing the now partially reduced smaller vector.
1951 SDValue Partial
= DAG
.getNode(CombineOpc
, dl
, LoOpVT
, Lo
, Hi
, N
->getFlags());
1952 return DAG
.getNode(N
->getOpcode(), dl
, ResVT
, Partial
, N
->getFlags());
1955 SDValue
DAGTypeLegalizer::SplitVecOp_UnaryOp(SDNode
*N
) {
1956 // The result has a legal vector type, but the input needs splitting.
1957 EVT ResVT
= N
->getValueType(0);
1960 GetSplitVector(N
->getOperand(0), Lo
, Hi
);
1961 EVT InVT
= Lo
.getValueType();
1963 EVT OutVT
= EVT::getVectorVT(*DAG
.getContext(), ResVT
.getVectorElementType(),
1964 InVT
.getVectorNumElements());
1966 Lo
= DAG
.getNode(N
->getOpcode(), dl
, OutVT
, Lo
);
1967 Hi
= DAG
.getNode(N
->getOpcode(), dl
, OutVT
, Hi
);
1969 return DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, ResVT
, Lo
, Hi
);
1972 SDValue
DAGTypeLegalizer::SplitVecOp_BITCAST(SDNode
*N
) {
1973 // For example, i64 = BITCAST v4i16 on alpha. Typically the vector will
1974 // end up being split all the way down to individual components. Convert the
1975 // split pieces into integers and reassemble.
1977 GetSplitVector(N
->getOperand(0), Lo
, Hi
);
1978 Lo
= BitConvertToInteger(Lo
);
1979 Hi
= BitConvertToInteger(Hi
);
1981 if (DAG
.getDataLayout().isBigEndian())
1984 return DAG
.getNode(ISD::BITCAST
, SDLoc(N
), N
->getValueType(0),
1985 JoinIntegers(Lo
, Hi
));
1988 SDValue
DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode
*N
) {
1989 // We know that the extracted result type is legal.
1990 EVT SubVT
= N
->getValueType(0);
1991 SDValue Idx
= N
->getOperand(1);
1994 GetSplitVector(N
->getOperand(0), Lo
, Hi
);
1996 uint64_t LoElts
= Lo
.getValueType().getVectorNumElements();
1997 uint64_t IdxVal
= cast
<ConstantSDNode
>(Idx
)->getZExtValue();
1999 if (IdxVal
< LoElts
) {
2000 assert(IdxVal
+ SubVT
.getVectorNumElements() <= LoElts
&&
2001 "Extracted subvector crosses vector split!");
2002 return DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, dl
, SubVT
, Lo
, Idx
);
2004 return DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, dl
, SubVT
, Hi
,
2005 DAG
.getConstant(IdxVal
- LoElts
, dl
,
2006 Idx
.getValueType()));
2010 SDValue
DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode
*N
) {
2011 SDValue Vec
= N
->getOperand(0);
2012 SDValue Idx
= N
->getOperand(1);
2013 EVT VecVT
= Vec
.getValueType();
2015 if (isa
<ConstantSDNode
>(Idx
)) {
2016 uint64_t IdxVal
= cast
<ConstantSDNode
>(Idx
)->getZExtValue();
2019 GetSplitVector(Vec
, Lo
, Hi
);
2021 uint64_t LoElts
= Lo
.getValueType().getVectorNumElements();
2023 if (IdxVal
< LoElts
)
2024 return SDValue(DAG
.UpdateNodeOperands(N
, Lo
, Idx
), 0);
2025 return SDValue(DAG
.UpdateNodeOperands(N
, Hi
,
2026 DAG
.getConstant(IdxVal
- LoElts
, SDLoc(N
),
2027 Idx
.getValueType())), 0);
2030 // See if the target wants to custom expand this node.
2031 if (CustomLowerNode(N
, N
->getValueType(0), true))
2034 // Make the vector elements byte-addressable if they aren't already.
2036 EVT EltVT
= VecVT
.getVectorElementType();
2037 if (VecVT
.getScalarSizeInBits() < 8) {
2039 VecVT
= EVT::getVectorVT(*DAG
.getContext(), EltVT
,
2040 VecVT
.getVectorNumElements());
2041 Vec
= DAG
.getNode(ISD::ANY_EXTEND
, dl
, VecVT
, Vec
);
2044 // Store the vector to the stack.
2045 SDValue StackPtr
= DAG
.CreateStackTemporary(VecVT
);
2046 auto &MF
= DAG
.getMachineFunction();
2047 auto FrameIndex
= cast
<FrameIndexSDNode
>(StackPtr
.getNode())->getIndex();
2048 auto PtrInfo
= MachinePointerInfo::getFixedStack(MF
, FrameIndex
);
2049 SDValue Store
= DAG
.getStore(DAG
.getEntryNode(), dl
, Vec
, StackPtr
, PtrInfo
);
2051 // Load back the required element.
2052 StackPtr
= TLI
.getVectorElementPointer(DAG
, StackPtr
, VecVT
, Idx
);
2054 // FIXME: This is to handle i1 vectors with elements promoted to i8.
2055 // i1 vector handling needs general improvement.
2056 if (N
->getValueType(0).bitsLT(EltVT
)) {
2057 SDValue Load
= DAG
.getLoad(EltVT
, dl
, Store
, StackPtr
,
2058 MachinePointerInfo::getUnknownStack(DAG
.getMachineFunction()));
2059 return DAG
.getZExtOrTrunc(Load
, dl
, N
->getValueType(0));
2062 return DAG
.getExtLoad(
2063 ISD::EXTLOAD
, dl
, N
->getValueType(0), Store
, StackPtr
,
2064 MachinePointerInfo::getUnknownStack(DAG
.getMachineFunction()), EltVT
);
2067 SDValue
DAGTypeLegalizer::SplitVecOp_ExtVecInRegOp(SDNode
*N
) {
2070 // *_EXTEND_VECTOR_INREG only reference the lower half of the input, so
2071 // splitting the result has the same effect as splitting the input operand.
2072 SplitVecRes_ExtVecInRegOp(N
, Lo
, Hi
);
2074 return DAG
.getNode(ISD::CONCAT_VECTORS
, SDLoc(N
), N
->getValueType(0), Lo
, Hi
);
2077 SDValue
DAGTypeLegalizer::SplitVecOp_MGATHER(MaskedGatherSDNode
*MGT
,
2081 std::tie(LoVT
, HiVT
) = DAG
.GetSplitDestVTs(MGT
->getValueType(0));
2083 SDValue Ch
= MGT
->getChain();
2084 SDValue Ptr
= MGT
->getBasePtr();
2085 SDValue Index
= MGT
->getIndex();
2086 SDValue Scale
= MGT
->getScale();
2087 SDValue Mask
= MGT
->getMask();
2088 SDValue PassThru
= MGT
->getPassThru();
2089 unsigned Alignment
= MGT
->getOriginalAlignment();
2091 SDValue MaskLo
, MaskHi
;
2092 if (getTypeAction(Mask
.getValueType()) == TargetLowering::TypeSplitVector
)
2093 // Split Mask operand
2094 GetSplitVector(Mask
, MaskLo
, MaskHi
);
2096 std::tie(MaskLo
, MaskHi
) = DAG
.SplitVector(Mask
, dl
);
2098 EVT MemoryVT
= MGT
->getMemoryVT();
2099 EVT LoMemVT
, HiMemVT
;
2100 std::tie(LoMemVT
, HiMemVT
) = DAG
.GetSplitDestVTs(MemoryVT
);
2102 SDValue PassThruLo
, PassThruHi
;
2103 if (getTypeAction(PassThru
.getValueType()) == TargetLowering::TypeSplitVector
)
2104 GetSplitVector(PassThru
, PassThruLo
, PassThruHi
);
2106 std::tie(PassThruLo
, PassThruHi
) = DAG
.SplitVector(PassThru
, dl
);
2108 SDValue IndexHi
, IndexLo
;
2109 if (getTypeAction(Index
.getValueType()) == TargetLowering::TypeSplitVector
)
2110 GetSplitVector(Index
, IndexLo
, IndexHi
);
2112 std::tie(IndexLo
, IndexHi
) = DAG
.SplitVector(Index
, dl
);
2114 MachineMemOperand
*MMO
= DAG
.getMachineFunction().
2115 getMachineMemOperand(MGT
->getPointerInfo(),
2116 MachineMemOperand::MOLoad
, LoMemVT
.getStoreSize(),
2117 Alignment
, MGT
->getAAInfo(), MGT
->getRanges());
2119 SDValue OpsLo
[] = {Ch
, PassThruLo
, MaskLo
, Ptr
, IndexLo
, Scale
};
2120 SDValue Lo
= DAG
.getMaskedGather(DAG
.getVTList(LoVT
, MVT::Other
), LoVT
, dl
,
2123 MMO
= DAG
.getMachineFunction().
2124 getMachineMemOperand(MGT
->getPointerInfo(),
2125 MachineMemOperand::MOLoad
, HiMemVT
.getStoreSize(),
2126 Alignment
, MGT
->getAAInfo(),
2129 SDValue OpsHi
[] = {Ch
, PassThruHi
, MaskHi
, Ptr
, IndexHi
, Scale
};
2130 SDValue Hi
= DAG
.getMaskedGather(DAG
.getVTList(HiVT
, MVT::Other
), HiVT
, dl
,
2133 // Build a factor node to remember that this load is independent of the
2135 Ch
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, Lo
.getValue(1),
2138 // Legalize the chain result - switch anything that used the old chain to
2140 ReplaceValueWith(SDValue(MGT
, 1), Ch
);
2142 SDValue Res
= DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, MGT
->getValueType(0), Lo
,
2144 ReplaceValueWith(SDValue(MGT
, 0), Res
);
2148 SDValue
DAGTypeLegalizer::SplitVecOp_MSTORE(MaskedStoreSDNode
*N
,
2150 SDValue Ch
= N
->getChain();
2151 SDValue Ptr
= N
->getBasePtr();
2152 SDValue Mask
= N
->getMask();
2153 SDValue Data
= N
->getValue();
2154 EVT MemoryVT
= N
->getMemoryVT();
2155 unsigned Alignment
= N
->getOriginalAlignment();
2158 EVT LoMemVT
, HiMemVT
;
2159 std::tie(LoMemVT
, HiMemVT
) = DAG
.GetSplitDestVTs(MemoryVT
);
2161 SDValue DataLo
, DataHi
;
2162 if (getTypeAction(Data
.getValueType()) == TargetLowering::TypeSplitVector
)
2163 // Split Data operand
2164 GetSplitVector(Data
, DataLo
, DataHi
);
2166 std::tie(DataLo
, DataHi
) = DAG
.SplitVector(Data
, DL
);
2168 SDValue MaskLo
, MaskHi
;
2169 if (getTypeAction(Mask
.getValueType()) == TargetLowering::TypeSplitVector
)
2170 // Split Mask operand
2171 GetSplitVector(Mask
, MaskLo
, MaskHi
);
2173 std::tie(MaskLo
, MaskHi
) = DAG
.SplitVector(Mask
, DL
);
2175 // if Alignment is equal to the vector size,
2176 // take the half of it for the second part
2177 unsigned SecondHalfAlignment
=
2178 (Alignment
== Data
->getValueType(0).getSizeInBits()/8) ?
2179 Alignment
/2 : Alignment
;
2182 MachineMemOperand
*MMO
= DAG
.getMachineFunction().
2183 getMachineMemOperand(N
->getPointerInfo(),
2184 MachineMemOperand::MOStore
, LoMemVT
.getStoreSize(),
2185 Alignment
, N
->getAAInfo(), N
->getRanges());
2187 Lo
= DAG
.getMaskedStore(Ch
, DL
, DataLo
, Ptr
, MaskLo
, LoMemVT
, MMO
,
2188 N
->isTruncatingStore(),
2189 N
->isCompressingStore());
2191 Ptr
= TLI
.IncrementMemoryAddress(Ptr
, MaskLo
, DL
, LoMemVT
, DAG
,
2192 N
->isCompressingStore());
2193 unsigned HiOffset
= LoMemVT
.getStoreSize();
2195 MMO
= DAG
.getMachineFunction().getMachineMemOperand(
2196 N
->getPointerInfo().getWithOffset(HiOffset
), MachineMemOperand::MOStore
,
2197 HiMemVT
.getStoreSize(), SecondHalfAlignment
, N
->getAAInfo(),
2200 Hi
= DAG
.getMaskedStore(Ch
, DL
, DataHi
, Ptr
, MaskHi
, HiMemVT
, MMO
,
2201 N
->isTruncatingStore(), N
->isCompressingStore());
2203 // Build a factor node to remember that this store is independent of the
2205 return DAG
.getNode(ISD::TokenFactor
, DL
, MVT::Other
, Lo
, Hi
);
2208 SDValue
DAGTypeLegalizer::SplitVecOp_MSCATTER(MaskedScatterSDNode
*N
,
2210 SDValue Ch
= N
->getChain();
2211 SDValue Ptr
= N
->getBasePtr();
2212 SDValue Mask
= N
->getMask();
2213 SDValue Index
= N
->getIndex();
2214 SDValue Scale
= N
->getScale();
2215 SDValue Data
= N
->getValue();
2216 EVT MemoryVT
= N
->getMemoryVT();
2217 unsigned Alignment
= N
->getOriginalAlignment();
2220 // Split all operands
2221 EVT LoMemVT
, HiMemVT
;
2222 std::tie(LoMemVT
, HiMemVT
) = DAG
.GetSplitDestVTs(MemoryVT
);
2224 SDValue DataLo
, DataHi
;
2225 if (getTypeAction(Data
.getValueType()) == TargetLowering::TypeSplitVector
)
2226 // Split Data operand
2227 GetSplitVector(Data
, DataLo
, DataHi
);
2229 std::tie(DataLo
, DataHi
) = DAG
.SplitVector(Data
, DL
);
2231 SDValue MaskLo
, MaskHi
;
2232 if (getTypeAction(Mask
.getValueType()) == TargetLowering::TypeSplitVector
)
2233 // Split Mask operand
2234 GetSplitVector(Mask
, MaskLo
, MaskHi
);
2236 std::tie(MaskLo
, MaskHi
) = DAG
.SplitVector(Mask
, DL
);
2238 SDValue IndexHi
, IndexLo
;
2239 if (getTypeAction(Index
.getValueType()) == TargetLowering::TypeSplitVector
)
2240 GetSplitVector(Index
, IndexLo
, IndexHi
);
2242 std::tie(IndexLo
, IndexHi
) = DAG
.SplitVector(Index
, DL
);
2245 MachineMemOperand
*MMO
= DAG
.getMachineFunction().
2246 getMachineMemOperand(N
->getPointerInfo(),
2247 MachineMemOperand::MOStore
, LoMemVT
.getStoreSize(),
2248 Alignment
, N
->getAAInfo(), N
->getRanges());
2250 SDValue OpsLo
[] = {Ch
, DataLo
, MaskLo
, Ptr
, IndexLo
, Scale
};
2251 Lo
= DAG
.getMaskedScatter(DAG
.getVTList(MVT::Other
), DataLo
.getValueType(),
2254 MMO
= DAG
.getMachineFunction().
2255 getMachineMemOperand(N
->getPointerInfo(),
2256 MachineMemOperand::MOStore
, HiMemVT
.getStoreSize(),
2257 Alignment
, N
->getAAInfo(), N
->getRanges());
2259 // The order of the Scatter operation after split is well defined. The "Hi"
2260 // part comes after the "Lo". So these two operations should be chained one
2262 SDValue OpsHi
[] = {Lo
, DataHi
, MaskHi
, Ptr
, IndexHi
, Scale
};
2263 return DAG
.getMaskedScatter(DAG
.getVTList(MVT::Other
), DataHi
.getValueType(),
2267 SDValue
DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode
*N
, unsigned OpNo
) {
2268 assert(N
->isUnindexed() && "Indexed store of vector?");
2269 assert(OpNo
== 1 && "Can only split the stored value");
2272 bool isTruncating
= N
->isTruncatingStore();
2273 SDValue Ch
= N
->getChain();
2274 SDValue Ptr
= N
->getBasePtr();
2275 EVT MemoryVT
= N
->getMemoryVT();
2276 unsigned Alignment
= N
->getOriginalAlignment();
2277 MachineMemOperand::Flags MMOFlags
= N
->getMemOperand()->getFlags();
2278 AAMDNodes AAInfo
= N
->getAAInfo();
2280 GetSplitVector(N
->getOperand(1), Lo
, Hi
);
2282 EVT LoMemVT
, HiMemVT
;
2283 std::tie(LoMemVT
, HiMemVT
) = DAG
.GetSplitDestVTs(MemoryVT
);
2285 // Scalarize if the split halves are not byte-sized.
2286 if (!LoMemVT
.isByteSized() || !HiMemVT
.isByteSized())
2287 return TLI
.scalarizeVectorStore(N
, DAG
);
2289 unsigned IncrementSize
= LoMemVT
.getSizeInBits()/8;
2292 Lo
= DAG
.getTruncStore(Ch
, DL
, Lo
, Ptr
, N
->getPointerInfo(), LoMemVT
,
2293 Alignment
, MMOFlags
, AAInfo
);
2295 Lo
= DAG
.getStore(Ch
, DL
, Lo
, Ptr
, N
->getPointerInfo(), Alignment
, MMOFlags
,
2298 // Increment the pointer to the other half.
2299 Ptr
= DAG
.getObjectPtrOffset(DL
, Ptr
, IncrementSize
);
2302 Hi
= DAG
.getTruncStore(Ch
, DL
, Hi
, Ptr
,
2303 N
->getPointerInfo().getWithOffset(IncrementSize
),
2304 HiMemVT
, Alignment
, MMOFlags
, AAInfo
);
2306 Hi
= DAG
.getStore(Ch
, DL
, Hi
, Ptr
,
2307 N
->getPointerInfo().getWithOffset(IncrementSize
),
2308 Alignment
, MMOFlags
, AAInfo
);
2310 return DAG
.getNode(ISD::TokenFactor
, DL
, MVT::Other
, Lo
, Hi
);
2313 SDValue
DAGTypeLegalizer::SplitVecOp_CONCAT_VECTORS(SDNode
*N
) {
2316 // The input operands all must have the same type, and we know the result
2317 // type is valid. Convert this to a buildvector which extracts all the
2319 // TODO: If the input elements are power-two vectors, we could convert this to
2320 // a new CONCAT_VECTORS node with elements that are half-wide.
2321 SmallVector
<SDValue
, 32> Elts
;
2322 EVT EltVT
= N
->getValueType(0).getVectorElementType();
2323 for (const SDValue
&Op
: N
->op_values()) {
2324 for (unsigned i
= 0, e
= Op
.getValueType().getVectorNumElements();
2326 Elts
.push_back(DAG
.getNode(
2327 ISD::EXTRACT_VECTOR_ELT
, DL
, EltVT
, Op
,
2328 DAG
.getConstant(i
, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout()))));
2332 return DAG
.getBuildVector(N
->getValueType(0), DL
, Elts
);
2335 SDValue
DAGTypeLegalizer::SplitVecOp_TruncateHelper(SDNode
*N
) {
2336 // The result type is legal, but the input type is illegal. If splitting
2337 // ends up with the result type of each half still being legal, just
2338 // do that. If, however, that would result in an illegal result type,
2339 // we can try to get more clever with power-two vectors. Specifically,
2340 // split the input type, but also widen the result element size, then
2341 // concatenate the halves and truncate again. For example, consider a target
2342 // where v8i8 is legal and v8i32 is not (ARM, which doesn't have 256-bit
2343 // vectors). To perform a "%res = v8i8 trunc v8i32 %in" we do:
2344 // %inlo = v4i32 extract_subvector %in, 0
2345 // %inhi = v4i32 extract_subvector %in, 4
2346 // %lo16 = v4i16 trunc v4i32 %inlo
2347 // %hi16 = v4i16 trunc v4i32 %inhi
2348 // %in16 = v8i16 concat_vectors v4i16 %lo16, v4i16 %hi16
2349 // %res = v8i8 trunc v8i16 %in16
2351 // Without this transform, the original truncate would end up being
2352 // scalarized, which is pretty much always a last resort.
2353 SDValue InVec
= N
->getOperand(0);
2354 EVT InVT
= InVec
->getValueType(0);
2355 EVT OutVT
= N
->getValueType(0);
2356 unsigned NumElements
= OutVT
.getVectorNumElements();
2357 bool IsFloat
= OutVT
.isFloatingPoint();
2359 // Widening should have already made sure this is a power-two vector
2360 // if we're trying to split it at all. assert() that's true, just in case.
2361 assert(!(NumElements
& 1) && "Splitting vector, but not in half!");
2363 unsigned InElementSize
= InVT
.getScalarSizeInBits();
2364 unsigned OutElementSize
= OutVT
.getScalarSizeInBits();
2366 // Determine the split output VT. If its legal we can just split dirctly.
2367 EVT LoOutVT
, HiOutVT
;
2368 std::tie(LoOutVT
, HiOutVT
) = DAG
.GetSplitDestVTs(OutVT
);
2369 assert(LoOutVT
== HiOutVT
&& "Unequal split?");
2371 // If the input elements are only 1/2 the width of the result elements,
2372 // just use the normal splitting. Our trick only work if there's room
2373 // to split more than once.
2374 if (isTypeLegal(LoOutVT
) ||
2375 InElementSize
<= OutElementSize
* 2)
2376 return SplitVecOp_UnaryOp(N
);
2379 // Don't touch if this will be scalarized.
2381 while (getTypeAction(FinalVT
) == TargetLowering::TypeSplitVector
)
2382 FinalVT
= FinalVT
.getHalfNumVectorElementsVT(*DAG
.getContext());
2384 if (getTypeAction(FinalVT
) == TargetLowering::TypeScalarizeVector
)
2385 return SplitVecOp_UnaryOp(N
);
2387 // Get the split input vector.
2388 SDValue InLoVec
, InHiVec
;
2389 GetSplitVector(InVec
, InLoVec
, InHiVec
);
2391 // Truncate them to 1/2 the element size.
2392 EVT HalfElementVT
= IsFloat
?
2393 EVT::getFloatingPointVT(InElementSize
/2) :
2394 EVT::getIntegerVT(*DAG
.getContext(), InElementSize
/2);
2395 EVT HalfVT
= EVT::getVectorVT(*DAG
.getContext(), HalfElementVT
,
2397 SDValue HalfLo
= DAG
.getNode(N
->getOpcode(), DL
, HalfVT
, InLoVec
);
2398 SDValue HalfHi
= DAG
.getNode(N
->getOpcode(), DL
, HalfVT
, InHiVec
);
2399 // Concatenate them to get the full intermediate truncation result.
2400 EVT InterVT
= EVT::getVectorVT(*DAG
.getContext(), HalfElementVT
, NumElements
);
2401 SDValue InterVec
= DAG
.getNode(ISD::CONCAT_VECTORS
, DL
, InterVT
, HalfLo
,
2403 // Now finish up by truncating all the way down to the original result
2404 // type. This should normally be something that ends up being legal directly,
2405 // but in theory if a target has very wide vectors and an annoyingly
2406 // restricted set of legal types, this split can chain to build things up.
2408 ? DAG
.getNode(ISD::FP_ROUND
, DL
, OutVT
, InterVec
,
2409 DAG
.getTargetConstant(
2410 0, DL
, TLI
.getPointerTy(DAG
.getDataLayout())))
2411 : DAG
.getNode(ISD::TRUNCATE
, DL
, OutVT
, InterVec
);
2414 SDValue
DAGTypeLegalizer::SplitVecOp_VSETCC(SDNode
*N
) {
2415 assert(N
->getValueType(0).isVector() &&
2416 N
->getOperand(0).getValueType().isVector() &&
2417 "Operand types must be vectors");
2418 // The result has a legal vector type, but the input needs splitting.
2419 SDValue Lo0
, Hi0
, Lo1
, Hi1
, LoRes
, HiRes
;
2421 GetSplitVector(N
->getOperand(0), Lo0
, Hi0
);
2422 GetSplitVector(N
->getOperand(1), Lo1
, Hi1
);
2423 unsigned PartElements
= Lo0
.getValueType().getVectorNumElements();
2424 EVT PartResVT
= EVT::getVectorVT(*DAG
.getContext(), MVT::i1
, PartElements
);
2425 EVT WideResVT
= EVT::getVectorVT(*DAG
.getContext(), MVT::i1
, 2*PartElements
);
2427 LoRes
= DAG
.getNode(ISD::SETCC
, DL
, PartResVT
, Lo0
, Lo1
, N
->getOperand(2));
2428 HiRes
= DAG
.getNode(ISD::SETCC
, DL
, PartResVT
, Hi0
, Hi1
, N
->getOperand(2));
2429 SDValue Con
= DAG
.getNode(ISD::CONCAT_VECTORS
, DL
, WideResVT
, LoRes
, HiRes
);
2430 return PromoteTargetBoolean(Con
, N
->getValueType(0));
2434 SDValue
DAGTypeLegalizer::SplitVecOp_FP_ROUND(SDNode
*N
) {
2435 // The result has a legal vector type, but the input needs splitting.
2436 EVT ResVT
= N
->getValueType(0);
2439 GetSplitVector(N
->getOperand(0), Lo
, Hi
);
2440 EVT InVT
= Lo
.getValueType();
2442 EVT OutVT
= EVT::getVectorVT(*DAG
.getContext(), ResVT
.getVectorElementType(),
2443 InVT
.getVectorNumElements());
2445 Lo
= DAG
.getNode(ISD::FP_ROUND
, DL
, OutVT
, Lo
, N
->getOperand(1));
2446 Hi
= DAG
.getNode(ISD::FP_ROUND
, DL
, OutVT
, Hi
, N
->getOperand(1));
2448 return DAG
.getNode(ISD::CONCAT_VECTORS
, DL
, ResVT
, Lo
, Hi
);
2451 SDValue
DAGTypeLegalizer::SplitVecOp_FCOPYSIGN(SDNode
*N
) {
2452 // The result (and the first input) has a legal vector type, but the second
2453 // input needs splitting.
2454 return DAG
.UnrollVectorOp(N
, N
->getValueType(0).getVectorNumElements());
2458 //===----------------------------------------------------------------------===//
2459 // Result Vector Widening
2460 //===----------------------------------------------------------------------===//
2462 void DAGTypeLegalizer::WidenVectorResult(SDNode
*N
, unsigned ResNo
) {
2463 LLVM_DEBUG(dbgs() << "Widen node result " << ResNo
<< ": "; N
->dump(&DAG
);
2466 // See if the target wants to custom widen this node.
2467 if (CustomWidenLowerNode(N
, N
->getValueType(ResNo
)))
2470 SDValue Res
= SDValue();
2471 switch (N
->getOpcode()) {
2474 dbgs() << "WidenVectorResult #" << ResNo
<< ": ";
2478 llvm_unreachable("Do not know how to widen the result of this operator!");
2480 case ISD::MERGE_VALUES
: Res
= WidenVecRes_MERGE_VALUES(N
, ResNo
); break;
2481 case ISD::BITCAST
: Res
= WidenVecRes_BITCAST(N
); break;
2482 case ISD::BUILD_VECTOR
: Res
= WidenVecRes_BUILD_VECTOR(N
); break;
2483 case ISD::CONCAT_VECTORS
: Res
= WidenVecRes_CONCAT_VECTORS(N
); break;
2484 case ISD::EXTRACT_SUBVECTOR
: Res
= WidenVecRes_EXTRACT_SUBVECTOR(N
); break;
2485 case ISD::FP_ROUND_INREG
: Res
= WidenVecRes_InregOp(N
); break;
2486 case ISD::INSERT_VECTOR_ELT
: Res
= WidenVecRes_INSERT_VECTOR_ELT(N
); break;
2487 case ISD::LOAD
: Res
= WidenVecRes_LOAD(N
); break;
2488 case ISD::SCALAR_TO_VECTOR
: Res
= WidenVecRes_SCALAR_TO_VECTOR(N
); break;
2489 case ISD::SIGN_EXTEND_INREG
: Res
= WidenVecRes_InregOp(N
); break;
2491 case ISD::SELECT
: Res
= WidenVecRes_SELECT(N
); break;
2492 case ISD::SELECT_CC
: Res
= WidenVecRes_SELECT_CC(N
); break;
2493 case ISD::SETCC
: Res
= WidenVecRes_SETCC(N
); break;
2494 case ISD::UNDEF
: Res
= WidenVecRes_UNDEF(N
); break;
2495 case ISD::VECTOR_SHUFFLE
:
2496 Res
= WidenVecRes_VECTOR_SHUFFLE(cast
<ShuffleVectorSDNode
>(N
));
2499 Res
= WidenVecRes_MLOAD(cast
<MaskedLoadSDNode
>(N
));
2502 Res
= WidenVecRes_MGATHER(cast
<MaskedGatherSDNode
>(N
));
2525 Res
= WidenVecRes_Binary(N
);
2538 Res
= WidenVecRes_BinaryCanTrap(N
);
2541 case ISD::STRICT_FADD
:
2542 case ISD::STRICT_FSUB
:
2543 case ISD::STRICT_FMUL
:
2544 case ISD::STRICT_FDIV
:
2545 case ISD::STRICT_FREM
:
2546 case ISD::STRICT_FSQRT
:
2547 case ISD::STRICT_FMA
:
2548 case ISD::STRICT_FPOW
:
2549 case ISD::STRICT_FPOWI
:
2550 case ISD::STRICT_FSIN
:
2551 case ISD::STRICT_FCOS
:
2552 case ISD::STRICT_FEXP
:
2553 case ISD::STRICT_FEXP2
:
2554 case ISD::STRICT_FLOG
:
2555 case ISD::STRICT_FLOG10
:
2556 case ISD::STRICT_FLOG2
:
2557 case ISD::STRICT_FRINT
:
2558 case ISD::STRICT_FNEARBYINT
:
2559 case ISD::STRICT_FMAXNUM
:
2560 case ISD::STRICT_FMINNUM
:
2561 case ISD::STRICT_FCEIL
:
2562 case ISD::STRICT_FFLOOR
:
2563 case ISD::STRICT_FROUND
:
2564 case ISD::STRICT_FTRUNC
:
2565 Res
= WidenVecRes_StrictFP(N
);
2574 Res
= WidenVecRes_OverflowOp(N
, ResNo
);
2577 case ISD::FCOPYSIGN
:
2578 Res
= WidenVecRes_FCOPYSIGN(N
);
2582 Res
= WidenVecRes_POWI(N
);
2588 Res
= WidenVecRes_Shift(N
);
2591 case ISD::ANY_EXTEND_VECTOR_INREG
:
2592 case ISD::SIGN_EXTEND_VECTOR_INREG
:
2593 case ISD::ZERO_EXTEND_VECTOR_INREG
:
2594 Res
= WidenVecRes_EXTEND_VECTOR_INREG(N
);
2597 case ISD::ANY_EXTEND
:
2598 case ISD::FP_EXTEND
:
2600 case ISD::FP_TO_SINT
:
2601 case ISD::FP_TO_UINT
:
2602 case ISD::SIGN_EXTEND
:
2603 case ISD::SINT_TO_FP
:
2605 case ISD::UINT_TO_FP
:
2606 case ISD::ZERO_EXTEND
:
2607 Res
= WidenVecRes_Convert(N
);
2619 case ISD::FNEARBYINT
:
2625 // We're going to widen this vector op to a legal type by padding with undef
2626 // elements. If the wide vector op is eventually going to be expanded to
2627 // scalar libcalls, then unroll into scalar ops now to avoid unnecessary
2628 // libcalls on the undef elements. We are assuming that if the scalar op
2629 // requires expanding, then the vector op needs expanding too.
2630 EVT VT
= N
->getValueType(0);
2631 if (TLI
.isOperationExpand(N
->getOpcode(), VT
.getScalarType())) {
2632 EVT WideVecVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
2633 assert(!TLI
.isOperationLegalOrCustom(N
->getOpcode(), WideVecVT
) &&
2634 "Target supports vector op, but scalar requires expansion?");
2635 Res
= DAG
.UnrollVectorOp(N
, WideVecVT
.getVectorNumElements());
2639 // If the target has custom/legal support for the scalar FP intrinsic ops
2640 // (they are probably not destined to become libcalls), then widen those like
2641 // any other unary ops.
2644 case ISD::BITREVERSE
:
2650 case ISD::FCANONICALIZE
:
2651 Res
= WidenVecRes_Unary(N
);
2654 Res
= WidenVecRes_Ternary(N
);
2658 // If Res is null, the sub-method took care of registering the result.
2660 SetWidenedVector(SDValue(N
, ResNo
), Res
);
2663 SDValue
DAGTypeLegalizer::WidenVecRes_Ternary(SDNode
*N
) {
2664 // Ternary op widening.
2666 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
2667 SDValue InOp1
= GetWidenedVector(N
->getOperand(0));
2668 SDValue InOp2
= GetWidenedVector(N
->getOperand(1));
2669 SDValue InOp3
= GetWidenedVector(N
->getOperand(2));
2670 return DAG
.getNode(N
->getOpcode(), dl
, WidenVT
, InOp1
, InOp2
, InOp3
);
2673 SDValue
DAGTypeLegalizer::WidenVecRes_Binary(SDNode
*N
) {
2674 // Binary op widening.
2676 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
2677 SDValue InOp1
= GetWidenedVector(N
->getOperand(0));
2678 SDValue InOp2
= GetWidenedVector(N
->getOperand(1));
2679 return DAG
.getNode(N
->getOpcode(), dl
, WidenVT
, InOp1
, InOp2
, N
->getFlags());
2682 // Given a vector of operations that have been broken up to widen, see
2683 // if we can collect them together into the next widest legal VT. This
2684 // implementation is trap-safe.
2685 static SDValue
CollectOpsToWiden(SelectionDAG
&DAG
, const TargetLowering
&TLI
,
2686 SmallVectorImpl
<SDValue
> &ConcatOps
,
2687 unsigned ConcatEnd
, EVT VT
, EVT MaxVT
,
2689 // Check to see if we have a single operation with the widen type.
2690 if (ConcatEnd
== 1) {
2691 VT
= ConcatOps
[0].getValueType();
2693 return ConcatOps
[0];
2696 SDLoc
dl(ConcatOps
[0]);
2697 EVT WidenEltVT
= WidenVT
.getVectorElementType();
2700 // while (Some element of ConcatOps is not of type MaxVT) {
2701 // From the end of ConcatOps, collect elements of the same type and put
2702 // them into an op of the next larger supported type
2704 while (ConcatOps
[ConcatEnd
-1].getValueType() != MaxVT
) {
2705 Idx
= ConcatEnd
- 1;
2706 VT
= ConcatOps
[Idx
--].getValueType();
2707 while (Idx
>= 0 && ConcatOps
[Idx
].getValueType() == VT
)
2710 int NextSize
= VT
.isVector() ? VT
.getVectorNumElements() : 1;
2714 NextVT
= EVT::getVectorVT(*DAG
.getContext(), WidenEltVT
, NextSize
);
2715 } while (!TLI
.isTypeLegal(NextVT
));
2717 if (!VT
.isVector()) {
2718 // Scalar type, create an INSERT_VECTOR_ELEMENT of type NextVT
2719 SDValue VecOp
= DAG
.getUNDEF(NextVT
);
2720 unsigned NumToInsert
= ConcatEnd
- Idx
- 1;
2721 for (unsigned i
= 0, OpIdx
= Idx
+1; i
< NumToInsert
; i
++, OpIdx
++) {
2722 VecOp
= DAG
.getNode(
2723 ISD::INSERT_VECTOR_ELT
, dl
, NextVT
, VecOp
, ConcatOps
[OpIdx
],
2724 DAG
.getConstant(i
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
2726 ConcatOps
[Idx
+1] = VecOp
;
2727 ConcatEnd
= Idx
+ 2;
2729 // Vector type, create a CONCAT_VECTORS of type NextVT
2730 SDValue undefVec
= DAG
.getUNDEF(VT
);
2731 unsigned OpsToConcat
= NextSize
/VT
.getVectorNumElements();
2732 SmallVector
<SDValue
, 16> SubConcatOps(OpsToConcat
);
2733 unsigned RealVals
= ConcatEnd
- Idx
- 1;
2734 unsigned SubConcatEnd
= 0;
2735 unsigned SubConcatIdx
= Idx
+ 1;
2736 while (SubConcatEnd
< RealVals
)
2737 SubConcatOps
[SubConcatEnd
++] = ConcatOps
[++Idx
];
2738 while (SubConcatEnd
< OpsToConcat
)
2739 SubConcatOps
[SubConcatEnd
++] = undefVec
;
2740 ConcatOps
[SubConcatIdx
] = DAG
.getNode(ISD::CONCAT_VECTORS
, dl
,
2741 NextVT
, SubConcatOps
);
2742 ConcatEnd
= SubConcatIdx
+ 1;
2746 // Check to see if we have a single operation with the widen type.
2747 if (ConcatEnd
== 1) {
2748 VT
= ConcatOps
[0].getValueType();
2750 return ConcatOps
[0];
2753 // add undefs of size MaxVT until ConcatOps grows to length of WidenVT
2754 unsigned NumOps
= WidenVT
.getVectorNumElements()/MaxVT
.getVectorNumElements();
2755 if (NumOps
!= ConcatEnd
) {
2756 SDValue UndefVal
= DAG
.getUNDEF(MaxVT
);
2757 for (unsigned j
= ConcatEnd
; j
< NumOps
; ++j
)
2758 ConcatOps
[j
] = UndefVal
;
2760 return DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, WidenVT
,
2761 makeArrayRef(ConcatOps
.data(), NumOps
));
2764 SDValue
DAGTypeLegalizer::WidenVecRes_BinaryCanTrap(SDNode
*N
) {
2765 // Binary op widening for operations that can trap.
2766 unsigned Opcode
= N
->getOpcode();
2768 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
2769 EVT WidenEltVT
= WidenVT
.getVectorElementType();
2771 unsigned NumElts
= VT
.getVectorNumElements();
2772 const SDNodeFlags Flags
= N
->getFlags();
2773 while (!TLI
.isTypeLegal(VT
) && NumElts
!= 1) {
2774 NumElts
= NumElts
/ 2;
2775 VT
= EVT::getVectorVT(*DAG
.getContext(), WidenEltVT
, NumElts
);
2778 if (NumElts
!= 1 && !TLI
.canOpTrap(N
->getOpcode(), VT
)) {
2779 // Operation doesn't trap so just widen as normal.
2780 SDValue InOp1
= GetWidenedVector(N
->getOperand(0));
2781 SDValue InOp2
= GetWidenedVector(N
->getOperand(1));
2782 return DAG
.getNode(N
->getOpcode(), dl
, WidenVT
, InOp1
, InOp2
, Flags
);
2785 // No legal vector version so unroll the vector operation and then widen.
2787 return DAG
.UnrollVectorOp(N
, WidenVT
.getVectorNumElements());
2789 // Since the operation can trap, apply operation on the original vector.
2791 SDValue InOp1
= GetWidenedVector(N
->getOperand(0));
2792 SDValue InOp2
= GetWidenedVector(N
->getOperand(1));
2793 unsigned CurNumElts
= N
->getValueType(0).getVectorNumElements();
2795 SmallVector
<SDValue
, 16> ConcatOps(CurNumElts
);
2796 unsigned ConcatEnd
= 0; // Current ConcatOps index.
2797 int Idx
= 0; // Current Idx into input vectors.
2799 // NumElts := greatest legal vector size (at most WidenVT)
2800 // while (orig. vector has unhandled elements) {
2801 // take munches of size NumElts from the beginning and add to ConcatOps
2802 // NumElts := next smaller supported vector size or 1
2804 while (CurNumElts
!= 0) {
2805 while (CurNumElts
>= NumElts
) {
2806 SDValue EOp1
= DAG
.getNode(
2807 ISD::EXTRACT_SUBVECTOR
, dl
, VT
, InOp1
,
2808 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
2809 SDValue EOp2
= DAG
.getNode(
2810 ISD::EXTRACT_SUBVECTOR
, dl
, VT
, InOp2
,
2811 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
2812 ConcatOps
[ConcatEnd
++] = DAG
.getNode(Opcode
, dl
, VT
, EOp1
, EOp2
, Flags
);
2814 CurNumElts
-= NumElts
;
2817 NumElts
= NumElts
/ 2;
2818 VT
= EVT::getVectorVT(*DAG
.getContext(), WidenEltVT
, NumElts
);
2819 } while (!TLI
.isTypeLegal(VT
) && NumElts
!= 1);
2822 for (unsigned i
= 0; i
!= CurNumElts
; ++i
, ++Idx
) {
2823 SDValue EOp1
= DAG
.getNode(
2824 ISD::EXTRACT_VECTOR_ELT
, dl
, WidenEltVT
, InOp1
,
2825 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
2826 SDValue EOp2
= DAG
.getNode(
2827 ISD::EXTRACT_VECTOR_ELT
, dl
, WidenEltVT
, InOp2
,
2828 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
2829 ConcatOps
[ConcatEnd
++] = DAG
.getNode(Opcode
, dl
, WidenEltVT
,
2836 return CollectOpsToWiden(DAG
, TLI
, ConcatOps
, ConcatEnd
, VT
, MaxVT
, WidenVT
);
2839 SDValue
DAGTypeLegalizer::WidenVecRes_StrictFP(SDNode
*N
) {
2840 // StrictFP op widening for operations that can trap.
2841 unsigned NumOpers
= N
->getNumOperands();
2842 unsigned Opcode
= N
->getOpcode();
2844 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
2845 EVT WidenEltVT
= WidenVT
.getVectorElementType();
2847 unsigned NumElts
= VT
.getVectorNumElements();
2848 while (!TLI
.isTypeLegal(VT
) && NumElts
!= 1) {
2849 NumElts
= NumElts
/ 2;
2850 VT
= EVT::getVectorVT(*DAG
.getContext(), WidenEltVT
, NumElts
);
2853 // No legal vector version so unroll the vector operation and then widen.
2855 return DAG
.UnrollVectorOp(N
, WidenVT
.getVectorNumElements());
2857 // Since the operation can trap, apply operation on the original vector.
2859 SmallVector
<SDValue
, 4> InOps
;
2860 unsigned CurNumElts
= N
->getValueType(0).getVectorNumElements();
2862 SmallVector
<SDValue
, 16> ConcatOps(CurNumElts
);
2863 SmallVector
<SDValue
, 16> Chains
;
2864 unsigned ConcatEnd
= 0; // Current ConcatOps index.
2865 int Idx
= 0; // Current Idx into input vectors.
2867 // The Chain is the first operand.
2868 InOps
.push_back(N
->getOperand(0));
2870 // Now process the remaining operands.
2871 for (unsigned i
= 1; i
< NumOpers
; ++i
) {
2872 SDValue Oper
= N
->getOperand(i
);
2874 if (Oper
.getValueType().isVector()) {
2875 assert(Oper
.getValueType() == N
->getValueType(0) &&
2876 "Invalid operand type to widen!");
2877 Oper
= GetWidenedVector(Oper
);
2880 InOps
.push_back(Oper
);
2883 // NumElts := greatest legal vector size (at most WidenVT)
2884 // while (orig. vector has unhandled elements) {
2885 // take munches of size NumElts from the beginning and add to ConcatOps
2886 // NumElts := next smaller supported vector size or 1
2888 while (CurNumElts
!= 0) {
2889 while (CurNumElts
>= NumElts
) {
2890 SmallVector
<SDValue
, 4> EOps
;
2892 for (unsigned i
= 0; i
< NumOpers
; ++i
) {
2893 SDValue Op
= InOps
[i
];
2895 if (Op
.getValueType().isVector())
2897 ISD::EXTRACT_SUBVECTOR
, dl
, VT
, Op
,
2898 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
2903 EVT OperVT
[] = {VT
, MVT::Other
};
2904 SDValue Oper
= DAG
.getNode(Opcode
, dl
, OperVT
, EOps
);
2905 ConcatOps
[ConcatEnd
++] = Oper
;
2906 Chains
.push_back(Oper
.getValue(1));
2908 CurNumElts
-= NumElts
;
2911 NumElts
= NumElts
/ 2;
2912 VT
= EVT::getVectorVT(*DAG
.getContext(), WidenEltVT
, NumElts
);
2913 } while (!TLI
.isTypeLegal(VT
) && NumElts
!= 1);
2916 for (unsigned i
= 0; i
!= CurNumElts
; ++i
, ++Idx
) {
2917 SmallVector
<SDValue
, 4> EOps
;
2919 for (unsigned i
= 0; i
< NumOpers
; ++i
) {
2920 SDValue Op
= InOps
[i
];
2922 if (Op
.getValueType().isVector())
2924 ISD::EXTRACT_VECTOR_ELT
, dl
, WidenEltVT
, Op
,
2925 DAG
.getConstant(Idx
, dl
,
2926 TLI
.getVectorIdxTy(DAG
.getDataLayout())));
2931 EVT WidenVT
[] = {WidenEltVT
, MVT::Other
};
2932 SDValue Oper
= DAG
.getNode(Opcode
, dl
, WidenVT
, EOps
);
2933 ConcatOps
[ConcatEnd
++] = Oper
;
2934 Chains
.push_back(Oper
.getValue(1));
2940 // Build a factor node to remember all the Ops that have been created.
2942 if (Chains
.size() == 1)
2943 NewChain
= Chains
[0];
2945 NewChain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, Chains
);
2946 ReplaceValueWith(SDValue(N
, 1), NewChain
);
2948 return CollectOpsToWiden(DAG
, TLI
, ConcatOps
, ConcatEnd
, VT
, MaxVT
, WidenVT
);
2951 SDValue
DAGTypeLegalizer::WidenVecRes_OverflowOp(SDNode
*N
, unsigned ResNo
) {
2953 EVT ResVT
= N
->getValueType(0);
2954 EVT OvVT
= N
->getValueType(1);
2955 EVT WideResVT
, WideOvVT
;
2956 SDValue WideLHS
, WideRHS
;
2958 // TODO: This might result in a widen/split loop.
2960 WideResVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), ResVT
);
2961 WideOvVT
= EVT::getVectorVT(
2962 *DAG
.getContext(), OvVT
.getVectorElementType(),
2963 WideResVT
.getVectorNumElements());
2965 WideLHS
= GetWidenedVector(N
->getOperand(0));
2966 WideRHS
= GetWidenedVector(N
->getOperand(1));
2968 WideOvVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), OvVT
);
2969 WideResVT
= EVT::getVectorVT(
2970 *DAG
.getContext(), ResVT
.getVectorElementType(),
2971 WideOvVT
.getVectorNumElements());
2973 SDValue Zero
= DAG
.getConstant(
2974 0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout()));
2975 WideLHS
= DAG
.getNode(
2976 ISD::INSERT_SUBVECTOR
, DL
, WideResVT
, DAG
.getUNDEF(WideResVT
),
2977 N
->getOperand(0), Zero
);
2978 WideRHS
= DAG
.getNode(
2979 ISD::INSERT_SUBVECTOR
, DL
, WideResVT
, DAG
.getUNDEF(WideResVT
),
2980 N
->getOperand(1), Zero
);
2983 SDVTList WideVTs
= DAG
.getVTList(WideResVT
, WideOvVT
);
2984 SDNode
*WideNode
= DAG
.getNode(
2985 N
->getOpcode(), DL
, WideVTs
, WideLHS
, WideRHS
).getNode();
2987 // Replace the other vector result not being explicitly widened here.
2988 unsigned OtherNo
= 1 - ResNo
;
2989 EVT OtherVT
= N
->getValueType(OtherNo
);
2990 if (getTypeAction(OtherVT
) == TargetLowering::TypeWidenVector
) {
2991 SetWidenedVector(SDValue(N
, OtherNo
), SDValue(WideNode
, OtherNo
));
2993 SDValue Zero
= DAG
.getConstant(
2994 0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout()));
2995 SDValue OtherVal
= DAG
.getNode(
2996 ISD::EXTRACT_SUBVECTOR
, DL
, OtherVT
, SDValue(WideNode
, OtherNo
), Zero
);
2997 ReplaceValueWith(SDValue(N
, OtherNo
), OtherVal
);
3000 return SDValue(WideNode
, ResNo
);
3003 SDValue
DAGTypeLegalizer::WidenVecRes_Convert(SDNode
*N
) {
3004 SDValue InOp
= N
->getOperand(0);
3007 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3008 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
3010 EVT InVT
= InOp
.getValueType();
3011 EVT InEltVT
= InVT
.getVectorElementType();
3012 EVT InWidenVT
= EVT::getVectorVT(*DAG
.getContext(), InEltVT
, WidenNumElts
);
3014 unsigned Opcode
= N
->getOpcode();
3015 unsigned InVTNumElts
= InVT
.getVectorNumElements();
3016 const SDNodeFlags Flags
= N
->getFlags();
3017 if (getTypeAction(InVT
) == TargetLowering::TypeWidenVector
) {
3018 InOp
= GetWidenedVector(N
->getOperand(0));
3019 InVT
= InOp
.getValueType();
3020 InVTNumElts
= InVT
.getVectorNumElements();
3021 if (InVTNumElts
== WidenNumElts
) {
3022 if (N
->getNumOperands() == 1)
3023 return DAG
.getNode(Opcode
, DL
, WidenVT
, InOp
);
3024 return DAG
.getNode(Opcode
, DL
, WidenVT
, InOp
, N
->getOperand(1), Flags
);
3026 if (WidenVT
.getSizeInBits() == InVT
.getSizeInBits()) {
3027 // If both input and result vector types are of same width, extend
3028 // operations should be done with SIGN/ZERO_EXTEND_VECTOR_INREG, which
3029 // accepts fewer elements in the result than in the input.
3030 if (Opcode
== ISD::ANY_EXTEND
)
3031 return DAG
.getNode(ISD::ANY_EXTEND_VECTOR_INREG
, DL
, WidenVT
, InOp
);
3032 if (Opcode
== ISD::SIGN_EXTEND
)
3033 return DAG
.getNode(ISD::SIGN_EXTEND_VECTOR_INREG
, DL
, WidenVT
, InOp
);
3034 if (Opcode
== ISD::ZERO_EXTEND
)
3035 return DAG
.getNode(ISD::ZERO_EXTEND_VECTOR_INREG
, DL
, WidenVT
, InOp
);
3039 if (TLI
.isTypeLegal(InWidenVT
)) {
3040 // Because the result and the input are different vector types, widening
3041 // the result could create a legal type but widening the input might make
3042 // it an illegal type that might lead to repeatedly splitting the input
3043 // and then widening it. To avoid this, we widen the input only if
3044 // it results in a legal type.
3045 if (WidenNumElts
% InVTNumElts
== 0) {
3046 // Widen the input and call convert on the widened input vector.
3047 unsigned NumConcat
= WidenNumElts
/InVTNumElts
;
3048 SmallVector
<SDValue
, 16> Ops(NumConcat
, DAG
.getUNDEF(InVT
));
3050 SDValue InVec
= DAG
.getNode(ISD::CONCAT_VECTORS
, DL
, InWidenVT
, Ops
);
3051 if (N
->getNumOperands() == 1)
3052 return DAG
.getNode(Opcode
, DL
, WidenVT
, InVec
);
3053 return DAG
.getNode(Opcode
, DL
, WidenVT
, InVec
, N
->getOperand(1), Flags
);
3056 if (InVTNumElts
% WidenNumElts
== 0) {
3057 SDValue InVal
= DAG
.getNode(
3058 ISD::EXTRACT_SUBVECTOR
, DL
, InWidenVT
, InOp
,
3059 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3060 // Extract the input and convert the shorten input vector.
3061 if (N
->getNumOperands() == 1)
3062 return DAG
.getNode(Opcode
, DL
, WidenVT
, InVal
);
3063 return DAG
.getNode(Opcode
, DL
, WidenVT
, InVal
, N
->getOperand(1), Flags
);
3067 // Otherwise unroll into some nasty scalar code and rebuild the vector.
3068 EVT EltVT
= WidenVT
.getVectorElementType();
3069 SmallVector
<SDValue
, 16> Ops(WidenNumElts
, DAG
.getUNDEF(EltVT
));
3070 // Use the original element count so we don't do more scalar opts than
3072 unsigned MinElts
= N
->getValueType(0).getVectorNumElements();
3073 for (unsigned i
=0; i
< MinElts
; ++i
) {
3074 SDValue Val
= DAG
.getNode(
3075 ISD::EXTRACT_VECTOR_ELT
, DL
, InEltVT
, InOp
,
3076 DAG
.getConstant(i
, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3077 if (N
->getNumOperands() == 1)
3078 Ops
[i
] = DAG
.getNode(Opcode
, DL
, EltVT
, Val
);
3080 Ops
[i
] = DAG
.getNode(Opcode
, DL
, EltVT
, Val
, N
->getOperand(1), Flags
);
3083 return DAG
.getBuildVector(WidenVT
, DL
, Ops
);
3086 SDValue
DAGTypeLegalizer::WidenVecRes_EXTEND_VECTOR_INREG(SDNode
*N
) {
3087 unsigned Opcode
= N
->getOpcode();
3088 SDValue InOp
= N
->getOperand(0);
3091 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3092 EVT WidenSVT
= WidenVT
.getVectorElementType();
3093 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
3095 EVT InVT
= InOp
.getValueType();
3096 EVT InSVT
= InVT
.getVectorElementType();
3097 unsigned InVTNumElts
= InVT
.getVectorNumElements();
3099 if (getTypeAction(InVT
) == TargetLowering::TypeWidenVector
) {
3100 InOp
= GetWidenedVector(InOp
);
3101 InVT
= InOp
.getValueType();
3102 if (InVT
.getSizeInBits() == WidenVT
.getSizeInBits()) {
3104 case ISD::ANY_EXTEND_VECTOR_INREG
:
3105 case ISD::SIGN_EXTEND_VECTOR_INREG
:
3106 case ISD::ZERO_EXTEND_VECTOR_INREG
:
3107 return DAG
.getNode(Opcode
, DL
, WidenVT
, InOp
);
3112 // Unroll, extend the scalars and rebuild the vector.
3113 SmallVector
<SDValue
, 16> Ops
;
3114 for (unsigned i
= 0, e
= std::min(InVTNumElts
, WidenNumElts
); i
!= e
; ++i
) {
3115 SDValue Val
= DAG
.getNode(ISD::EXTRACT_VECTOR_ELT
, DL
, InSVT
, InOp
,
3116 DAG
.getConstant(i
, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3118 case ISD::ANY_EXTEND_VECTOR_INREG
:
3119 Val
= DAG
.getNode(ISD::ANY_EXTEND
, DL
, WidenSVT
, Val
);
3121 case ISD::SIGN_EXTEND_VECTOR_INREG
:
3122 Val
= DAG
.getNode(ISD::SIGN_EXTEND
, DL
, WidenSVT
, Val
);
3124 case ISD::ZERO_EXTEND_VECTOR_INREG
:
3125 Val
= DAG
.getNode(ISD::ZERO_EXTEND
, DL
, WidenSVT
, Val
);
3128 llvm_unreachable("A *_EXTEND_VECTOR_INREG node was expected");
3133 while (Ops
.size() != WidenNumElts
)
3134 Ops
.push_back(DAG
.getUNDEF(WidenSVT
));
3136 return DAG
.getBuildVector(WidenVT
, DL
, Ops
);
3139 SDValue
DAGTypeLegalizer::WidenVecRes_FCOPYSIGN(SDNode
*N
) {
3140 // If this is an FCOPYSIGN with same input types, we can treat it as a
3141 // normal (can trap) binary op.
3142 if (N
->getOperand(0).getValueType() == N
->getOperand(1).getValueType())
3143 return WidenVecRes_BinaryCanTrap(N
);
3145 // If the types are different, fall back to unrolling.
3146 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3147 return DAG
.UnrollVectorOp(N
, WidenVT
.getVectorNumElements());
3150 SDValue
DAGTypeLegalizer::WidenVecRes_POWI(SDNode
*N
) {
3151 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3152 SDValue InOp
= GetWidenedVector(N
->getOperand(0));
3153 SDValue ShOp
= N
->getOperand(1);
3154 return DAG
.getNode(N
->getOpcode(), SDLoc(N
), WidenVT
, InOp
, ShOp
);
3157 SDValue
DAGTypeLegalizer::WidenVecRes_Shift(SDNode
*N
) {
3158 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3159 SDValue InOp
= GetWidenedVector(N
->getOperand(0));
3160 SDValue ShOp
= N
->getOperand(1);
3162 EVT ShVT
= ShOp
.getValueType();
3163 if (getTypeAction(ShVT
) == TargetLowering::TypeWidenVector
) {
3164 ShOp
= GetWidenedVector(ShOp
);
3165 ShVT
= ShOp
.getValueType();
3167 EVT ShWidenVT
= EVT::getVectorVT(*DAG
.getContext(),
3168 ShVT
.getVectorElementType(),
3169 WidenVT
.getVectorNumElements());
3170 if (ShVT
!= ShWidenVT
)
3171 ShOp
= ModifyToType(ShOp
, ShWidenVT
);
3173 return DAG
.getNode(N
->getOpcode(), SDLoc(N
), WidenVT
, InOp
, ShOp
);
3176 SDValue
DAGTypeLegalizer::WidenVecRes_Unary(SDNode
*N
) {
3177 // Unary op widening.
3178 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3179 SDValue InOp
= GetWidenedVector(N
->getOperand(0));
3180 return DAG
.getNode(N
->getOpcode(), SDLoc(N
), WidenVT
, InOp
);
3183 SDValue
DAGTypeLegalizer::WidenVecRes_InregOp(SDNode
*N
) {
3184 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3185 EVT ExtVT
= EVT::getVectorVT(*DAG
.getContext(),
3186 cast
<VTSDNode
>(N
->getOperand(1))->getVT()
3187 .getVectorElementType(),
3188 WidenVT
.getVectorNumElements());
3189 SDValue WidenLHS
= GetWidenedVector(N
->getOperand(0));
3190 return DAG
.getNode(N
->getOpcode(), SDLoc(N
),
3191 WidenVT
, WidenLHS
, DAG
.getValueType(ExtVT
));
3194 SDValue
DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(SDNode
*N
, unsigned ResNo
) {
3195 SDValue WidenVec
= DisintegrateMERGE_VALUES(N
, ResNo
);
3196 return GetWidenedVector(WidenVec
);
3199 SDValue
DAGTypeLegalizer::WidenVecRes_BITCAST(SDNode
*N
) {
3200 SDValue InOp
= N
->getOperand(0);
3201 EVT InVT
= InOp
.getValueType();
3202 EVT VT
= N
->getValueType(0);
3203 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
3206 switch (getTypeAction(InVT
)) {
3207 case TargetLowering::TypeLegal
:
3209 case TargetLowering::TypePromoteInteger
:
3210 // If the incoming type is a vector that is being promoted, then
3211 // we know that the elements are arranged differently and that we
3212 // must perform the conversion using a stack slot.
3213 if (InVT
.isVector())
3216 // If the InOp is promoted to the same size, convert it. Otherwise,
3217 // fall out of the switch and widen the promoted input.
3218 InOp
= GetPromotedInteger(InOp
);
3219 InVT
= InOp
.getValueType();
3220 if (WidenVT
.bitsEq(InVT
))
3221 return DAG
.getNode(ISD::BITCAST
, dl
, WidenVT
, InOp
);
3223 case TargetLowering::TypeSoftenFloat
:
3224 case TargetLowering::TypePromoteFloat
:
3225 case TargetLowering::TypeExpandInteger
:
3226 case TargetLowering::TypeExpandFloat
:
3227 case TargetLowering::TypeScalarizeVector
:
3228 case TargetLowering::TypeSplitVector
:
3230 case TargetLowering::TypeWidenVector
:
3231 // If the InOp is widened to the same size, convert it. Otherwise, fall
3232 // out of the switch and widen the widened input.
3233 InOp
= GetWidenedVector(InOp
);
3234 InVT
= InOp
.getValueType();
3235 if (WidenVT
.bitsEq(InVT
))
3236 // The input widens to the same size. Convert to the widen value.
3237 return DAG
.getNode(ISD::BITCAST
, dl
, WidenVT
, InOp
);
3241 unsigned WidenSize
= WidenVT
.getSizeInBits();
3242 unsigned InSize
= InVT
.getSizeInBits();
3243 // x86mmx is not an acceptable vector element type, so don't try.
3244 if (WidenSize
% InSize
== 0 && InVT
!= MVT::x86mmx
) {
3245 // Determine new input vector type. The new input vector type will use
3246 // the same element type (if its a vector) or use the input type as a
3247 // vector. It is the same size as the type to widen to.
3249 unsigned NewNumElts
= WidenSize
/ InSize
;
3250 if (InVT
.isVector()) {
3251 EVT InEltVT
= InVT
.getVectorElementType();
3252 NewInVT
= EVT::getVectorVT(*DAG
.getContext(), InEltVT
,
3253 WidenSize
/ InEltVT
.getSizeInBits());
3255 NewInVT
= EVT::getVectorVT(*DAG
.getContext(), InVT
, NewNumElts
);
3258 if (TLI
.isTypeLegal(NewInVT
)) {
3260 if (InVT
.isVector()) {
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 SmallVector
<SDValue
, 16> Ops(NewNumElts
, DAG
.getUNDEF(InVT
));
3269 NewVec
= DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, NewInVT
, Ops
);
3271 NewVec
= DAG
.getNode(ISD::SCALAR_TO_VECTOR
, dl
, NewInVT
, InOp
);
3273 return DAG
.getNode(ISD::BITCAST
, dl
, WidenVT
, NewVec
);
3277 return CreateStackStoreLoad(InOp
, WidenVT
);
3280 SDValue
DAGTypeLegalizer::WidenVecRes_BUILD_VECTOR(SDNode
*N
) {
3282 // Build a vector with undefined for the new nodes.
3283 EVT VT
= N
->getValueType(0);
3285 // Integer BUILD_VECTOR operands may be larger than the node's vector element
3286 // type. The UNDEFs need to have the same type as the existing operands.
3287 EVT EltVT
= N
->getOperand(0).getValueType();
3288 unsigned NumElts
= VT
.getVectorNumElements();
3290 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
3291 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
3293 SmallVector
<SDValue
, 16> NewOps(N
->op_begin(), N
->op_end());
3294 assert(WidenNumElts
>= NumElts
&& "Shrinking vector instead of widening!");
3295 NewOps
.append(WidenNumElts
- NumElts
, DAG
.getUNDEF(EltVT
));
3297 return DAG
.getBuildVector(WidenVT
, dl
, NewOps
);
3300 SDValue
DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode
*N
) {
3301 EVT InVT
= N
->getOperand(0).getValueType();
3302 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3304 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
3305 unsigned NumInElts
= InVT
.getVectorNumElements();
3306 unsigned NumOperands
= N
->getNumOperands();
3308 bool InputWidened
= false; // Indicates we need to widen the input.
3309 if (getTypeAction(InVT
) != TargetLowering::TypeWidenVector
) {
3310 if (WidenVT
.getVectorNumElements() % InVT
.getVectorNumElements() == 0) {
3311 // Add undef vectors to widen to correct length.
3312 unsigned NumConcat
= WidenVT
.getVectorNumElements() /
3313 InVT
.getVectorNumElements();
3314 SDValue UndefVal
= DAG
.getUNDEF(InVT
);
3315 SmallVector
<SDValue
, 16> Ops(NumConcat
);
3316 for (unsigned i
=0; i
< NumOperands
; ++i
)
3317 Ops
[i
] = N
->getOperand(i
);
3318 for (unsigned i
= NumOperands
; i
!= NumConcat
; ++i
)
3320 return DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, WidenVT
, Ops
);
3323 InputWidened
= true;
3324 if (WidenVT
== TLI
.getTypeToTransformTo(*DAG
.getContext(), InVT
)) {
3325 // The inputs and the result are widen to the same value.
3327 for (i
=1; i
< NumOperands
; ++i
)
3328 if (!N
->getOperand(i
).isUndef())
3331 if (i
== NumOperands
)
3332 // Everything but the first operand is an UNDEF so just return the
3333 // widened first operand.
3334 return GetWidenedVector(N
->getOperand(0));
3336 if (NumOperands
== 2) {
3337 // Replace concat of two operands with a shuffle.
3338 SmallVector
<int, 16> MaskOps(WidenNumElts
, -1);
3339 for (unsigned i
= 0; i
< NumInElts
; ++i
) {
3341 MaskOps
[i
+ NumInElts
] = i
+ WidenNumElts
;
3343 return DAG
.getVectorShuffle(WidenVT
, dl
,
3344 GetWidenedVector(N
->getOperand(0)),
3345 GetWidenedVector(N
->getOperand(1)),
3351 // Fall back to use extracts and build vector.
3352 EVT EltVT
= WidenVT
.getVectorElementType();
3353 SmallVector
<SDValue
, 16> Ops(WidenNumElts
);
3355 for (unsigned i
=0; i
< NumOperands
; ++i
) {
3356 SDValue InOp
= N
->getOperand(i
);
3358 InOp
= GetWidenedVector(InOp
);
3359 for (unsigned j
=0; j
< NumInElts
; ++j
)
3360 Ops
[Idx
++] = DAG
.getNode(
3361 ISD::EXTRACT_VECTOR_ELT
, dl
, EltVT
, InOp
,
3362 DAG
.getConstant(j
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3364 SDValue UndefVal
= DAG
.getUNDEF(EltVT
);
3365 for (; Idx
< WidenNumElts
; ++Idx
)
3366 Ops
[Idx
] = UndefVal
;
3367 return DAG
.getBuildVector(WidenVT
, dl
, Ops
);
3370 SDValue
DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode
*N
) {
3371 EVT VT
= N
->getValueType(0);
3372 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
3373 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
3374 SDValue InOp
= N
->getOperand(0);
3375 SDValue Idx
= N
->getOperand(1);
3378 if (getTypeAction(InOp
.getValueType()) == TargetLowering::TypeWidenVector
)
3379 InOp
= GetWidenedVector(InOp
);
3381 EVT InVT
= InOp
.getValueType();
3383 // Check if we can just return the input vector after widening.
3384 uint64_t IdxVal
= cast
<ConstantSDNode
>(Idx
)->getZExtValue();
3385 if (IdxVal
== 0 && InVT
== WidenVT
)
3388 // Check if we can extract from the vector.
3389 unsigned InNumElts
= InVT
.getVectorNumElements();
3390 if (IdxVal
% WidenNumElts
== 0 && IdxVal
+ WidenNumElts
< InNumElts
)
3391 return DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, dl
, WidenVT
, InOp
, Idx
);
3393 // We could try widening the input to the right length but for now, extract
3394 // the original elements, fill the rest with undefs and build a vector.
3395 SmallVector
<SDValue
, 16> Ops(WidenNumElts
);
3396 EVT EltVT
= VT
.getVectorElementType();
3397 unsigned NumElts
= VT
.getVectorNumElements();
3399 for (i
=0; i
< NumElts
; ++i
)
3401 DAG
.getNode(ISD::EXTRACT_VECTOR_ELT
, dl
, EltVT
, InOp
,
3402 DAG
.getConstant(IdxVal
+ i
, dl
,
3403 TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3405 SDValue UndefVal
= DAG
.getUNDEF(EltVT
);
3406 for (; i
< WidenNumElts
; ++i
)
3408 return DAG
.getBuildVector(WidenVT
, dl
, Ops
);
3411 SDValue
DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode
*N
) {
3412 SDValue InOp
= GetWidenedVector(N
->getOperand(0));
3413 return DAG
.getNode(ISD::INSERT_VECTOR_ELT
, SDLoc(N
),
3414 InOp
.getValueType(), InOp
,
3415 N
->getOperand(1), N
->getOperand(2));
3418 SDValue
DAGTypeLegalizer::WidenVecRes_LOAD(SDNode
*N
) {
3419 LoadSDNode
*LD
= cast
<LoadSDNode
>(N
);
3420 ISD::LoadExtType ExtType
= LD
->getExtensionType();
3423 SmallVector
<SDValue
, 16> LdChain
; // Chain for the series of load
3424 if (ExtType
!= ISD::NON_EXTLOAD
)
3425 Result
= GenWidenVectorExtLoads(LdChain
, LD
, ExtType
);
3427 Result
= GenWidenVectorLoads(LdChain
, LD
);
3429 // If we generate a single load, we can use that for the chain. Otherwise,
3430 // build a factor node to remember the multiple loads are independent and
3433 if (LdChain
.size() == 1)
3434 NewChain
= LdChain
[0];
3436 NewChain
= DAG
.getNode(ISD::TokenFactor
, SDLoc(LD
), MVT::Other
, LdChain
);
3438 // Modified the chain - switch anything that used the old chain to use
3440 ReplaceValueWith(SDValue(N
, 1), NewChain
);
3445 SDValue
DAGTypeLegalizer::WidenVecRes_MLOAD(MaskedLoadSDNode
*N
) {
3447 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(),N
->getValueType(0));
3448 SDValue Mask
= N
->getMask();
3449 EVT MaskVT
= Mask
.getValueType();
3450 SDValue PassThru
= GetWidenedVector(N
->getPassThru());
3451 ISD::LoadExtType ExtType
= N
->getExtensionType();
3454 // The mask should be widened as well
3455 EVT WideMaskVT
= EVT::getVectorVT(*DAG
.getContext(),
3456 MaskVT
.getVectorElementType(),
3457 WidenVT
.getVectorNumElements());
3458 Mask
= ModifyToType(Mask
, WideMaskVT
, true);
3460 SDValue Res
= DAG
.getMaskedLoad(WidenVT
, dl
, N
->getChain(), N
->getBasePtr(),
3461 Mask
, PassThru
, N
->getMemoryVT(),
3462 N
->getMemOperand(), ExtType
,
3463 N
->isExpandingLoad());
3464 // Legalize the chain result - switch anything that used the old chain to
3466 ReplaceValueWith(SDValue(N
, 1), Res
.getValue(1));
3470 SDValue
DAGTypeLegalizer::WidenVecRes_MGATHER(MaskedGatherSDNode
*N
) {
3472 EVT WideVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3473 SDValue Mask
= N
->getMask();
3474 EVT MaskVT
= Mask
.getValueType();
3475 SDValue PassThru
= GetWidenedVector(N
->getPassThru());
3476 SDValue Scale
= N
->getScale();
3477 unsigned NumElts
= WideVT
.getVectorNumElements();
3480 // The mask should be widened as well
3481 EVT WideMaskVT
= EVT::getVectorVT(*DAG
.getContext(),
3482 MaskVT
.getVectorElementType(),
3483 WideVT
.getVectorNumElements());
3484 Mask
= ModifyToType(Mask
, WideMaskVT
, true);
3486 // Widen the Index operand
3487 SDValue Index
= N
->getIndex();
3488 EVT WideIndexVT
= EVT::getVectorVT(*DAG
.getContext(),
3489 Index
.getValueType().getScalarType(),
3491 Index
= ModifyToType(Index
, WideIndexVT
);
3492 SDValue Ops
[] = { N
->getChain(), PassThru
, Mask
, N
->getBasePtr(), Index
,
3494 SDValue Res
= DAG
.getMaskedGather(DAG
.getVTList(WideVT
, MVT::Other
),
3495 N
->getMemoryVT(), dl
, Ops
,
3496 N
->getMemOperand());
3498 // Legalize the chain result - switch anything that used the old chain to
3500 ReplaceValueWith(SDValue(N
, 1), Res
.getValue(1));
3504 SDValue
DAGTypeLegalizer::WidenVecRes_SCALAR_TO_VECTOR(SDNode
*N
) {
3505 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3506 return DAG
.getNode(ISD::SCALAR_TO_VECTOR
, SDLoc(N
),
3507 WidenVT
, N
->getOperand(0));
3510 // Return true if this is a node that could have two SETCCs as operands.
3511 static inline bool isLogicalMaskOp(unsigned Opcode
) {
3521 // This is used just for the assert in convertMask(). Check that this either
3522 // a SETCC or a previously handled SETCC by convertMask().
3524 static inline bool isSETCCorConvertedSETCC(SDValue N
) {
3525 if (N
.getOpcode() == ISD::EXTRACT_SUBVECTOR
)
3526 N
= N
.getOperand(0);
3527 else if (N
.getOpcode() == ISD::CONCAT_VECTORS
) {
3528 for (unsigned i
= 1; i
< N
->getNumOperands(); ++i
)
3529 if (!N
->getOperand(i
)->isUndef())
3531 N
= N
.getOperand(0);
3534 if (N
.getOpcode() == ISD::TRUNCATE
)
3535 N
= N
.getOperand(0);
3536 else if (N
.getOpcode() == ISD::SIGN_EXTEND
)
3537 N
= N
.getOperand(0);
3539 if (isLogicalMaskOp(N
.getOpcode()))
3540 return isSETCCorConvertedSETCC(N
.getOperand(0)) &&
3541 isSETCCorConvertedSETCC(N
.getOperand(1));
3543 return (N
.getOpcode() == ISD::SETCC
||
3544 ISD::isBuildVectorOfConstantSDNodes(N
.getNode()));
3548 // Return a mask of vector type MaskVT to replace InMask. Also adjust MaskVT
3549 // to ToMaskVT if needed with vector extension or truncation.
3550 SDValue
DAGTypeLegalizer::convertMask(SDValue InMask
, EVT MaskVT
,
3552 // Currently a SETCC or a AND/OR/XOR with two SETCCs are handled.
3553 // FIXME: This code seems to be too restrictive, we might consider
3554 // generalizing it or dropping it.
3555 assert(isSETCCorConvertedSETCC(InMask
) && "Unexpected mask argument.");
3557 // Make a new Mask node, with a legal result VT.
3558 SmallVector
<SDValue
, 4> Ops
;
3559 for (unsigned i
= 0, e
= InMask
->getNumOperands(); i
< e
; ++i
)
3560 Ops
.push_back(InMask
->getOperand(i
));
3561 SDValue Mask
= DAG
.getNode(InMask
->getOpcode(), SDLoc(InMask
), MaskVT
, Ops
);
3563 // If MaskVT has smaller or bigger elements than ToMaskVT, a vector sign
3564 // extend or truncate is needed.
3565 LLVMContext
&Ctx
= *DAG
.getContext();
3566 unsigned MaskScalarBits
= MaskVT
.getScalarSizeInBits();
3567 unsigned ToMaskScalBits
= ToMaskVT
.getScalarSizeInBits();
3568 if (MaskScalarBits
< ToMaskScalBits
) {
3569 EVT ExtVT
= EVT::getVectorVT(Ctx
, ToMaskVT
.getVectorElementType(),
3570 MaskVT
.getVectorNumElements());
3571 Mask
= DAG
.getNode(ISD::SIGN_EXTEND
, SDLoc(Mask
), ExtVT
, Mask
);
3572 } else if (MaskScalarBits
> ToMaskScalBits
) {
3573 EVT TruncVT
= EVT::getVectorVT(Ctx
, ToMaskVT
.getVectorElementType(),
3574 MaskVT
.getVectorNumElements());
3575 Mask
= DAG
.getNode(ISD::TRUNCATE
, SDLoc(Mask
), TruncVT
, Mask
);
3578 assert(Mask
->getValueType(0).getScalarSizeInBits() ==
3579 ToMaskVT
.getScalarSizeInBits() &&
3580 "Mask should have the right element size by now.");
3582 // Adjust Mask to the right number of elements.
3583 unsigned CurrMaskNumEls
= Mask
->getValueType(0).getVectorNumElements();
3584 if (CurrMaskNumEls
> ToMaskVT
.getVectorNumElements()) {
3585 MVT IdxTy
= TLI
.getVectorIdxTy(DAG
.getDataLayout());
3586 SDValue ZeroIdx
= DAG
.getConstant(0, SDLoc(Mask
), IdxTy
);
3587 Mask
= DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, SDLoc(Mask
), ToMaskVT
, Mask
,
3589 } else if (CurrMaskNumEls
< ToMaskVT
.getVectorNumElements()) {
3590 unsigned NumSubVecs
= (ToMaskVT
.getVectorNumElements() / CurrMaskNumEls
);
3591 EVT SubVT
= Mask
->getValueType(0);
3592 SmallVector
<SDValue
, 16> SubOps(NumSubVecs
, DAG
.getUNDEF(SubVT
));
3594 Mask
= DAG
.getNode(ISD::CONCAT_VECTORS
, SDLoc(Mask
), ToMaskVT
, SubOps
);
3597 assert((Mask
->getValueType(0) == ToMaskVT
) &&
3598 "A mask of ToMaskVT should have been produced by now.");
3603 // This method tries to handle VSELECT and its mask by legalizing operands
3604 // (which may require widening) and if needed adjusting the mask vector type
3605 // to match that of the VSELECT. Without it, many cases end up with
3606 // scalarization of the SETCC, with many unnecessary instructions.
3607 SDValue
DAGTypeLegalizer::WidenVSELECTAndMask(SDNode
*N
) {
3608 LLVMContext
&Ctx
= *DAG
.getContext();
3609 SDValue Cond
= N
->getOperand(0);
3611 if (N
->getOpcode() != ISD::VSELECT
)
3614 if (Cond
->getOpcode() != ISD::SETCC
&& !isLogicalMaskOp(Cond
->getOpcode()))
3617 // If this is a splitted VSELECT that was previously already handled, do
3619 EVT CondVT
= Cond
->getValueType(0);
3620 if (CondVT
.getScalarSizeInBits() != 1)
3623 EVT VSelVT
= N
->getValueType(0);
3624 // Only handle vector types which are a power of 2.
3625 if (!isPowerOf2_64(VSelVT
.getSizeInBits()))
3628 // Don't touch if this will be scalarized.
3629 EVT FinalVT
= VSelVT
;
3630 while (getTypeAction(FinalVT
) == TargetLowering::TypeSplitVector
)
3631 FinalVT
= FinalVT
.getHalfNumVectorElementsVT(Ctx
);
3633 if (FinalVT
.getVectorNumElements() == 1)
3636 // If there is support for an i1 vector mask, don't touch.
3637 if (Cond
.getOpcode() == ISD::SETCC
) {
3638 EVT SetCCOpVT
= Cond
->getOperand(0).getValueType();
3639 while (TLI
.getTypeAction(Ctx
, SetCCOpVT
) != TargetLowering::TypeLegal
)
3640 SetCCOpVT
= TLI
.getTypeToTransformTo(Ctx
, SetCCOpVT
);
3641 EVT SetCCResVT
= getSetCCResultType(SetCCOpVT
);
3642 if (SetCCResVT
.getScalarSizeInBits() == 1)
3644 } else if (CondVT
.getScalarType() == MVT::i1
) {
3645 // If there is support for an i1 vector mask (or only scalar i1 conditions),
3647 while (TLI
.getTypeAction(Ctx
, CondVT
) != TargetLowering::TypeLegal
)
3648 CondVT
= TLI
.getTypeToTransformTo(Ctx
, CondVT
);
3650 if (CondVT
.getScalarType() == MVT::i1
)
3654 // Get the VT and operands for VSELECT, and widen if needed.
3655 SDValue VSelOp1
= N
->getOperand(1);
3656 SDValue VSelOp2
= N
->getOperand(2);
3657 if (getTypeAction(VSelVT
) == TargetLowering::TypeWidenVector
) {
3658 VSelVT
= TLI
.getTypeToTransformTo(Ctx
, VSelVT
);
3659 VSelOp1
= GetWidenedVector(VSelOp1
);
3660 VSelOp2
= GetWidenedVector(VSelOp2
);
3663 // The mask of the VSELECT should have integer elements.
3664 EVT ToMaskVT
= VSelVT
;
3665 if (!ToMaskVT
.getScalarType().isInteger())
3666 ToMaskVT
= ToMaskVT
.changeVectorElementTypeToInteger();
3669 if (Cond
->getOpcode() == ISD::SETCC
) {
3670 EVT MaskVT
= getSetCCResultType(Cond
.getOperand(0).getValueType());
3671 Mask
= convertMask(Cond
, MaskVT
, ToMaskVT
);
3672 } else if (isLogicalMaskOp(Cond
->getOpcode()) &&
3673 Cond
->getOperand(0).getOpcode() == ISD::SETCC
&&
3674 Cond
->getOperand(1).getOpcode() == ISD::SETCC
) {
3675 // Cond is (AND/OR/XOR (SETCC, SETCC))
3676 SDValue SETCC0
= Cond
->getOperand(0);
3677 SDValue SETCC1
= Cond
->getOperand(1);
3678 EVT VT0
= getSetCCResultType(SETCC0
.getOperand(0).getValueType());
3679 EVT VT1
= getSetCCResultType(SETCC1
.getOperand(0).getValueType());
3680 unsigned ScalarBits0
= VT0
.getScalarSizeInBits();
3681 unsigned ScalarBits1
= VT1
.getScalarSizeInBits();
3682 unsigned ScalarBits_ToMask
= ToMaskVT
.getScalarSizeInBits();
3684 // If the two SETCCs have different VTs, either extend/truncate one of
3685 // them to the other "towards" ToMaskVT, or truncate one and extend the
3686 // other to ToMaskVT.
3687 if (ScalarBits0
!= ScalarBits1
) {
3688 EVT NarrowVT
= ((ScalarBits0
< ScalarBits1
) ? VT0
: VT1
);
3689 EVT WideVT
= ((NarrowVT
== VT0
) ? VT1
: VT0
);
3690 if (ScalarBits_ToMask
>= WideVT
.getScalarSizeInBits())
3692 else if (ScalarBits_ToMask
<= NarrowVT
.getScalarSizeInBits())
3697 // If the two SETCCs have the same VT, don't change it.
3700 // Make new SETCCs and logical nodes.
3701 SETCC0
= convertMask(SETCC0
, VT0
, MaskVT
);
3702 SETCC1
= convertMask(SETCC1
, VT1
, MaskVT
);
3703 Cond
= DAG
.getNode(Cond
->getOpcode(), SDLoc(Cond
), MaskVT
, SETCC0
, SETCC1
);
3705 // Convert the logical op for VSELECT if needed.
3706 Mask
= convertMask(Cond
, MaskVT
, ToMaskVT
);
3710 return DAG
.getNode(ISD::VSELECT
, SDLoc(N
), VSelVT
, Mask
, VSelOp1
, VSelOp2
);
3713 SDValue
DAGTypeLegalizer::WidenVecRes_SELECT(SDNode
*N
) {
3714 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3715 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
3717 SDValue Cond1
= N
->getOperand(0);
3718 EVT CondVT
= Cond1
.getValueType();
3719 if (CondVT
.isVector()) {
3720 if (SDValue Res
= WidenVSELECTAndMask(N
))
3723 EVT CondEltVT
= CondVT
.getVectorElementType();
3724 EVT CondWidenVT
= EVT::getVectorVT(*DAG
.getContext(),
3725 CondEltVT
, WidenNumElts
);
3726 if (getTypeAction(CondVT
) == TargetLowering::TypeWidenVector
)
3727 Cond1
= GetWidenedVector(Cond1
);
3729 // If we have to split the condition there is no point in widening the
3730 // select. This would result in an cycle of widening the select ->
3731 // widening the condition operand -> splitting the condition operand ->
3732 // splitting the select -> widening the select. Instead split this select
3733 // further and widen the resulting type.
3734 if (getTypeAction(CondVT
) == TargetLowering::TypeSplitVector
) {
3735 SDValue SplitSelect
= SplitVecOp_VSELECT(N
, 0);
3736 SDValue Res
= ModifyToType(SplitSelect
, WidenVT
);
3740 if (Cond1
.getValueType() != CondWidenVT
)
3741 Cond1
= ModifyToType(Cond1
, CondWidenVT
);
3744 SDValue InOp1
= GetWidenedVector(N
->getOperand(1));
3745 SDValue InOp2
= GetWidenedVector(N
->getOperand(2));
3746 assert(InOp1
.getValueType() == WidenVT
&& InOp2
.getValueType() == WidenVT
);
3747 return DAG
.getNode(N
->getOpcode(), SDLoc(N
),
3748 WidenVT
, Cond1
, InOp1
, InOp2
);
3751 SDValue
DAGTypeLegalizer::WidenVecRes_SELECT_CC(SDNode
*N
) {
3752 SDValue InOp1
= GetWidenedVector(N
->getOperand(2));
3753 SDValue InOp2
= GetWidenedVector(N
->getOperand(3));
3754 return DAG
.getNode(ISD::SELECT_CC
, SDLoc(N
),
3755 InOp1
.getValueType(), N
->getOperand(0),
3756 N
->getOperand(1), InOp1
, InOp2
, N
->getOperand(4));
3759 SDValue
DAGTypeLegalizer::WidenVecRes_UNDEF(SDNode
*N
) {
3760 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3761 return DAG
.getUNDEF(WidenVT
);
3764 SDValue
DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode
*N
) {
3765 EVT VT
= N
->getValueType(0);
3768 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
3769 unsigned NumElts
= VT
.getVectorNumElements();
3770 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
3772 SDValue InOp1
= GetWidenedVector(N
->getOperand(0));
3773 SDValue InOp2
= GetWidenedVector(N
->getOperand(1));
3775 // Adjust mask based on new input vector length.
3776 SmallVector
<int, 16> NewMask
;
3777 for (unsigned i
= 0; i
!= NumElts
; ++i
) {
3778 int Idx
= N
->getMaskElt(i
);
3779 if (Idx
< (int)NumElts
)
3780 NewMask
.push_back(Idx
);
3782 NewMask
.push_back(Idx
- NumElts
+ WidenNumElts
);
3784 for (unsigned i
= NumElts
; i
!= WidenNumElts
; ++i
)
3785 NewMask
.push_back(-1);
3786 return DAG
.getVectorShuffle(WidenVT
, dl
, InOp1
, InOp2
, NewMask
);
3789 SDValue
DAGTypeLegalizer::WidenVecRes_SETCC(SDNode
*N
) {
3790 assert(N
->getValueType(0).isVector() &&
3791 N
->getOperand(0).getValueType().isVector() &&
3792 "Operands must be vectors");
3793 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
3794 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
3796 SDValue InOp1
= N
->getOperand(0);
3797 EVT InVT
= InOp1
.getValueType();
3798 assert(InVT
.isVector() && "can not widen non-vector type");
3799 EVT WidenInVT
= EVT::getVectorVT(*DAG
.getContext(),
3800 InVT
.getVectorElementType(), WidenNumElts
);
3802 // The input and output types often differ here, and it could be that while
3803 // we'd prefer to widen the result type, the input operands have been split.
3804 // In this case, we also need to split the result of this node as well.
3805 if (getTypeAction(InVT
) == TargetLowering::TypeSplitVector
) {
3806 SDValue SplitVSetCC
= SplitVecOp_VSETCC(N
);
3807 SDValue Res
= ModifyToType(SplitVSetCC
, WidenVT
);
3811 InOp1
= GetWidenedVector(InOp1
);
3812 SDValue InOp2
= GetWidenedVector(N
->getOperand(1));
3814 // Assume that the input and output will be widen appropriately. If not,
3815 // we will have to unroll it at some point.
3816 assert(InOp1
.getValueType() == WidenInVT
&&
3817 InOp2
.getValueType() == WidenInVT
&&
3818 "Input not widened to expected type!");
3820 return DAG
.getNode(ISD::SETCC
, SDLoc(N
),
3821 WidenVT
, InOp1
, InOp2
, N
->getOperand(2));
3825 //===----------------------------------------------------------------------===//
3826 // Widen Vector Operand
3827 //===----------------------------------------------------------------------===//
3828 bool DAGTypeLegalizer::WidenVectorOperand(SDNode
*N
, unsigned OpNo
) {
3829 LLVM_DEBUG(dbgs() << "Widen node operand " << OpNo
<< ": "; N
->dump(&DAG
);
3831 SDValue Res
= SDValue();
3833 // See if the target wants to custom widen this node.
3834 if (CustomLowerNode(N
, N
->getOperand(OpNo
).getValueType(), false))
3837 switch (N
->getOpcode()) {
3840 dbgs() << "WidenVectorOperand op #" << OpNo
<< ": ";
3844 llvm_unreachable("Do not know how to widen this operator's operand!");
3846 case ISD::BITCAST
: Res
= WidenVecOp_BITCAST(N
); break;
3847 case ISD::CONCAT_VECTORS
: Res
= WidenVecOp_CONCAT_VECTORS(N
); break;
3848 case ISD::EXTRACT_SUBVECTOR
: Res
= WidenVecOp_EXTRACT_SUBVECTOR(N
); break;
3849 case ISD::EXTRACT_VECTOR_ELT
: Res
= WidenVecOp_EXTRACT_VECTOR_ELT(N
); break;
3850 case ISD::STORE
: Res
= WidenVecOp_STORE(N
); break;
3851 case ISD::MSTORE
: Res
= WidenVecOp_MSTORE(N
, OpNo
); break;
3852 case ISD::MGATHER
: Res
= WidenVecOp_MGATHER(N
, OpNo
); break;
3853 case ISD::MSCATTER
: Res
= WidenVecOp_MSCATTER(N
, OpNo
); break;
3854 case ISD::SETCC
: Res
= WidenVecOp_SETCC(N
); break;
3855 case ISD::FCOPYSIGN
: Res
= WidenVecOp_FCOPYSIGN(N
); break;
3857 case ISD::ANY_EXTEND
:
3858 case ISD::SIGN_EXTEND
:
3859 case ISD::ZERO_EXTEND
:
3860 Res
= WidenVecOp_EXTEND(N
);
3863 case ISD::FP_EXTEND
:
3864 case ISD::FP_TO_SINT
:
3865 case ISD::FP_TO_UINT
:
3866 case ISD::SINT_TO_FP
:
3867 case ISD::UINT_TO_FP
:
3869 Res
= WidenVecOp_Convert(N
);
3873 // If Res is null, the sub-method took care of registering the result.
3874 if (!Res
.getNode()) return false;
3876 // If the result is N, the sub-method updated N in place. Tell the legalizer
3878 if (Res
.getNode() == N
)
3882 assert(Res
.getValueType() == N
->getValueType(0) && N
->getNumValues() == 1 &&
3883 "Invalid operand expansion");
3885 ReplaceValueWith(SDValue(N
, 0), Res
);
3889 SDValue
DAGTypeLegalizer::WidenVecOp_EXTEND(SDNode
*N
) {
3891 EVT VT
= N
->getValueType(0);
3893 SDValue InOp
= N
->getOperand(0);
3894 assert(getTypeAction(InOp
.getValueType()) ==
3895 TargetLowering::TypeWidenVector
&&
3896 "Unexpected type action");
3897 InOp
= GetWidenedVector(InOp
);
3898 assert(VT
.getVectorNumElements() <
3899 InOp
.getValueType().getVectorNumElements() &&
3900 "Input wasn't widened!");
3902 // We may need to further widen the operand until it has the same total
3903 // vector size as the result.
3904 EVT InVT
= InOp
.getValueType();
3905 if (InVT
.getSizeInBits() != VT
.getSizeInBits()) {
3906 EVT InEltVT
= InVT
.getVectorElementType();
3907 for (int i
= MVT::FIRST_VECTOR_VALUETYPE
, e
= MVT::LAST_VECTOR_VALUETYPE
; i
< e
; ++i
) {
3908 EVT FixedVT
= (MVT::SimpleValueType
)i
;
3909 EVT FixedEltVT
= FixedVT
.getVectorElementType();
3910 if (TLI
.isTypeLegal(FixedVT
) &&
3911 FixedVT
.getSizeInBits() == VT
.getSizeInBits() &&
3912 FixedEltVT
== InEltVT
) {
3913 assert(FixedVT
.getVectorNumElements() >= VT
.getVectorNumElements() &&
3914 "Not enough elements in the fixed type for the operand!");
3915 assert(FixedVT
.getVectorNumElements() != InVT
.getVectorNumElements() &&
3916 "We can't have the same type as we started with!");
3917 if (FixedVT
.getVectorNumElements() > InVT
.getVectorNumElements())
3919 ISD::INSERT_SUBVECTOR
, DL
, FixedVT
, DAG
.getUNDEF(FixedVT
), InOp
,
3920 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3923 ISD::EXTRACT_SUBVECTOR
, DL
, FixedVT
, InOp
,
3924 DAG
.getConstant(0, DL
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3928 InVT
= InOp
.getValueType();
3929 if (InVT
.getSizeInBits() != VT
.getSizeInBits())
3930 // We couldn't find a legal vector type that was a widening of the input
3931 // and could be extended in-register to the result type, so we have to
3933 return WidenVecOp_Convert(N
);
3936 // Use special DAG nodes to represent the operation of extending the
3938 switch (N
->getOpcode()) {
3940 llvm_unreachable("Extend legalization on extend operation!");
3941 case ISD::ANY_EXTEND
:
3942 return DAG
.getNode(ISD::ANY_EXTEND_VECTOR_INREG
, DL
, VT
, InOp
);
3943 case ISD::SIGN_EXTEND
:
3944 return DAG
.getNode(ISD::SIGN_EXTEND_VECTOR_INREG
, DL
, VT
, InOp
);
3945 case ISD::ZERO_EXTEND
:
3946 return DAG
.getNode(ISD::ZERO_EXTEND_VECTOR_INREG
, DL
, VT
, InOp
);
3950 SDValue
DAGTypeLegalizer::WidenVecOp_FCOPYSIGN(SDNode
*N
) {
3951 // The result (and first input) is legal, but the second input is illegal.
3952 // We can't do much to fix that, so just unroll and let the extracts off of
3953 // the second input be widened as needed later.
3954 return DAG
.UnrollVectorOp(N
);
3957 SDValue
DAGTypeLegalizer::WidenVecOp_Convert(SDNode
*N
) {
3958 // Since the result is legal and the input is illegal.
3959 EVT VT
= N
->getValueType(0);
3960 EVT EltVT
= VT
.getVectorElementType();
3962 unsigned NumElts
= VT
.getVectorNumElements();
3963 SDValue InOp
= N
->getOperand(0);
3964 assert(getTypeAction(InOp
.getValueType()) ==
3965 TargetLowering::TypeWidenVector
&&
3966 "Unexpected type action");
3967 InOp
= GetWidenedVector(InOp
);
3968 EVT InVT
= InOp
.getValueType();
3969 unsigned Opcode
= N
->getOpcode();
3971 // See if a widened result type would be legal, if so widen the node.
3972 EVT WideVT
= EVT::getVectorVT(*DAG
.getContext(), EltVT
,
3973 InVT
.getVectorNumElements());
3974 if (TLI
.isTypeLegal(WideVT
)) {
3975 SDValue Res
= DAG
.getNode(Opcode
, dl
, WideVT
, InOp
);
3977 ISD::EXTRACT_SUBVECTOR
, dl
, VT
, Res
,
3978 DAG
.getConstant(0, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
3981 EVT InEltVT
= InVT
.getVectorElementType();
3983 // Unroll the convert into some scalar code and create a nasty build vector.
3984 SmallVector
<SDValue
, 16> Ops(NumElts
);
3985 for (unsigned i
=0; i
< NumElts
; ++i
)
3986 Ops
[i
] = DAG
.getNode(
3989 ISD::EXTRACT_VECTOR_ELT
, dl
, InEltVT
, InOp
,
3990 DAG
.getConstant(i
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout()))));
3992 return DAG
.getBuildVector(VT
, dl
, Ops
);
3995 SDValue
DAGTypeLegalizer::WidenVecOp_BITCAST(SDNode
*N
) {
3996 EVT VT
= N
->getValueType(0);
3997 SDValue InOp
= GetWidenedVector(N
->getOperand(0));
3998 EVT InWidenVT
= InOp
.getValueType();
4001 // Check if we can convert between two legal vector types and extract.
4002 unsigned InWidenSize
= InWidenVT
.getSizeInBits();
4003 unsigned Size
= VT
.getSizeInBits();
4004 // x86mmx is not an acceptable vector element type, so don't try.
4005 if (InWidenSize
% Size
== 0 && !VT
.isVector() && VT
!= MVT::x86mmx
) {
4006 unsigned NewNumElts
= InWidenSize
/ Size
;
4007 EVT NewVT
= EVT::getVectorVT(*DAG
.getContext(), VT
, NewNumElts
);
4008 if (TLI
.isTypeLegal(NewVT
)) {
4009 SDValue BitOp
= DAG
.getNode(ISD::BITCAST
, dl
, NewVT
, InOp
);
4011 ISD::EXTRACT_VECTOR_ELT
, dl
, VT
, BitOp
,
4012 DAG
.getConstant(0, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4016 return CreateStackStoreLoad(InOp
, VT
);
4019 SDValue
DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode
*N
) {
4020 EVT VT
= N
->getValueType(0);
4021 EVT EltVT
= VT
.getVectorElementType();
4022 EVT InVT
= N
->getOperand(0).getValueType();
4025 // If the widen width for this operand is the same as the width of the concat
4026 // and all but the first operand is undef, just use the widened operand.
4027 unsigned NumOperands
= N
->getNumOperands();
4028 if (VT
== TLI
.getTypeToTransformTo(*DAG
.getContext(), InVT
)) {
4030 for (i
= 1; i
< NumOperands
; ++i
)
4031 if (!N
->getOperand(i
).isUndef())
4034 if (i
== NumOperands
)
4035 return GetWidenedVector(N
->getOperand(0));
4038 // Otherwise, fall back to a nasty build vector.
4039 unsigned NumElts
= VT
.getVectorNumElements();
4040 SmallVector
<SDValue
, 16> Ops(NumElts
);
4042 unsigned NumInElts
= InVT
.getVectorNumElements();
4045 for (unsigned i
=0; i
< NumOperands
; ++i
) {
4046 SDValue InOp
= N
->getOperand(i
);
4047 assert(getTypeAction(InOp
.getValueType()) ==
4048 TargetLowering::TypeWidenVector
&&
4049 "Unexpected type action");
4050 InOp
= GetWidenedVector(InOp
);
4051 for (unsigned j
=0; j
< NumInElts
; ++j
)
4052 Ops
[Idx
++] = DAG
.getNode(
4053 ISD::EXTRACT_VECTOR_ELT
, dl
, EltVT
, InOp
,
4054 DAG
.getConstant(j
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4056 return DAG
.getBuildVector(VT
, dl
, Ops
);
4059 SDValue
DAGTypeLegalizer::WidenVecOp_EXTRACT_SUBVECTOR(SDNode
*N
) {
4060 SDValue InOp
= GetWidenedVector(N
->getOperand(0));
4061 return DAG
.getNode(ISD::EXTRACT_SUBVECTOR
, SDLoc(N
),
4062 N
->getValueType(0), InOp
, N
->getOperand(1));
4065 SDValue
DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(SDNode
*N
) {
4066 SDValue InOp
= GetWidenedVector(N
->getOperand(0));
4067 return DAG
.getNode(ISD::EXTRACT_VECTOR_ELT
, SDLoc(N
),
4068 N
->getValueType(0), InOp
, N
->getOperand(1));
4071 SDValue
DAGTypeLegalizer::WidenVecOp_STORE(SDNode
*N
) {
4072 // We have to widen the value, but we want only to store the original
4074 StoreSDNode
*ST
= cast
<StoreSDNode
>(N
);
4076 if (!ST
->getMemoryVT().getScalarType().isByteSized())
4077 return TLI
.scalarizeVectorStore(ST
, DAG
);
4079 SmallVector
<SDValue
, 16> StChain
;
4080 if (ST
->isTruncatingStore())
4081 GenWidenVectorTruncStores(StChain
, ST
);
4083 GenWidenVectorStores(StChain
, ST
);
4085 if (StChain
.size() == 1)
4088 return DAG
.getNode(ISD::TokenFactor
, SDLoc(ST
), MVT::Other
, StChain
);
4091 SDValue
DAGTypeLegalizer::WidenVecOp_MSTORE(SDNode
*N
, unsigned OpNo
) {
4092 assert((OpNo
== 1 || OpNo
== 3) &&
4093 "Can widen only data or mask operand of mstore");
4094 MaskedStoreSDNode
*MST
= cast
<MaskedStoreSDNode
>(N
);
4095 SDValue Mask
= MST
->getMask();
4096 EVT MaskVT
= Mask
.getValueType();
4097 SDValue StVal
= MST
->getValue();
4102 StVal
= GetWidenedVector(StVal
);
4104 // The mask should be widened as well.
4105 EVT WideVT
= StVal
.getValueType();
4106 EVT WideMaskVT
= EVT::getVectorVT(*DAG
.getContext(),
4107 MaskVT
.getVectorElementType(),
4108 WideVT
.getVectorNumElements());
4109 Mask
= ModifyToType(Mask
, WideMaskVT
, true);
4112 EVT WideMaskVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), MaskVT
);
4113 Mask
= ModifyToType(Mask
, WideMaskVT
, true);
4115 EVT ValueVT
= StVal
.getValueType();
4116 EVT WideVT
= EVT::getVectorVT(*DAG
.getContext(),
4117 ValueVT
.getVectorElementType(),
4118 WideMaskVT
.getVectorNumElements());
4119 StVal
= ModifyToType(StVal
, WideVT
);
4122 assert(Mask
.getValueType().getVectorNumElements() ==
4123 StVal
.getValueType().getVectorNumElements() &&
4124 "Mask and data vectors should have the same number of elements");
4125 return DAG
.getMaskedStore(MST
->getChain(), dl
, StVal
, MST
->getBasePtr(),
4126 Mask
, MST
->getMemoryVT(), MST
->getMemOperand(),
4127 false, MST
->isCompressingStore());
4130 SDValue
DAGTypeLegalizer::WidenVecOp_MGATHER(SDNode
*N
, unsigned OpNo
) {
4131 assert(OpNo
== 4 && "Can widen only the index of mgather");
4132 auto *MG
= cast
<MaskedGatherSDNode
>(N
);
4133 SDValue DataOp
= MG
->getPassThru();
4134 SDValue Mask
= MG
->getMask();
4135 SDValue Scale
= MG
->getScale();
4137 // Just widen the index. It's allowed to have extra elements.
4138 SDValue Index
= GetWidenedVector(MG
->getIndex());
4141 SDValue Ops
[] = {MG
->getChain(), DataOp
, Mask
, MG
->getBasePtr(), Index
,
4143 SDValue Res
= DAG
.getMaskedGather(MG
->getVTList(), MG
->getMemoryVT(), dl
, Ops
,
4144 MG
->getMemOperand());
4145 ReplaceValueWith(SDValue(N
, 1), Res
.getValue(1));
4146 ReplaceValueWith(SDValue(N
, 0), Res
.getValue(0));
4150 SDValue
DAGTypeLegalizer::WidenVecOp_MSCATTER(SDNode
*N
, unsigned OpNo
) {
4151 MaskedScatterSDNode
*MSC
= cast
<MaskedScatterSDNode
>(N
);
4152 SDValue DataOp
= MSC
->getValue();
4153 SDValue Mask
= MSC
->getMask();
4154 SDValue Index
= MSC
->getIndex();
4155 SDValue Scale
= MSC
->getScale();
4159 DataOp
= GetWidenedVector(DataOp
);
4160 NumElts
= DataOp
.getValueType().getVectorNumElements();
4163 EVT IndexVT
= Index
.getValueType();
4164 EVT WideIndexVT
= EVT::getVectorVT(*DAG
.getContext(),
4165 IndexVT
.getVectorElementType(), NumElts
);
4166 Index
= ModifyToType(Index
, WideIndexVT
);
4168 // The mask should be widened as well.
4169 EVT MaskVT
= Mask
.getValueType();
4170 EVT WideMaskVT
= EVT::getVectorVT(*DAG
.getContext(),
4171 MaskVT
.getVectorElementType(), NumElts
);
4172 Mask
= ModifyToType(Mask
, WideMaskVT
, true);
4173 } else if (OpNo
== 4) {
4174 // Just widen the index. It's allowed to have extra elements.
4175 Index
= GetWidenedVector(Index
);
4177 llvm_unreachable("Can't widen this operand of mscatter");
4179 SDValue Ops
[] = {MSC
->getChain(), DataOp
, Mask
, MSC
->getBasePtr(), Index
,
4181 return DAG
.getMaskedScatter(DAG
.getVTList(MVT::Other
),
4182 MSC
->getMemoryVT(), SDLoc(N
), Ops
,
4183 MSC
->getMemOperand());
4186 SDValue
DAGTypeLegalizer::WidenVecOp_SETCC(SDNode
*N
) {
4187 SDValue InOp0
= GetWidenedVector(N
->getOperand(0));
4188 SDValue InOp1
= GetWidenedVector(N
->getOperand(1));
4190 EVT VT
= N
->getValueType(0);
4192 // WARNING: In this code we widen the compare instruction with garbage.
4193 // This garbage may contain denormal floats which may be slow. Is this a real
4194 // concern ? Should we zero the unused lanes if this is a float compare ?
4196 // Get a new SETCC node to compare the newly widened operands.
4197 // Only some of the compared elements are legal.
4198 EVT SVT
= TLI
.getSetCCResultType(DAG
.getDataLayout(), *DAG
.getContext(),
4199 InOp0
.getValueType());
4200 // The result type is legal, if its vXi1, keep vXi1 for the new SETCC.
4201 if (VT
.getScalarType() == MVT::i1
)
4202 SVT
= EVT::getVectorVT(*DAG
.getContext(), MVT::i1
,
4203 SVT
.getVectorNumElements());
4205 SDValue WideSETCC
= DAG
.getNode(ISD::SETCC
, SDLoc(N
),
4206 SVT
, InOp0
, InOp1
, N
->getOperand(2));
4208 // Extract the needed results from the result vector.
4209 EVT ResVT
= EVT::getVectorVT(*DAG
.getContext(),
4210 SVT
.getVectorElementType(),
4211 VT
.getVectorNumElements());
4212 SDValue CC
= DAG
.getNode(
4213 ISD::EXTRACT_SUBVECTOR
, dl
, ResVT
, WideSETCC
,
4214 DAG
.getConstant(0, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4216 return PromoteTargetBoolean(CC
, VT
);
4220 //===----------------------------------------------------------------------===//
4221 // Vector Widening Utilities
4222 //===----------------------------------------------------------------------===//
4224 // Utility function to find the type to chop up a widen vector for load/store
4225 // TLI: Target lowering used to determine legal types.
4226 // Width: Width left need to load/store.
4227 // WidenVT: The widen vector type to load to/store from
4228 // Align: If 0, don't allow use of a wider type
4229 // WidenEx: If Align is not 0, the amount additional we can load/store from.
4231 static EVT
FindMemType(SelectionDAG
& DAG
, const TargetLowering
&TLI
,
4232 unsigned Width
, EVT WidenVT
,
4233 unsigned Align
= 0, unsigned WidenEx
= 0) {
4234 EVT WidenEltVT
= WidenVT
.getVectorElementType();
4235 unsigned WidenWidth
= WidenVT
.getSizeInBits();
4236 unsigned WidenEltWidth
= WidenEltVT
.getSizeInBits();
4237 unsigned AlignInBits
= Align
*8;
4239 // If we have one element to load/store, return it.
4240 EVT RetVT
= WidenEltVT
;
4241 if (Width
== WidenEltWidth
)
4244 // See if there is larger legal integer than the element type to load/store.
4246 for (VT
= (unsigned)MVT::LAST_INTEGER_VALUETYPE
;
4247 VT
>= (unsigned)MVT::FIRST_INTEGER_VALUETYPE
; --VT
) {
4248 EVT
MemVT((MVT::SimpleValueType
) VT
);
4249 unsigned MemVTWidth
= MemVT
.getSizeInBits();
4250 if (MemVT
.getSizeInBits() <= WidenEltWidth
)
4252 auto Action
= TLI
.getTypeAction(*DAG
.getContext(), MemVT
);
4253 if ((Action
== TargetLowering::TypeLegal
||
4254 Action
== TargetLowering::TypePromoteInteger
) &&
4255 (WidenWidth
% MemVTWidth
) == 0 &&
4256 isPowerOf2_32(WidenWidth
/ MemVTWidth
) &&
4257 (MemVTWidth
<= Width
||
4258 (Align
!=0 && MemVTWidth
<=AlignInBits
&& MemVTWidth
<=Width
+WidenEx
))) {
4264 // See if there is a larger vector type to load/store that has the same vector
4265 // element type and is evenly divisible with the WidenVT.
4266 for (VT
= (unsigned)MVT::LAST_VECTOR_VALUETYPE
;
4267 VT
>= (unsigned)MVT::FIRST_VECTOR_VALUETYPE
; --VT
) {
4268 EVT MemVT
= (MVT::SimpleValueType
) VT
;
4269 unsigned MemVTWidth
= MemVT
.getSizeInBits();
4270 if (TLI
.isTypeLegal(MemVT
) && WidenEltVT
== MemVT
.getVectorElementType() &&
4271 (WidenWidth
% MemVTWidth
) == 0 &&
4272 isPowerOf2_32(WidenWidth
/ MemVTWidth
) &&
4273 (MemVTWidth
<= Width
||
4274 (Align
!=0 && MemVTWidth
<=AlignInBits
&& MemVTWidth
<=Width
+WidenEx
))) {
4275 if (RetVT
.getSizeInBits() < MemVTWidth
|| MemVT
== WidenVT
)
4283 // Builds a vector type from scalar loads
4284 // VecTy: Resulting Vector type
4285 // LDOps: Load operators to build a vector type
4286 // [Start,End) the list of loads to use.
4287 static SDValue
BuildVectorFromScalar(SelectionDAG
& DAG
, EVT VecTy
,
4288 SmallVectorImpl
<SDValue
> &LdOps
,
4289 unsigned Start
, unsigned End
) {
4290 const TargetLowering
&TLI
= DAG
.getTargetLoweringInfo();
4291 SDLoc
dl(LdOps
[Start
]);
4292 EVT LdTy
= LdOps
[Start
].getValueType();
4293 unsigned Width
= VecTy
.getSizeInBits();
4294 unsigned NumElts
= Width
/ LdTy
.getSizeInBits();
4295 EVT NewVecVT
= EVT::getVectorVT(*DAG
.getContext(), LdTy
, NumElts
);
4298 SDValue VecOp
= DAG
.getNode(ISD::SCALAR_TO_VECTOR
, dl
, NewVecVT
,LdOps
[Start
]);
4300 for (unsigned i
= Start
+ 1; i
!= End
; ++i
) {
4301 EVT NewLdTy
= LdOps
[i
].getValueType();
4302 if (NewLdTy
!= LdTy
) {
4303 NumElts
= Width
/ NewLdTy
.getSizeInBits();
4304 NewVecVT
= EVT::getVectorVT(*DAG
.getContext(), NewLdTy
, NumElts
);
4305 VecOp
= DAG
.getNode(ISD::BITCAST
, dl
, NewVecVT
, VecOp
);
4306 // Readjust position and vector position based on new load type.
4307 Idx
= Idx
* LdTy
.getSizeInBits() / NewLdTy
.getSizeInBits();
4310 VecOp
= DAG
.getNode(
4311 ISD::INSERT_VECTOR_ELT
, dl
, NewVecVT
, VecOp
, LdOps
[i
],
4312 DAG
.getConstant(Idx
++, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4314 return DAG
.getNode(ISD::BITCAST
, dl
, VecTy
, VecOp
);
4317 SDValue
DAGTypeLegalizer::GenWidenVectorLoads(SmallVectorImpl
<SDValue
> &LdChain
,
4319 // The strategy assumes that we can efficiently load power-of-two widths.
4320 // The routine chops the vector into the largest vector loads with the same
4321 // element type or scalar loads and then recombines it to the widen vector
4323 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(),LD
->getValueType(0));
4324 unsigned WidenWidth
= WidenVT
.getSizeInBits();
4325 EVT LdVT
= LD
->getMemoryVT();
4327 assert(LdVT
.isVector() && WidenVT
.isVector());
4328 assert(LdVT
.getVectorElementType() == WidenVT
.getVectorElementType());
4331 SDValue Chain
= LD
->getChain();
4332 SDValue BasePtr
= LD
->getBasePtr();
4333 unsigned Align
= LD
->getAlignment();
4334 MachineMemOperand::Flags MMOFlags
= LD
->getMemOperand()->getFlags();
4335 AAMDNodes AAInfo
= LD
->getAAInfo();
4337 int LdWidth
= LdVT
.getSizeInBits();
4338 int WidthDiff
= WidenWidth
- LdWidth
;
4339 unsigned LdAlign
= LD
->isVolatile() ? 0 : Align
; // Allow wider loads.
4341 // Find the vector type that can load from.
4342 EVT NewVT
= FindMemType(DAG
, TLI
, LdWidth
, WidenVT
, LdAlign
, WidthDiff
);
4343 int NewVTWidth
= NewVT
.getSizeInBits();
4344 SDValue LdOp
= DAG
.getLoad(NewVT
, dl
, Chain
, BasePtr
, LD
->getPointerInfo(),
4345 Align
, MMOFlags
, AAInfo
);
4346 LdChain
.push_back(LdOp
.getValue(1));
4348 // Check if we can load the element with one instruction.
4349 if (LdWidth
<= NewVTWidth
) {
4350 if (!NewVT
.isVector()) {
4351 unsigned NumElts
= WidenWidth
/ NewVTWidth
;
4352 EVT NewVecVT
= EVT::getVectorVT(*DAG
.getContext(), NewVT
, NumElts
);
4353 SDValue VecOp
= DAG
.getNode(ISD::SCALAR_TO_VECTOR
, dl
, NewVecVT
, LdOp
);
4354 return DAG
.getNode(ISD::BITCAST
, dl
, WidenVT
, VecOp
);
4356 if (NewVT
== WidenVT
)
4359 assert(WidenWidth
% NewVTWidth
== 0);
4360 unsigned NumConcat
= WidenWidth
/ NewVTWidth
;
4361 SmallVector
<SDValue
, 16> ConcatOps(NumConcat
);
4362 SDValue UndefVal
= DAG
.getUNDEF(NewVT
);
4363 ConcatOps
[0] = LdOp
;
4364 for (unsigned i
= 1; i
!= NumConcat
; ++i
)
4365 ConcatOps
[i
] = UndefVal
;
4366 return DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, WidenVT
, ConcatOps
);
4369 // Load vector by using multiple loads from largest vector to scalar.
4370 SmallVector
<SDValue
, 16> LdOps
;
4371 LdOps
.push_back(LdOp
);
4373 LdWidth
-= NewVTWidth
;
4374 unsigned Offset
= 0;
4376 while (LdWidth
> 0) {
4377 unsigned Increment
= NewVTWidth
/ 8;
4378 Offset
+= Increment
;
4379 BasePtr
= DAG
.getObjectPtrOffset(dl
, BasePtr
, Increment
);
4382 if (LdWidth
< NewVTWidth
) {
4383 // The current type we are using is too large. Find a better size.
4384 NewVT
= FindMemType(DAG
, TLI
, LdWidth
, WidenVT
, LdAlign
, WidthDiff
);
4385 NewVTWidth
= NewVT
.getSizeInBits();
4386 L
= DAG
.getLoad(NewVT
, dl
, Chain
, BasePtr
,
4387 LD
->getPointerInfo().getWithOffset(Offset
),
4388 MinAlign(Align
, Increment
), MMOFlags
, AAInfo
);
4389 LdChain
.push_back(L
.getValue(1));
4390 if (L
->getValueType(0).isVector() && NewVTWidth
>= LdWidth
) {
4391 // Later code assumes the vector loads produced will be mergeable, so we
4392 // must pad the final entry up to the previous width. Scalars are
4393 // combined separately.
4394 SmallVector
<SDValue
, 16> Loads
;
4396 unsigned size
= L
->getValueSizeInBits(0);
4397 while (size
< LdOp
->getValueSizeInBits(0)) {
4398 Loads
.push_back(DAG
.getUNDEF(L
->getValueType(0)));
4399 size
+= L
->getValueSizeInBits(0);
4401 L
= DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, LdOp
->getValueType(0), Loads
);
4404 L
= DAG
.getLoad(NewVT
, dl
, Chain
, BasePtr
,
4405 LD
->getPointerInfo().getWithOffset(Offset
),
4406 MinAlign(Align
, Increment
), MMOFlags
, AAInfo
);
4407 LdChain
.push_back(L
.getValue(1));
4413 LdWidth
-= NewVTWidth
;
4416 // Build the vector from the load operations.
4417 unsigned End
= LdOps
.size();
4418 if (!LdOps
[0].getValueType().isVector())
4419 // All the loads are scalar loads.
4420 return BuildVectorFromScalar(DAG
, WidenVT
, LdOps
, 0, End
);
4422 // If the load contains vectors, build the vector using concat vector.
4423 // All of the vectors used to load are power-of-2, and the scalar loads can be
4424 // combined to make a power-of-2 vector.
4425 SmallVector
<SDValue
, 16> ConcatOps(End
);
4428 EVT LdTy
= LdOps
[i
].getValueType();
4429 // First, combine the scalar loads to a vector.
4430 if (!LdTy
.isVector()) {
4431 for (--i
; i
>= 0; --i
) {
4432 LdTy
= LdOps
[i
].getValueType();
4433 if (LdTy
.isVector())
4436 ConcatOps
[--Idx
] = BuildVectorFromScalar(DAG
, LdTy
, LdOps
, i
+ 1, End
);
4438 ConcatOps
[--Idx
] = LdOps
[i
];
4439 for (--i
; i
>= 0; --i
) {
4440 EVT NewLdTy
= LdOps
[i
].getValueType();
4441 if (NewLdTy
!= LdTy
) {
4442 // Create a larger vector.
4443 ConcatOps
[End
-1] = DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, NewLdTy
,
4444 makeArrayRef(&ConcatOps
[Idx
], End
- Idx
));
4448 ConcatOps
[--Idx
] = LdOps
[i
];
4451 if (WidenWidth
== LdTy
.getSizeInBits() * (End
- Idx
))
4452 return DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, WidenVT
,
4453 makeArrayRef(&ConcatOps
[Idx
], End
- Idx
));
4455 // We need to fill the rest with undefs to build the vector.
4456 unsigned NumOps
= WidenWidth
/ LdTy
.getSizeInBits();
4457 SmallVector
<SDValue
, 16> WidenOps(NumOps
);
4458 SDValue UndefVal
= DAG
.getUNDEF(LdTy
);
4461 for (; i
!= End
-Idx
; ++i
)
4462 WidenOps
[i
] = ConcatOps
[Idx
+i
];
4463 for (; i
!= NumOps
; ++i
)
4464 WidenOps
[i
] = UndefVal
;
4466 return DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, WidenVT
, WidenOps
);
4470 DAGTypeLegalizer::GenWidenVectorExtLoads(SmallVectorImpl
<SDValue
> &LdChain
,
4472 ISD::LoadExtType ExtType
) {
4473 // For extension loads, it may not be more efficient to chop up the vector
4474 // and then extend it. Instead, we unroll the load and build a new vector.
4475 EVT WidenVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(),LD
->getValueType(0));
4476 EVT LdVT
= LD
->getMemoryVT();
4478 assert(LdVT
.isVector() && WidenVT
.isVector());
4481 SDValue Chain
= LD
->getChain();
4482 SDValue BasePtr
= LD
->getBasePtr();
4483 unsigned Align
= LD
->getAlignment();
4484 MachineMemOperand::Flags MMOFlags
= LD
->getMemOperand()->getFlags();
4485 AAMDNodes AAInfo
= LD
->getAAInfo();
4487 EVT EltVT
= WidenVT
.getVectorElementType();
4488 EVT LdEltVT
= LdVT
.getVectorElementType();
4489 unsigned NumElts
= LdVT
.getVectorNumElements();
4491 // Load each element and widen.
4492 unsigned WidenNumElts
= WidenVT
.getVectorNumElements();
4493 SmallVector
<SDValue
, 16> Ops(WidenNumElts
);
4494 unsigned Increment
= LdEltVT
.getSizeInBits() / 8;
4496 DAG
.getExtLoad(ExtType
, dl
, EltVT
, Chain
, BasePtr
, LD
->getPointerInfo(),
4497 LdEltVT
, Align
, MMOFlags
, AAInfo
);
4498 LdChain
.push_back(Ops
[0].getValue(1));
4499 unsigned i
= 0, Offset
= Increment
;
4500 for (i
=1; i
< NumElts
; ++i
, Offset
+= Increment
) {
4501 SDValue NewBasePtr
= DAG
.getObjectPtrOffset(dl
, BasePtr
, Offset
);
4502 Ops
[i
] = DAG
.getExtLoad(ExtType
, dl
, EltVT
, Chain
, NewBasePtr
,
4503 LD
->getPointerInfo().getWithOffset(Offset
), LdEltVT
,
4504 Align
, MMOFlags
, AAInfo
);
4505 LdChain
.push_back(Ops
[i
].getValue(1));
4508 // Fill the rest with undefs.
4509 SDValue UndefVal
= DAG
.getUNDEF(EltVT
);
4510 for (; i
!= WidenNumElts
; ++i
)
4513 return DAG
.getBuildVector(WidenVT
, dl
, Ops
);
4516 void DAGTypeLegalizer::GenWidenVectorStores(SmallVectorImpl
<SDValue
> &StChain
,
4518 // The strategy assumes that we can efficiently store power-of-two widths.
4519 // The routine chops the vector into the largest vector stores with the same
4520 // element type or scalar stores.
4521 SDValue Chain
= ST
->getChain();
4522 SDValue BasePtr
= ST
->getBasePtr();
4523 unsigned Align
= ST
->getAlignment();
4524 MachineMemOperand::Flags MMOFlags
= ST
->getMemOperand()->getFlags();
4525 AAMDNodes AAInfo
= ST
->getAAInfo();
4526 SDValue ValOp
= GetWidenedVector(ST
->getValue());
4529 EVT StVT
= ST
->getMemoryVT();
4530 unsigned StWidth
= StVT
.getSizeInBits();
4531 EVT ValVT
= ValOp
.getValueType();
4532 unsigned ValWidth
= ValVT
.getSizeInBits();
4533 EVT ValEltVT
= ValVT
.getVectorElementType();
4534 unsigned ValEltWidth
= ValEltVT
.getSizeInBits();
4535 assert(StVT
.getVectorElementType() == ValEltVT
);
4537 int Idx
= 0; // current index to store
4538 unsigned Offset
= 0; // offset from base to store
4539 while (StWidth
!= 0) {
4540 // Find the largest vector type we can store with.
4541 EVT NewVT
= FindMemType(DAG
, TLI
, StWidth
, ValVT
);
4542 unsigned NewVTWidth
= NewVT
.getSizeInBits();
4543 unsigned Increment
= NewVTWidth
/ 8;
4544 if (NewVT
.isVector()) {
4545 unsigned NumVTElts
= NewVT
.getVectorNumElements();
4547 SDValue EOp
= DAG
.getNode(
4548 ISD::EXTRACT_SUBVECTOR
, dl
, NewVT
, ValOp
,
4549 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4550 StChain
.push_back(DAG
.getStore(
4551 Chain
, dl
, EOp
, BasePtr
, ST
->getPointerInfo().getWithOffset(Offset
),
4552 MinAlign(Align
, Offset
), MMOFlags
, AAInfo
));
4553 StWidth
-= NewVTWidth
;
4554 Offset
+= Increment
;
4557 BasePtr
= DAG
.getObjectPtrOffset(dl
, BasePtr
, Increment
);
4558 } while (StWidth
!= 0 && StWidth
>= NewVTWidth
);
4560 // Cast the vector to the scalar type we can store.
4561 unsigned NumElts
= ValWidth
/ NewVTWidth
;
4562 EVT NewVecVT
= EVT::getVectorVT(*DAG
.getContext(), NewVT
, NumElts
);
4563 SDValue VecOp
= DAG
.getNode(ISD::BITCAST
, dl
, NewVecVT
, ValOp
);
4564 // Readjust index position based on new vector type.
4565 Idx
= Idx
* ValEltWidth
/ NewVTWidth
;
4567 SDValue EOp
= DAG
.getNode(
4568 ISD::EXTRACT_VECTOR_ELT
, dl
, NewVT
, VecOp
,
4569 DAG
.getConstant(Idx
++, dl
,
4570 TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4571 StChain
.push_back(DAG
.getStore(
4572 Chain
, dl
, EOp
, BasePtr
, ST
->getPointerInfo().getWithOffset(Offset
),
4573 MinAlign(Align
, Offset
), MMOFlags
, AAInfo
));
4574 StWidth
-= NewVTWidth
;
4575 Offset
+= Increment
;
4576 BasePtr
= DAG
.getObjectPtrOffset(dl
, BasePtr
, Increment
);
4577 } while (StWidth
!= 0 && StWidth
>= NewVTWidth
);
4578 // Restore index back to be relative to the original widen element type.
4579 Idx
= Idx
* NewVTWidth
/ ValEltWidth
;
4585 DAGTypeLegalizer::GenWidenVectorTruncStores(SmallVectorImpl
<SDValue
> &StChain
,
4587 // For extension loads, it may not be more efficient to truncate the vector
4588 // and then store it. Instead, we extract each element and then store it.
4589 SDValue Chain
= ST
->getChain();
4590 SDValue BasePtr
= ST
->getBasePtr();
4591 unsigned Align
= ST
->getAlignment();
4592 MachineMemOperand::Flags MMOFlags
= ST
->getMemOperand()->getFlags();
4593 AAMDNodes AAInfo
= ST
->getAAInfo();
4594 SDValue ValOp
= GetWidenedVector(ST
->getValue());
4597 EVT StVT
= ST
->getMemoryVT();
4598 EVT ValVT
= ValOp
.getValueType();
4600 // It must be true that the wide vector type is bigger than where we need to
4602 assert(StVT
.isVector() && ValOp
.getValueType().isVector());
4603 assert(StVT
.bitsLT(ValOp
.getValueType()));
4605 // For truncating stores, we can not play the tricks of chopping legal vector
4606 // types and bitcast it to the right type. Instead, we unroll the store.
4607 EVT StEltVT
= StVT
.getVectorElementType();
4608 EVT ValEltVT
= ValVT
.getVectorElementType();
4609 unsigned Increment
= ValEltVT
.getSizeInBits() / 8;
4610 unsigned NumElts
= StVT
.getVectorNumElements();
4611 SDValue EOp
= DAG
.getNode(
4612 ISD::EXTRACT_VECTOR_ELT
, dl
, ValEltVT
, ValOp
,
4613 DAG
.getConstant(0, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4614 StChain
.push_back(DAG
.getTruncStore(Chain
, dl
, EOp
, BasePtr
,
4615 ST
->getPointerInfo(), StEltVT
, Align
,
4617 unsigned Offset
= Increment
;
4618 for (unsigned i
=1; i
< NumElts
; ++i
, Offset
+= Increment
) {
4619 SDValue NewBasePtr
= DAG
.getObjectPtrOffset(dl
, BasePtr
, Offset
);
4620 SDValue EOp
= DAG
.getNode(
4621 ISD::EXTRACT_VECTOR_ELT
, dl
, ValEltVT
, ValOp
,
4622 DAG
.getConstant(0, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4623 StChain
.push_back(DAG
.getTruncStore(
4624 Chain
, dl
, EOp
, NewBasePtr
, ST
->getPointerInfo().getWithOffset(Offset
),
4625 StEltVT
, MinAlign(Align
, Offset
), MMOFlags
, AAInfo
));
4629 /// Modifies a vector input (widen or narrows) to a vector of NVT. The
4630 /// input vector must have the same element type as NVT.
4631 /// FillWithZeroes specifies that the vector should be widened with zeroes.
4632 SDValue
DAGTypeLegalizer::ModifyToType(SDValue InOp
, EVT NVT
,
4633 bool FillWithZeroes
) {
4634 // Note that InOp might have been widened so it might already have
4635 // the right width or it might need be narrowed.
4636 EVT InVT
= InOp
.getValueType();
4637 assert(InVT
.getVectorElementType() == NVT
.getVectorElementType() &&
4638 "input and widen element type must match");
4641 // Check if InOp already has the right width.
4645 unsigned InNumElts
= InVT
.getVectorNumElements();
4646 unsigned WidenNumElts
= NVT
.getVectorNumElements();
4647 if (WidenNumElts
> InNumElts
&& WidenNumElts
% InNumElts
== 0) {
4648 unsigned NumConcat
= WidenNumElts
/ InNumElts
;
4649 SmallVector
<SDValue
, 16> Ops(NumConcat
);
4650 SDValue FillVal
= FillWithZeroes
? DAG
.getConstant(0, dl
, InVT
) :
4653 for (unsigned i
= 1; i
!= NumConcat
; ++i
)
4656 return DAG
.getNode(ISD::CONCAT_VECTORS
, dl
, NVT
, Ops
);
4659 if (WidenNumElts
< InNumElts
&& InNumElts
% WidenNumElts
)
4661 ISD::EXTRACT_SUBVECTOR
, dl
, NVT
, InOp
,
4662 DAG
.getConstant(0, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4664 // Fall back to extract and build.
4665 SmallVector
<SDValue
, 16> Ops(WidenNumElts
);
4666 EVT EltVT
= NVT
.getVectorElementType();
4667 unsigned MinNumElts
= std::min(WidenNumElts
, InNumElts
);
4669 for (Idx
= 0; Idx
< MinNumElts
; ++Idx
)
4670 Ops
[Idx
] = DAG
.getNode(
4671 ISD::EXTRACT_VECTOR_ELT
, dl
, EltVT
, InOp
,
4672 DAG
.getConstant(Idx
, dl
, TLI
.getVectorIdxTy(DAG
.getDataLayout())));
4674 SDValue FillVal
= FillWithZeroes
? DAG
.getConstant(0, dl
, EltVT
) :
4675 DAG
.getUNDEF(EltVT
);
4676 for ( ; Idx
< WidenNumElts
; ++Idx
)
4678 return DAG
.getBuildVector(NVT
, dl
, Ops
);