26#include "llvm/IR/IntrinsicsARM.h"
45#define DEBUG_TYPE "armtti"
49 cl::desc(
"Enable the generation of masked loads and stores"));
53 cl::desc(
"Disable the generation of low-overhead loops"));
57 cl::desc(
"Enable the generation of WLS loops"));
68 "Threshold for forced unrolling of small loops in Arm architecture"));
80 unsigned Alignment = IntrAlign->getLimitedValue() < MemAlign
82 : IntrAlign->getLimitedValue();
87 return Builder.CreateAlignedLoad(
II.getType(),
II.getArgOperand(0),
94 if (ST->hasMVEIntegerOps())
97 if (L->getHeader()->getParent()->hasOptSize())
100 if (ST->isMClass() && ST->isThumb2() &&
101 L->getNumBlocks() == 1)
107std::optional<Instruction *>
114 case Intrinsic::arm_neon_vld1: {
124 case Intrinsic::arm_neon_vld2:
125 case Intrinsic::arm_neon_vld3:
126 case Intrinsic::arm_neon_vld4:
127 case Intrinsic::arm_neon_vld2lane:
128 case Intrinsic::arm_neon_vld3lane:
129 case Intrinsic::arm_neon_vld4lane:
130 case Intrinsic::arm_neon_vst1:
131 case Intrinsic::arm_neon_vst2:
132 case Intrinsic::arm_neon_vst3:
133 case Intrinsic::arm_neon_vst4:
134 case Intrinsic::arm_neon_vst2lane:
135 case Intrinsic::arm_neon_vst3lane:
136 case Intrinsic::arm_neon_vst4lane: {
140 unsigned AlignArg =
II.arg_size() - 1;
141 Value *AlignArgOp =
II.getArgOperand(AlignArg);
152 case Intrinsic::arm_neon_vld1x2:
153 case Intrinsic::arm_neon_vld1x3:
154 case Intrinsic::arm_neon_vld1x4:
155 case Intrinsic::arm_neon_vst1x2:
156 case Intrinsic::arm_neon_vst1x3:
157 case Intrinsic::arm_neon_vst1x4: {
161 Align OldAlign =
II.getParamAlign(0).valueOrOne();
162 if (NewAlign > OldAlign)
168 case Intrinsic::arm_mve_pred_i2v: {
169 Value *Arg =
II.getArgOperand(0);
182 if (CI->getValue().trunc(16).isAllOnes()) {
197 case Intrinsic::arm_mve_pred_v2i: {
198 Value *Arg =
II.getArgOperand(0);
205 if (
II.getMetadata(LLVMContext::MD_range))
210 if (
auto CurrentRange =
II.getRange()) {
212 if (
Range == CurrentRange)
217 II.addRetAttr(Attribute::NoUndef);
220 case Intrinsic::arm_mve_vadc:
221 case Intrinsic::arm_mve_vadc_predicated: {
223 (
II.getIntrinsicID() == Intrinsic::arm_mve_vadc_predicated) ? 3 : 2;
224 assert(
II.getArgOperand(CarryOp)->getType()->getScalarSizeInBits() == 32 &&
225 "Bad type for intrinsic!");
234 case Intrinsic::arm_mve_vmldava: {
236 if (
I->hasOneUse()) {
241 Value *OpX =
I->getOperand(4);
242 Value *OpY =
I->getOperand(5);
248 {
I->getOperand(0),
I->getOperand(1),
249 I->getOperand(2), OpZ, OpX, OpY});
265 SimplifyAndSetOp)
const {
270 auto SimplifyNarrowInstrTopBottom =[&](
unsigned TopOpc) {
279 SimplifyAndSetOp(&
II, 0, OrigDemandedElts & DemandedElts, UndefElts);
286 switch (
II.getIntrinsicID()) {
289 case Intrinsic::arm_mve_vcvt_narrow:
290 SimplifyNarrowInstrTopBottom(2);
292 case Intrinsic::arm_mve_vqmovn:
293 SimplifyNarrowInstrTopBottom(4);
295 case Intrinsic::arm_mve_vshrn:
296 SimplifyNarrowInstrTopBottom(7);
305 assert(Ty->isIntegerTy());
307 unsigned Bits = Ty->getPrimitiveSizeInBits();
308 if (Bits == 0 ||
Imm.getActiveBits() >= 64)
311 int64_t SImmVal =
Imm.getSExtValue();
312 uint64_t ZImmVal =
Imm.getZExtValue();
313 if (!ST->isThumb()) {
314 if ((SImmVal >= 0 && SImmVal < 65536) ||
318 return ST->hasV6T2Ops() ? 2 : 3;
320 if (ST->isThumb2()) {
321 if ((SImmVal >= 0 && SImmVal < 65536) ||
325 return ST->hasV6T2Ops() ? 2 : 3;
328 if (Bits == 8 || (SImmVal >= 0 && SImmVal < 256))
341 if (
Imm.isNonNegative() &&
Imm.getLimitedValue() < 256)
357 C->getValue() ==
Imm &&
Imm.isNegative() &&
Imm.isNegatedPowerOf2()) {
359 auto isSSatMin = [&](
Value *MinInst) {
361 Value *MinLHS, *MinRHS;
385 if (
Imm.getBitWidth() != 64 ||
404 if ((Opcode == Instruction::SDiv || Opcode == Instruction::UDiv ||
405 Opcode == Instruction::SRem || Opcode == Instruction::URem) &&
411 if (Opcode == Instruction::GetElementPtr && Idx != 0)
414 if (Opcode == Instruction::And) {
416 if (
Imm == 255 ||
Imm == 65535)
423 if (Opcode == Instruction::Add)
428 if (Opcode == Instruction::ICmp &&
Imm.isNegative() &&
429 Ty->getIntegerBitWidth() == 32) {
430 int64_t NegImm = -
Imm.getSExtValue();
431 if (ST->isThumb2() && NegImm < 1<<12)
434 if (ST->isThumb() && NegImm < 1<<8)
440 if (Opcode == Instruction::Xor &&
Imm.isAllOnes())
445 if (Inst && ((ST->hasV6Ops() && !ST->isThumb()) || ST->isThumb2()) &&
446 Ty->getIntegerBitWidth() <= 32) {
457 if (Inst && Opcode == Instruction::ICmp && Idx == 1 &&
Imm.isAllOnes()) {
471 (ST->hasNEON() || ST->hasMVEIntegerOps())) {
486 int ISD = TLI->InstructionOpcodeToISD(Opcode);
492 return Cost == 0 ? 0 : 1;
495 auto IsLegalFPType = [
this](
EVT VT) {
497 return (EltVT == MVT::f32 && ST->hasVFP2Base()) ||
498 (EltVT == MVT::f64 && ST->hasFP64()) ||
499 (EltVT == MVT::f16 && ST->hasFullFP16());
502 EVT SrcTy = TLI->getValueType(
DL, Src);
503 EVT DstTy = TLI->getValueType(
DL, Dst);
505 if (!SrcTy.isSimple() || !DstTy.
isSimple())
512 if ((ST->hasMVEIntegerOps() &&
513 (Opcode == Instruction::Trunc || Opcode == Instruction::ZExt ||
514 Opcode == Instruction::SExt)) ||
515 (ST->hasMVEFloatOps() &&
516 (Opcode == Instruction::FPExt || Opcode == Instruction::FPTrunc) &&
517 IsLegalFPType(SrcTy) && IsLegalFPType(DstTy)))
520 ST->getMVEVectorCostFactor(
CostKind);
540 LoadConversionTbl,
ISD, DstTy.
getSimpleVT(), SrcTy.getSimpleVT()))
541 return AdjustCost(Entry->Cost);
560 if (SrcTy.isVector() && ST->hasMVEIntegerOps()) {
561 if (
const auto *Entry =
564 return Entry->Cost * ST->getMVEVectorCostFactor(
CostKind);
572 if (SrcTy.isVector() && ST->hasMVEFloatOps()) {
573 if (
const auto *Entry =
576 return Entry->Cost * ST->getMVEVectorCostFactor(
CostKind);
589 if (SrcTy.isVector() && ST->hasMVEIntegerOps()) {
590 if (
const auto *Entry =
593 return Entry->Cost * ST->getMVEVectorCostFactor(
CostKind);
600 if (SrcTy.isVector() && ST->hasMVEFloatOps()) {
601 if (
const auto *Entry =
604 return Entry->Cost * ST->getMVEVectorCostFactor(
CostKind);
610 I &&
I->hasOneUse() && ST->hasNEON() && SrcTy.isVector()) {
613 {
ISD::ADD, MVT::v4i32, MVT::v4i16, 0 },
614 {
ISD::ADD, MVT::v8i16, MVT::v8i8, 0 },
616 {
ISD::SUB, MVT::v4i32, MVT::v4i16, 0 },
617 {
ISD::SUB, MVT::v8i16, MVT::v8i8, 0 },
619 {
ISD::MUL, MVT::v4i32, MVT::v4i16, 0 },
620 {
ISD::MUL, MVT::v8i16, MVT::v8i8, 0 },
622 {
ISD::SHL, MVT::v4i32, MVT::v4i16, 0 },
623 {
ISD::SHL, MVT::v8i16, MVT::v8i8, 0 },
627 int UserISD = TLI->InstructionOpcodeToISD(
User->getOpcode());
630 SrcTy.getSimpleVT())) {
631 return AdjustCost(Entry->Cost);
636 if (Src->isVectorTy() && ST->hasNEON() &&
649 return AdjustCost(LT.first * Entry->Cost);
738 if (SrcTy.isVector() && ST->hasNEON()) {
741 SrcTy.getSimpleVT()))
742 return AdjustCost(Entry->Cost);
768 if (SrcTy.isFloatingPoint() && ST->hasNEON()) {
771 SrcTy.getSimpleVT()))
772 return AdjustCost(Entry->Cost);
799 if (SrcTy.isInteger() && ST->hasNEON()) {
802 SrcTy.getSimpleVT()))
803 return AdjustCost(Entry->Cost);
824 if (SrcTy.isVector() && ST->hasMVEIntegerOps()) {
827 SrcTy.getSimpleVT()))
828 return Entry->Cost * ST->getMVEVectorCostFactor(
CostKind);
838 if (SrcTy.isFixedLengthVector())
839 Lanes = SrcTy.getVectorNumElements();
841 if (IsLegalFPType(SrcTy) && IsLegalFPType(DstTy))
844 return Lanes * CallCost;
848 SrcTy.isFixedLengthVector()) {
851 if ((SrcTy.getScalarType() == MVT::i8 ||
852 SrcTy.getScalarType() == MVT::i16 ||
853 SrcTy.getScalarType() == MVT::i32) &&
854 SrcTy.getSizeInBits() > 128 &&
856 return SrcTy.getVectorNumElements() * 2;
871 if (SrcTy.isInteger()) {
874 SrcTy.getSimpleVT()))
875 return AdjustCost(Entry->Cost);
878 int BaseCost = ST->hasMVEIntegerOps() && Src->isVectorTy()
879 ? ST->getMVEVectorCostFactor(
CostKind)
890 if (ST->hasSlowLoadDSubregister() && Opcode == Instruction::InsertElement &&
894 if (ST->hasNEON() && (Opcode == Instruction::InsertElement ||
895 Opcode == Instruction::ExtractElement)) {
905 return std::max<InstructionCost>(
911 if (ST->hasMVEIntegerOps() && (Opcode == Instruction::InsertElement ||
912 Opcode == Instruction::ExtractElement)) {
916 std::pair<InstructionCost, MVT> LT =
918 return LT.first * (ValTy->
getScalarType()->isIntegerTy() ? 4 : 1);
929 int ISD = TLI->InstructionOpcodeToISD(Opcode);
935 if (TLI->getValueType(
DL, ValTy,
true) == MVT::Other)
959 if ((Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) && Sel &&
964 const Value *LHS, *RHS;
969 IID = Intrinsic::abs;
972 IID = Intrinsic::smin;
975 IID = Intrinsic::smax;
978 IID = Intrinsic::umin;
981 IID = Intrinsic::umax;
984 IID = Intrinsic::minnum;
987 IID = Intrinsic::maxnum;
1005 {
ISD::SELECT, MVT::v4i1, MVT::v4i64, 4*4 + 1*2 + 1 },
1010 EVT SelCondTy = TLI->getValueType(
DL, CondTy);
1011 EVT SelValTy = TLI->getValueType(
DL, ValTy);
1023 if (ST->hasMVEIntegerOps() && ValTy->
isVectorTy() &&
1024 (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) &&
1032 if (Opcode == Instruction::FCmp && !ST->hasMVEFloatOps()) {
1046 int BaseCost = ST->getMVEVectorCostFactor(
CostKind);
1052 if (LT.second.isVector() && LT.second.getVectorNumElements() > 2) {
1054 return LT.first * BaseCost +
1064 if (ST->hasMVEIntegerOps() && ValTy->
isVectorTy())
1065 BaseCost = ST->getMVEVectorCostFactor(
CostKind);
1079 unsigned NumVectorInstToHideOverhead = 10;
1080 int MaxMergeDistance = 64;
1082 if (ST->hasNEON()) {
1085 return NumVectorInstToHideOverhead;
1098 switch (
II->getIntrinsicID()) {
1099 case Intrinsic::arm_mve_vctp8:
1100 case Intrinsic::arm_mve_vctp16:
1101 case Intrinsic::arm_mve_vctp32:
1102 case Intrinsic::arm_mve_vctp64:
1119 if (VecTy->getNumElements() == 2)
1124 if (VecWidth != 128 && VecTy->getElementType()->isFloatingPointTy())
1129 return (EltWidth == 32 && Alignment >= 4) ||
1130 (EltWidth == 16 && Alignment >= 2) || (EltWidth == 8);
1137 unsigned EltWidth = Ty->getScalarSizeInBits();
1138 return ((EltWidth == 32 && Alignment >= 4) ||
1139 (EltWidth == 16 && Alignment >= 2) || EltWidth == 8);
1147 unsigned DstAddrSpace = ~0u;
1148 unsigned SrcAddrSpace = ~0u;
1149 const Function *
F =
I->getParent()->getParent();
1157 const unsigned Size =
C->getValue().getZExtValue();
1158 const Align DstAlign = MC->getDestAlign().valueOrOne();
1159 const Align SrcAlign = MC->getSourceAlign().valueOrOne();
1164 DstAddrSpace = MC->getDestAddressSpace();
1165 SrcAddrSpace = MC->getSourceAddressSpace();
1173 const unsigned Size =
C->getValue().getZExtValue();
1174 const Align DstAlign = MS->getDestAlign().valueOrOne();
1178 DstAddrSpace = MS->getDestAddressSpace();
1183 unsigned Limit, Factor = 2;
1184 switch(
I->getIntrinsicID()) {
1185 case Intrinsic::memcpy:
1186 Limit = TLI->getMaxStoresPerMemcpy(
F->hasMinSize());
1188 case Intrinsic::memmove:
1189 Limit = TLI->getMaxStoresPerMemmove(
F->hasMinSize());
1191 case Intrinsic::memset:
1192 Limit = TLI->getMaxStoresPerMemset(
F->hasMinSize());
1202 std::vector<EVT> MemOps;
1204 if (getTLI()->findOptimalMemOpLowering(
C, MemOps, Limit, MOp, DstAddrSpace,
1205 SrcAddrSpace,
F->getAttributes(),
1207 return MemOps.size() * Factor;
1230 "Expected the Mask to match the return size if given");
1232 "Expected the same scalar types");
1237 if (IsExtractSubvector)
1239 if (ST->hasNEON()) {
1256 if (
const auto *Entry =
1258 return LT.first * Entry->Cost;
1277 if (
const auto *Entry =
1279 return LT.first * Entry->Cost;
1303 return LT.first * Entry->Cost;
1308 if (!Mask.empty()) {
1311 if (LT.second.isVector() &&
1312 Mask.size() <= LT.second.getVectorNumElements() &&
1324 if (ST->hasMVEIntegerOps()) {
1337 return LT.first * Entry->Cost * ST->getMVEVectorCostFactor(
CostKind);
1340 if (!Mask.empty()) {
1347 (LT.second.getScalarSizeInBits() == 8 ||
1348 LT.second.getScalarSizeInBits() == 16 ||
1349 LT.second.getScalarSizeInBits() == 32) &&
1350 LT.second.getSizeInBits() == 128 &&
1351 ((TLI->getMaxSupportedInterleaveFactor() >= 2 &&
1353 (TLI->getMaxSupportedInterleaveFactor() == 4 &&
1355 return ST->getMVEVectorCostFactor(
CostKind) *
1356 std::max<InstructionCost>(1, LT.first / 4);
1363 (LT.second.getScalarSizeInBits() == 8 ||
1364 LT.second.getScalarSizeInBits() == 16 ||
1365 LT.second.getScalarSizeInBits() == 32) &&
1366 LT.second.getSizeInBits() == 128 &&
1367 ((TLI->getMaxSupportedInterleaveFactor() >= 2 &&
1369 Mask, 2, SrcTy->getElementCount().getKnownMinValue() * 2)) ||
1370 (TLI->getMaxSupportedInterleaveFactor() == 4 &&
1372 Mask, 4, SrcTy->getElementCount().getKnownMinValue() * 2))))
1373 return ST->getMVEVectorCostFactor(
CostKind) * LT.first;
1375 if (LT.second.isVector() &&
1376 Mask.size() <= LT.second.getVectorNumElements() &&
1379 return ST->getMVEVectorCostFactor(
CostKind) * LT.first;
1384 if (IsExtractSubvector)
1386 int BaseCost = ST->hasMVEIntegerOps() && SrcTy->isVectorTy()
1387 ? ST->getMVEVectorCostFactor(
CostKind)
1397 int ISDOpcode = TLI->InstructionOpcodeToISD(Opcode);
1402 switch (ISDOpcode) {
1415 if (ST->hasNEON()) {
1416 const unsigned FunctionCallDivCost = 20;
1417 const unsigned ReciprocalDivCost = 10;
1423 {
ISD::SDIV, MVT::v1i64, 1 * FunctionCallDivCost},
1424 {
ISD::UDIV, MVT::v1i64, 1 * FunctionCallDivCost},
1425 {
ISD::SREM, MVT::v1i64, 1 * FunctionCallDivCost},
1426 {
ISD::UREM, MVT::v1i64, 1 * FunctionCallDivCost},
1427 {
ISD::SDIV, MVT::v2i32, 2 * FunctionCallDivCost},
1428 {
ISD::UDIV, MVT::v2i32, 2 * FunctionCallDivCost},
1429 {
ISD::SREM, MVT::v2i32, 2 * FunctionCallDivCost},
1430 {
ISD::UREM, MVT::v2i32, 2 * FunctionCallDivCost},
1431 {
ISD::SDIV, MVT::v4i16, ReciprocalDivCost},
1432 {
ISD::UDIV, MVT::v4i16, ReciprocalDivCost},
1433 {
ISD::SREM, MVT::v4i16, 4 * FunctionCallDivCost},
1434 {
ISD::UREM, MVT::v4i16, 4 * FunctionCallDivCost},
1435 {
ISD::SDIV, MVT::v8i8, ReciprocalDivCost},
1436 {
ISD::UDIV, MVT::v8i8, ReciprocalDivCost},
1437 {
ISD::SREM, MVT::v8i8, 8 * FunctionCallDivCost},
1438 {
ISD::UREM, MVT::v8i8, 8 * FunctionCallDivCost},
1440 {
ISD::SDIV, MVT::v2i64, 2 * FunctionCallDivCost},
1441 {
ISD::UDIV, MVT::v2i64, 2 * FunctionCallDivCost},
1442 {
ISD::SREM, MVT::v2i64, 2 * FunctionCallDivCost},
1443 {
ISD::UREM, MVT::v2i64, 2 * FunctionCallDivCost},
1444 {
ISD::SDIV, MVT::v4i32, 4 * FunctionCallDivCost},
1445 {
ISD::UDIV, MVT::v4i32, 4 * FunctionCallDivCost},
1446 {
ISD::SREM, MVT::v4i32, 4 * FunctionCallDivCost},
1447 {
ISD::UREM, MVT::v4i32, 4 * FunctionCallDivCost},
1448 {
ISD::SDIV, MVT::v8i16, 8 * FunctionCallDivCost},
1449 {
ISD::UDIV, MVT::v8i16, 8 * FunctionCallDivCost},
1450 {
ISD::SREM, MVT::v8i16, 8 * FunctionCallDivCost},
1451 {
ISD::UREM, MVT::v8i16, 8 * FunctionCallDivCost},
1452 {
ISD::SDIV, MVT::v16i8, 16 * FunctionCallDivCost},
1453 {
ISD::UDIV, MVT::v16i8, 16 * FunctionCallDivCost},
1454 {
ISD::SREM, MVT::v16i8, 16 * FunctionCallDivCost},
1455 {
ISD::UREM, MVT::v16i8, 16 * FunctionCallDivCost},
1459 if (
const auto *Entry =
CostTableLookup(CostTbl, ISDOpcode, LT.second))
1460 return LT.first * Entry->Cost;
1463 Opcode, Ty,
CostKind, Op1Info, Op2Info);
1480 auto LooksLikeAFreeShift = [&]() {
1481 if (ST->isThumb1Only() || Ty->isVectorTy())
1491 case Instruction::Add:
1492 case Instruction::Sub:
1493 case Instruction::And:
1494 case Instruction::Xor:
1495 case Instruction::Or:
1496 case Instruction::ICmp:
1502 if (LooksLikeAFreeShift())
1512 auto MulInDSPMLALPattern = [&](
const Instruction *
I,
unsigned Opcode,
1520 if (Opcode != Instruction::Mul)
1523 if (Ty->isVectorTy())
1526 auto ValueOpcodesEqual = [](
const Value *LHS,
const Value *RHS) ->
bool {
1530 auto IsExtInst = [](
const Value *V) ->
bool {
1533 auto IsExtensionFromHalf = [](
const Value *V) ->
bool {
1541 Value *Op0 = BinOp->getOperand(0);
1542 Value *Op1 = BinOp->getOperand(1);
1543 if (IsExtInst(Op0) && IsExtInst(Op1) && ValueOpcodesEqual(Op0, Op1)) {
1545 if (!
I->getType()->isIntegerTy(32) || !IsExtensionFromHalf(Op0) ||
1546 !IsExtensionFromHalf(Op1))
1550 for (
auto *U :
I->users())
1559 if (MulInDSPMLALPattern(CtxI, Opcode, Ty))
1565 if (ST->hasMVEIntegerOps() && Ty->isVectorTy())
1566 BaseCost = ST->getMVEVectorCostFactor(
CostKind);
1572 if (TLI->isOperationLegalOrCustomOrPromote(ISDOpcode, LT.second))
1573 return LT.first * BaseCost;
1577 unsigned Num = VTy->getNumElements();
1606 if (TLI->getValueType(
DL, Src,
true) == MVT::Other)
1610 if (ST->hasNEON() && Src->isVectorTy() && Alignment !=
Align(16) &&
1615 return LT.first * 4;
1621 ((Opcode == Instruction::Load &&
I->hasOneUse() &&
1626 Opcode == Instruction::Load
1627 ? (*
I->user_begin())->getType()
1631 return ST->getMVEVectorCostFactor(
CostKind);
1634 int BaseCost = ST->hasMVEIntegerOps() && Src->isVectorTy()
1635 ? ST->getMVEVectorCostFactor(
CostKind)
1644 switch (MICA.
getID()) {
1645 case Intrinsic::masked_scatter:
1646 case Intrinsic::masked_gather:
1648 case Intrinsic::masked_load:
1649 case Intrinsic::masked_store:
1658 unsigned IID = MICA.
getID();
1662 if (ST->hasMVEIntegerOps()) {
1663 if (IID == Intrinsic::masked_load &&
1665 return ST->getMVEVectorCostFactor(
CostKind);
1666 if (IID == Intrinsic::masked_store &&
1668 return ST->getMVEVectorCostFactor(
CostKind);
1680 bool UseMaskForCond,
bool UseMaskForGaps)
const {
1681 assert(Factor >= 2 &&
"Invalid interleave factor");
1685 bool EltIs64Bits =
DL.getTypeSizeInBits(VecTy->
getScalarType()) == 64;
1687 if (Factor <= TLI->getMaxSupportedInterleaveFactor() && !EltIs64Bits &&
1688 !UseMaskForCond && !UseMaskForGaps) {
1697 ST->hasMVEIntegerOps() ? ST->getMVEVectorCostFactor(
CostKind) : 1;
1698 if (NumElts % Factor == 0 &&
1699 TLI->isLegalInterleavedAccessType(Factor, SubVecTy, Alignment,
DL))
1700 return Factor * BaseCost * TLI->getNumInterleavedAccesses(SubVecTy,
DL);
1707 if (ST->hasMVEIntegerOps() && Factor == 2 && NumElts / Factor > 2 &&
1709 DL.getTypeSizeInBits(SubVecTy).getFixedValue() <= 64)
1710 return 2 * BaseCost;
1715 UseMaskForCond, UseMaskForGaps);
1737 unsigned NumElems = VTy->getNumElements();
1738 unsigned EltSize = VTy->getScalarSizeInBits();
1747 NumElems * LT.first * ST->getMVEVectorCostFactor(
CostKind);
1753 NumElems * LT.first + (VariableMask ? NumElems * 5 : 0) +
1759 if (EltSize < 8 || Alignment < EltSize / 8)
1762 unsigned ExtSize = EltSize;
1768 if ((
I->getOpcode() == Instruction::Load ||
1771 const User *Us = *
I->users().begin();
1776 if (((
TypeSize == 32 && (EltSize == 8 || EltSize == 16)) ||
1777 (
TypeSize == 16 && EltSize == 8)) &&
1785 if ((
I->getOpcode() == Instruction::Store ||
1789 unsigned TypeSize =
T->getOperand(0)->getType()->getScalarSizeInBits();
1790 if (((EltSize == 16 &&
TypeSize == 32) ||
1797 if (ExtSize * NumElems != 128 || NumElems < 4)
1806 if (ExtSize != 8 && ExtSize != 16)
1810 Ptr = BC->getOperand(0);
1812 if (
GEP->getNumOperands() != 2)
1814 unsigned Scale =
DL.getTypeAllocSize(
GEP->getResultElementType());
1816 if (Scale != 1 && Scale * 8 != ExtSize)
1820 if (ZExt->getOperand(0)->getType()->getScalarSizeInBits() <= ExtSize)
1830 std::optional<FastMathFlags> FMF,
1833 EVT ValVT = TLI->getValueType(
DL, ValTy);
1834 int ISD = TLI->InstructionOpcodeToISD(Opcode);
1841 ((EltSize == 32 && ST->hasVFP2Base()) ||
1842 (EltSize == 64 && ST->hasFP64()) ||
1843 (EltSize == 16 && ST->hasFullFP16()))) {
1845 unsigned VecLimit = ST->hasMVEFloatOps() ? 128 : (ST->hasNEON() ? 64 : -1);
1848 NumElts * EltSize > VecLimit) {
1859 VecCost += ST->getMVEVectorCostFactor(
CostKind) * 2;
1862 ExtractCost = NumElts / 2;
1864 return VecCost + ExtractCost +
1870 (EltSize == 64 || EltSize == 32 || EltSize == 16 || EltSize == 8)) {
1873 ST->hasMVEIntegerOps() ? 128 : (ST->hasNEON() ? 64 : -1);
1875 while (
isPowerOf2_32(NumElts) && NumElts * EltSize > VecLimit) {
1883 NumElts * EltSize == 64) {
1885 VecCost += ST->getMVEVectorCostFactor(
CostKind) +
1892 return VecCost + ExtractCost +
1909 return Entry->Cost * ST->getMVEVectorCostFactor(
CostKind) * LT.first;
1915 unsigned Opcode,
bool IsUnsigned,
Type *ResTy,
VectorType *ValTy,
1917 EVT ValVT = TLI->getValueType(
DL, ValTy);
1918 EVT ResVT = TLI->getValueType(
DL, ResTy);
1920 int ISD = TLI->InstructionOpcodeToISD(Opcode);
1935 ((LT.second == MVT::v16i8 && RevVTSize <= 32) ||
1936 (LT.second == MVT::v8i16 && RevVTSize <= 32) ||
1937 (LT.second == MVT::v4i32 && RevVTSize <= 64)))
1938 return ST->getMVEVectorCostFactor(
CostKind) * LT.first;
1952 if (RedOpcode != Instruction::Add)
1954 EVT ValVT = TLI->getValueType(
DL, ValTy);
1955 EVT ResVT = TLI->getValueType(
DL, ResTy);
1968 ((LT.second == MVT::v16i8 && RevVTSize <= 32) ||
1969 (LT.second == MVT::v8i16 && RevVTSize <= 64) ||
1970 (LT.second == MVT::v4i32 && RevVTSize <= 64)))
1971 return ST->getMVEVectorCostFactor(
CostKind) * LT.first;
1982 EVT ValVT = TLI->getValueType(
DL, Ty);
1987 if ((IID == Intrinsic::minnum || IID == Intrinsic::maxnum) &&
1993 unsigned VecLimit = ST->hasMVEFloatOps() ? 128 : (ST->hasNEON() ? 64 : -1);
1995 while (
isPowerOf2_32(NumElts) && NumElts * EltSize > VecLimit) {
2007 VecCost += ST->getMVEVectorCostFactor(
CostKind) * 2;
2013 {Ty->getElementType(), Ty->getElementType()},
2015 return VecCost + ExtractCost +
2019 if (IID == Intrinsic::smin || IID == Intrinsic::smax ||
2020 IID == Intrinsic::umin || IID == Intrinsic::umax) {
2032 return Entry->Cost * ST->getMVEVectorCostFactor(
CostKind) * LT.first;
2043 case Intrinsic::get_active_lane_mask:
2051 if (ST->hasMVEIntegerOps())
2054 case Intrinsic::sadd_sat:
2055 case Intrinsic::ssub_sat:
2056 case Intrinsic::uadd_sat:
2057 case Intrinsic::usub_sat: {
2058 bool IsAdd = (
Opc == Intrinsic::sadd_sat ||
Opc == Intrinsic::ssub_sat);
2059 bool IsSigned = (
Opc == Intrinsic::sadd_sat ||
Opc == Intrinsic::ssub_sat);
2063 if (IsSigned && ST->hasDSP() && ITy->getBitWidth() == 32)
2065 if (ST->hasDSP() && (ITy->getBitWidth() == 8 || ITy->getBitWidth() == 16))
2079 if (!ST->hasMVEIntegerOps())
2083 if (LT.second == MVT::v4i32 || LT.second == MVT::v8i16 ||
2084 LT.second == MVT::v16i8) {
2090 return LT.first * ST->getMVEVectorCostFactor(
CostKind) * Instrs;
2094 case Intrinsic::abs:
2095 case Intrinsic::smin:
2096 case Intrinsic::smax:
2097 case Intrinsic::umin:
2098 case Intrinsic::umax: {
2099 if (!ST->hasMVEIntegerOps())
2104 if (LT.second == MVT::v4i32 || LT.second == MVT::v8i16 ||
2105 LT.second == MVT::v16i8)
2106 return LT.first * ST->getMVEVectorCostFactor(
CostKind);
2109 case Intrinsic::minnum:
2110 case Intrinsic::maxnum: {
2111 if (!ST->hasMVEFloatOps())
2115 if (LT.second == MVT::v4f32 || LT.second == MVT::v8f16)
2116 return LT.first * ST->getMVEVectorCostFactor(
CostKind);
2119 case Intrinsic::fptosi_sat:
2120 case Intrinsic::fptoui_sat: {
2123 bool IsSigned =
Opc == Intrinsic::fptosi_sat;
2127 if ((ST->hasVFP2Base() && LT.second == MVT::f32 && MTy == MVT::i32) ||
2128 (ST->hasFP64() && LT.second == MVT::f64 && MTy == MVT::i32) ||
2129 (ST->hasFullFP16() && LT.second == MVT::f16 && MTy == MVT::i32))
2133 if (ST->hasMVEFloatOps() &&
2134 (LT.second == MVT::v4f32 || LT.second == MVT::v8f16) &&
2136 return LT.first * ST->getMVEVectorCostFactor(
CostKind);
2139 if (((ST->hasVFP2Base() && LT.second == MVT::f32) ||
2140 (ST->hasFP64() && LT.second == MVT::f64) ||
2141 (ST->hasFullFP16() && LT.second == MVT::f16) ||
2142 (ST->hasMVEFloatOps() &&
2143 (LT.second == MVT::v4f32 || LT.second == MVT::v8f16))) &&
2146 LT.second.getScalarSizeInBits());
2148 LT.second.isVector() ? ST->getMVEVectorCostFactor(
CostKind) : 1;
2151 LegalTy, {LegalTy, LegalTy});
2155 LegalTy, {LegalTy, LegalTy});
2157 return LT.first *
Cost;
2185 if (!
F->isIntrinsic())
2189 if (
F->getName().starts_with(
"llvm.arm"))
2192 switch (
F->getIntrinsicID()) {
2194 case Intrinsic::powi:
2195 case Intrinsic::sin:
2196 case Intrinsic::cos:
2197 case Intrinsic::sincos:
2198 case Intrinsic::pow:
2199 case Intrinsic::log:
2200 case Intrinsic::log10:
2201 case Intrinsic::log2:
2202 case Intrinsic::exp:
2203 case Intrinsic::exp2:
2205 case Intrinsic::sqrt:
2206 case Intrinsic::fabs:
2207 case Intrinsic::copysign:
2208 case Intrinsic::floor:
2209 case Intrinsic::ceil:
2210 case Intrinsic::trunc:
2211 case Intrinsic::rint:
2212 case Intrinsic::nearbyint:
2213 case Intrinsic::round:
2214 case Intrinsic::canonicalize:
2215 case Intrinsic::lround:
2216 case Intrinsic::llround:
2217 case Intrinsic::lrint:
2218 case Intrinsic::llrint:
2219 if (
F->getReturnType()->isDoubleTy() && !ST->hasFP64())
2221 if (
F->getReturnType()->isHalfTy() && !ST->hasFullFP16())
2226 return !ST->hasFPARMv8Base() && !ST->hasVFP2Base();
2227 case Intrinsic::masked_store:
2228 case Intrinsic::masked_load:
2229 case Intrinsic::masked_gather:
2230 case Intrinsic::masked_scatter:
2231 return !ST->hasMVEIntegerOps();
2232 case Intrinsic::sadd_with_overflow:
2233 case Intrinsic::uadd_with_overflow:
2234 case Intrinsic::ssub_with_overflow:
2235 case Intrinsic::usub_with_overflow:
2236 case Intrinsic::sadd_sat:
2237 case Intrinsic::uadd_sat:
2238 case Intrinsic::ssub_sat:
2239 case Intrinsic::usub_sat:
2247 unsigned ISD = TLI->InstructionOpcodeToISD(
I.getOpcode());
2248 EVT VT = TLI->getValueType(
DL,
I.getType(),
true);
2256 switch(
II->getIntrinsicID()) {
2257 case Intrinsic::memcpy:
2258 case Intrinsic::memset:
2259 case Intrinsic::memmove:
2271 switch (
I.getOpcode()) {
2274 case Instruction::FPToSI:
2275 case Instruction::FPToUI:
2276 case Instruction::SIToFP:
2277 case Instruction::UIToFP:
2278 case Instruction::FPTrunc:
2279 case Instruction::FPExt:
2280 return !ST->hasFPARMv8Base();
2308 if (TLI->useSoftFloat()) {
2309 switch (
I.getOpcode()) {
2312 case Instruction::Alloca:
2313 case Instruction::Load:
2314 case Instruction::Store:
2315 case Instruction::Select:
2316 case Instruction::PHI:
2323 if (
I.getType()->isDoubleTy() && !ST->hasFP64())
2327 if (
I.getType()->isHalfTy() && !ST->hasFullFP16())
2355 const SCEV *TripCountSCEV =
2361 LLVM_DEBUG(
dbgs() <<
"ARMHWLoops: Trip count does not fit into 32bits\n");
2370 switch (
Call->getIntrinsicID()) {
2373 case Intrinsic::start_loop_iterations:
2374 case Intrinsic::test_start_loop_iterations:
2375 case Intrinsic::loop_decrement:
2376 case Intrinsic::loop_decrement_reg:
2386 bool IsTailPredLoop =
false;
2387 auto ScanLoop = [&](
Loop *L) {
2388 for (
auto *BB : L->getBlocks()) {
2389 for (
auto &
I : *BB) {
2397 II->getIntrinsicID() == Intrinsic::get_active_lane_mask ||
2398 II->getIntrinsicID() == Intrinsic::arm_mve_vctp8 ||
2399 II->getIntrinsicID() == Intrinsic::arm_mve_vctp16 ||
2400 II->getIntrinsicID() == Intrinsic::arm_mve_vctp32 ||
2401 II->getIntrinsicID() == Intrinsic::arm_mve_vctp64;
2408 for (
auto *Inner : *L)
2409 if (!ScanLoop(Inner))
2441 if ((
II->getIntrinsicID() == Intrinsic::smin ||
2442 II->getIntrinsicID() == Intrinsic::smax ||
2443 II->getIntrinsicID() == Intrinsic::umin ||
2444 II->getIntrinsicID() == Intrinsic::umax) &&
2483 LLVM_DEBUG(
dbgs() <<
"Tail-predication: checking allowed instructions\n");
2494 bool ReductionsDisabled =
2498 for (
auto *
I : LiveOuts) {
2499 if (!
I->getType()->isIntegerTy() && !
I->getType()->isFloatTy() &&
2500 !
I->getType()->isHalfTy()) {
2501 LLVM_DEBUG(
dbgs() <<
"Don't tail-predicate loop with non-integer/float "
2502 "live-out value\n");
2505 if (ReductionsDisabled) {
2525 if (
T->getScalarSizeInBits() > 32) {
2532 int64_t NextStride =
2534 if (NextStride == 1) {
2539 }
else if (NextStride == -1 ||
2543 <<
"Consecutive strides of 2 found, vld2/vstr2 can't "
2544 "be tail-predicated\n.");
2554 const SCEV *Step = AR->getStepRecurrence(*PSE.
getSE());
2560 "tail-predicate\n.");
2566 LLVM_DEBUG(
dbgs() <<
"tail-predication: all instructions allowed!\n");
2579 if (!ST->hasMVEIntegerOps())
2586 if (L->getNumBlocks() > 1) {
2587 LLVM_DEBUG(
dbgs() <<
"preferTailFoldingOverEpilogue: not a single block "
2592 assert(L->isInnermost() &&
2593 "preferTailFoldingOverEpilogue: inner-loop expected");
2598 LLVM_DEBUG(
dbgs() <<
"preferTailFoldingOverEpilogue: hardware-loop is not "
2609 LLVM_DEBUG(
dbgs() <<
"preferTailFoldingOverEpilogue: hardware-loop is not "
2616 LLVM_DEBUG(
dbgs() <<
"preferTailFoldingOverEpilogue: hardware-loop is not "
2643 return isa<IntrinsicInst>(I) &&
2644 cast<IntrinsicInst>(I).getIntrinsicID() ==
2645 Intrinsic::get_active_lane_mask;
2649 if (!ST->isMClass())
2655 if (L->getHeader()->getParent()->hasOptSize())
2659 L->getExitingBlocks(ExitingBlocks);
2661 <<
"Blocks: " << L->getNumBlocks() <<
"\n"
2662 <<
"Exit blocks: " << ExitingBlocks.
size() <<
"\n");
2666 if (ExitingBlocks.
size() > 2)
2671 if (ST->hasBranchPredictor() && L->getNumBlocks() > 4)
2681 for (
auto *BB : L->getBlocks()) {
2682 for (
auto &
I : *BB) {
2685 if (
I.getType()->isVectorTy())
2708 unsigned UnrollCount = 4;
2709 if (ST->isThumb1Only()) {
2710 unsigned ExitingValues = 0;
2712 L->getExitBlocks(ExitBlocks);
2713 for (
auto *Exit : ExitBlocks) {
2716 unsigned LiveOuts =
count_if(Exit->phis(), [](
auto &PH) {
2717 return PH.getNumOperands() != 1 ||
2718 !isa<GetElementPtrInst>(PH.getOperand(0));
2720 ExitingValues = ExitingValues < LiveOuts ? LiveOuts : ExitingValues;
2723 UnrollCount /= ExitingValues;
2724 if (UnrollCount <= 1)
2741 auto *Outer = L->getOutermostLoop();
2742 if ((L != Outer && Outer != L->getParentLoop()) ||
2750 LLVM_DEBUG(
dbgs() <<
"Default Runtime Unroll Count: " << UnrollCount <<
"\n");
2771 if (!ST->hasMVEIntegerOps())
2774 unsigned ScalarBits = Ty->getScalarSizeInBits();
2777 return ScalarBits <= 64;
2784 if (!ST->hasMVEIntegerOps())
2791 bool HasBaseReg, int64_t Scale,
2792 unsigned AddrSpace)
const {
2801 return AM.
Scale < 0 ? 1 : 0;
2811 return ST->hasMVEIntegerOps();
2819 return ST->isThumb2() || ST->hasV8MBaselineOps();
2823 return ST->hasARMOps();
2833 return Ext->getType()->getScalarSizeInBits() ==
2834 2 * Ext->getOperand(0)->getType()->getScalarSizeInBits();
2853 if (!
I->getType()->isVectorTy())
2856 if (ST->hasNEON()) {
2857 switch (
I->getOpcode()) {
2858 case Instruction::Sub:
2859 case Instruction::Add: {
2862 Ops.push_back(&
I->getOperandUse(0));
2863 Ops.push_back(&
I->getOperandUse(1));
2871 if (!ST->hasMVEIntegerOps())
2875 if (!
I->hasOneUse())
2878 return Sub->getOpcode() == Instruction::FSub &&
Sub->getOperand(1) ==
I;
2888 switch (
I->getOpcode()) {
2889 case Instruction::Add:
2890 case Instruction::Mul:
2891 case Instruction::FAdd:
2892 case Instruction::ICmp:
2893 case Instruction::FCmp:
2895 case Instruction::FMul:
2896 return !IsFMSMul(
I);
2897 case Instruction::Sub:
2898 case Instruction::FSub:
2899 case Instruction::Shl:
2900 case Instruction::LShr:
2901 case Instruction::AShr:
2902 return Operand == 1;
2903 case Instruction::Call:
2905 switch (
II->getIntrinsicID()) {
2906 case Intrinsic::fma:
2908 case Intrinsic::sadd_sat:
2909 case Intrinsic::uadd_sat:
2910 case Intrinsic::arm_mve_add_predicated:
2911 case Intrinsic::arm_mve_mul_predicated:
2912 case Intrinsic::arm_mve_qadd_predicated:
2913 case Intrinsic::arm_mve_vhadd:
2914 case Intrinsic::arm_mve_hadd_predicated:
2915 case Intrinsic::arm_mve_vqdmull:
2916 case Intrinsic::arm_mve_vqdmull_predicated:
2917 case Intrinsic::arm_mve_vqdmulh:
2918 case Intrinsic::arm_mve_qdmulh_predicated:
2919 case Intrinsic::arm_mve_vqrdmulh:
2920 case Intrinsic::arm_mve_qrdmulh_predicated:
2921 case Intrinsic::arm_mve_fma_predicated:
2923 case Intrinsic::ssub_sat:
2924 case Intrinsic::usub_sat:
2925 case Intrinsic::arm_mve_sub_predicated:
2926 case Intrinsic::arm_mve_qsub_predicated:
2927 case Intrinsic::arm_mve_hsub_predicated:
2928 case Intrinsic::arm_mve_vhsub:
2929 return Operand == 1;
2940 for (
auto OpIdx :
enumerate(
I->operands())) {
2947 if (Shuffle->
getOpcode() == Instruction::BitCast)
2954 if (!IsSinker(
I, OpIdx.index()))
2959 for (
Use &U :
Op->uses()) {
2961 if (!IsSinker(Insn, U.getOperandNo()))
2967 Ops.push_back(&
Op->getOperandUse(0));
2968 Ops.push_back(&OpIdx.value());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
cl::opt< unsigned > MVEMaxSupportedInterleaveFactor("mve-max-interleave-factor", cl::Hidden, cl::desc("Maximum interleave factor for MVE VLDn to generate."), cl::init(2))
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
Cost tables and simple lookup functions.
This file provides the interface for the instcombine pass implementation.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file defines the LoopVectorizationLegality class.
static const Function * getCalledFunction(const Value *V)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
This file defines the SmallVector class.
Class for arbitrary precision integers.
unsigned getBitWidth() const
Return the number of bits in the APInt.
static LLVM_ABI APInt getSplat(unsigned NewLen, const APInt &V)
Return a value containing V broadcasted over NewLen bits.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
InstructionCost getGatherScatterOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getMaskedMemoryOpCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
InstructionCost getMemcpyCost(const Instruction *I) const override
bool maybeLoweredToCall(Instruction &I) const
bool preferInLoopReduction(RecurKind Kind, Type *Ty) const override
InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
InstructionCost getMulAccReductionCost(bool IsUnsigned, unsigned RedOpcode, Type *ResTy, VectorType *ValTy, TTI::TargetCostKind CostKind) const override
InstructionCost getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const override
InstructionCost getIntImmCost(const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind) const override
bool hasArmWideBranch(bool Thumb) const override
bool shouldConsiderVectorizationRegPressure() const override
bool preferTailFoldingOverEpilogue(TailFoldingInfo *TFI) const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
int getNumMemOps(const IntrinsicInst *I) const
Given a memcpy/memset/memmove instruction, return the number of memory operations performed,...
InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
InstructionCost getIntImmCodeSizeCost(unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty) const override
bool isLoweredToCall(const Function *F) const override
InstructionCost getExtendedReductionCost(unsigned Opcode, bool IsUnsigned, Type *ResTy, VectorType *ValTy, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
bool isProfitableToSinkOperands(Instruction *I, SmallVectorImpl< Use * > &Ops) const override
Check if sinking I's operands to I's basic block is profitable, because the operands can be folded in...
bool isLegalMaskedStore(Type *DataTy, Align Alignment, unsigned AddressSpace, TTI::MaskKind MaskKind=TTI::MaskKind::VariableOrConstantMask) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr) const override
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *ValTy, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
std::optional< Value * > simplifyDemandedVectorEltsIntrinsic(InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts, APInt &UndefElts2, APInt &UndefElts3, std::function< void(Instruction *, unsigned, APInt, APInt &)> SimplifyAndSetOp) const override
bool isLegalMaskedLoad(Type *DataTy, Align Alignment, unsigned AddressSpace, TTI::MaskKind MaskKind=TTI::MaskKind::VariableOrConstantMask) const override
TailFoldingStyle getPreferredTailFoldingStyle() const override
InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm, Type *Ty, TTI::TargetCostKind CostKind, Instruction *Inst=nullptr) const override
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const override
std::optional< Instruction * > instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const override
void getPeelingPreferences(Loop *L, ScalarEvolution &SE, TTI::PeelingPreferences &PP) const override
InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const override
TTI::AddressingModeKind getPreferredAddressingMode(const Loop *L, ScalarEvolution *SE) const override
InstructionCost getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const override
bool preferPredicatedReductionSelect() const override
bool isLegalMaskedGather(Type *Ty, Align Alignment) const override
InstructionCost getAddressComputationCost(Type *Ty, ScalarEvolution *SE, const SCEV *Ptr, TTI::TargetCostKind CostKind) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
bool isProfitableLSRChainElement(Instruction *I) const override
bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE, AssumptionCache &AC, TargetLibraryInfo *LibInfo, HardwareLoopInfo &HWLoopInfo) const override
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, TTI::UnrollingPreferences &UP, OptimizationRemarkEmitter *ORE) const override
InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, StackOffset BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace) const override
getScalingFactorCost - Return the cost of the scaling used in addressing mode represented by AM.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
A cache of @llvm.assume calls within a function.
static LLVM_ABI Attribute getWithAlignment(LLVMContext &Context, Align Alignment)
Return a uniquified Attribute object that has the specific alignment set.
LLVM Basic Block Representation.
InstructionCost getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef< unsigned > Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, bool UseMaskForCond=false, bool UseMaskForGaps=false) const override
InstructionCost getMinMaxReductionCost(Intrinsic::ID IID, VectorType *Ty, FastMathFlags FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
TTI::ShuffleKind improveShuffleKindFromMask(TTI::ShuffleKind Kind, ArrayRef< int > Mask, VectorType *SrcTy, int &Index, VectorType *&SubTy) const
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace, Instruction *I=nullptr, int64_t ScalableOffset=0) const override
InstructionCost getScalarizationOverhead(VectorType *InTy, const APInt &DemandedElts, bool Insert, bool Extract, TTI::TargetCostKind CostKind, bool ForPoisonSrc=true, ArrayRef< Value * > VL={}, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getArithmeticReductionCost(unsigned Opcode, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy, CmpInst::Predicate VecPred, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Op1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Op2Info={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
InstructionCost getArithmeticInstrCost(unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind, TTI::OperandValueInfo Opd1Info={TTI::OK_AnyValue, TTI::OP_None}, TTI::OperandValueInfo Opd2Info={TTI::OK_AnyValue, TTI::OP_None}, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr) const override
InstructionCost getCallInstrCost(Function *F, Type *RetTy, ArrayRef< Type * > Tys, TTI::TargetCostKind CostKind) const override
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE, TTI::UnrollingPreferences &UP, OptimizationRemarkEmitter *ORE) const override
void getPeelingPreferences(Loop *L, ScalarEvolution &SE, TTI::PeelingPreferences &PP) const override
InstructionCost getMulAccReductionCost(bool IsUnsigned, unsigned RedOpcode, Type *ResTy, VectorType *Ty, TTI::TargetCostKind CostKind) const override
InstructionCost getShuffleCost(TTI::ShuffleKind Kind, VectorType *DstTy, VectorType *SrcTy, TTI::TargetCostKind CostKind, ArrayRef< int > Mask, int Index, VectorType *SubTp, ArrayRef< const Value * > Args={}, const Instruction *CtxI=nullptr, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src, TTI::CastContextHint CCH, TTI::TargetCostKind CostKind, const Instruction *I=nullptr) const override
std::pair< InstructionCost, MVT > getTypeLegalizationCost(Type *Ty) const
InstructionCost getVectorInstrCost(unsigned Opcode, Type *Val, TTI::TargetCostKind CostKind, unsigned Index, const Value *Op0, const Value *Op1, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None) const override
InstructionCost getExtendedReductionCost(unsigned Opcode, bool IsUnsigned, Type *ResTy, VectorType *Ty, std::optional< FastMathFlags > FMF, TTI::TargetCostKind CostKind) const override
InstructionCost getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA, TTI::TargetCostKind CostKind) const override
InstructionCost getAddressComputationCost(Type *PtrTy, ScalarEvolution *, const SCEV *, TTI::TargetCostKind) const override
InstructionCost getMemIntrinsicInstrCost(const MemIntrinsicCostAttributes &MICA, TTI::TargetCostKind CostKind) const override
InstructionCost getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, TTI::OperandValueInfo OpInfo={TTI::OK_AnyValue, TTI::OP_None}, const Instruction *I=nullptr) const override
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLE
signed less or equal
@ ICMP_SGT
signed greater than
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
This is the shared class of boolean and integer constants.
const APInt & getValue() const
Return the constant as an APInt value reference.
This class represents a range of values.
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Convenience struct for specifying and reasoning about fast-math flags.
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
LLVM_ABI Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
ConstantInt * getTrue()
Get the constant value for i1 true.
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
The core instruction combiner logic.
const DataLayout & getDataLayout() const
virtual Instruction * eraseInstFromFunction(Instruction &I)=0
Combiner aware instruction erasure.
DominatorTree & getDominatorTree() const
Instruction * replaceInstUsesWith(Instruction &I, Value *V)
A combiner-aware RAUW-like routine.
virtual bool SimplifyDemandedBits(Instruction *I, unsigned OpNo, const APInt &DemandedMask, KnownBits &Known, const SimplifyQuery &Q, unsigned Depth=0)=0
IRBuilder< TargetFolder, IRBuilderInstCombineInserter > BuilderTy
An IRBuilder that automatically inserts new instructions into the worklist.
Instruction * replaceOperand(Instruction &I, unsigned OpNum, Value *V)
Replace operand of instruction and add old operand to the worklist.
AssumptionCache & getAssumptionCache() const
static InstructionCost getInvalid(CostType Val=0)
Instruction * user_back()
user_iterator user_begin()
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
const SmallVectorImpl< Type * > & getArgTypes() const
Type * getReturnType() const
Intrinsic::ID getID() const
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Drive the analysis of memory accesses in the loop.
const PredicatedScalarEvolution & getPSE() const
Used to add runtime SCEV checks.
LoopVectorizationLegality checks if it is legal to vectorize a loop, and to what vectorization factor...
LoopInfo * getLoopInfo() const
DominatorTree * getDominatorTree() const
AssumptionCache * getAssumptionCache() const
const LoopAccessInfo * getLAI() const
ScalarEvolution * getScalarEvolution() const
Represents a single loop in the control flow graph.
Information for memory intrinsic cost model.
Align getAlignment() const
unsigned getAddressSpace() const
Type * getDataType() const
const Value * getPointer() const
bool getVariableMask() const
Intrinsic::ID getID() const
const Instruction * getInst() const
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
ScalarEvolution * getSE() const
Returns the ScalarEvolution analysis used.
This class represents an analyzed expression in the program.
Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
LLVM_ABI const SCEV * getBackedgeTakenCount(const Loop *L, ExitCountKind Kind=Exact)
If the specified loop has a predictable backedge-taken count, return it, otherwise return a SCEVCould...
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
LLVM_ABI bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
LLVM_ABI SCEVUse getAddExpr(SmallVectorImpl< SCEVUse > &Ops, SCEVFlagsPair Flags={}, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
LLVM_ABI bool hasLoopInvariantBackedgeTakenCount(const Loop *L)
Return true if the specified loop has an analyzable loop-invariant backedge-taken count.
APInt getUnsignedRangeMax(const SCEV *S)
Determine the max of the unsigned range for a particular SCEV.
static LLVM_ABI bool isDeInterleaveMaskOfFactor(ArrayRef< int > Mask, unsigned Factor, unsigned &Index)
Check if the mask is a DE-interleave mask of the given factor Factor like: <Index,...
static LLVM_ABI bool isInterleaveMask(ArrayRef< int > Mask, unsigned Factor, unsigned NumInputElts, SmallVectorImpl< unsigned > &StartIndexes)
Return true if the mask interleaves one or more input vectors together.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
static StackOffset getScalable(int64_t Scalable)
static StackOffset getFixed(int64_t Fixed)
Provides information about what library functions are available for the current target.
This class represents a truncation of integer types.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
LLVM_ABI bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
bool isIntegerTy() const
True if this is an instance of IntegerType.
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
A Use represents the edge between a Value definition and its users.
const Use & getOperandUse(unsigned i) const
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI bool hasNUses(unsigned N) const
Return true if this Value has exactly N uses.
Base class of all SIMD vector types.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Type * getElementType() const
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
bool isThumbImmShiftedVal(unsigned V)
isThumbImmShiftedVal - Return true if the specified value can be obtained by left shifting a 8-bit im...
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
ISD namespace - This namespace contains an enum which represents all of the SelectionDAG node types a...
@ ADD
Simple integer binary arithmetic operators.
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ FADD
Simple binary floating point operators.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ SIGN_EXTEND
Conversion operators.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_Constant()
Match an arbitrary Constant and ignore it.
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
match_combine_or< CastInst_match< OpTy, ZExtInst >, CastInst_match< OpTy, SExtInst > > m_ZExtOrSExt(const OpTy &Op)
FNeg_match< OpTy > m_FNeg(const OpTy &X)
Match 'fneg X' as 'fsub -0.0, X'.
auto m_Undef()
Match an arbitrary undef constant.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
@ ForceEnabledNoReductions
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool isVTRN_v_undef_Mask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
isVTRN_v_undef_Mask - Special case of isVTRNMask for canonical form of "vector_shuffle v,...
const CostTblEntryT< CostType > * CostTableLookup(ArrayRef< CostTblEntryT< CostType > > Tbl, int ISD, MVT Ty)
Find in cost table.
LLVM_ABI bool getBooleanLoopAttribute(const Loop *TheLoop, StringRef Name)
Returns true if Name is applied to TheLoop and enabled.
bool isVZIPMask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Runtime
Detect stack use after return if not disabled runtime with (ASAN_OPTIONS=detect_stack_use_after_retur...
const Value * getLoadStorePointerOperand(const Value *V)
A helper function that returns the pointer operand of a load or store instruction.
LLVM_ABI std::optional< int64_t > getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr, const Loop *Lp, const DominatorTree &DT, const SymbolicStrideMap &StridesMap=SymbolicStrideMap(), bool ShouldCheckWrap=true, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
If the pointer has a constant stride return it in units of the access type size.
auto dyn_cast_or_null(const Y &Val)
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 SmallVector< Instruction *, 8 > findDefsUsedOutsideOfLoop(Loop *L)
Returns the instructions that use values defined in the loop.
SelectPatternFlavor
Specific patterns of select instructions we can match.
@ SPF_ABS
Floating point maxnum.
@ SPF_FMAXNUM
Floating point minnum.
@ SPF_UMIN
Signed minimum.
@ SPF_UMAX
Signed maximum.
@ SPF_SMAX
Unsigned minimum.
@ SPF_FMINNUM
Unsigned maximum.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp=nullptr, unsigned Depth=0)
Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind and providing the out param...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isVUZPMask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
bool isVTRNMask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
RecurKind
These are the kinds of recurrences that we support.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
bool isVUZP_v_undef_Mask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
isVUZP_v_undef_Mask - Special case of isVUZPMask for canonical form of "vector_shuffle v,...
TypeConversionCostTblEntryT< uint16_t > TypeConversionCostTblEntry
CostTblEntryT< uint16_t > CostTblEntry
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
Type * getLoadStoreType(const Value *I)
A helper function that returns the type of a load or store instruction.
bool isVREVMask(ArrayRef< int > M, EVT VT, unsigned BlockSize)
isVREVMask - Check if a vector shuffle corresponds to a VREV instruction with the specified blocksize...
@ DataWithoutLaneMask
Same as Data, but avoids using the get.active.lane.mask intrinsic to calculate the mask and instead i...
@ Data
Use predicate only to mask operations on data in the loop.
const TypeConversionCostTblEntryT< CostType > * ConvertCostTableLookup(ArrayRef< TypeConversionCostTblEntryT< CostType > > Tbl, int ISD, MVT Dst, MVT Src)
Find in type conversion cost table.
bool isVZIP_v_undef_Mask(ArrayRef< int > M, EVT VT, unsigned &WhichResult)
isVZIP_v_undef_Mask - Special case of isVZIPMask for canonical form of "vector_shuffle v,...
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool isInteger() const
Return true if this is an integer or a vector integer type.
Attributes of a target dependent hardware loop.
LLVM_ABI bool canAnalyze(LoopInfo &LI)
LLVM_ABI bool isHardwareLoopCandidate(ScalarEvolution &SE, LoopInfo &LI, DominatorTree &DT, bool ForceNestedLoop=false, bool ForceHardwareLoopPHI=false)
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
static MemOp Set(uint64_t Size, bool DstAlignCanChange, Align DstAlign, bool IsZeroMemset, bool IsVolatile)
static MemOp Move(uint64_t Size, bool DstAlignCanChange, Align DstAlign, Align SrcAlign, bool IsVolatile)
SelectPatternFlavor Flavor
LoopVectorizationLegality * LVL
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...