51#define DEBUG_TYPE "legalizevectorops"
55class VectorLegalizer {
67 LegalizedNodes.
insert(std::make_pair(
From, To));
70 LegalizedNodes.
insert(std::make_pair(To, To));
142 std::pair<SDValue, SDValue> ExpandLoad(
SDNode *
N);
157 bool tryExpandVecMathCall(
SDNode *
Node, RTLIB::Libcall LC,
159 bool tryExpandVecMathCall(
SDNode *
Node, RTLIB::Libcall Call_F32,
160 RTLIB::Libcall Call_F64, RTLIB::Libcall Call_F80,
161 RTLIB::Libcall Call_F128,
162 RTLIB::Libcall Call_PPCF128,
208bool VectorLegalizer::Run() {
210 bool HasVectors =
false;
212 E = std::prev(DAG.allnodes_end());
I != std::next(E); ++
I) {
232 DAG.AssignTopologicalOrder();
234 E = std::prev(DAG.allnodes_end());
I != std::next(E); ++
I)
238 SDValue OldRoot = DAG.getRoot();
239 assert(LegalizedNodes.count(OldRoot) &&
"Root didn't get legalized?");
240 DAG.setRoot(LegalizedNodes[OldRoot]);
242 LegalizedNodes.clear();
245 DAG.RemoveDeadNodes();
252 "Unexpected number of results");
254 for (
unsigned i = 0, e =
Op->getNumValues(); i != e; ++i)
255 AddLegalizedOperand(
Op.getValue(i),
SDValue(Result, i));
260VectorLegalizer::RecursivelyLegalizeResults(
SDValue Op,
263 "Unexpected number of results");
265 for (
unsigned i = 0, e =
Results.
size(); i != e; ++i) {
267 AddLegalizedOperand(
Op.getValue(i),
Results[i]);
277 if (
I != LegalizedNodes.end())
return I->second;
281 for (
const SDValue &Oper :
Op->op_values())
284 SDNode *
Node = DAG.UpdateNodeOperands(
Op.getNode(), Ops);
286 bool HasVectorValueOrOp =
289 [](
SDValue O) { return O.getValueType().isVector(); });
290 if (!HasVectorValueOrOp)
291 return TranslateLegalizeResults(
Op,
Node);
295 switch (
Op.getOpcode()) {
297 return TranslateLegalizeResults(
Op,
Node);
301 EVT LoadedVT =
LD->getMemoryVT();
303 Action = TLI.getLoadExtAction(ExtType,
LD->getValueType(0), LoadedVT);
308 EVT StVT =
ST->getMemoryVT();
309 MVT ValVT =
ST->getValue().getSimpleValueType();
310 if (StVT.
isVector() &&
ST->isTruncatingStore())
311 Action = TLI.getTruncStoreAction(ValVT, StVT);
315 Action = TLI.getOperationAction(
Node->getOpcode(),
Node->getValueType(0));
318 if (Action == TargetLowering::Legal)
319 Action = TargetLowering::Expand;
321#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
322 case ISD::STRICT_##DAGN:
323#include "llvm/IR/ConstrainedOps.def"
324 ValVT =
Node->getValueType(0);
327 ValVT =
Node->getOperand(1).getValueType();
330 MVT OpVT =
Node->getOperand(1).getSimpleValueType();
332 Action = TLI.getCondCodeAction(CCCode, OpVT);
333 if (Action == TargetLowering::Legal)
334 Action = TLI.getOperationAction(
Node->getOpcode(), OpVT);
336 Action = TLI.getOperationAction(
Node->getOpcode(), ValVT);
343 if (Action == TargetLowering::Expand && !TLI.isStrictFPEnabled() &&
344 TLI.getStrictFPOperationAction(
Node->getOpcode(), ValVT) ==
345 TargetLowering::Legal) {
347 if (TLI.getOperationAction(
Node->getOpcode(), EltVT)
348 == TargetLowering::Expand &&
349 TLI.getStrictFPOperationAction(
Node->getOpcode(), EltVT)
350 == TargetLowering::Legal)
351 Action = TargetLowering::Legal;
478 Action = TLI.getOperationAction(
Node->getOpcode(),
Node->getValueType(0));
488 unsigned Scale =
Node->getConstantOperandVal(2);
489 Action = TLI.getFixedPointOperationAction(
Node->getOpcode(),
490 Node->getValueType(0), Scale);
515 Action = TLI.getOperationAction(
Node->getOpcode(),
516 Node->getOperand(0).getValueType());
520 Action = TLI.getOperationAction(
Node->getOpcode(),
521 Node->getOperand(1).getValueType());
524 MVT OpVT =
Node->getOperand(0).getSimpleValueType();
526 Action = TLI.getCondCodeAction(CCCode, OpVT);
527 if (Action == TargetLowering::Legal)
528 Action = TLI.getOperationAction(
Node->getOpcode(), OpVT);
535 TLI.getPartialReduceMLAAction(
Op.getOpcode(),
Node->getValueType(0),
536 Node->getOperand(1).getValueType());
539#define BEGIN_REGISTER_VP_SDNODE(VPID, LEGALPOS, ...) \
541 EVT LegalizeVT = LEGALPOS < 0 ? Node->getValueType(-(1 + LEGALPOS)) \
542 : Node->getOperand(LEGALPOS).getValueType(); \
543 if (ISD::VPID == ISD::VP_SETCC) { \
544 ISD::CondCode CCCode = cast<CondCodeSDNode>(Node->getOperand(2))->get(); \
545 Action = TLI.getCondCodeAction(CCCode, LegalizeVT.getSimpleVT()); \
546 if (Action != TargetLowering::Legal) \
550 if (!Node->getValueType(0).isVector() && \
551 Node->getValueType(0) != MVT::Other) { \
552 Action = TargetLowering::Legal; \
555 Action = TLI.getOperationAction(Node->getOpcode(), LegalizeVT); \
557#include "llvm/IR/VPIntrinsics.def"
565 case TargetLowering::Promote:
567 "This action is not supported yet!");
569 Promote(
Node, ResultVals);
570 assert(!ResultVals.
empty() &&
"No results for promotion?");
572 case TargetLowering::Legal:
575 case TargetLowering::Custom:
577 if (LowerOperationWrapper(
Node, ResultVals))
581 case TargetLowering::Expand:
583 Expand(
Node, ResultVals);
587 if (ResultVals.
empty())
588 return TranslateLegalizeResults(
Op,
Node);
591 return RecursivelyLegalizeResults(
Op, ResultVals);
596bool VectorLegalizer::LowerOperationWrapper(
SDNode *
Node,
608 if (
Node->getNumValues() == 1) {
616 "Lowering returned the wrong number of results!");
619 for (
unsigned I = 0, E =
Node->getNumValues();
I != E; ++
I)
625void VectorLegalizer::PromoteSETCC(
SDNode *
Node,
627 MVT VecVT =
Node->getOperand(0).getSimpleValueType();
628 MVT NewVecVT = TLI.getTypeToPromoteTo(
Node->getOpcode(), VecVT);
635 Operands[0] = DAG.getNode(ExtOp,
DL, NewVecVT,
Node->getOperand(0));
636 Operands[1] = DAG.getNode(ExtOp,
DL, NewVecVT,
Node->getOperand(1));
639 if (
Node->getOpcode() == ISD::VP_SETCC) {
650void VectorLegalizer::PromoteSTRICT(
SDNode *
Node,
652 MVT VecVT =
Node->getOperand(1).getSimpleValueType();
653 MVT NewVecVT = TLI.getTypeToPromoteTo(
Node->getOpcode(), VecVT);
661 for (
unsigned j = 1;
j !=
Node->getNumOperands(); ++
j)
662 if (
Node->getOperand(j).getValueType().isVector() &&
669 {
Node->getOperand(0),
Node->getOperand(j)});
675 SDVTList VTs = DAG.getVTList(NewVecVT,
Node->getValueType(1));
685 DAG.getIntPtrConstant(0,
DL,
true)});
691void VectorLegalizer::PromoteFloatVECREDUCE(
SDNode *
Node,
693 bool NonArithmetic) {
694 MVT OpVT =
Node->getOperand(0).getSimpleValueType();
696 MVT NewOpVT = TLI.getTypeToPromoteTo(
Node->getOpcode(), OpVT);
705 DAG.getIntPtrConstant(NonArithmetic,
DL,
true));
712 switch (
Node->getOpcode()) {
755 case ISD::VP_FCOPYSIGN:
767 "Can't promote a vector with multiple results!");
768 MVT VT =
Node->getSimpleValueType(0);
769 MVT NVT = TLI.getTypeToPromoteTo(
Node->getOpcode(), VT);
773 for (
unsigned j = 0;
j !=
Node->getNumOperands(); ++
j) {
777 if (
Node->getOperand(j).getValueType().isVector() && !SkipPromote)
778 if (
Node->getOperand(j)
780 .getVectorElementType()
781 .isFloatingPoint() &&
788 DAG.getNode(ISD::VP_FP_EXTEND, dl, NVT,
Node->getOperand(j),
789 Node->getOperand(MaskIdx),
Node->getOperand(EVLIdx));
809 Res = DAG.
getNode(ISD::VP_FP_ROUND, dl, VT, Res,
810 Node->getOperand(MaskIdx),
Node->getOperand(EVLIdx));
813 DAG.getIntPtrConstant(0, dl,
true));
821void VectorLegalizer::PromoteINT_TO_FP(
SDNode *
Node,
825 bool IsStrict =
Node->isStrictFPOpcode();
826 MVT VT =
Node->getOperand(IsStrict ? 1 : 0).getSimpleValueType();
827 MVT NVT = TLI.getTypeToPromoteTo(
Node->getOpcode(), VT);
829 "Vectors have different number of elements!");
838 for (
unsigned j = 0;
j !=
Node->getNumOperands(); ++
j) {
839 if (
Node->getOperand(j).getValueType().isVector())
862void VectorLegalizer::PromoteFP_TO_INT(
SDNode *
Node,
864 MVT VT =
Node->getSimpleValueType(0);
865 MVT NVT = TLI.getTypeToPromoteTo(
Node->getOpcode(), VT);
866 bool IsStrict =
Node->isStrictFPOpcode();
868 "Vectors have different number of elements!");
870 unsigned NewOpc =
Node->getOpcode();
884 Promoted = DAG.
getNode(NewOpc, dl, {NVT, MVT::Other},
885 {
Node->getOperand(0),
Node->getOperand(1)});
888 Promoted = DAG.
getNode(NewOpc, dl, NVT,
Node->getOperand(0));
899 Promoted = DAG.
getNode(NewOpc, dl, NVT, Promoted,
907std::pair<SDValue, SDValue> VectorLegalizer::ExpandLoad(
SDNode *
N) {
909 return TLI.scalarizeVectorLoad(LD, DAG);
914 SDValue TF = TLI.scalarizeVectorStore(ST, DAG);
919 switch (
Node->getOpcode()) {
921 std::pair<SDValue, SDValue> Tmp = ExpandLoad(
Node);
930 for (
unsigned i = 0, e =
Node->getNumValues(); i != e; ++i)
940 Results.push_back(ExpandANY_EXTEND_VECTOR_INREG(
Node));
943 Results.push_back(ExpandSIGN_EXTEND_VECTOR_INREG(
Node));
946 Results.push_back(ExpandZERO_EXTEND_VECTOR_INREG(
Node));
988 case ISD::VP_FCOPYSIGN:
1001 if (
Node->getValueType(0).isScalableVector()) {
1002 EVT CondVT = TLI.getSetCCResultType(
1003 DAG.getDataLayout(), *DAG.getContext(),
Node->getValueType(0));
1006 Node->getOperand(1),
Node->getOperand(4));
1008 Node->getOperand(2),
1009 Node->getOperand(3)));
1046 if (
SDValue Expanded = TLI.expandABS(
Node, DAG)) {
1053 if (
SDValue Expanded = TLI.expandABD(
Node, DAG)) {
1062 if (
SDValue Expanded = TLI.expandAVG(
Node, DAG)) {
1073 case ISD::VP_BITREVERSE:
1074 if (
SDValue Expanded = TLI.expandVPBITREVERSE(
Node, DAG)) {
1080 if (
SDValue Expanded = TLI.expandCTPOP(
Node, DAG)) {
1086 if (
SDValue Expanded = TLI.expandVPCTPOP(
Node, DAG)) {
1093 if (
SDValue Expanded = TLI.expandCTLZ(
Node, DAG)) {
1099 case ISD::VP_CTLZ_ZERO_UNDEF:
1100 if (
SDValue Expanded = TLI.expandVPCTLZ(
Node, DAG)) {
1107 if (
SDValue Expanded = TLI.expandCTTZ(
Node, DAG)) {
1113 case ISD::VP_CTTZ_ZERO_UNDEF:
1114 if (
SDValue Expanded = TLI.expandVPCTTZ(
Node, DAG)) {
1123 if (
SDValue Expanded = TLI.expandFunnelShift(
Node, DAG)) {
1130 if (
SDValue Expanded = TLI.expandROT(
Node,
false , DAG)) {
1137 if (
SDValue Expanded = TLI.expandFMINNUM_FMAXNUM(
Node, DAG)) {
1144 Results.push_back(TLI.expandFMINIMUM_FMAXIMUM(
Node, DAG));
1148 Results.push_back(TLI.expandFMINIMUMNUM_FMAXIMUMNUM(
Node, DAG));
1154 if (
SDValue Expanded = TLI.expandIntMINMAX(
Node, DAG)) {
1175 if (
SDValue Expanded = TLI.expandAddSubSat(
Node, DAG)) {
1182 if (
SDValue Expanded = TLI.expandShlSat(
Node, DAG)) {
1190 if (
Node->getValueType(0).isScalableVector()) {
1191 if (
SDValue Expanded = TLI.expandFP_TO_INT_SAT(
Node, DAG)) {
1199 if (
SDValue Expanded = TLI.expandFixedPointMul(
Node, DAG)) {
1218#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
1219 case ISD::STRICT_##DAGN:
1220#include "llvm/IR/ConstrainedOps.def"
1238 Results.push_back(TLI.expandVecReduce(
Node, DAG));
1243 Results.push_back(TLI.expandPartialReduceMLA(
Node, DAG));
1247 Results.push_back(TLI.expandVecReduceSeq(
Node, DAG));
1260 if (tryExpandVecMathCall(
Node, RTLIB::REM_F32, RTLIB::REM_F64,
1261 RTLIB::REM_F80, RTLIB::REM_F128,
1268 EVT VT =
Node->getValueType(0).getVectorElementType();
1272 if (DAG.expandMultipleResultFPLibCall(LC,
Node,
Results))
1279 if (DAG.expandMultipleResultFPLibCall(LC,
Node,
Results,
1285 Results.push_back(TLI.expandVECTOR_COMPRESS(
Node, DAG));
1288 Results.push_back(TLI.expandVectorFindLastActive(
Node, DAG));
1307 if (
SDValue Expanded = TLI.expandVectorNaryOpBySplitting(
Node, DAG)) {
1315 if (
Node->getNumValues() == 1) {
1319 "VectorLegalizer Expand returned wrong number of results!");
1329 EVT VT =
Node->getValueType(0);
1347 if (TLI.getOperationAction(
ISD::AND, VT) == TargetLowering::Expand ||
1348 TLI.getOperationAction(
ISD::XOR, VT) == TargetLowering::Expand ||
1349 TLI.getOperationAction(
ISD::OR, VT) == TargetLowering::Expand ||
1352 VT) == TargetLowering::Expand)
1361 Mask = DAG.getSelect(
DL, BitTy, Mask, DAG.getAllOnesConstant(
DL, BitTy),
1362 DAG.getConstant(0,
DL, BitTy));
1365 Mask = DAG.getSplat(MaskTy,
DL, Mask);
1373 SDValue NotMask = DAG.getNOT(
DL, Mask, MaskTy);
1382 EVT VT =
Node->getValueType(0);
1385 if (TLI.getOperationAction(
ISD::SRA, VT) == TargetLowering::Expand ||
1386 TLI.getOperationAction(
ISD::SHL, VT) == TargetLowering::Expand)
1390 EVT OrigTy = cast<VTSDNode>(
Node->getOperand(1))->getVT();
1394 SDValue ShiftSz = DAG.getConstant(BW - OrigBW,
DL, VT);
1404 EVT VT =
Node->getValueType(0);
1407 EVT SrcVT = Src.getValueType();
1414 "ANY_EXTEND_VECTOR_INREG vector size mismatch");
1418 Src = DAG.getInsertSubvector(
DL, DAG.getUNDEF(SrcVT), Src, 0);
1423 ShuffleMask.
resize(NumSrcElements, -1);
1426 int ExtLaneScale = NumSrcElements / NumElements;
1427 int EndianOffset = DAG.getDataLayout().isBigEndian() ? ExtLaneScale - 1 : 0;
1428 for (
int i = 0; i < NumElements; ++i)
1429 ShuffleMask[i * ExtLaneScale + EndianOffset] = i;
1433 DAG.getVectorShuffle(SrcVT,
DL, Src, DAG.getUNDEF(SrcVT), ShuffleMask));
1438 EVT VT =
Node->getValueType(0);
1440 EVT SrcVT = Src.getValueType();
1451 SDValue ShiftAmount = DAG.getConstant(EltWidth - SrcEltWidth,
DL, VT);
1462 EVT VT =
Node->getValueType(0);
1465 EVT SrcVT = Src.getValueType();
1472 "ZERO_EXTEND_VECTOR_INREG vector size mismatch");
1476 Src = DAG.getInsertSubvector(
DL, DAG.getUNDEF(SrcVT), Src, 0);
1484 auto ShuffleMask = llvm::to_vector<16>(llvm::seq<int>(0, NumSrcElements));
1486 int ExtLaneScale = NumSrcElements / NumElements;
1487 int EndianOffset = DAG.getDataLayout().isBigEndian() ? ExtLaneScale - 1 : 0;
1488 for (
int i = 0; i < NumElements; ++i)
1489 ShuffleMask[i * ExtLaneScale + EndianOffset] = NumSrcElements + i;
1492 DAG.getVectorShuffle(SrcVT,
DL, Zero, Src, ShuffleMask));
1498 for (
int J = ScalarSizeInBytes - 1; J >= 0; --J)
1499 ShuffleMask.
push_back((
I * ScalarSizeInBytes) + J);
1503 EVT VT =
Node->getValueType(0);
1507 return TLI.expandBSWAP(
Node, DAG);
1515 if (TLI.isShuffleMaskLegal(ShuffleMask, ByteVT)) {
1518 Op = DAG.getVectorShuffle(ByteVT,
DL,
Op, DAG.getUNDEF(ByteVT), ShuffleMask);
1524 if (TLI.isOperationLegalOrCustom(
ISD::SHL, VT) &&
1525 TLI.isOperationLegalOrCustom(
ISD::SRL, VT) &&
1526 TLI.isOperationLegalOrCustomOrPromote(
ISD::AND, VT) &&
1527 TLI.isOperationLegalOrCustomOrPromote(
ISD::OR, VT))
1528 return TLI.expandBSWAP(
Node, DAG);
1535 EVT VT =
Node->getValueType(0);
1539 return TLI.expandBITREVERSE(
Node, DAG);
1549 if (ScalarSizeInBits > 8 && (ScalarSizeInBits % 8) == 0) {
1554 if (TLI.isShuffleMaskLegal(BSWAPMask, ByteVT) &&
1556 (TLI.isOperationLegalOrCustom(
ISD::SHL, ByteVT) &&
1557 TLI.isOperationLegalOrCustom(
ISD::SRL, ByteVT) &&
1558 TLI.isOperationLegalOrCustomOrPromote(
ISD::AND, ByteVT) &&
1559 TLI.isOperationLegalOrCustomOrPromote(
ISD::OR, ByteVT)))) {
1562 Op = DAG.getVectorShuffle(ByteVT,
DL,
Op, DAG.getUNDEF(ByteVT),
1572 if (TLI.isOperationLegalOrCustom(
ISD::SHL, VT) &&
1573 TLI.isOperationLegalOrCustom(
ISD::SRL, VT) &&
1574 TLI.isOperationLegalOrCustomOrPromote(
ISD::AND, VT) &&
1575 TLI.isOperationLegalOrCustomOrPromote(
ISD::OR, VT))
1576 return TLI.expandBITREVERSE(
Node, DAG);
1597 if (TLI.getOperationAction(
ISD::AND, VT) == TargetLowering::Expand ||
1598 TLI.getOperationAction(
ISD::XOR, VT) == TargetLowering::Expand ||
1599 TLI.getOperationAction(
ISD::OR, VT) == TargetLowering::Expand)
1606 auto BoolContents = TLI.getBooleanContents(Op1.
getValueType());
1607 if (BoolContents != TargetLowering::ZeroOrNegativeOneBooleanContent &&
1608 !(BoolContents == TargetLowering::ZeroOrOneBooleanContent &&
1624 SDValue NotMask = DAG.getNOT(
DL, Mask, VT);
1646 if (TLI.getOperationAction(ISD::VP_AND, VT) == TargetLowering::Expand ||
1647 TLI.getOperationAction(ISD::VP_XOR, VT) == TargetLowering::Expand ||
1648 TLI.getOperationAction(ISD::VP_OR, VT) == TargetLowering::Expand)
1655 SDValue Ones = DAG.getAllOnesConstant(
DL, VT);
1658 Op1 = DAG.
getNode(ISD::VP_AND,
DL, VT, Op1, Mask, Ones, EVL);
1659 Op2 = DAG.
getNode(ISD::VP_AND,
DL, VT, Op2, NotMask, Ones, EVL);
1660 return DAG.getNode(ISD::VP_OR,
DL, VT, Op1, Op2, Ones, EVL);
1675 EVT MaskVT =
Mask.getValueType();
1691 if (TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(),
1692 EVLVecVT) != MaskVT)
1695 SDValue StepVec = DAG.getStepVector(
DL, EVLVecVT);
1696 SDValue SplatEVL = DAG.getSplat(EVLVecVT,
DL, EVL);
1698 DAG.getSetCC(
DL, MaskVT, StepVec, SplatEVL, ISD::CondCode::SETULT);
1701 return DAG.getSelect(
DL,
Node->getValueType(0), FullMask, Op1, Op2);
1706 EVT VT =
Node->getValueType(0);
1708 unsigned DivOpc =
Node->getOpcode() == ISD::VP_SREM ? ISD::VP_SDIV : ISD::VP_UDIV;
1710 if (!TLI.isOperationLegalOrCustom(DivOpc, VT) ||
1711 !TLI.isOperationLegalOrCustom(ISD::VP_MUL, VT) ||
1712 !TLI.isOperationLegalOrCustom(ISD::VP_SUB, VT))
1724 SDValue Mul = DAG.getNode(ISD::VP_MUL,
DL, VT, Divisor, Div, Mask, EVL);
1725 return DAG.getNode(ISD::VP_SUB,
DL, VT, Dividend,
Mul, Mask, EVL);
1729 EVT VT =
Node->getValueType(0);
1732 if (!TLI.isOperationLegalOrCustom(ISD::VP_XOR, IntVT))
1740 SDValue SignMask = DAG.getConstant(
1742 SDValue Xor = DAG.getNode(ISD::VP_XOR,
DL, IntVT, Cast, SignMask, Mask, EVL);
1747 EVT VT =
Node->getValueType(0);
1750 if (!TLI.isOperationLegalOrCustom(ISD::VP_AND, IntVT))
1758 SDValue ClearSignMask = DAG.getConstant(
1761 DAG.
getNode(ISD::VP_AND,
DL, IntVT, Cast, ClearSignMask, Mask, EVL);
1766 EVT VT =
Node->getValueType(0);
1768 if (VT !=
Node->getOperand(1).getValueType())
1772 if (!TLI.isOperationLegalOrCustom(ISD::VP_AND, IntVT) ||
1773 !TLI.isOperationLegalOrCustom(ISD::VP_XOR, IntVT))
1783 SDValue SignMask = DAG.getConstant(
1786 DAG.
getNode(ISD::VP_AND,
DL, IntVT, Sign, SignMask, Mask, EVL);
1788 SDValue ClearSignMask = DAG.getConstant(
1791 DAG.
getNode(ISD::VP_AND,
DL, IntVT, Mag, ClearSignMask, Mask, EVL);
1793 SDValue CopiedSign = DAG.
getNode(ISD::VP_OR,
DL, IntVT, ClearedSign, SignBit,
1799void VectorLegalizer::ExpandFP_TO_UINT(
SDNode *
Node,
1803 if (TLI.expandFP_TO_UINT(
Node, Result, Chain, DAG)) {
1805 if (
Node->isStrictFPOpcode())
1811 if (
Node->isStrictFPOpcode()) {
1819void VectorLegalizer::ExpandUINT_TO_FLOAT(
SDNode *
Node,
1821 bool IsStrict =
Node->isStrictFPOpcode();
1822 unsigned OpNo = IsStrict ? 1 : 0;
1824 EVT SrcVT = Src.getValueType();
1825 EVT DstVT =
Node->getValueType(0);
1831 if (TLI.expandUINT_TO_FP(
Node, Result, Chain, DAG)) {
1840 TargetLowering::Expand) ||
1842 TargetLowering::Expand)) ||
1843 TLI.getOperationAction(
ISD::SRL, SrcVT) == TargetLowering::Expand) {
1854 assert((BW == 64 || BW == 32) &&
1855 "Elements in vector-UINT_TO_FP must be 32 or 64 bits wide");
1859 if ((!IsStrict && !TLI.isOperationLegalOrCustom(
ISD::FMUL, DstVT)) ||
1861 EVT FPVT = BW == 32 ? MVT::f32 : MVT::f64;
1864 SDValue TargetZero = DAG.getIntPtrConstant(0,
DL,
true);
1868 {
Node->getOperand(0), Src});
1870 {
Node->getOperand(0), UIToFP, TargetZero});
1882 SDValue HalfWord = DAG.getConstant(BW / 2,
DL, SrcVT);
1887 uint64_t HWMask = (BW == 64) ? 0x00000000FFFFFFFF : 0x0000FFFF;
1888 SDValue HalfWordMask = DAG.getConstant(HWMask,
DL, SrcVT);
1891 SDValue TWOHW = DAG.getConstantFP(1ULL << (BW / 2),
DL, DstVT);
1902 {
Node->getOperand(0),
HI});
1906 {
Node->getOperand(0),
LO});
1932 EVT VT =
Node->getValueType(0);
1935 if (!TLI.isOperationLegalOrCustom(
ISD::XOR, IntVT))
1939 if (!TLI.isOperationLegalOrCustomOrPromote(
ISD::FSUB, VT) &&
1945 SDValue SignMask = DAG.getConstant(
1952 EVT VT =
Node->getValueType(0);
1955 if (!TLI.isOperationLegalOrCustom(
ISD::AND, IntVT))
1959 if (!TLI.isOperationLegalOrCustomOrPromote(
ISD::FSUB, VT) &&
1965 SDValue ClearSignMask = DAG.getConstant(
1972 EVT VT =
Node->getValueType(0);
1975 if (VT !=
Node->getOperand(1).getValueType() ||
1976 !TLI.isOperationLegalOrCustom(
ISD::AND, IntVT) ||
1977 !TLI.isOperationLegalOrCustom(
ISD::OR, IntVT))
1981 if (!TLI.isOperationLegalOrCustomOrPromote(
ISD::FSUB, VT) &&
1989 SDValue SignMask = DAG.getConstant(
1993 SDValue ClearSignMask = DAG.getConstant(
2003void VectorLegalizer::ExpandFSUB(
SDNode *
Node,
2008 EVT VT =
Node->getValueType(0);
2009 if (TLI.isOperationLegalOrCustom(
ISD::FNEG, VT) &&
2010 TLI.isOperationLegalOrCustom(
ISD::FADD, VT))
2013 if (
SDValue Expanded = TLI.expandVectorNaryOpBySplitting(
Node, DAG)) {
2022void VectorLegalizer::ExpandSETCC(
SDNode *
Node,
2024 bool NeedInvert =
false;
2025 bool IsVP =
Node->getOpcode() == ISD::VP_SETCC;
2029 unsigned Offset = IsStrict ? 1 : 0;
2036 MVT OpVT =
LHS.getSimpleValueType();
2039 if (TLI.getCondCodeAction(CCCode, OpVT) != TargetLowering::Expand) {
2056 TLI.LegalizeSetCCCondCode(DAG,
Node->getValueType(0), LHS, RHS, CC, Mask,
2057 EVL, NeedInvert, dl, Chain, IsSignaling);
2064 LHS = DAG.getNode(
Node->getOpcode(), dl,
Node->getVTList(),
2065 {Chain, LHS, RHS, CC},
Node->getFlags());
2066 Chain =
LHS.getValue(1);
2068 LHS = DAG.getNode(ISD::VP_SETCC, dl,
Node->getValueType(0),
2069 {LHS, RHS, CC, Mask, EVL},
Node->getFlags());
2080 LHS = DAG.getLogicalNOT(dl, LHS,
LHS->getValueType(0));
2082 LHS = DAG.getVPLogicalNOT(dl, LHS, Mask, EVL,
LHS->getValueType(0));
2085 assert(!IsStrict &&
"Don't know how to expand for strict nodes.");
2089 EVT VT =
Node->getValueType(0);
2091 DAG.getBoolConstant(
true, dl, VT,
LHS.getValueType()),
2092 DAG.getBoolConstant(
false, dl, VT,
LHS.getValueType()),
2093 CC,
Node->getFlags());
2101void VectorLegalizer::ExpandUADDSUBO(
SDNode *
Node,
2104 TLI.expandUADDSUBO(
Node, Result, Overflow, DAG);
2109void VectorLegalizer::ExpandSADDSUBO(
SDNode *
Node,
2112 TLI.expandSADDSUBO(
Node, Result, Overflow, DAG);
2117void VectorLegalizer::ExpandMULO(
SDNode *
Node,
2120 if (!TLI.expandMULO(
Node, Result, Overflow, DAG))
2121 std::tie(Result, Overflow) = DAG.UnrollVectorOverflowOp(
Node);
2127void VectorLegalizer::ExpandFixedPointDiv(
SDNode *
Node,
2130 if (
SDValue Expanded = TLI.expandFixedPointDiv(
N->getOpcode(),
SDLoc(
N),
2131 N->getOperand(0),
N->getOperand(1),
N->getConstantOperandVal(2), DAG))
2135void VectorLegalizer::ExpandStrictFPOp(
SDNode *
Node,
2158 "Expected REM node");
2161 if (!TLI.expandREM(
Node, Result, DAG))
2172bool VectorLegalizer::tryExpandVecMathCall(
SDNode *
Node, RTLIB::Libcall LC,
2176 assert(!
Node->isStrictFPOpcode() &&
"Unexpected strict fp operation!");
2178 const char *LCName = TLI.getLibcallName(LC);
2181 LLVM_DEBUG(
dbgs() <<
"Looking for vector variant of " << LCName <<
"\n");
2183 EVT VT =
Node->getValueType(0);
2201 for (
unsigned i = 0; i <
Node->getNumOperands(); ++i) {
2202 assert(
Node->getOperand(i).getValueType() == VT &&
2203 "Expected matching vector types!");
2206 FunctionType *ScalarFTy = FunctionType::get(ScalarTy, ArgTys,
false);
2218 if (OptVFInfo->Shape.Parameters.size() !=
2228 for (
auto &VFParam : OptVFInfo->Shape.Parameters) {
2229 if (VFParam.ParamKind == VFParamKind::GlobalPredicate) {
2230 EVT MaskVT = TLI.getSetCCResultType(DAG.getDataLayout(), *Ctx, VT);
2231 Args.emplace_back(DAG.getBoolConstant(
true,
DL, MaskVT, VT),
2237 if (VFParam.ParamKind != VFParamKind::Vector)
2240 Args.emplace_back(
Node->getOperand(OpNum++), Ty);
2245 TLI.getPointerTy(DAG.getDataLayout()));
2248 .setChain(DAG.getEntryNode())
2251 std::pair<SDValue, SDValue> CallResult = TLI.LowerCallTo(CLI);
2252 Results.push_back(CallResult.first);
2257bool VectorLegalizer::tryExpandVecMathCall(
2258 SDNode *
Node, RTLIB::Libcall Call_F32, RTLIB::Libcall Call_F64,
2259 RTLIB::Libcall Call_F80, RTLIB::Libcall Call_F128,
2262 Node->getValueType(0).getVectorElementType(), Call_F32, Call_F64,
2263 Call_F80, Call_F128, Call_PPCF128);
2265 if (LC == RTLIB::UNKNOWN_LIBCALL)
2271void VectorLegalizer::UnrollStrictFPOp(
SDNode *
Node,
2273 EVT VT =
Node->getValueType(0);
2276 unsigned NumOpers =
Node->getNumOperands();
2279 EVT TmpEltVT = EltVT;
2283 *DAG.getContext(), TmpEltVT);
2285 EVT ValueVTs[] = {TmpEltVT, MVT::Other};
2291 for (
unsigned i = 0; i < NumElems; ++i) {
2293 SDValue Idx = DAG.getVectorIdxConstant(i, dl);
2299 for (
unsigned j = 1;
j < NumOpers; ++
j) {
2316 ScalarResult = DAG.getSelect(dl, EltVT, ScalarResult,
2317 DAG.getAllOnesConstant(dl, EltVT),
2318 DAG.getConstant(0, dl, EltVT));
2332 EVT VT =
Node->getValueType(0);
2338 EVT TmpEltVT =
LHS.getValueType().getVectorElementType();
2341 for (
unsigned i = 0; i < NumElems; ++i) {
2343 DAG.getVectorIdxConstant(i, dl));
2345 DAG.getVectorIdxConstant(i, dl));
2349 *DAG.getContext(), TmpEltVT),
2350 LHSElem, RHSElem, CC);
2351 Ops[i] = DAG.getSelect(dl, EltVT, Ops[i],
2352 DAG.getBoolConstant(
true, dl, EltVT, VT),
2353 DAG.getConstant(0, dl, EltVT));
2355 return DAG.getBuildVector(VT, dl, Ops);
2359 return VectorLegalizer(*this).Run();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
BlockVerifier::State From
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
static void createBSWAPShuffleMask(EVT VT, SmallVectorImpl< int > &ShuffleMask)
mir Rename Register Operands
This file defines the SmallVector class.
This file describes how to lower LLVM code to machine code.
DEMANGLE_DUMP_METHOD void dump() const
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
This class represents an Operation in the Expression.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is an important class for using LLVM in a threaded context.
This class is used to represent ISD::LOAD nodes.
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
MVT getVectorElementType() const
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI bool LegalizeVectors()
This transforms the SelectionDAG into a SelectionDAG that only uses vector math operations supported ...
const TargetLowering & getTargetLoweringInfo() const
ilist< SDNode >::iterator allnodes_iterator
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Provides information about what library functions are available for the current target.
const VecDesc * getVectorMappingInfo(StringRef F, const ElementCount &VF, bool Masked) const
LegalizeAction
This enum indicates whether operations are valid for a target, and if not, what action should be used...
virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const
Return the ValueType of the result of SETCC operations.
std::vector< ArgListEntry > ArgListTy
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
The instances of the Type class are immutable: once they are created, they are never changed.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Provides info so a possible vectorization of a function can be computed.
LLVM_ABI std::string getVectorFunctionABIVariantString() const
Returns a vector function ABI variant string on the form: ZGV<isa><mask><vlen><vparams><scalarname>(<...
StringRef getVectorFnName() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ VECREDUCE_SEQ_FADD
Generic reduction nodes.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ SMULFIX
RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on 2 integers with the same...
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ SMULFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ VECTOR_FIND_LAST_ACTIVE
@ FMODF
FMODF - Decomposes the operand into integral and fractional parts, each having the same type and sign...
@ FATAN2
FATAN2 - atan2, inspired by libm.
@ FSINCOSPI
FSINCOSPI - Compute both the sine and cosine times pi more accurately than FSINCOS(pi*x),...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ VECREDUCE_FMAX
FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
@ FADD
Simple binary floating point operators.
@ VECREDUCE_FMAXIMUM
FMINIMUM/FMAXIMUM nodes propatate NaNs and signed zeroes using the llvm.minimum and llvm....
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ FPTRUNC_ROUND
FPTRUNC_ROUND - This corresponds to the fptrunc_round intrinsic.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ SDIVFIX
RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on 2 integers with the same width...
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ VECREDUCE_FADD
These reductions have relaxed evaluation order semantics, and have a single vector operand.
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ SSUBO
Same for subtraction.
@ STEP_VECTOR
STEP_VECTOR(IMM) - Returns a scalable vector whose lanes are comprised of a linear sequence of unsign...
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ SSHLSAT
RESULT = [US]SHLSAT(LHS, RHS) - Perform saturation left shift.
@ SMULO
Same for multiplication.
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ SDIVFIXSAT
Same as the corresponding unsaturated fixed point instructions, but the result is clamped between the...
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ AVGFLOORS
AVGFLOORS/AVGFLOORU - Averaging add - Add two integers using an integer of type i[N+1],...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FFREXP
FFREXP - frexp, extract fractional and exponent component of a floating-point value.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ VECTOR_COMPRESS
VECTOR_COMPRESS(Vec, Mask, Passthru) consecutively place vector elements based on mask e....
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ FP_TO_SINT_SAT
FP_TO_[US]INT_SAT - Convert floating point value in operand 0 to a signed or unsigned scalar integer ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
LLVM_ABI std::optional< unsigned > getVPMaskIdx(unsigned Opcode)
The operand position of the vector mask.
LLVM_ABI std::optional< unsigned > getVPExplicitVectorLengthIdx(unsigned Opcode)
The operand position of the explicit vector length parameter.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI bool isVPOpcode(unsigned Opcode)
Whether this is a vector-predicated Opcode.
LLVM_ABI Libcall getSINCOSPI(EVT RetVT)
getSINCOSPI - Return the SINCOSPI_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getMODF(EVT RetVT)
getMODF - Return the MODF_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPLibCall(EVT VT, Libcall Call_F32, Libcall Call_F64, Libcall Call_F80, Libcall Call_F128, Libcall Call_PPCF128)
GetFPLibCall - Helper to return the right libcall for the given floating point type,...
LLVM_ABI Libcall getSINCOS(EVT RetVT)
getSINCOS - Return the SINCOS_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI std::optional< VFInfo > tryDemangleForVFABI(StringRef MangledName, const FunctionType *FTy)
Function to construct a VFInfo out of a mangled names in the following format:
This is an optimization pass for GlobalISel generic memory operations.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
@ Xor
Bitwise or logical XOR of integers.
DWARFExpression::Operation Op
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
ElementCount getVectorElementCount() const
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
bool isFixedLengthVector() const
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
EVT changeVectorElementType(EVT EltVT) const
Return a VT for a vector type whose attributes match ourselves with the exception of the element type...
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This structure contains all information that is necessary for lowering calls.